From cb00405c98bb20e57145cad68c2cae566e229a5c Mon Sep 17 00:00:00 2001 From: caheckman <48068198+caheckman@users.noreply.github.com> Date: Sat, 28 Oct 2023 00:13:32 +0000 Subject: [PATCH 1/3] GP-3981 Fix CPUI_FLOAT_NAN case --- Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc index 55a3bdd579..86652ccaef 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc @@ -9110,12 +9110,12 @@ bool RuleConditionalMove::BoolExpress::initialize(Varnode *vn) case CPUI_FLOAT_NOTEQUAL: case CPUI_FLOAT_LESS: case CPUI_FLOAT_LESSEQUAL: - case CPUI_FLOAT_NAN: in0 = op->getIn(0); in1 = op->getIn(1); optype = 2; break; case CPUI_BOOL_NEGATE: + case CPUI_FLOAT_NAN: in0 = op->getIn(0); optype = 1; break; From 6d7dc046f023f0c7b2f2956f62d21f086ba216d5 Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Fri, 3 Nov 2023 12:30:13 -0400 Subject: [PATCH 2/3] GP-3677: Fixed pop instructions with stack-pointer-based operands --- Ghidra/Processors/x86/data/languages/ia.sinc | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Ghidra/Processors/x86/data/languages/ia.sinc b/Ghidra/Processors/x86/data/languages/ia.sinc index 6bc2423d5d..82e10937be 100644 --- a/Ghidra/Processors/x86/data/languages/ia.sinc +++ b/Ghidra/Processors/x86/data/languages/ia.sinc @@ -3295,22 +3295,22 @@ define pcodeop swap_bytes; :PAUSE is vexMode=0 & opsize=0 & $(PRE_F3) & byte=0x90 { } :PAUSE is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x90 { } -:POP rm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0x8f; rm16 & reg_opcode=0 ... { pop22(rm16); } -:POP rm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0x8f; rm16 & reg_opcode=0 ... { pop42(rm16); } -:POP rm32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0x8f; rm32 & reg_opcode=0 ... { pop24(rm32); } -:POP rm32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0x8f; rm32 & reg_opcode=0 ... { pop44(rm32); } +:POP rm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0x8f; rm16 & reg_opcode=0 ... { local val:2 = 0; pop22(val); build rm16; rm16 = val; } +:POP rm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0x8f; rm16 & reg_opcode=0 ... { local val:2 = 0; pop42(val); build rm16; rm16 = val; } +:POP rm32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0x8f; rm32 & reg_opcode=0 ... { local val:4 = 0; pop24(val); build rm32; rm32 = val; } +:POP rm32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0x8f; rm32 & reg_opcode=0 ... { local val:4 = 0; pop44(val); build rm32; rm32 = val; } @ifdef IA64 -:POP rm16 is $(LONGMODE_ON) & vexMode=0 & opsize=0 & byte=0x8f; rm16 & reg_opcode=0 ... { pop82(rm16); } -:POP rm64 is $(LONGMODE_ON) & vexMode=0 & byte=0x8f; rm64 & reg_opcode=0 ... { pop88(rm64); } +:POP rm16 is $(LONGMODE_ON) & vexMode=0 & opsize=0 & byte=0x8f; rm16 & reg_opcode=0 ... { local val:2 = 0; pop82(val); build rm16; rm16 = val; } +:POP rm64 is $(LONGMODE_ON) & vexMode=0 & byte=0x8f; rm64 & reg_opcode=0 ... { local val:8 = 0; pop88(val); build rm64; rm64 = val; } @endif -:POP Rmr16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & row=5 & page=1 & Rmr16 { pop22(Rmr16); } -:POP Rmr16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & row=5 & page=1 & Rmr16 { pop42(Rmr16); } -:POP Rmr32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & row=5 & page=1 & Rmr32 { pop24(Rmr32); } -:POP Rmr32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & row=5 & page=1 & Rmr32 { pop44(Rmr32); } +:POP Rmr16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & row=5 & page=1 & Rmr16 { local val:2 = 0; pop22(val); Rmr16 = val; } +:POP Rmr16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & row=5 & page=1 & Rmr16 { local val:2 = 0; pop22(val); Rmr16 = val; } +:POP Rmr32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & row=5 & page=1 & Rmr32 { local val:4 = 0; pop44(val); Rmr32 = val; } +:POP Rmr32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & row=5 & page=1 & Rmr32 { local val:4 = 0; pop44(val); Rmr32 = val; } @ifdef IA64 -:POP Rmr16 is $(LONGMODE_ON) & vexMode=0 & opsize=0 & row=5 & page=1 & Rmr16 { pop82(Rmr16); } -:POP Rmr64 is $(LONGMODE_ON) & vexMode=0 & row=5 & page=1 & Rmr64 { pop88(Rmr64); } +:POP Rmr16 is $(LONGMODE_ON) & vexMode=0 & opsize=0 & row=5 & page=1 & Rmr16 { local val:2 = 0; pop82(val); Rmr16 = val; } +:POP Rmr64 is $(LONGMODE_ON) & vexMode=0 & row=5 & page=1 & Rmr64 { local val:8 = 0; pop88(val); Rmr64 = val; } @endif :POP DS is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & byte=0x1f & DS { pop22(DS); } From 3d1b865543b5b91976c8ddad9ab78ecc2d1e939b Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Fri, 3 Nov 2023 12:30:51 -0400 Subject: [PATCH 3/3] GP-3879: Implemented lzcount in several instructions --- .../68000/data/languages/68000.sinc | 25 +-- .../AARCH64/data/languages/AARCH64base.sinc | 63 +------ .../data/languages/avr32a_bit_operations.sinc | 162 +----------------- .../HCS12/data/languages/XGATE.sinc | 6 +- .../tricore/data/languages/tricore.sinc | 17 +- 5 files changed, 33 insertions(+), 240 deletions(-) diff --git a/Ghidra/Processors/68000/data/languages/68000.sinc b/Ghidra/Processors/68000/data/languages/68000.sinc index 504b1deb0f..c33f4be592 100644 --- a/Ghidra/Processors/68000/data/languages/68000.sinc +++ b/Ghidra/Processors/68000/data/languages/68000.sinc @@ -1065,21 +1065,25 @@ with : extGUARD=1 { # f_off and f_wd specify the offset and width of the field of the source to consider. # If f_off=0 and f_wd=0 then this means the full 32-bit source is examined (implemented here). # - tmp:4 = e2l; + local tmp:4 = e2l; NF = (tmp & 0x80000000) != 0; ZF = (tmp == 0); VF = 0; CF = 0; - tmp2:4 = lzcount(tmp); - # NB- it seems the MSB left most bit is really at offset 0, - # and the right LSB is at offset 31 - tmp3:4 = (tmp2 % 32); # need mod for when there are all zeros, when tmp2 would = 32 - f_reg = tmp3; + f_reg = zext(tmp != 0) * lzcount(tmp); } -# TODO: complete bfffo for when f_off or f_wd !=0, and for when f_off and f_wd are in registers -:bfffo e2l{f_off:f_wd},f_reg is opbig=0xed & op67=3 & $(DAT_DIR_CTL_ADDR_MODES); f_off & f_wd & f_reg ; e2l - [ savmod2=savmod1; regtsan=regtfan; ] unimpl +:bfffo e2l{f_off:f_wd},f_reg is opbig=0xed & op67=3 & $(DAT_DIR_CTL_ADDR_MODES); f_off & f_wd & f_reg ; e2l [ savmod2=savmod1; regtsan=regtfan; ] { + local tmp:4 = e2l; + tmp = (tmp << f_off) >> (32 - f_wd); + tmp = (tmp << (32 - f_wd)); + local offw = f_off + f_wd; + NF = (tmp & 0x80000000) != 0; + ZF = (tmp == 0); + VF = 0; + CF = 0; + f_reg = (zext(tmp != 0) * lzcount(tmp)) + (zext(tmp == 0) * zext(offw)); +} :bfins f_reg,e2l{f_off:f_wd} is opbig=0xef & op67=3 & $(DAT_DIR_CTL_ADDR_MODES); f_off & f_wd & f_reg; e2l [ savmod2=savmod1; regtsan=regtfan; ] { @@ -2930,10 +2934,9 @@ accreg: ACC1 is ACC1 & acclsb=1 ; accmsb=0 { export ACC1; } accreg: ACC2 is ACC2 & acclsb=0 ; accmsb=1 { export ACC2; } accreg: ACC3 is ACC3 & acclsb=1 ; accmsb=1 { export ACC3; } -define pcodeop findFirstOne; :ff1 regdn is reg315=0x98 & regdn { - regdn = findFirstOne(regdn); + regdn = lzcount(regdn); VF = 0; CF = 0; resflags(regdn); diff --git a/Ghidra/Processors/AARCH64/data/languages/AARCH64base.sinc b/Ghidra/Processors/AARCH64/data/languages/AARCH64base.sinc index b9c0ccb649..6fb9d2e799 100644 --- a/Ghidra/Processors/AARCH64/data/languages/AARCH64base.sinc +++ b/Ghidra/Processors/AARCH64/data/languages/AARCH64base.sinc @@ -1445,19 +1445,8 @@ is b_2431=0xd5 & b_2223=0 & l=0 & Op0=0 & Op1=3 & CRn=0x3 & CRm_uimm4_def15 & Op is sf=0 & b_3030=1 & S=0 & b_2428=0x1a & b_2123=6 & dp1.opcode2=0x0 & b_1015=0x5 & Rn_GPR32 & Rd_GPR32 & Rd_GPR64 { local tmp:4 = (Rn_GPR32 ^ (Rn_GPR32<<1))|0x1; - # first make all lower bits =1 - tmp = tmp | (tmp >> 1); - tmp = tmp | (tmp >> 2); - tmp = tmp | (tmp >> 4); - tmp = tmp | (tmp >> 8); - tmp = tmp | (tmp >> 16); - # now add the 1 bits together, voila - tmp = ((tmp & 0xaaaaaaaa)>>1) + (tmp & 0x55555555); - tmp = ((tmp & 0xcccccccc)>>2) + (tmp & 0x33333333); - tmp = ((tmp & 0xf0f0f0f0)>>4) + (tmp & 0x0f0f0f0f); - tmp = ((tmp & 0xff00ff00)>>8) + (tmp & 0x00ff00ff); - tmp = ((tmp & 0xffff0000)>>16) + (tmp & 0x0000ffff); - Rd_GPR64 = zext(32 - (tmp & 0x3f)); + + Rd_GPR64 = lzcount(tmp); } # C6.2.57 CLS page C6-1243 line 72939 MATCH x5ac01400/mask=x7ffffc00 @@ -1468,21 +1457,8 @@ is sf=0 & b_3030=1 & S=0 & b_2428=0x1a & b_2123=6 & dp1.opcode2=0x0 & b_1015=0x5 is sf=1 & b_3030=1 & S=0 & b_2428=0x1a & b_2123=6 & dp1.opcode2=0x0 & b_1015=0x5 & Rn_GPR64 & Rd_GPR64 { local tmp:8 = (Rn_GPR64 ^ (Rn_GPR64<<1))|0x1; - # first make all lower bits =1 - tmp = tmp | (tmp >> 1); - tmp = tmp | (tmp >> 2); - tmp = tmp | (tmp >> 4); - tmp = tmp | (tmp >> 8); - tmp = tmp | (tmp >> 16); - tmp = tmp | (tmp >> 32); - # now add the 1 bits together, voila - tmp = ((tmp & 0xaaaaaaaaaaaaaaaa)>>1) + (tmp & 0x5555555555555555); - tmp = ((tmp & 0xcccccccccccccccc)>>2) + (tmp & 0x3333333333333333); - tmp = ((tmp & 0xf0f0f0f0f0f0f0f0)>>4) + (tmp & 0x0f0f0f0f0f0f0f0f); - tmp = ((tmp & 0xff00ff00ff00ff00)>>8) + (tmp & 0x00ff00ff00ff00ff); - tmp = ((tmp & 0xffff0000ffff0000)>>16) + (tmp & 0x0000ffff0000ffff); - tmp = ((tmp & 0xffffffff00000000)>>32) + (tmp & 0x00000000ffffffff); - Rd_GPR64 = 64 - (tmp & 0x7f); + + Rd_GPR64 = lzcount(tmp); } # C6.2.58 CLZ page C6-1245 line 73022 MATCH x5ac01000/mask=x7ffffc00 @@ -1493,19 +1469,7 @@ is sf=1 & b_3030=1 & S=0 & b_2428=0x1a & b_2123=6 & dp1.opcode2=0x0 & b_1015=0x5 is sf=0 & b_3030=1 & S=0 & b_2428=0x1a & b_2123=6 & dp1.opcode2=0x0 & b_1015=0x4 & Rn_GPR32 & Rd_GPR32 & Rd_GPR64 { local tmp:4 = Rn_GPR32; - # first make all lower bits =1 - tmp = tmp | (tmp >> 1); - tmp = tmp | (tmp >> 2); - tmp = tmp | (tmp >> 4); - tmp = tmp | (tmp >> 8); - tmp = tmp | (tmp >> 16); - # now add the 1 bits together, voila - tmp = ((tmp & 0xaaaaaaaa)>>1) + (tmp & 0x55555555); - tmp = ((tmp & 0xcccccccc)>>2) + (tmp & 0x33333333); - tmp = ((tmp & 0xf0f0f0f0)>>4) + (tmp & 0x0f0f0f0f); - tmp = ((tmp & 0xff00ff00)>>8) + (tmp & 0x00ff00ff); - tmp = ((tmp & 0xffff0000)>>16) + (tmp & 0x0000ffff); - Rd_GPR64 = zext(32 - (tmp & 0x3f)); + Rd_GPR64 = lzcount(tmp); } # C6.2.58 CLZ page C6-1245 line 73022 MATCH x5ac01000/mask=x7ffffc00 @@ -1516,21 +1480,8 @@ is sf=0 & b_3030=1 & S=0 & b_2428=0x1a & b_2123=6 & dp1.opcode2=0x0 & b_1015=0x4 is sf=1 & b_3030=1 & S=0 & b_2428=0x1a & b_2123=6 & dp1.opcode2=0x0 & b_1015=0x4 & Rn_GPR64 & Rd_GPR64 { local tmp:8 = Rn_GPR64; - # first make all lower bits =1 - tmp = tmp | (tmp >> 1); - tmp = tmp | (tmp >> 2); - tmp = tmp | (tmp >> 4); - tmp = tmp | (tmp >> 8); - tmp = tmp | (tmp >> 16); - tmp = tmp | (tmp >> 32); - # now add the 1 bits together, voila - tmp = ((tmp & 0xaaaaaaaaaaaaaaaa)>>1) + (tmp & 0x5555555555555555); - tmp = ((tmp & 0xcccccccccccccccc)>>2) + (tmp & 0x3333333333333333); - tmp = ((tmp & 0xf0f0f0f0f0f0f0f0)>>4) + (tmp & 0x0f0f0f0f0f0f0f0f); - tmp = ((tmp & 0xff00ff00ff00ff00)>>8) + (tmp & 0x00ff00ff00ff00ff); - tmp = ((tmp & 0xffff0000ffff0000)>>16) + (tmp & 0x0000ffff0000ffff); - tmp = ((tmp & 0xffffffff00000000)>>32) + (tmp & 0x00000000ffffffff); - Rd_GPR64 = 64 - (tmp & 0x7f); + + Rd_GPR64 = lzcount(tmp); } # C6.2.59 CMN (extended register) page C6-1246 line 73092 MATCH x2b20001f/mask=x7fe0001f diff --git a/Ghidra/Processors/Atmel/data/languages/avr32a_bit_operations.sinc b/Ghidra/Processors/Atmel/data/languages/avr32a_bit_operations.sinc index df6b05c04b..7b74ff4543 100644 --- a/Ghidra/Processors/Atmel/data/languages/avr32a_bit_operations.sinc +++ b/Ghidra/Processors/Atmel/data/languages/avr32a_bit_operations.sinc @@ -231,167 +231,7 @@ CSBRH: off is bp9_4 & bp4_1 :CLZ rd0, RS9A is op13_3=0x7 & op4_5=0x0 & rd0 & RS9A ; eop0_16=0x1200 { - continueloop:4 = 1; - count:4 = 0; - mask:4 = 0x80000000; - - test:4 = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - count = count + test * continueloop; - continueloop = continueloop * test; - mask = mask >> 1; - - test = zext((mask & RS9A) == 0); - rd0 = count + test * continueloop; + rd0 = lzcount(RS9A); Z = (rd0 == 0); C = (rd0 == 32); diff --git a/Ghidra/Processors/HCS12/data/languages/XGATE.sinc b/Ghidra/Processors/HCS12/data/languages/XGATE.sinc index c03f63b6a0..fb41da5c59 100644 --- a/Ghidra/Processors/HCS12/data/languages/XGATE.sinc +++ b/Ghidra/Processors/HCS12/data/languages/XGATE.sinc @@ -54,7 +54,6 @@ attach variables [reg8_hi ] [R0.H R1.H R2.H R3.H R4.H R5.H R6.H R7.H]; # Pseudo Instructions ################################################################ -define pcodeop findFirstOne; define pcodeop leftShiftCarry; define pcodeop rightShiftCarry; define pcodeop parity; @@ -277,9 +276,8 @@ rd_hi: reg8 is reg8 & reg8_hi { export reg8_hi; } { # 15 - count leading zeros tmp:2 = rs1; - $(XC) = (rd == 0); - #TODO: implement findFirstOne behavior - rd = findFirstOne(tmp); + $(XC) = (rs1 == 0); + rd = zext(tmp != 0) * (15 - lzcount(tmp)); default_flags(rd); } diff --git a/Ghidra/Processors/tricore/data/languages/tricore.sinc b/Ghidra/Processors/tricore/data/languages/tricore.sinc index 1c20278230..adffa29601 100644 --- a/Ghidra/Processors/tricore/data/languages/tricore.sinc +++ b/Ghidra/Processors/tricore/data/languages/tricore.sinc @@ -490,7 +490,6 @@ define pcodeop cache_index_ivld; define pcodeop cache_index_wb; define pcodeop cache_index_wi; define pcodeop round16; -define pcodeop leading_signs; define pcodeop crc32; # float @@ -1844,8 +1843,8 @@ SC: [a10]const0815Z10zz is PCPMode=0 & a10 & const0815Z10zz & op0003=8 & op0404= # CLO.H D[c], D[a] (RR) :clo.h Rd2831,Rd0811 is PCPMode=0 & Rd0811 & op0007=0xf & op1215=0x0 ; Rd2831 & op1627=0x7d0 { - local tmp1:4 = zext(Rd0811[16,16]); - local tmp0:4 = zext(Rd0811[0,16]); + local tmp1:2 = Rd0811[16,16]; + local tmp0:2 = Rd0811[0,16]; Rd2831[16,16] = lzcount(~tmp1); Rd2831[0,16] = lzcount(~tmp0); } @@ -1853,16 +1852,18 @@ SC: [a10]const0815Z10zz is PCPMode=0 & a10 & const0815Z10zz & op0003=8 & op0404= # CLS D[c], D[a] (RR) :cls Rd2831,Rd0811 is PCPMode=0 & Rd0811 & op0007=0xf & op1215=0x0 ; Rd2831 & op1627=0x1d0 { - Rd2831 = leading_signs(Rd0811) - 1; + local tmp:4 = (Rd0811 ^ (Rd0811<<1))|0x1; + + Rd2831 = lzcount(tmp); } # CLS.H D[c], D[a] (RR) :cls.h Rd2831,Rd0811 is PCPMode=0 & Rd0811 & op0007=0xf & op1215=0x0 ; Rd2831 & op1627=0x7e0 { - local tmp1:4 = zext(Rd0811[16,16]); - local tmp0:4 = zext(Rd0811[0,16]); - Rd2831[16,16] = leading_signs(tmp1) - 1; - Rd2831[0,16] = leading_signs(tmp0) - 1; + local tmp1:2 = (Rd0811[16,16] ^ (Rd0811[16,16]<<1))|0x1; + local tmp0:2 = (Rd0811[0,16] ^ (Rd0811[0,16]<<1))|0x1; + Rd2831[16,16] = lzcount(tmp1); + Rd2831[0,16] = lzcount(tmp0); } # CLZ D[c], D[a] (RR)