Create and use LZCOUNT Pcode op

This commit is contained in:
Pokechu22
2022-07-11 12:40:19 -07:00
parent 865cd22cab
commit 14880b53c4
47 changed files with 288 additions and 247 deletions

View File

@@ -2,7 +2,6 @@
<processor_spec>
<properties>
<property key="emulateInstructionStateModifierClass" value="ghidra.program.emulation.m68kEmulateInstructionStateModifier"/>
<property key="assemblyRating:68000:BE:32:default" value="PLATINUM"/>
</properties>
<programcounter register="PC"/>

View File

@@ -825,8 +825,6 @@ with : extGUARD=1 {
logflags(); tmp:4 = e2l; getbitfield(tmp, f_off, f_wd); f_reg = tmp; resbitflags(f_reg, f_wd-1);
}
define pcodeop countLeadingZeros;
:bfffo e2l{f_off:f_wd},f_reg is opbig=0xed & op67=3 & $(DAT_DIR_CTL_ADDR_MODES); f_off & f_wd & f_reg & flddo=0 & fldoffdat=0 & flddw=0 & fldwddat=0; e2l
[ savmod2=savmod1; regtsan=regtfan; ] {
# "Find First One in Bit Field" pronounced "boo-foe"
@@ -839,7 +837,7 @@ define pcodeop countLeadingZeros;
ZF = (tmp == 0);
VF = 0;
CF = 0;
tmp2:4 = countLeadingZeros(tmp);
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:4; # need mod for when there are all zeros, when tmp2 would = 32

View File

@@ -17,7 +17,6 @@ package ghidra.program.emulation;
import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.emulate.EmulateInstructionStateModifier;
import ghidra.pcode.emulate.callother.CountLeadingZerosOpBehavior;
import ghidra.pcode.emulate.callother.OpBehaviorOther;
import ghidra.pcode.memstate.MemoryState;
import ghidra.pcodeCPort.error.LowlevelError;
@@ -45,10 +44,6 @@ public class m68kEmulateInstructionStateModifier extends EmulateInstructionState
ISA_MODE0 = new RegisterValue(isaModeReg, BigInteger.ZERO);
*/
// These classes are defined here:
// ghidra/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/emulate/callother
registerPcodeOpBehavior("countLeadingZeros", new CountLeadingZerosOpBehavior());
registerPcodeOpBehavior("findFirstOne", new FindFirstOneOpBehavior());
}

View File

@@ -117,7 +117,6 @@ define context contextreg
ARMcondCk = (35,35) # Finished ARM condition check phase
;
define pcodeop count_leading_zeroes;
define pcodeop coprocessor_function;
define pcodeop coprocessor_function2;
define pcodeop coprocessor_load;

View File

@@ -1608,7 +1608,7 @@ define pcodeop IndexCheck;
:clz^ItCond Rd0811,Rm0003 is TMode=1 & ItCond & op4=0xfab & Rm0003; op12=15 & Rd0811
{
build ItCond;
Rd0811 = count_leading_zeroes(Rm0003);
Rd0811 = lzcount(Rm0003);
}
:cmn^ItCond Rn0003,ThumbExpandImm12 is TMode=1 & ItCond & (op11=0x1e & thc0909=0 & sop0508=8 & thc0404=1 & Rn0003; thc1515=0 & thc0811=15) & ThumbExpandImm12

View File

@@ -2484,7 +2484,7 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate
{
build COND;
build rm;
Rd = count_leading_zeroes(rm);
Rd = lzcount(rm);
}
@endif # VERSION_5

View File

@@ -19,7 +19,6 @@ import java.math.BigInteger;
import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.emulate.EmulateInstructionStateModifier;
import ghidra.pcode.emulate.callother.CountLeadingZerosOpBehavior;
import ghidra.pcode.error.LowlevelError;
import ghidra.program.model.address.Address;
import ghidra.program.model.lang.Register;
@@ -46,8 +45,6 @@ public class ARMEmulateInstructionStateModifier extends EmulateInstructionStateM
aMode = new RegisterValue(TModeReg, BigInteger.ZERO);
}
registerPcodeOpBehavior("count_leading_zeroes", new CountLeadingZerosOpBehavior());
/**
* We could registerPcodeOpBehavior for one or more of the following pcodeop's:
*
@@ -85,7 +82,6 @@ public class ARMEmulateInstructionStateModifier extends EmulateInstructionStateM
coprocessor_store2
coprocessor_storelong
coprocessor_storelong2
count_leading_zeroes
disableDataAbortInterrupts
disableFIQinterrupts
disableIRQinterrupts

View File

@@ -1001,12 +1001,6 @@ define pcodeop getCopRegH;
define pcodeop setCopReg;
define pcodeop setCopRegH;
# countLeadingOnes(val)
define pcodeop countLeadingOnes;
# countLeadingZeros(val)
define pcodeop countLeadingZeros;
# extractField(value, msbd, lsb)
define pcodeop extractField;

View File

@@ -980,13 +980,13 @@ define pcodeop SYNC;
# 0111 00ss ssst tttt dddd d000 0010 0001
:clo RD, RSsrc is $(AMODE) & REL6=0 & prime=0x1C & sa=0x0 & fct=0x21 & RD & RSsrc {
# Count leading ones in a word
RD = countLeadingOnes( RSsrc );
RD = lzcount( ~RSsrc );
}
# 0111 00ss ssst tttt dddd d000 0010 0000
:clz RD, RSsrc is $(AMODE) & REL6=0 & prime=0x1C & sa=0x0 & fct=0x20 & RD & RSsrc {
# Count leading zeros in a word
RD = countLeadingZeros( RSsrc );
RD = lzcount( RSsrc );
}
# 0000 00ss ssst tttt 0000 0000 0001 1010
@@ -1573,11 +1573,11 @@ define pcodeop SYNC;
}
:clo RD, RSsrc is $(AMODE) & REL6=1 & prime=0x00 & op=0 & sa=0x1 & fct=0x11 & RD & RSsrc {
RD = countLeadingOnes( RSsrc );
RD = lzcount( ~RSsrc );
}
:clz RD, RSsrc is $(AMODE) & REL6=1 & prime=0x00 & op=0 & sa=0x1 & fct=0x10 & RD & RSsrc {
RD = countLeadingZeros( RSsrc );
RD = lzcount( RSsrc );
}
:div RD, RS32src, RT32src is $(AMODE) & REL6=1 & prime=0x00 & fct=0x1A & fct2=0x02 & RD & RS32src & RT32src {

View File

@@ -7,11 +7,11 @@
# 0111 00ss ssst tttt dddd d000 0010 0101
:dclo RD, RSsrc is $(AMODE) & ((REL6=0 & prime=0x1C & sa=0x0 & fct=0x25) | (REL6=1 & prime=0x00 & sa=0x1 & fct=0x13 & op=0)) & RD & RSsrc {
RD = countLeadingOnes( RSsrc );
RD = lzcount( ~RSsrc );
}
# 0111 00ss ssst tttt dddd d000 0010 0100
:dclz RD, RSsrc is $(AMODE) & ((REL6=0 & prime=0x1C & sa=0x0 & fct=0x24) | (REL6=1 & prime=0x00 & sa=0x1 & fct=0x12 & op=0)) & RD & RSsrc {
RD = countLeadingZeros( RSsrc );
RD = lzcount( RSsrc );
}
# 0111 11ss ssst tttt mmmm mLLL LL00 0011

View File

@@ -697,11 +697,11 @@ STORE_TOP16: STORE_SREG^ra,EXT_CODE4E(sp) is mic_listr6 & REL6=1 & STORE_SREG &
}
:clo mic_rt32_5, RS0L is ISA_MODE=1 & RELP=0 & mic_op=0b000000 & mic_rt32_5 & RS0L ; micb_poolax=0b111100 & micb_axf=0b0100101100 {
mic_rt32_5 = countLeadingOnes( RS0L );
mic_rt32_5 = lzcount( ~RS0L );
}
:clz mic_rt32_5, RS0L is ISA_MODE=1 & RELP=0 & mic_op=0b000000 & mic_rt32_5 & RS0L ; micb_poolax=0b111100 & micb_axf=0b0101101100 {
mic_rt32_5 = countLeadingZeros( RS0L );
mic_rt32_5 = lzcount( RS0L );
}
:cop2 EXT_MU23 is ISA_MODE=1 & RELP=0 & mic_op=0b000000 & mic_code ; micb_cop=0b010 & EXT_MU23 [ ext_32_code=mic_code; ] {
@@ -1676,11 +1676,11 @@ STORE_TOP16: STORE_SREG^ra,EXT_CODE4E(sp) is mic_listr6 & REL6=1 & STORE_SREG &
}
:dclo mic_rt32_5, mic_rs32_0 is ISA_MODE=1 & RELP=0 & mic_op=0b010110 & mic_rt32_5 & mic_rs32_0 ; micb_poolax=0b111100 & micb_axf=0b0100101100 {
mic_rt32_5 = countLeadingOnes( mic_rs32_0 );
mic_rt32_5 = lzcount( ~mic_rs32_0 );
}
:dclz mic_rt32_5, mic_rs32_0 is ISA_MODE=1 & RELP=0 & mic_op=0b010110 & mic_rt32_5 & mic_rs32_0 ; micb_poolax=0b111100 & micb_axf=0b0101101100 {
mic_rt32_5 = countLeadingZeros( mic_rs32_0 );
mic_rt32_5 = lzcount( mic_rs32_0 );
}
:dext mic_rt32_5, mic_rs32_0, micb_pos, SIZEP is ISA_MODE=1 & RELP=0 & mic_op=0b010110 & REL6=1 & mic_rt32_5 & mic_rs32_0 ; micb_poolax=0b101100 & micb_pos & SIZEP {

View File

@@ -19,8 +19,6 @@ import java.math.BigInteger;
import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.emulate.EmulateInstructionStateModifier;
import ghidra.pcode.emulate.callother.CountLeadingOnesOpBehavior;
import ghidra.pcode.emulate.callother.CountLeadingZerosOpBehavior;
import ghidra.pcode.error.LowlevelError;
import ghidra.program.model.address.Address;
import ghidra.program.model.lang.Register;
@@ -49,13 +47,6 @@ public class MIPSEmulateInstructionStateModifier extends EmulateInstructionState
ISA_MODE0 = new RegisterValue(isaModeReg, BigInteger.ZERO);
}
// These classes are defined here:
// ghidra/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/emulate/callother
registerPcodeOpBehavior("countLeadingZeros", new CountLeadingZerosOpBehavior());
registerPcodeOpBehavior("countLeadingOnes", new CountLeadingOnesOpBehavior());
/**
* We could registerPcodeOpBehavior for one or more of the following
* pcodeop's:

View File

@@ -1415,7 +1415,6 @@ attach variables vrC_8_15 [vr0_8_15 vr1_8_15 vr2_8_15 vr3_8_15 vr4_8_15 vr5_8_15
################################################################
define pcodeop clearHistory;
define pcodeop countLeadingZeros;
define pcodeop countTrailingZeros;
define pcodeop dataCacheBlockAllocate;
define pcodeop dataCacheBlockFlush;

View File

@@ -814,13 +814,13 @@
#cntlzd r0,r0 0x7c 00 00 74
:cntlzd A,S is OP=31 & S & A & BITS_11_15=0 & XOP_1_10=58 & Rc=0
{
A = countLeadingZeros(S);
A = lzcount(S);
}
#cntlzd. r0,r0 0x7c 00 00 75
:cntlzd. A,S is OP=31 & S & A & BITS_11_15=0 & XOP_1_10=58 & Rc=1
{
A = countLeadingZeros(S);
A = lzcount(S);
cr0flags(A);
}
@endif
@@ -828,13 +828,13 @@
#cntlzw r0,r0 0x7c 00 00 34
:cntlzw A,S is OP=31 & S & A & BITS_11_15=0 & XOP_1_10=26 & Rc=0
{
A = countLeadingZeros(S:4);
A = lzcount(S:4);
}
#cntlzw. r0,r0 0x7c 00 00 35
:cntlzw. A,S is OP=31 & S & A & BITS_11_15=0 & XOP_1_10=26 & Rc=1
{
A = countLeadingZeros(S:4);
A = lzcount(S:4);
cr0flags(A);
}
#===========================================================

View File

@@ -19,7 +19,6 @@ import java.math.BigInteger;
import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.emulate.EmulateInstructionStateModifier;
import ghidra.pcode.emulate.callother.CountLeadingZerosOpBehavior;
import ghidra.pcode.emulate.callother.OpBehaviorOther;
import ghidra.pcode.memstate.MemoryState;
import ghidra.pcodeCPort.error.LowlevelError;
@@ -30,7 +29,6 @@ public class PPCEmulateInstructionStateModifier extends EmulateInstructionStateM
public PPCEmulateInstructionStateModifier(Emulate emu) {
super(emu);
registerPcodeOpBehavior("countLeadingZeros", new CountLeadingZerosOpBehavior());
registerPcodeOpBehavior("vectorPermute", new vectorPermuteOpBehavior());
}

View File

@@ -490,8 +490,6 @@ define pcodeop cache_index_ivld;
define pcodeop cache_index_wb;
define pcodeop cache_index_wi;
define pcodeop round16;
define pcodeop leading_ones;
define pcodeop leading_zeros;
define pcodeop leading_signs;
define pcodeop crc32;
@@ -1840,7 +1838,7 @@ SC: [a10]const0815Z10zz is PCPMode=0 & a10 & const0815Z10zz & op0003=8 & op0404=
# CLO D[c], D[a] (RR)
:clo Rd2831,Rd0811 is PCPMode=0 & Rd0811 & op0007=0xf & op1215=0x0 ; Rd2831 & op1627=0x1c0
{
Rd2831 = leading_ones(Rd0811);
Rd2831 = lzcount(~Rd0811);
}
# CLO.H D[c], D[a] (RR)
@@ -1848,8 +1846,8 @@ SC: [a10]const0815Z10zz is PCPMode=0 & a10 & const0815Z10zz & op0003=8 & op0404=
{
local tmp1:4 = zext(Rd0811[16,16]);
local tmp0:4 = zext(Rd0811[0,16]);
Rd2831[16,16] = leading_ones(tmp1);
Rd2831[0,16] = leading_ones(tmp0);
Rd2831[16,16] = lzcount(~tmp1);
Rd2831[0,16] = lzcount(~tmp0);
}
# CLS D[c], D[a] (RR)
@@ -1870,13 +1868,13 @@ SC: [a10]const0815Z10zz is PCPMode=0 & a10 & const0815Z10zz & op0003=8 & op0404=
# CLZ D[c], D[a] (RR)
:clz Rd2831,Rd0811 is PCPMode=0 & Rd0811 & op0007=0xf & op1215=0x0 ; Rd2831 & op1627=0x1b0
{
Rd2831 = leading_zeros(Rd0811);
Rd2831 = lzcount(Rd0811);
}
# CLZ.H D[c], D[a] (RR)
:clz.h Rd2831,Rd0811 is PCPMode=0 & Rd0811 & op0007=0xf & op1215=0x0 ; Rd2831 & op1627=0x7c0
{
local result:4 = (leading_zeros(Rd0811[16,16]) << 16) | leading_zeros(Rd0811[0,16]);
local result:4 = (lzcount(Rd0811[16,16]) << 16) | lzcount(Rd0811[0,16]);
Rd2831 = result;
}

View File

@@ -11,57 +11,22 @@ macro lzcntflags(input, output) {
:LZCNT Reg16, rm16 is vexMode=0 & opsize=0 & $(PRE_66) & $(PRE_F3) & byte=0x0F; byte=0xBD; Reg16 ... & rm16 {
countTmp:2 = 0;
inputTmp:2 = rm16;
<loopbegin>
if ((inputTmp & 0x8000) != 0) goto <loopend>;
countTmp = countTmp + 1;
inputTmp = (inputTmp << 1) | 1;
goto <loopbegin>;
<loopend>
lzcntflags(rm16, countTmp);
Reg16 = countTmp;
Reg16 = lzcount(rm16);
lzcntflags(rm16, Reg16);
}
:LZCNT Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0F; byte=0xBD; Reg32 ... & check_Reg32_dest ... & rm32 {
countTmp:4 = 0;
inputTmp:4 = rm32;
<loopbegin>
if ((inputTmp & 0x80000000) != 0) goto <loopend>;
countTmp = countTmp + 1;
inputTmp = (inputTmp << 1) | 1;
goto <loopbegin>;
<loopend>
lzcntflags(rm32, countTmp);
Reg32 = countTmp;
Reg32 = lzcount(rm32);
lzcntflags(rm32, Reg32);
build check_Reg32_dest;
}
@ifdef IA64
:LZCNT Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0xBD; Reg64 ... & rm64 {
countTmp:8 = 0;
inputTmp:8 = rm64;
<loopbegin>
if ((inputTmp & 0x8000000000000000) != 0) goto <loopend>;
countTmp = countTmp + 1;
inputTmp = (inputTmp << 1) | 1;
goto <loopbegin>;
<loopend>
lzcntflags(rm64, countTmp);
Reg64 = countTmp;
Reg64 = lzcount(rm64);
lzcntflags(rm64, Reg64);
}
@endif