mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-3879: Implemented lzcount in several instructions
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user