powerpc: sstep: Add support for maddhd, maddhdu, maddld instructions
This adds emulation support for the following integer instructions: * Multiply-Add High Doubleword (maddhd) * Multiply-Add High Doubleword Unsigned (maddhdu) * Multiply-Add Low Doubleword (maddld) As suggested by Michael, this uses a raw .long for specifying the instruction word when using inline assembly to retain compatibility with older binutils. Signed-off-by: Sandipan Das <sandipan@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
		
							parent
							
								
									d608898abc
								
							
						
					
					
						commit
						930d6288a2
					
				| @ -335,6 +335,9 @@ | ||||
| #define PPC_INST_MULLW			0x7c0001d6 | ||||
| #define PPC_INST_MULHWU			0x7c000016 | ||||
| #define PPC_INST_MULLI			0x1c000000 | ||||
| #define PPC_INST_MADDHD			0x10000030 | ||||
| #define PPC_INST_MADDHDU		0x10000031 | ||||
| #define PPC_INST_MADDLD			0x10000033 | ||||
| #define PPC_INST_DIVWU			0x7c000396 | ||||
| #define PPC_INST_DIVD			0x7c0003d2 | ||||
| #define PPC_INST_RLWINM			0x54000000 | ||||
| @ -377,6 +380,7 @@ | ||||
| /* macros to insert fields into opcodes */ | ||||
| #define ___PPC_RA(a)	(((a) & 0x1f) << 16) | ||||
| #define ___PPC_RB(b)	(((b) & 0x1f) << 11) | ||||
| #define ___PPC_RC(c)	(((c) & 0x1f) << 6) | ||||
| #define ___PPC_RS(s)	(((s) & 0x1f) << 21) | ||||
| #define ___PPC_RT(t)	___PPC_RS(t) | ||||
| #define ___PPC_R(r)	(((r) & 0x1) << 16) | ||||
| @ -396,7 +400,7 @@ | ||||
| #define __PPC_WS(w)	(((w) & 0x1f) << 11) | ||||
| #define __PPC_SH(s)	__PPC_WS(s) | ||||
| #define __PPC_SH64(s)	(__PPC_SH(s) | (((s) & 0x20) >> 4)) | ||||
| #define __PPC_MB(s)	(((s) & 0x1f) << 6) | ||||
| #define __PPC_MB(s)	___PPC_RC(s) | ||||
| #define __PPC_ME(s)	(((s) & 0x1f) << 1) | ||||
| #define __PPC_MB64(s)	(__PPC_MB(s) | ((s) & 0x20)) | ||||
| #define __PPC_ME64(s)	__PPC_MB64(s) | ||||
| @ -438,6 +442,15 @@ | ||||
| #define PPC_STQCX(t, a, b)	stringify_in_c(.long PPC_INST_STQCX | \ | ||||
| 					___PPC_RT(t) | ___PPC_RA(a) | \ | ||||
| 					___PPC_RB(b)) | ||||
| #define PPC_MADDHD(t, a, b, c)	stringify_in_c(.long PPC_INST_MADDHD | \ | ||||
| 					___PPC_RT(t) | ___PPC_RA(a)  | \ | ||||
| 					___PPC_RB(b) | ___PPC_RC(c)) | ||||
| #define PPC_MADDHDU(t, a, b, c)	stringify_in_c(.long PPC_INST_MADDHDU | \ | ||||
| 					___PPC_RT(t) | ___PPC_RA(a)   | \ | ||||
| 					___PPC_RB(b) | ___PPC_RC(c)) | ||||
| #define PPC_MADDLD(t, a, b, c)	stringify_in_c(.long PPC_INST_MADDLD | \ | ||||
| 					___PPC_RT(t) | ___PPC_RA(a)  | \ | ||||
| 					___PPC_RB(b) | ___PPC_RC(c)) | ||||
| #define PPC_MSGSND(b)		stringify_in_c(.long PPC_INST_MSGSND | \ | ||||
| 					___PPC_RB(b)) | ||||
| #define PPC_MSGSYNC		stringify_in_c(.long PPC_INST_MSGSYNC) | ||||
|  | ||||
| @ -1169,7 +1169,7 @@ static nokprobe_inline int trap_compare(long v1, long v2) | ||||
| int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, | ||||
| 		  unsigned int instr) | ||||
| { | ||||
| 	unsigned int opcode, ra, rb, rd, spr, u; | ||||
| 	unsigned int opcode, ra, rb, rc, rd, spr, u; | ||||
| 	unsigned long int imm; | ||||
| 	unsigned long int val, val2; | ||||
| 	unsigned int mb, me, sh; | ||||
| @ -1292,6 +1292,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, | ||||
| 	rd = (instr >> 21) & 0x1f; | ||||
| 	ra = (instr >> 16) & 0x1f; | ||||
| 	rb = (instr >> 11) & 0x1f; | ||||
| 	rc = (instr >> 6) & 0x1f; | ||||
| 
 | ||||
| 	switch (opcode) { | ||||
| #ifdef __powerpc64__ | ||||
| @ -1305,6 +1306,38 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, | ||||
| 			goto trap; | ||||
| 		return 1; | ||||
| 
 | ||||
| #ifdef __powerpc64__ | ||||
| 	case 4: | ||||
| 		if (!cpu_has_feature(CPU_FTR_ARCH_300)) | ||||
| 			return -1; | ||||
| 
 | ||||
| 		switch (instr & 0x3f) { | ||||
| 		case 48:	/* maddhd */ | ||||
| 			asm volatile(PPC_MADDHD(%0, %1, %2, %3) : | ||||
| 				     "=r" (op->val) : "r" (regs->gpr[ra]), | ||||
| 				     "r" (regs->gpr[rb]), "r" (regs->gpr[rc])); | ||||
| 			goto compute_done; | ||||
| 
 | ||||
| 		case 49:	/* maddhdu */ | ||||
| 			asm volatile(PPC_MADDHDU(%0, %1, %2, %3) : | ||||
| 				     "=r" (op->val) : "r" (regs->gpr[ra]), | ||||
| 				     "r" (regs->gpr[rb]), "r" (regs->gpr[rc])); | ||||
| 			goto compute_done; | ||||
| 
 | ||||
| 		case 51:	/* maddld */ | ||||
| 			asm volatile(PPC_MADDLD(%0, %1, %2, %3) : | ||||
| 				     "=r" (op->val) : "r" (regs->gpr[ra]), | ||||
| 				     "r" (regs->gpr[rb]), "r" (regs->gpr[rc])); | ||||
| 			goto compute_done; | ||||
| 		} | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * There are other instructions from ISA 3.0 with the same | ||||
| 		 * primary opcode which do not have emulation support yet. | ||||
| 		 */ | ||||
| 		return -1; | ||||
| #endif | ||||
| 
 | ||||
| 	case 7:		/* mulli */ | ||||
| 		op->val = regs->gpr[ra] * (short) instr; | ||||
| 		goto compute_done; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user