mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
Create and use LZCOUNT Pcode op
This commit is contained in:
@@ -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"/>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
#===========================================================
|
||||
|
||||
@@ -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());
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user