From 905ec75e3203e474481797ee469f54d663e48e29 Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Tue, 30 Nov 2021 07:53:13 -0500 Subject: [PATCH] GP-1250: Several PPC instruction fixes --- .../PowerPC/data/languages/altivec.sinc | 24 +- .../PowerPC/data/languages/ppc_common.sinc | 98 ++++-- .../data/languages/ppc_instructions.sinc | 278 +++++++++--------- .../PowerPC/data/languages/ppc_isa.sinc | 163 ++++------ .../PowerPC/data/languages/ppc_vle.sinc | 2 +- 5 files changed, 291 insertions(+), 274 deletions(-) diff --git a/Ghidra/Processors/PowerPC/data/languages/altivec.sinc b/Ghidra/Processors/PowerPC/data/languages/altivec.sinc index 8a40f5a39d..7f4b339b42 100644 --- a/Ghidra/Processors/PowerPC/data/languages/altivec.sinc +++ b/Ghidra/Processors/PowerPC/data/languages/altivec.sinc @@ -356,10 +356,10 @@ vaddubm_part2: is vrA_8_8 & vrA_8_9 & vrA_8_10 & vrA_8_11 & vrA_8_12 & vrA_8_13 & vrD_16_0 & vrD_16_1 & vrD_16_2 & vrD_16_3 & vrD_16_4 & vrD_16_5 & vrD_16_6 & vrD_16_7 { vrD_16_0 = vrA_16_0 + vrB_16_0; - vrD_16_1 = vrA_16_1 + vrB_16_0; + vrD_16_1 = vrA_16_1 + vrB_16_1; vrD_16_2 = vrA_16_2 + vrB_16_2; vrD_16_3 = vrA_16_3 + vrB_16_3; - vrD_16_4 = vrA_16_3 + vrB_16_4; + vrD_16_4 = vrA_16_4 + vrB_16_4; vrD_16_5 = vrA_16_5 + vrB_16_5; vrD_16_6 = vrA_16_6 + vrB_16_6; vrD_16_7 = vrA_16_7 + vrB_16_7; @@ -1079,16 +1079,16 @@ vaddubm_part2: is vrA_8_8 & vrA_8_9 & vrA_8_10 & vrA_8_11 & vrA_8_12 & vrA_8_13 :vsubuhm vrD,vrA,vrB is OP=4 & vrD & vrA & vrB & XOP_0_10=1088 & vrA_16_0 & vrA_16_1 & vrA_16_2 & vrA_16_3 & vrA_16_4 & vrA_16_5 & vrA_16_6 & vrA_16_7 & vrB_16_0 & vrB_16_1 & vrB_16_2 & vrB_16_3 & vrB_16_4 & vrB_16_5 & vrB_16_6 & vrB_16_7 - & vrC_16_0 & vrC_16_1 & vrC_16_2 & vrC_16_3 & vrC_16_4 & vrC_16_5 & vrC_16_6 & vrC_16_7 + & vrD_16_0 & vrD_16_1 & vrD_16_2 & vrD_16_3 & vrD_16_4 & vrD_16_5 & vrD_16_6 & vrD_16_7 { - vrC_16_0 = vrA_16_0 - vrB_16_0; - vrC_16_1 = vrA_16_1 - vrB_16_1; - vrC_16_2 = vrA_16_2 - vrB_16_2; - vrC_16_3 = vrA_16_3 - vrB_16_3; - vrC_16_4 = vrA_16_4 - vrB_16_4; - vrC_16_5 = vrA_16_5 - vrB_16_5; - vrC_16_6 = vrA_16_6 - vrB_16_6; - vrC_16_7 = vrA_16_7 - vrB_16_7; + vrD_16_0 = vrA_16_0 - vrB_16_0; + vrD_16_1 = vrA_16_1 - vrB_16_1; + vrD_16_2 = vrA_16_2 - vrB_16_2; + vrD_16_3 = vrA_16_3 - vrB_16_3; + vrD_16_4 = vrA_16_4 - vrB_16_4; + vrD_16_5 = vrA_16_5 - vrB_16_5; + vrD_16_6 = vrA_16_6 - vrB_16_6; + vrD_16_7 = vrA_16_7 - vrB_16_7; } :vsubuhs vrD,vrA,vrB is OP=4 & vrD & vrA & vrB & XOP_0_10=1600 @@ -1705,7 +1705,7 @@ define pcodeop altv300_71; :vextractd vrD,vrB,UIMB is OP=4 & vrD & BITS_20_20=0 & UIMB & vrB & XOP_0_10=717 { # if UIMB > 8 the result is undefined - vrD = (vrB >> (16 * (8 - UIMB))) & 0xffffffffffffffff; + vrD = (vrB >> (8 * (8 - UIMB))) & 0xffffffffffffffff; } :vextractub vrD,vrB,UIMB is OP=4 & vrD & BITS_20_20=0 & UIMB & vrB & XOP_0_10=525 { diff --git a/Ghidra/Processors/PowerPC/data/languages/ppc_common.sinc b/Ghidra/Processors/PowerPC/data/languages/ppc_common.sinc index 9345366692..0a2514114a 100644 --- a/Ghidra/Processors/PowerPC/data/languages/ppc_common.sinc +++ b/Ghidra/Processors/PowerPC/data/languages/ppc_common.sinc @@ -1555,7 +1555,7 @@ macro getCrBit(crReg, bitIndex, result) macro setCrBit(crReg, bitIndex, bit) { shift:1 = 3-bitIndex; - mask:1 = ~(1<>8) $and 1)*0xffffffff) $xor (0x7fffffff>>ME) $xor (0xffffffff>>MBL); ] { export *[const]:4 mask; } +@ifdef BIT_64 +MB: mbValue is MBH & MBL [ mbValue=(MBH<<5)|MBL; ] { export *[const]:4 mbValue; } +SH: shValue is SHH & SHL [ shValue=(SHH<<5)|SHL; ] { export *[const]:4 shValue; } + +rotmask: mask is MBL & ME [mask = ((((ME-MBL)>>8) $and 1)*0xffffffffffffffff) $xor (0x7fffffff>>ME) $xor (0xffffffff>>MBL); ] { export *[const]:8 mask; } + +rotmask_SH: masksh, mbValue, shValue is MBL & MBH & SHL & SHH + [ mbValue= (MBH<<5)|MBL; + shValue= (SHH<<5)|SHL; + masksh = ((((shValue-mbValue)>>8) $and 1)*0xffffffffffffffff) $xor ((0x7fffffffffffffff >> shValue) $xor (0xffffffffffffffff >> mbValue)); + ] +{ + local start:4 = mbValue; + local stop:4 = 63-shValue; + mask_tmp:8 = (zext(start > stop) * 0xffffffffffffffff) ^ (0x7fffffffffffffff>>stop) ^ (0xffffffffffffffff>>start); + export *[const]:8 mask_tmp; +} + +rotmask_Z: mask, mbValue is MBL & MBH [mbValue= (MBH<<5)|MBL; mask = ~(0xffffffffffffffff >> (mbValue+1)); ] +{ mask_tmp:8 = ~(0xffffffffffffffff >> (mbValue+1)); export *[const]:8 mask_tmp; } + +@else +rotmask: mask is MBL & ME [ mask = ((((ME-MBL)>>8) $and 1)*0xffffffff) $xor (0x7fffffff>>ME) $xor (0xffffffff>>MBL); ] { export *[const]:4 mask; } +@endif DSIZE: "w" is L {} # L is a don't care bit in 32-bit languages although it should always be 0 @ifdef BIT_64 # L can only be 1 when in 64 bit language @@ -1935,11 +1984,6 @@ CRM_CR: cr2 is CRM=32 & cr2 {tmp:4 = zext(cr2) << 20;export tmp;} CRM_CR: cr1 is CRM=64 & cr1 {tmp:4 = zext(cr1) << 24;export tmp;} CRM_CR: cr0 is CRM=128 & cr0 {tmp:4 = zext(cr0) << 28;export tmp;} -@ifdef BIT_64 -MB: mbValue is MBH & MBL [ mbValue=(MBH<<5)|MBL; ] { export *[const]:4 mbValue; } -SH: shValue is SHH & SHL [ shValue=(SHH<<5)|SHL; ] { export *[const]:4 shValue; } - -@endif ################################################################ # Instructions diff --git a/Ghidra/Processors/PowerPC/data/languages/ppc_instructions.sinc b/Ghidra/Processors/PowerPC/data/languages/ppc_instructions.sinc index c3003c7d16..a3fa7a8f76 100644 --- a/Ghidra/Processors/PowerPC/data/languages/ppc_instructions.sinc +++ b/Ghidra/Processors/PowerPC/data/languages/ppc_instructions.sinc @@ -66,20 +66,16 @@ :adde D,A,B is OP=31 & D & A & B & OE=0 & XOP_1_9=138 & Rc=0 { zextCarry:$(REGISTER_SIZE) = zext(xer_ca); - xer_ca = carry(B, zextCarry); - tmp:$(REGISTER_SIZE)=B + zextCarry; - xer_ca = xer_ca || carry(A, tmp); - D=A+tmp; + addExtendedCarry(A,B); + D=A + B + zextCarry; } #adde. r1,r2,r3 0x7c 22 19 15 :adde. D,A,B is OP=31 & D & A & B & OE=0 & XOP_1_9=138 & Rc=1 { zextCarry:$(REGISTER_SIZE) = zext(xer_ca); - xer_ca = carry(B, zextCarry); - tmp:$(REGISTER_SIZE)=B + zextCarry; - xer_ca = xer_ca || carry(A, tmp); - D=A+tmp; + addExtendedCarry(A,B); + D=A + B + zextCarry; cr0flags(D); } @@ -87,26 +83,21 @@ :addeo D,A,B is OP=31 & D & A & B & OE=1 & XOP_1_9=138 & Rc=0 { zextCarry:$(REGISTER_SIZE) = zext(xer_ca); - xer_ca = carry(B, zextCarry); - addOverflow(B, zextCarry); - tmp:$(REGISTER_SIZE)=B + zextCarry; - addOverflowAgain(A,tmp); - xer_ca = xer_ca || carry(A, tmp); - D=A+tmp; + addExtendedOverflow(A,B); + addExtendedCarry(A,B); + D=A + B + zextCarry; } #addeo. r1,r2,r3 0x7c 22 1d 15 :addeo. D,A,B is OP=31 & D & A & B & OE=1 & XOP_1_9=138 & Rc=1 { zextCarry:$(REGISTER_SIZE) = zext(xer_ca); - xer_ca = carry(B, zextCarry); - addOverflow(B, zextCarry); - tmp:$(REGISTER_SIZE)=B + zextCarry; - addOverflowAgain(A,tmp); - xer_ca = xer_ca || carry(A, tmp); - D=A+tmp; + addExtendedOverflow(A,B); + addExtendedCarry(A,B); + D=A + B + zextCarry; cr0flags(D); } + #addi r0,0x7fff 0x38 00 7f ff #addi r0,1 0x38 01 00 01 :addi D,A,SIMM is $(NOTVLE) & OP=14 & D & A & SIMM_SIGN=0 & SIMM @@ -189,36 +180,40 @@ #addme r0,r0 0x7c 00 01 D4 :addme D,A is OP=31 & D & A & BITS_11_15=0 & OE=0 & XOP_1_9=234 & Rc=0 { - tmp:$(REGISTER_SIZE) = zext(xer_ca) - 1; - xer_ca = carry(A, tmp); - D = A + tmp; + local zextCarry:$(REGISTER_SIZE) = zext(xer_ca); + local BVal:$(REGISTER_SIZE) = ~(0); + addExtendedCarry(A,BVal); + D=A + BVal + zextCarry; } #addme. r0,r0 0x7c 00 01 D5 :addme. D,A is OP=31 & D & A & BITS_11_15=0 & OE=0 & XOP_1_9=234 & Rc=1 { - tmp:$(REGISTER_SIZE) = zext(xer_ca) - 1; - xer_ca = carry(A, tmp); - D = A + tmp; + local zextCarry:$(REGISTER_SIZE) = zext(xer_ca); + local BVal:$(REGISTER_SIZE) = ~(0); + addExtendedCarry(A,BVal); + D=A + BVal + zextCarry; cr0flags(D); } #addmeo r0,r0 0x7C 00 05 D4 :addmeo D,A is OP=31 & D & A & BITS_11_15=0 & OE=1 & XOP_1_9=234 & Rc=0 { - tmp:$(REGISTER_SIZE) = zext(xer_ca) - 1; - xer_ca = carry(A, tmp); - addOverflow(A, tmp); - D = A + tmp; + local zextCarry:$(REGISTER_SIZE) = zext(xer_ca); + local BVal:$(REGISTER_SIZE) = ~(0); + addExtendedOverflow(A,BVal); + addExtendedCarry(A,BVal); + D=A + BVal + zextCarry; } #addmeo. r0,r0 0x7C 00 05 D5 :addmeo. D,A is OP=31 & D & A & BITS_11_15=0 & OE=1 & XOP_1_9=234 & Rc=1 { - tmp:$(REGISTER_SIZE) = zext(xer_ca) - 1; - xer_ca = carry(A, tmp); - addOverflow(A, tmp); - D = A + tmp; + local zextCarry:$(REGISTER_SIZE) = zext(xer_ca); + local BVal:$(REGISTER_SIZE) = ~(0); + addExtendedOverflow(A,BVal); + addExtendedCarry(A,BVal); + D=A + BVal + zextCarry; cr0flags(D); } @@ -892,7 +887,7 @@ #crorc 4*cr1+lt,4*cr2+gt,4*cr3+eq 0x4c 89 73 42 :crorc CC_D_OP,CC_OP,CC_B_OP is $(NOTVLE) & OP=19 & CC_D_OP & CC_OP & CC_B_OP & CR_D & CR_D_CC & XOP_1_10=417 & BIT_0=0 { - setCrBit(CR_D,CR_D_CC,(CC_B_OP | (!CC_OP))); + setCrBit(CR_D,CR_D_CC,((!CC_B_OP) | CC_OP)); } #crxor lt,lt,lt 0x4c 00 01 82 @@ -2768,7 +2763,7 @@ define pcodeop lswxOp; # mulhwu r0,r0,r0 0x10 00 03 10 :mullhwu D,A,B is OP=4 & D & A & B & XOP_1_10=392 & Rc=0 { - D = mullhwu(D, A, B); + D = mullhwu(D, A, B); } @endif @@ -3179,32 +3174,33 @@ define pcodeop lswxOp; MSR = (MSR & ~mask) | (S & mask); } @endif +CRM_val: crmval is CRM [crmval = CRM+0;] {export *[const]:1 crmval;} #mtocrf 10,r0 0x7c 21 01 20 -:mtocrf CRM,S is OP=31 & S & BIT_20=1 & CRM & CRM0 & CRM1 & CRM2 & CRM3 & CRM4 & CRM5 & CRM6 & CRM7 & BIT_11=0 & XOP_1_10=144 & BIT_0=0 +:mtocrf CRM_val,S is OP=31 & S & BIT_20=1 & CRM_val & CRM0 & CRM1 & CRM2 & CRM3 & CRM4 & CRM5 & CRM6 & CRM7 & BIT_11=0 & XOP_1_10=144 & BIT_0=0 { tmp:$(REGISTER_SIZE) = (S >> 28) & 0xf; - cr0 = (cr0 * (CRM0:1 == 0)) | (tmp:1 * (CRM0:1 == 1)); + cr0 = (cr0 * (CRM_val != 128)) | (tmp:1 * (CRM_val == 128)); tmp = (S >> 24) & 0xf; - cr1 = (cr1 * (CRM1:1 == 0)) | (tmp:1 * (CRM1:1 == 1)); + cr1 = (cr1 * (CRM_val != 64)) | (tmp:1 * (CRM_val == 64)); tmp = (S >> 20) & 0xf; - cr2 = (cr2 * (CRM2:1 == 0)) | (tmp:1 * (CRM2:1 == 1)); + cr2 = (cr2 * (CRM_val != 32)) | (tmp:1 * (CRM_val == 32)); tmp = (S >> 16) & 0xf; - cr3 = (cr3 * (CRM3:1 == 0)) | (tmp:1 * (CRM3:1 == 1)); + cr3 = (cr3 * (CRM_val != 16)) | (tmp:1 * (CRM_val == 16)); tmp = (S >> 12) & 0xf; - cr4 = (cr4 * (CRM4:1 == 0)) | (tmp:1 * (CRM4:1 == 1)); + cr4 = (cr4 * (CRM_val != 8)) | (tmp:1 * (CRM_val == 8)); tmp = (S >> 8) & 0xf; - cr5 = (cr5 * (CRM5:1 == 0)) | (tmp:1 * (CRM5:1 == 1)); + cr5 = (cr5 * (CRM_val != 4)) | (tmp:1 * (CRM_val == 4)); tmp = (S >> 4) & 0xf; - cr6 = (cr6 * (CRM6:1 == 0)) | (tmp:1 * (CRM6:1 == 1)); + cr6 = (cr6 * (CRM_val != 2)) | (tmp:1 * (CRM_val == 2)); tmp = S & 0xf; - cr7 = (cr7 * (CRM7:1 == 0)) | (tmp:1 * (CRM7:1 == 1)); + cr7 = (cr7 * (CRM_val != 1)) | (tmp:1 * (CRM_val == 1)); } ### is this pcode correct on 64-bit bridge? @@ -3280,7 +3276,7 @@ define pcodeop lswxOp; @ifdef BIT_64 tmp:8 = sext(A:4) * sext(B:4); tmp2:4 = tmp(4); - D = sext(tmp2); + D = zext(tmp2); @else tmp:8 = sext(A) * sext(B); D = tmp(4); @@ -3293,7 +3289,7 @@ define pcodeop lswxOp; @ifdef BIT_64 tmp:8 = sext(A:4) * sext(B:4); tmp2:4 = tmp(4); - D = sext(tmp2); + D = zext(tmp2); @else tmp:8 = sext(A) * sext(B); D = tmp(4); @@ -3357,7 +3353,7 @@ define pcodeop lswxOp; tmp:16 = sext(A) * sext(B); D = tmp:8; mulOverflow128(tmp); - cr0flags(D); + cr0flags(D); } @endif @@ -3370,7 +3366,7 @@ define pcodeop lswxOp; #mullw r0,r0,r0 0x7C 00 01 D6 :mullw D,A,B is OP=31 & D & A & B & OE=0 & XOP_1_9=235 & Rc=0 -{ +{ @ifdef BIT_64 D = sext(A:4) * sext(B:4); @else @@ -3399,7 +3395,7 @@ define pcodeop lswxOp; tmp:8 = sext(A) * sext(B); mulOverflow64(tmp); D = tmp:4; -@endif +@endif } #mullwo. r0,r0,r0 0x7C 00 05 D7 @@ -3412,7 +3408,7 @@ define pcodeop lswxOp; tmp:8 = sext(A) * sext(B); mulOverflow64(tmp); D = tmp:4; -@endif +@endif cr0flags(D); } @@ -3533,38 +3529,37 @@ define pcodeop lswxOp; cr0flags(A); } #rldcr r0,r0,r0,0 0x78 00 00 12 -:rldcr A,S,B,MB is $(NOTVLE) & OP=30 & S & A & B & MB & XOP_1_4=9 & Rc=0 +:rldcr A,S,B,MB is $(NOTVLE) & OP=30 & S & A & B & MB & XOP_1_4=9 & Rc=0 & rotmask_Z { shift:$(REGISTER_SIZE) = B & 0x3f; tmp:$(REGISTER_SIZE)=(S<>(64-shift)); - A = tmp & (0xffffffffffffffff >> MB); + A = tmp & rotmask_Z; } #rldcr. r0,r0,r0,0 0x78 00 00 13 -:rldcr. A,S,B,MB is $(NOTVLE) & OP=30 & S & A & B & MB & XOP_1_4=9 & Rc=1 +:rldcr. A,S,B,MB is $(NOTVLE) & OP=30 & S & A & B & MB & XOP_1_4=9 & Rc=1 & rotmask_Z { shift:$(REGISTER_SIZE) = B & 0x3f; tmp:$(REGISTER_SIZE)=(S<>(64-shift)); - A = tmp & (0xffffffffffffffff << (64-MB)); + A = tmp & rotmask_Z; cr0flags(A); } #rldic r0,r0,r0,0 0x78 00 00 08 -:rldic A,S,SH,MB is $(NOTVLE) & OP=30 & S & A & B & SH & MB & XOP_2_4=2 & Rc=0 +:rldic A,S,SH,MB is $(NOTVLE) & OP=30 & S & A & B & SH & MB & XOP_2_4=2 & Rc=0 & rotmask_SH { shift:4 = SH; tmp:$(REGISTER_SIZE)=(S<>(64-shift)); - mask:$(REGISTER_SIZE) = (0xffffffffffffffff >> MB) & (0xffffffffffffffff << shift); - A = tmp & mask; + A = tmp & rotmask_SH; } #rldic. r0,r0,r0,0 0x78 00 00 09 -:rldic. A,S,SH,MB is $(NOTVLE) & OP=30 & S & A & B & SH & MB & XOP_2_4=2 & Rc=1 +:rldic. A,S,SH,MB is $(NOTVLE) & OP=30 & S & A & B & SH & MB & XOP_2_4=2 & Rc=1 & rotmask_SH { shift:4 = SH; tmp:$(REGISTER_SIZE)=(S<>(64-shift)); - mask:$(REGISTER_SIZE) = (0xffffffffffffffff >> MB) & (0xffffffffffffffff << shift); - A = tmp & mask; + A = tmp & rotmask_SH; cr0flags(A); } + #rldicl r0,r0,r0,0 0x78 00 00 00 :rldicl A,S,SH,MB is $(NOTVLE) & OP=30 & S & A & B & SH & MB & XOP_2_4=0 & Rc=0 { @@ -3596,20 +3591,18 @@ define pcodeop lswxOp; cr0flags(A); } #rldimi r0,r0,r0,0 0x78 00 00 0c -:rldimi A,S,SH,MB is $(NOTVLE) & OP=30 & S & A & B & SH & MB & XOP_2_4=3 & Rc=0 +:rldimi A,S,SH,MB is $(NOTVLE) & OP=30 & S & A & B & SH & MB & XOP_2_4=3 & Rc=0 & rotmask_SH { shift:4 = SH; tmp:$(REGISTER_SIZE)=(S<>(64-shift)); - mask:$(REGISTER_SIZE) = (0xffffffffffffffff >> MB) & (0xffffffffffffffff << shift); - A = (tmp & mask) | (A & ~mask); + A = (tmp & rotmask_SH) | (A & ~rotmask_SH); } #rldimi. r0,r0,r0,0 0x78 00 00 0d -:rldimi. A,S,SH,MB is $(NOTVLE) & OP=30 & S & A & B & SH & MB & XOP_2_4=3 & Rc=1 +:rldimi. A,S,SH,MB is $(NOTVLE) & OP=30 & S & A & B & SH & MB & XOP_2_4=3 & Rc=1 & rotmask_SH { shift:4 = SH; tmp:$(REGISTER_SIZE)=(S<>(64-shift)); - mask:$(REGISTER_SIZE) = (0xffffffffffffffff >> MB) & (0xffffffffffffffff << shift); - A = (tmp & mask) | (A & ~mask); + A = (tmp & rotmask_SH) | (A & ~rotmask_SH); cr0flags(A); } @endif @@ -3621,9 +3614,9 @@ define pcodeop lswxOp; { shift:1 = SHL; @ifdef BIT_64 - tmp:4 = S:4; - tmp2:4 = (tmp<>(32-shift)); - A = zext(tmp2 & rotmask) | (A & ~zext(rotmask)); + tmp:$(REGISTER_SIZE) = (S << 32) | (S & 0xffffffff); + tmp2:$(REGISTER_SIZE) = (tmp<>(64-shift)); + A = (tmp2 & rotmask) | (A & ~(rotmask)); @else tmp = (S<>(32-shift)); A = (tmp & rotmask) | (A & ~rotmask); @@ -3635,9 +3628,9 @@ define pcodeop lswxOp; { shift:1 = SHL; @ifdef BIT_64 - tmp:4 = S:4; - tmp2:4 = (tmp<>(32-shift)); - A = zext(tmp2 & rotmask) | (A & ~zext(rotmask)); + tmp:$(REGISTER_SIZE) = (S << 32) | (S & 0xffffffff); + tmp2:$(REGISTER_SIZE) = (tmp<>(64-shift)); + A = (tmp2 & rotmask) | (A & ~(rotmask)); @else tmp = (S<>(32-shift)); A = (tmp & rotmask) | (A & ~rotmask); @@ -3650,9 +3643,9 @@ define pcodeop lswxOp; { shift:1 = SHL; @ifdef BIT_64 - tmp:4 = S:4; - tmp2:4 = (tmp<>(32-shift)); - A = zext(tmp2 & rotmask); + tmp:$(REGISTER_SIZE) = (S << 32) | (S & 0xffffffff); + tmp2:$(REGISTER_SIZE) = (tmp<>(64-shift)); + A = tmp2 & rotmask; @else tmp = (S<>(32-shift)); A = (tmp & rotmask); @@ -3664,9 +3657,9 @@ define pcodeop lswxOp; { shift:1 = SHL; @ifdef BIT_64 - tmp:4 = S:4; - tmp2:4 = (tmp<>(32-shift)); - A = zext(tmp2 & rotmask); + tmp:$(REGISTER_SIZE) = (S << 32) | (S & 0xffffffff); + tmp2:$(REGISTER_SIZE) = (tmp<>(64-shift)); + A = tmp2 & rotmask; @else tmp = (S<>(32-shift)); A = (tmp & rotmask); @@ -3679,9 +3672,9 @@ define pcodeop lswxOp; { shift:$(REGISTER_SIZE) = B & 0x1f; @ifdef BIT_64 - tmp:4 = S:4; - tmp2:4 = (tmp<>(32-shift)); - A = zext(tmp2 & rotmask); + tmp:$(REGISTER_SIZE) = (S << 32) | (S & 0xffffffff); + tmp2:$(REGISTER_SIZE) = (tmp<>(64-shift)); + A = tmp2 & rotmask; @else tmp = (S<>(32-shift)); A = (tmp & rotmask); @@ -3693,9 +3686,9 @@ define pcodeop lswxOp; { shift:$(REGISTER_SIZE) = B & 0x1f; @ifdef BIT_64 - tmp:4 = S:4; - tmp2:4 = (tmp<>(32-shift)); - A = zext(tmp2 & rotmask); + tmp:$(REGISTER_SIZE) = (S << 32) | (S & 0xffffffff); + tmp2:$(REGISTER_SIZE) = (tmp<>(64-shift)); + A = tmp2 & rotmask; @else tmp = (S<>(32-shift)); A = (tmp & rotmask); @@ -3758,10 +3751,12 @@ define pcodeop lswxOp; :slw A,S,B is OP=31 & S & A & B & XOP_1_10=24 & Rc=0 { @ifdef BIT_64 - tmp:4 = S:4 << B; - A = (A & 0xffffffff00000000) | zext(tmp); + shift:4 = B:4 & 0x3f; + tmp:4 = S:4 << shift; + A = zext(tmp); @else - A = S << B; + shift = B & 0x3f; + A = S << shift; @endif } @@ -3770,10 +3765,12 @@ define pcodeop lswxOp; :slw. A,S,B is OP=31 & S & A & B & XOP_1_10=24 & Rc=1 { @ifdef BIT_64 - tmp:4 = S:4 << B; - A = (A & 0xffffffff00000000) | zext(tmp); + shift:4 = B:4 & 0x3f; + tmp:4 = S:4 << shift; + A = zext(tmp); @else - A = S << B; + shift = B & 0x3f; + A = S << shift; @endif cr0flags(A); } @@ -3816,12 +3813,13 @@ define pcodeop lswxOp; #sraw r0,r0,r0 0x7C 00 06 30 :sraw A,S,B is OP=31 & A & S & B & XOP_1_10=792 & Rc=0 { - shift:$(REGISTER_SIZE) = B & 0x3f; @ifdef BIT_64 + shift:4 = B:4 & 0x3f; shiftCarry(S:4,shift); tmp2:4 = S:4 s>> shift; - A = (A & 0xffffffff00000000) | zext(tmp2); + A = sext(tmp2); @else + shift = B & 0x3f; shiftCarry(S,shift); A = S s>> shift; @endif @@ -3829,12 +3827,13 @@ define pcodeop lswxOp; #sraw. r0,r0,r0 0x7C 00 06 31 :sraw. A,S,B is OP=31 & A & S & B & XOP_1_10=792 & Rc=1 { - shift:$(REGISTER_SIZE) = B & 0x3f; @ifdef BIT_64 + shift:4 = B:4 & 0x3f; shiftCarry(S:4,shift); tmp2:4 = S:4 s>> shift; - A = (A & 0xffffffff00000000) | zext(tmp2); + A = sext(tmp2); @else + shift = B & 0x3f; shiftCarry(S,shift); A = S s>> shift; @endif @@ -3848,7 +3847,7 @@ define pcodeop lswxOp; shift:4 = SHL; shiftCarry(S:4,shift); tmp2:4 = S:4 s>> shift; - A = (A & 0xffffffff00000000) | zext(tmp2); + A = sext(tmp2); @else shiftCarry(S,SHL); A = S s>> SHL; @@ -3861,7 +3860,7 @@ define pcodeop lswxOp; shift:4 = SHL; shiftCarry(S:4,shift); tmp2:4 = S:4 s>> shift; - A = (A & 0xffffffff00000000) | zext(tmp2); + A = sext(tmp2); @else shiftCarry(S,SHL); A = S s>> SHL; @@ -3888,10 +3887,12 @@ define pcodeop lswxOp; :srw A,S,B is OP=31 & S & A & B & XOP_1_10=536 & Rc=0 { @ifdef BIT_64 - tmp:4 = S:4 >> B; - A = (A & 0xffffffff00000000) | zext(tmp); + shift:4 = B:4 & 0x3f; + tmp:4 = S:4 >> shift; + A = zext(tmp); @else - A = S >> B; + shift = B & 0x3f; + A = S >> shift; @endif } @@ -3900,10 +3901,12 @@ define pcodeop lswxOp; :srw. A,S,B is OP=31 & S & A & B & XOP_1_10=536 & Rc=1 { @ifdef BIT_64 - tmp:4 = S:4 >> B; - A = (A & 0xffffffff00000000) | zext(tmp); + shift:4 = B:4 & 0x3f; + tmp:4 = S:4 >> shift; + A = zext(tmp); @else - A = S >> B; + shift = B & 0x3f; + A = S >> shift; @endif cr0flags(A); } @@ -4253,26 +4256,26 @@ define pcodeop stswxOp; #subfe r0,r0,r0 0x7c 00 01 10 :subfe D,A,B is OP=31 & D & A & B & OE=0 & XOP_1_9=136 & Rc=0 { - tmp:$(REGISTER_SIZE) = zext(!xer_ca)+A; - xer_ca= (tmp<=B); + tmp:$(REGISTER_SIZE) = A + zext(!xer_ca); + subExtendedCarry(B,A); D = B - tmp; } #subfe. r0,r0,r0 0x7c 00 01 11 :subfe. D,A,B is OP=31 & D & A & B & OE=0 & XOP_1_9=136 & Rc=1 { - tmp:$(REGISTER_SIZE) = zext(!xer_ca)+A; - xer_ca= (tmp<=B); - D = B - tmp; + tmp:$(REGISTER_SIZE) = A + zext(!xer_ca); + subExtendedCarry(B,A); + D = B - tmp; cr0flags(D); } #subfeo r0,r0,r0 0x7c 00 05 10 :subfeo D,A,B is OP=31 & D & A & B & OE=1 & XOP_1_9=136 & Rc=0 { - tmp:$(REGISTER_SIZE) = zext(!xer_ca)+A; - xer_ca= (tmp<=B); - subOverflow( B, tmp ); + tmp:$(REGISTER_SIZE) = zext(!xer_ca)+A; + subExtendedOverflow(B,A); + subExtendedCarry(B,A); D = B - tmp; } @@ -4280,8 +4283,8 @@ define pcodeop stswxOp; :subfeo. D,A,B is OP=31 & D & A & B & OE=1 & XOP_1_9=136 & Rc=1 { tmp:$(REGISTER_SIZE) = zext(!xer_ca)+A; - xer_ca= (tmp<=B); - subOverflow( B, tmp ); + subExtendedOverflow(B,A); + subExtendedCarry(B,A); D = B - tmp; cr0flags(D); } @@ -4296,36 +4299,39 @@ define pcodeop stswxOp; #subfme r0,r0 0x7c 00 01 d0 :subfme D,A is OP=31 & D & A & BITS_11_15=0 & OE=0 & XOP_1_9=232 & Rc=0 { - tmp:$(REGISTER_SIZE)=zext(!xer_ca)+A; - xer_ca=!(-1 s< tmp); - D=-1-tmp; + tmp:$(REGISTER_SIZE) = A + zext(!xer_ca); + Bval:$(REGISTER_SIZE) = ~(0); + subExtendedCarry(Bval,A); + D = Bval - tmp; } #subfme. r0,r0 0x7c 00 01 d1 :subfme. D,A is OP=31 & D & A & BITS_11_15=0 & OE=0 & XOP_1_9=232 & Rc=1 { - tmp:$(REGISTER_SIZE)=zext(!xer_ca)+A; - xer_ca=!(-1 s< tmp); - D=-1-tmp; + tmp:$(REGISTER_SIZE) = A + zext(!xer_ca); + Bval:$(REGISTER_SIZE) = ~(0); + subExtendedCarry(Bval,A); + D = Bval - tmp; cr0flags(D); } -#subfmeo r0,r0 0x7c 00 05 d0 :subfmeo D,A is OP=31 & D & A & BITS_11_15=0 & OE=1 & XOP_1_9=232 & Rc=0 { - tmp:$(REGISTER_SIZE)=zext(!xer_ca)+A; - subOverflow(0xffffffff,tmp); - xer_ca=!(-1 s< tmp); - D=-1-tmp; + tmp:$(REGISTER_SIZE) = A + zext(!xer_ca); + Bval:$(REGISTER_SIZE) = ~(0); + subExtendedOverflow(Bval,A); + subExtendedCarry(Bval,A); + D = Bval - tmp; } #subfmeo. r0,r0 0x7c 00 05 d1 :subfmeo. D,A is OP=31 & D & A & BITS_11_15=0 & OE=1 & XOP_1_9=232 & Rc=1 { - tmp:$(REGISTER_SIZE)=zext(!xer_ca)+A; - subOverflow(0xffffffff,tmp); - xer_ca=!(-1 s< tmp); - D=-1-tmp; + tmp:$(REGISTER_SIZE) = A + zext(!xer_ca); + Bval:$(REGISTER_SIZE) = ~(0); + subExtendedOverflow(Bval,A); + subExtendedCarry(Bval,A); + D = Bval - tmp; cr0flags(D); } @@ -4333,7 +4339,8 @@ define pcodeop stswxOp; :subfze D,A is OP=31 & D & A & BITS_11_15=0 & OE=0 & XOP_1_9=200 & Rc=0 { tmp:$(REGISTER_SIZE) = zext(!xer_ca)+A; - xer_ca=!(0 s< tmp); + Bval:$(REGISTER_SIZE) = 0; + subExtendedCarry(Bval,A); D=-tmp; } @@ -4341,7 +4348,8 @@ define pcodeop stswxOp; :subfze. D,A is OP=31 & D & A & BITS_11_15=0 & OE=0 & XOP_1_9=200 & Rc=1 { tmp:$(REGISTER_SIZE) = zext(!xer_ca)+A; - xer_ca= !(0 s< tmp); + Bval:$(REGISTER_SIZE) = 0; + subExtendedCarry(Bval,A); D=-tmp; cr0flags(D); } @@ -4350,8 +4358,9 @@ define pcodeop stswxOp; :subfzeo D,A is OP=31 & D & A & BITS_11_15=0 & OE=1 & XOP_1_9=200 & Rc=0 { tmp:$(REGISTER_SIZE) = zext(!xer_ca)+A; - subOverflow(0,tmp); - xer_ca= !(0 s< tmp); + Bval:$(REGISTER_SIZE) = 0; + subExtendedOverflow(Bval,A); + subExtendedCarry(Bval,A); D=-tmp; } @@ -4359,8 +4368,9 @@ define pcodeop stswxOp; :subfzeo. D,A is OP=31 & D & A & BITS_11_15=0 & OE=1 & XOP_1_9=200 & Rc=1 { tmp:$(REGISTER_SIZE) = zext(!xer_ca)+A; - subOverflow(0,tmp); - xer_ca= !(0 s< tmp); + Bval:$(REGISTER_SIZE) = 0; + subExtendedOverflow(Bval,A); + subExtendedCarry(Bval,A); D=-tmp; cr0flags(D); } diff --git a/Ghidra/Processors/PowerPC/data/languages/ppc_isa.sinc b/Ghidra/Processors/PowerPC/data/languages/ppc_isa.sinc index 839370ed15..10f0cc691c 100644 --- a/Ghidra/Processors/PowerPC/data/languages/ppc_isa.sinc +++ b/Ghidra/Processors/PowerPC/data/languages/ppc_isa.sinc @@ -116,11 +116,11 @@ define pcodeop rvwinkleOp; b:8 = 0; tmp:8 = 0; - b = (64 - (i*8+7)); - tmp = (S >> (64 - (i*8+7))); b = tmp & 1; # GetBit + b = (63 - (i*8+7)); + tmp = (S >> (63 - (i*8+7))); b = tmp & 1; # GetBit s = s ^ b; i = i + 1; - if (i < 7) goto ; + if (i < 8) goto ; A = s; } @@ -134,22 +134,37 @@ define pcodeop rvwinkleOp; # binutils: power7.d: 90: 7c 83 2b f8 cmpb r3,r4,r5 # name cmpb code 7c0003f8 mask ff0700fc00000000 flags @POWER6 @476 @A2 operands 31 3b 38 0 0 0 0 0 :cmpb S,A,B is $(NOTVLE) & OP=31 & S & A & B & XOP_1_10=508 & BIT_0=0 { # PCODE-YES - i:8 = 0; tmpS:8 = 0; tmpB:8 = 0; val:8 = 0; - - tmpS = (S << (i*8)) & 0xFF; # get next S byte - tmpB = (S << (i*8)) & 0xFF; # get next B byte - if (tmpS == tmpB) goto ; - val = (val << (i*8)); # set low byte to 0x00 - goto ; - - val = (val << (i*8)); # set low byte to 0xFF - val = val | 0xFF; - - i = i + 1; - if (i < 7) goto ; + zero:8 = 0; + ones:8 = 0xff; + + # Unrolled the loop + tmpS = (S >> 56) & 0xFF; # get next S byte + tmpB = (B >> 56) & 0xFF; # get next B byte + val = (zext(tmpS == tmpB) * ones) + (zext(tmpS != tmpB) * zero); + tmpS = (S >> 48) & 0xFF; # get next S byte + tmpB = (B >> 48) & 0xFF; # get next B byte + val = val << 8 | (zext(tmpS == tmpB) * ones) + (zext(tmpS != tmpB) * zero); + tmpS = (S >> 40) & 0xFF; # get next S byte + tmpB = (B >> 40) & 0xFF; # get next B byte + val = val << 8 | (zext(tmpS == tmpB) * ones) + (zext(tmpS != tmpB) * zero); + tmpS = (S >> 32) & 0xFF; # get next S byte + tmpB = (B >> 32) & 0xFF; # get next B byte + val = val << 8 | (zext(tmpS == tmpB) * ones) + (zext(tmpS != tmpB) * zero); + tmpS = (S >> 24) & 0xFF; # get next S byte + tmpB = (B >> 24) & 0xFF; # get next B byte + val = val << 8 | (zext(tmpS == tmpB) * ones) + (zext(tmpS != tmpB) * zero); + tmpS = (S >> 16) & 0xFF; # get next S byte + tmpB = (B >> 16) & 0xFF; # get next B byte + val = val << 8 | (zext(tmpS == tmpB) * ones) + (zext(tmpS != tmpB) * zero); + tmpS = (S >> 8) & 0xFF; # get next S byte + tmpB = (B >> 8) & 0xFF; # get next B byte + val = val << 8 | (zext(tmpS == tmpB) * ones) + (zext(tmpS != tmpB) * zero); + tmpS = S & 0xFF; # get next S byte + tmpB = B & 0xFF; # get next B byte + val = val << 8 | (zext(tmpS == tmpB) * ones) + (zext(tmpS != tmpB) * zero); A = val; } # PowerISA II: 3.3.12 Fixed-Point Logical Instructions @@ -169,20 +184,12 @@ define pcodeop BitPermuteDoubleword; # binutils: a2.d: 64c: 7d 6a 02 f4 popcntw r10,r11 # binutils: power7.d: dc: 7e 8a 02 f4 popcntw r10,r20 # name popcntw code 7c0002f4 mask ffff00fc00000000 flags @POWER7 @A2 operands 31 3b 0 0 0 0 0 0 -:popcntw A,S is $(NOTVLE) & OP=31 & S & A & XOP_1_10=378 & Rc & BITS_11_15=0 { - i:8 = 0; - j:8 = 0; - n:8 = 0; - x:8 = 0; - tmp:8 = 0; - - n = 0; - - tmp = (S >> (64 - (j*8+7))); x = tmp & 1; # Get bit - n = n + x; - if (j < 31) goto ; - A = n; - if (i < 1) goto ; +:popcntw A,S is $(NOTVLE) & OP=31 & S & A & XOP_1_10=378 & Rc & BITS_11_15=0 { + local tmp1:4 = S(0); + tmp1 = popcount(tmp1); + local tmp2:4 = S(4); + tmp2 = popcount(tmp2); + A = (zext(tmp2) << 32) + zext(tmp1); } # PowerISA II: 3.3.12 Fixed-Point Logical Instructions @@ -192,23 +199,18 @@ define pcodeop BitPermuteDoubleword; # binutils: a2.d: 644: 7d 6a 00 f4 popcntb r10,r11 # name popcntb code 7c0000f4 mask ffff00fc00000000 flags @POWER5 operands 31 3b 0 0 0 0 0 0 :popcntb A,S is OP=31 & S & A & BITS_11_15=0 & XOP_1_10=122 & BIT_0=0 { - i:8 = 0; - j:8 = 0; - n:8 = 0; - x:8 = 0; - tmp:8 = 0; + local i:8 = 0; + local tmp:8 = 0; + local tmpb:1 = 0; + local mask:8 = 0xff; - n = 0; - - tmp = (S >> (64 - (i*8+j))); x = tmp & 1; # Get bit - if (x != 1) goto ; - n = n + 1; - - j = j + 1; - if (j < 7) goto ; - i = i + 1; - if (i < 7) goto ; - A = n; + tmp = (S >> (i*8)); + tmpb = tmp(0); + tmpb = popcount(tmpb); + A = (A & ~(mask)) + (zext(tmpb) << (i*8)); + mask = mask << 8; + i = i + 1; + if (i < 8) goto ; } @@ -221,24 +223,9 @@ define pcodeop BitPermuteDoubleword; # binutils: power7.d: 80: 7c 83 01 34 prtyw r3,r4 # name prtyw code 7c000134 mask ffff00fc00000000 flags @POWER6 @476 @A2 operands 31 3b 0 0 0 0 0 0 :prtyw A,S is $(NOTVLE) & OP=31 & S & A & BITS_11_15=0 & XOP_1_10=154 & BIT_0=0 { - s:8 = 0; - t:8 = 0; - i:8 = 0; - x:8 = 0; - tmp:8 = 0; - - tmp = (S >> (64 - (i*8+7))); x = tmp & 1; # get bit - s = s ^ x; - if (i < 3) goto ; - i = 4; - - tmp = (S >> (64 - (i*8+7))); x = tmp & 1; # get bit - t = t ^ x; - if (i < 7) goto ; - tmp = t; # upper 4 bytes has t value - tmp = (tmp << 32); - tmp = tmp & s; # lower 4 bytes has s value - S = tmp; + local temp:8 = S; + A[0,32] = zext(((popcount(temp & 0x01010101:8)) & 1:8) == 1:8); + A[32,32] = zext(((popcount(temp & 0x0101010100000000:8)) & 1:8) == 1:8); } # ======================================================================= @@ -500,14 +487,7 @@ define pcodeop DivideWordExtended4; # binutils: power7.d: e0: 7e 8a 03 f4 popcntd r10,r20 # name popcntd code 7c0003f4 mask ffff00fc00000000 flags @POWER7 @A2 operands 31 3b 0 0 0 0 0 0 :popcntd A,S is $(NOTVLE) & OP=31 & S & A & XOP_1_10=506 & Rc & BITS_11_15=0 { - n:8 = 0; - i:8 = 0; - tmp:8 = 0; - - tmp = (S >> (64 - (i*8+7))); b:8 = tmp & 1; - n = n + b; - if (i < 63) goto ; - A = n; + A = popcount(S); } # ======================================================================= @@ -838,7 +818,7 @@ define pcodeop DetermineLeftmostZeroByte; if ( tmpX == 8 ) goto ; tmpX = tmpX + 1; - if ( ( ( tmpD << ( (tmpX - 1) * 8 ) ) & 0xFF00000000000000 ) != 0 ) goto ; + if ( ( ( tmpD << ( (tmpX-1) * 8 ) ) & 0xFF00000000000000 ) != 0 ) goto ; @@ -884,12 +864,12 @@ define pcodeop DetermineLeftmostZeroByte1; if ( tmpX == 8 ) goto ; - tmpX = tmpX + 1; + tmpX = tmpX + 1; if ( ( ( tmpD << ( (tmpX - 1) * 8 ) ) & 0xFF00000000000000 ) != 0 ) goto ; - # matched - tmpY = 1; + # matched + tmpY = 1; @@ -905,38 +885,22 @@ define pcodeop DetermineLeftmostZeroByte1; # Rc section # Set bit 35 of CR to SO -@ifdef BIT_64 - cr0 = ( cr0 & 0xFFFFFFFFEFFFFFFF ) | ( xer_so << 28 ); -@else - cr0 = ( cr0 & 0xEFFFFFFF ) | ( xer_so << 28 ); -@endif + cr0 = (cr0 & 0xe) | zext( xer_so & 1); + # Set bits 32:34 of CR if ( tmpY != 1 ) goto ; if ( tmpX >= 5 ) goto ; -@ifdef BIT_64 - cr0 = ( cr0 & 0xFFFFFFFF1FFFFFFF ) | 0x0000000040000000; -@else - cr0 = ( cr0 & 0x1FFFFFFF ) | 0x40000000; -@endif + cr0 = ( cr0 & 0x1 ) | 4; goto ; -@ifdef BIT_64 - cr0 = ( cr0 & 0xFFFFFFFF1FFFFFFF ) | 0x0000000080000000; -@else - cr0 = ( cr0 & 0x1FFFFFFF ) | 0x80000000; -@endif + cr0 = ( cr0 & 0x1 ) | 8; goto ; -@ifdef BIT_64 - cr0 = ( cr0 & 0xFFFFFFFF1FFFFFFF ) | 0x0000000020000000; -@else - cr0 = ( cr0 & 0x1FFFFFFF ) | 0x20000000; -@endif - + cr0 = ( cr0 & 0x1 ) | 2; } @@ -2733,9 +2697,8 @@ define pcodeop InstructionCacheBlockLockSetX; :setb D,BFA is $(NOTVLE) & OP=31 & BITS_11_17=0 & BIT_0=0 & XOP_1_10=128 & D & BFA { tmpcr:8 = 1 << (8 * BFA:1); - tmpr0:1 = (crall & tmpcr) != 0; - tmpr1:1 = (crall & (tmpcr << 1)) != 0; - + tmpr0:1 = (BFA & 0x8) != 0; + tmpr1:1 = (BFA & 0x4) != 0; D = (-1 * zext(tmpr0)) + (1 * zext(tmpr0 == 0) * zext(tmpr1)); } diff --git a/Ghidra/Processors/PowerPC/data/languages/ppc_vle.sinc b/Ghidra/Processors/PowerPC/data/languages/ppc_vle.sinc index edbc88ab6f..3b62834704 100644 --- a/Ghidra/Processors/PowerPC/data/languages/ppc_vle.sinc +++ b/Ghidra/Processors/PowerPC/data/languages/ppc_vle.sinc @@ -34,7 +34,7 @@ sd4WPlusRxAddr: SD4_VLE(RX_VLE) is SD4_VLE & RX_VLE {tmp:$(REGISTER_SIZE) = R OIMM: val is UI5_VLE [ val = UI5_VLE+1; ] { export *[const]:$(REGISTER_SIZE) val; } @if REGISTER_SIZE == "4" -SCALE: val is BIT_10 & SCL_VLE & IMM8 [ val = (((0xFFFFFFFF << ((SCL_VLE*8) + 8)) | (0xFFFFFFFF >> (32 - (SCL_VLE*8)))) * BIT_10) | IMM8; ] { export *[const]:4 val;} +SCALE: val is BIT_10 & SCL_VLE & IMM8 [ val = (((0xFFFFFFFF << ((SCL_VLE*8) + 8)) | (0xFFFFFFFF >> (32 - (SCL_VLE*8)))) * BIT_10) | (IMM8 << (SCL_VLE*8)); ] { export *[const]:4 val;} @else # Due to the way this big >> would work in java (arithmetic), we have to modify the orig way this was done. # (0xFFFFFFFFFFFFFFFF >> (64 - (SCL_VLE*8)) <--- Original