From: Kumar Gala Date: Tue, 20 Nov 2007 03:35:29 +0000 (-0600) Subject: [POWERPC] Emulate isel (Integer Select) instruction X-Git-Tag: v2.6.25-rc1~1131^2~303 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c1469f13de275fc92b051328ea5764a32a5a43c9;p=linux-2.6 [POWERPC] Emulate isel (Integer Select) instruction isel (Integer Select) is a new user space instruction in the PowerISA 2.04 spec. Not all processors implement it so lets emulate to ensure code built with isel will run everywhere. Signed-off-by: Kumar Gala --- diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 59c464e26f..cad64840fc 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -622,6 +622,9 @@ static void parse_fpe(struct pt_regs *regs) #define INST_POPCNTB 0x7c0000f4 #define INST_POPCNTB_MASK 0xfc0007fe +#define INST_ISEL 0x7c00001e +#define INST_ISEL_MASK 0xfc00003e + static int emulate_string_inst(struct pt_regs *regs, u32 instword) { u8 rT = (instword >> 21) & 0x1f; @@ -707,6 +710,23 @@ static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword) return 0; } +static int emulate_isel(struct pt_regs *regs, u32 instword) +{ + u8 rT = (instword >> 21) & 0x1f; + u8 rA = (instword >> 16) & 0x1f; + u8 rB = (instword >> 11) & 0x1f; + u8 BC = (instword >> 6) & 0x1f; + u8 bit; + unsigned long tmp; + + tmp = (rA == 0) ? 0 : regs->gpr[rA]; + bit = (regs->ccr >> (31 - BC)) & 0x1; + + regs->gpr[rT] = bit ? tmp : regs->gpr[rB]; + + return 0; +} + static int emulate_instruction(struct pt_regs *regs) { u32 instword; @@ -749,6 +769,11 @@ static int emulate_instruction(struct pt_regs *regs) return emulate_popcntb_inst(regs, instword); } + /* Emulate isel (Integer Select) instruction */ + if ((instword & INST_ISEL_MASK) == INST_ISEL) { + return emulate_isel(regs, instword); + } + return -EINVAL; }