Merge remote-tracking branch 'origin/patch'

This commit is contained in:
Ryan Kurtz 2024-03-08 08:54:02 -05:00
commit 1cc9abad50
13 changed files with 506 additions and 41 deletions

View file

@ -129,6 +129,16 @@ PCodeTest({
'proc_test': 'arm', 'proc_test': 'arm',
}) })
PCodeTest({
'name': 'ARM_v8m',
'build_all': 1,
'build_exe': 1,
'qemu_command': 'qemu-arm -cpu cortex-m33',
'toolchain': 'ARM/arm-eabi',
'ccflags': '-mthumb -march=armv8-m.main -mfloat-abi=softfp -L %(toolchain_dir)s/lib/gcc/arm-eabi/%(gcc_version)s/thumb -lgcc',
'language_id': 'ARM:LE:32:Cortexv8m',
})
PCodeTest({ PCodeTest({
'name': 'AARCH64', 'name': 'AARCH64',
'build_all': 1, 'build_all': 1,

View file

@ -2162,6 +2162,26 @@ int4 ActionLikelyTrash::apply(Funcdata &data)
return 0; return 0;
} }
/// Return \b true if either the Varnode is a constant or if it is the not yet simplified
/// INT_ADD of constants.
/// \param vn is the given Varnode to test
/// \return \b true if the Varnode will be a constant
bool ActionRestructureVarnode::isDelayedConstant(Varnode *vn)
{
if (vn->isConstant()) return true;
if (!vn->isWritten()) return false;
PcodeOp *op = vn->getDef();
if (op->code() != CPUI_INT_ADD) return false;
if (!op->getIn(1)->isConstant()) return false;
Varnode *cvn = op->getIn(0);
if (cvn->isConstant()) return true;
if (!cvn->isWritten()) return false;
PcodeOp *copy = cvn->getDef();
if (copy->code() != CPUI_COPY) return false;
return copy->getIn(0)->isConstant();
}
/// Test if the path to the given BRANCHIND originates from a constant but passes through INDIRECT operations. /// Test if the path to the given BRANCHIND originates from a constant but passes through INDIRECT operations.
/// This indicates that the switch value is produced indirectly, so we mark these INDIRECT /// This indicates that the switch value is produced indirectly, so we mark these INDIRECT
/// operations as \e not \e collapsible, to guarantee that the indirect value is not lost during analysis. /// operations as \e not \e collapsible, to guarantee that the indirect value is not lost during analysis.
@ -2176,9 +2196,16 @@ void ActionRestructureVarnode::protectSwitchPathIndirects(PcodeOp *op)
uint4 evalType = curOp->getEvalType(); uint4 evalType = curOp->getEvalType();
if ((evalType & (PcodeOp::binary | PcodeOp::ternary)) != 0) { if ((evalType & (PcodeOp::binary | PcodeOp::ternary)) != 0) {
if (curOp->numInput() > 1) { if (curOp->numInput() > 1) {
if (!curOp->getIn(1)->isConstant()) return; // Multiple paths if (isDelayedConstant(curOp->getIn(1)))
curVn = curOp->getIn(0);
else if (isDelayedConstant(curOp->getIn(0)))
curVn = curOp->getIn(1);
else
return; // Multiple paths
}
else {
curVn = curOp->getIn(0);
} }
curVn = curOp->getIn(0);
} }
else if ((evalType & PcodeOp::unary) != 0) else if ((evalType & PcodeOp::unary) != 0)
curVn = curOp->getIn(0); curVn = curOp->getIn(0);

View file

@ -832,6 +832,7 @@ public:
/// This produces on intermediate view of symbols on the stack. /// This produces on intermediate view of symbols on the stack.
class ActionRestructureVarnode : public Action { class ActionRestructureVarnode : public Action {
int4 numpass; ///< Number of passes performed for this function int4 numpass; ///< Number of passes performed for this function
static bool isDelayedConstant(Varnode *vn); ///< Determine if given Varnode is or will be a constant
static void protectSwitchPathIndirects(PcodeOp *op); ///< Protect path to the given switch from INDIRECT collapse static void protectSwitchPathIndirects(PcodeOp *op); ///< Protect path to the given switch from INDIRECT collapse
static void protectSwitchPaths(Funcdata &data); ///< Look for switches and protect path of switch variable static void protectSwitchPaths(Funcdata &data); ///< Look for switches and protect path of switch variable
public: public:

View file

@ -20,8 +20,11 @@ data/languages/ARM7_be.slaspec||GHIDRA||||END|
data/languages/ARM7_le.slaspec||GHIDRA||||END| data/languages/ARM7_le.slaspec||GHIDRA||||END|
data/languages/ARM8_be.slaspec||GHIDRA||||END| data/languages/ARM8_be.slaspec||GHIDRA||||END|
data/languages/ARM8_le.slaspec||GHIDRA||||END| data/languages/ARM8_le.slaspec||GHIDRA||||END|
data/languages/ARM8m_be.slaspec||GHIDRA||||END|
data/languages/ARM8m_le.slaspec||GHIDRA||||END|
data/languages/ARMCortex.pspec||GHIDRA||||END| data/languages/ARMCortex.pspec||GHIDRA||||END|
data/languages/ARMTHUMBinstructions.sinc||GHIDRA||||END| data/languages/ARMTHUMBinstructions.sinc||GHIDRA||||END|
data/languages/ARM_CDE.sinc||GHIDRA||||END|
data/languages/ARM_v45.cspec||GHIDRA||||END| data/languages/ARM_v45.cspec||GHIDRA||||END|
data/languages/ARM_v45.pspec||GHIDRA||||END| data/languages/ARM_v45.pspec||GHIDRA||||END|
data/languages/ARM_win.cspec||GHIDRA||||END| data/languages/ARM_win.cspec||GHIDRA||||END|

View file

@ -16,9 +16,6 @@
<external_name tool="gnu" name="iwmmxt"/> <external_name tool="gnu" name="iwmmxt"/>
<external_name tool="gnu" name="armv8-a"/> <external_name tool="gnu" name="armv8-a"/>
<external_name tool="gnu" name="armv8-r"/> <external_name tool="gnu" name="armv8-r"/>
<external_name tool="gnu" name="armv8-m.base"/>
<external_name tool="gnu" name="armv8-m.main"/>
<external_name tool="gnu" name="armv8.1-m.main"/>
<external_name tool="gnu" name="arm_any"/> <external_name tool="gnu" name="arm_any"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/> <external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="arm"/> <external_name tool="IDA-PRO" name="arm"/>
@ -76,9 +73,6 @@
<external_name tool="gnu" name="iwmmxt"/> <external_name tool="gnu" name="iwmmxt"/>
<external_name tool="gnu" name="armv8-a"/> <external_name tool="gnu" name="armv8-a"/>
<external_name tool="gnu" name="armv8-r"/> <external_name tool="gnu" name="armv8-r"/>
<external_name tool="gnu" name="armv8-m.base"/>
<external_name tool="gnu" name="armv8-m.main"/>
<external_name tool="gnu" name="armv8.1-m.main"/>
<external_name tool="gnu" name="arm_any"/> <external_name tool="gnu" name="arm_any"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/> <external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="armb"/> <external_name tool="IDA-PRO" name="armb"/>
@ -175,6 +169,7 @@
<external_name tool="gnu" name="armv6kz"/> <external_name tool="gnu" name="armv6kz"/>
<external_name tool="gnu" name="armv6-m"/> <external_name tool="gnu" name="armv6-m"/>
<external_name tool="gnu" name="armv6s-m"/> <external_name tool="gnu" name="armv6s-m"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="arm"/> <external_name tool="IDA-PRO" name="arm"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/> <external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
<external_name tool="qemu" name="qemu-arm"/> <external_name tool="qemu" name="qemu-arm"/>
@ -195,11 +190,47 @@
<external_name tool="gnu" name="armv6kz"/> <external_name tool="gnu" name="armv6kz"/>
<external_name tool="gnu" name="armv6-m"/> <external_name tool="gnu" name="armv6-m"/>
<external_name tool="gnu" name="armv6s-m"/> <external_name tool="gnu" name="armv6s-m"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="armb"/> <external_name tool="IDA-PRO" name="armb"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/> <external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
<external_name tool="qemu" name="qemu-armeb"/> <external_name tool="qemu" name="qemu-armeb"/>
</language> </language>
<language processor="ARM"
endian="little"
size="32"
variant="v8-m"
version="1.107"
slafile="ARM8m_le.sla"
processorspec="ARMCortex.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:LE:32:v8-m">
<description>ARM Cortex v8-m little endian</description>
<compiler name="default" spec="ARM.cspec" id="default"/>
<external_name tool="gnu" name="armv8-m.base"/>
<external_name tool="gnu" name="armv8-m.main"/>
<external_name tool="gnu" name="armv8.1-m.main"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
</language>
<language processor="ARM"
endian="big"
size="32"
variant="v8-m"
version="1.107"
slafile="ARM8m_be.sla"
processorspec="ARMCortex.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:BE:32:v8-m">
<description>ARM Cortex v8-m big endian</description>
<compiler name="default" spec="ARM.cspec" id="default"/>
<external_name tool="gnu" name="armv8-m.base"/>
<external_name tool="gnu" name="armv8-m.main"/>
<external_name tool="gnu" name="armv8.1-m.main"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
</language>
<language processor="ARM" <language processor="ARM"
endian="little" endian="little"
size="32" size="32"

View file

@ -15,7 +15,7 @@ define register offset=0x0084 size=4 [ r14_svc r13_svc spsr_svc ];
define register offset=0x0090 size=8 [ mult_dat8 ]; # Special internal register for dealing with multiple stores/loads define register offset=0x0090 size=8 [ mult_dat8 ]; # Special internal register for dealing with multiple stores/loads
define register offset=0x0090 size=16 [ mult_dat16 ]; # Special internal register for dealing with multiple stores/loads define register offset=0x0090 size=16 [ mult_dat16 ]; # Special internal register for dealing with multiple stores/loads
define register offset=0x00A0 size=4 [ fpsr ]; # floating point state register (for FPA10 floating-point accelerator) define register offset=0x00A0 size=4 [ fpsr ]; # floating point state register (for FPA10 floating-point accelerator)
define register offset=0x00B0 size=1 [ ISAModeSwitch ]; # generic name for TB ThumbBit - set same as TB define register offset=0x0078 size=1 [ ISAModeSwitch ]; # generic name for TB ThumbBit - set same as TB
@define FPSCR_N "fpscr[31,1]" @define FPSCR_N "fpscr[31,1]"
@define FPSCR_Z "fpscr[30,1]" @define FPSCR_Z "fpscr[30,1]"
@ -23,7 +23,7 @@ define register offset=0x00B0 size=1 [ ISAModeSwitch ]; # generic name for TB T
@define FPSCR_V "fpscr[28,1]" @define FPSCR_V "fpscr[28,1]"
@if defined(VFPv2) || defined(VFPv3) || defined(SIMD) @if defined(VFPv2) || defined(VFPv3) || defined(SIMD)
define register offset=0x00B0 size=4 [ fpsid fpscr fpexc mvfr0 mvfr1 ]; define register offset=0x00B0 size=4 [ fpsid fpscr fpexc mvfr0 mvfr1 ];
@endif @endif
define register offset=0x0100 size=10 [ fp0 fp1 fp2 fp3 fp4 fp5 fp6 fp7 ]; # eight 80-bit floating registers define register offset=0x0100 size=10 [ fp0 fp1 fp2 fp3 fp4 fp5 fp6 fp7 ]; # eight 80-bit floating registers

View file

@ -0,0 +1,19 @@
@define ENDIAN "big"
@define T_VARIANT ""
@define VERSION_5 ""
@define VERSION_5E ""
@define VERSION_6 ""
@define VERSION_6K ""
@define VERSION_6T2 ""
@define VERSION_7 ""
@define VERSION_7M ""
@define VERSION_8 ""
@define SIMD ""
@define CDE ""
@define CORTEX ""
@define VFPv3 ""
@define VFPv4 ""
@include "ARM.sinc"
@include "ARM_CDE.sinc"

View file

@ -0,0 +1,19 @@
@define ENDIAN "little"
@define T_VARIANT ""
@define VERSION_5 ""
@define VERSION_5E ""
@define VERSION_6 ""
@define VERSION_6K ""
@define VERSION_6T2 ""
@define VERSION_7 ""
@define VERSION_7M ""
@define VERSION_8 ""
@define SIMD ""
@define CDE ""
@define CORTEX ""
@define VFPv3 ""
@define VFPv4 ""
@include "ARM.sinc"
@include "ARM_CDE.sinc"

View file

@ -40,6 +40,7 @@ define token instrThumb (16)
op9=(9,15) op9=(9,15)
op11=(11,15) op11=(11,15)
op12=(12,15) op12=(12,15)
op13=(13,15)
op0=(0,15) op0=(0,15)
sop0407=(4,7) sop0407=(4,7)
sop0507=(5,7) sop0507=(5,7)
@ -55,8 +56,10 @@ define token instrThumb (16)
Rd0003=(0,3) Rd0003=(0,3)
Rd0810=(8,10) Rd0810=(8,10)
Rd0811=(8,11) Rd0811=(8,11)
Rd1215hi=(12,15)
Rn0002=(0,2) Rn0002=(0,2)
Rn0003=(0,3) Rn0003=(0,3)
Rd0003hi=(0,3)
Rn0305=(3,5) Rn0305=(3,5)
Rn0810=(8,10) Rn0810=(8,10)
Rm0305=(3,5) Rm0305=(3,5)
@ -106,8 +109,13 @@ define token instrThumb (16)
thcond=(8,11) thcond=(8,11)
thcpn=(8,11) thcpn=(8,11)
thcop=(8,10)
thopcode1=(4,7) thopcode1=(4,7)
thop1=(4,6)
thopcode2=(5,7) thopcode2=(5,7)
thop2=(7,7)
thopcode3=(0,5)
thop3=(4,5)
l07=(7,7) l07=(7,7)
l11=(11,11) l11=(11,11)
h1=(7,7) h1=(7,7)
@ -194,16 +202,19 @@ define token instrThumb (16)
thc1315=(13,15) thc1315=(13,15)
thc1415=(14,15) thc1415=(14,15)
thc1515=(15,15) thc1515=(15,15)
; ;
attach variables [ Rd0002 Rd0810 Rn0002 Rn0305 Rn0810 Rm0305 Rm0608 Rs0305 ] attach variables [ Rd0002 Rd0810 Rn0002 Rn0305 Rn0810 Rm0305 Rm0608 Rs0305 ]
[ r0 r1 r2 r3 r4 r5 r6 r7 ]; [ r0 r1 r2 r3 r4 r5 r6 r7 ];
attach variables [ Rm0003 Rm0306 Rd0811 Rn0003 Rt1215 Rt0811 Ra1215 Rd0003 part2Rt part2Rd0003 ] [ r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp lr pc ]; attach variables [ Rm0003 Rm0306 Rd0811 Rn0003 Rt1215 Rt0811 Ra1215 Rd0003 part2Rt part2Rd0003 ] [ r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp lr pc ];
attach variables [ Rd1215hi Rd0003hi ] [ r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp lr pc _ ];
attach variables [ thCRn thCRd thCRm ] [ cr0 cr1 cr2 cr3 cr4 cr5 cr6 cr7 cr8 cr9 cr10 cr11 cr12 cr13 cr14 cr15 ]; attach variables [ thCRn thCRd thCRm ] [ cr0 cr1 cr2 cr3 cr4 cr5 cr6 cr7 cr8 cr9 cr10 cr11 cr12 cr13 cr14 cr15 ];
attach names [ thcpn ] [ p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 ]; attach names [ thcpn ] [ p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 ];
attach names [ thcop ] [ p0 p1 p2 p3 p4 p5 p6 p7 ];
attach variables [ hrn0002 hrm0305 hrd0002 ] attach variables [ hrn0002 hrm0305 hrd0002 ]
[ r8 r9 r10 r11 r12 sp lr pc ]; [ r8 r9 r10 r11 r12 sp lr pc ];
@ -262,6 +273,33 @@ macro th_affectflags() {
CY = tmpCY; ZR = tmpZR; NG = tmpNG; OV = tmpOV; CY = tmpCY; ZR = tmpZR; NG = tmpNG; OV = tmpOV;
} }
macro readAPSR_nzcvq(r) {
# TODO: GE bits have not been included
r = zext( (NG<<4) | (ZR<<3) | (CY<<2) | (OV<<1) | (Q) ) << 27;
}
macro writeAPSR_nzcvq(r) {
# TODO: GE bits have not been included
local tmp = r >> 27 & 0x1f;
Q = ((tmp ) & 0x1) != 0;
OV = ((tmp >> 1) & 0x1) != 0;
CY = ((tmp >> 2) & 0x1) != 0;
ZR = ((tmp >> 3) & 0x1) != 0;
NG = ((tmp >> 4) & 0x1) != 0;
}
macro readAPSR_nzcv(r) {
r = zext( (NG<<3) | (ZR<<2) | (CY<<1) | (OV) ) << 28;
}
macro writeAPSR_nzcv(r) {
local tmp = r >> 28 & 0xf;
OV = ((tmp) & 0x1) != 0;
CY = ((tmp >> 1) & 0x1) != 0;
ZR = ((tmp >> 2) & 0x1) != 0;
NG = ((tmp >> 3) & 0x1) != 0;
}
############################################################################### ###############################################################################
# conditionals for the branch instruction # conditionals for the branch instruction
@ -1589,6 +1627,7 @@ bxns: "ns" is thc0002=0b100 { }
@if defined(VERSION_6T2) || defined(VERSION_7) @if defined(VERSION_6T2) || defined(VERSION_7)
@ifndef CDE
:cdp^ItCond thcpn,thopcode1,thCRd,thCRn,thCRm,thopcode2 is TMode=1 & ItCond & op8=0xee & thopcode1 & thCRn; thCRd & thcpn & thopcode2 & thc0404=0 & thCRm :cdp^ItCond thcpn,thopcode1,thCRd,thCRn,thCRm,thopcode2 is TMode=1 & ItCond & op8=0xee & thopcode1 & thCRn; thCRd & thcpn & thopcode2 & thc0404=0 & thCRm
{ {
build ItCond; build ItCond;
@ -1606,6 +1645,7 @@ bxns: "ns" is thc0002=0b100 { }
t_op2:4 = thopcode2; t_op2:4 = thopcode2;
coprocessor_function2(t_cpn,t_op1,t_op2,thCRd,thCRn,thCRm); coprocessor_function2(t_cpn,t_op1,t_op2,thCRd,thCRn,thCRm);
} }
@endif #CDE
define pcodeop IndexCheck; define pcodeop IndexCheck;
@ -1902,6 +1942,7 @@ XYZ: X^Y^Z is TMode=1 & X & Y & Z { }
# just sets up the condition and If Then/Else mask # just sets up the condition and If Then/Else mask
} }
@ifndef CDE
:ldc^ItCond thcpn,thCRd,taddrmode5 is (TMode=1 & ItCond & op9=0x76 & thN6=0 & thL4=1; thCRd & thcpn) & taddrmode5 :ldc^ItCond thcpn,thCRd,taddrmode5 is (TMode=1 & ItCond & op9=0x76 & thN6=0 & thL4=1; thCRd & thcpn) & taddrmode5
{ {
build ItCond; build ItCond;
@ -1933,7 +1974,7 @@ XYZ: X^Y^Z is TMode=1 & X & Y & Z { }
t_cpn:4 = thcpn; t_cpn:4 = thcpn;
coprocessor_loadlong(t_cpn,thCRd,taddrmode5); coprocessor_loadlong(t_cpn,thCRd,taddrmode5);
} }
@endif # CDE
@endif # VERSION_6T2 || VERSION_7 @endif # VERSION_6T2 || VERSION_7
:ldmia^ItCond Rn_exclaim,ldbrace is TMode=1 & ItCond & op11=0x19 & Rn_exclaim & ldbrace & Rn_exclaim_WB :ldmia^ItCond Rn_exclaim,ldbrace is TMode=1 & ItCond & op11=0x19 & Rn_exclaim & ldbrace & Rn_exclaim_WB
@ -2541,7 +2582,7 @@ macro th_set_carry_for_lsr(op1,shift_count) {
@endif # VERSION_6T2 || VERSION_7 @endif # VERSION_6T2 || VERSION_7
@ifndef CDE
:mcr^ItCond thcpn,thc0507,Rt1215,thCRn,thCRm,thopcode2 is TMode=1 & ItCond & op8=0xee & thc0507 & thc0404=0 & thCRn; Rt1215 & thcpn & thopcode2 & thc0404=1 & thCRm :mcr^ItCond thcpn,thc0507,Rt1215,thCRn,thCRm,thopcode2 is TMode=1 & ItCond & op8=0xee & thc0507 & thc0404=0 & thCRn; Rt1215 & thcpn & thopcode2 & thc0404=1 & thCRm
{ {
build ItCond; build ItCond;
@ -2575,7 +2616,7 @@ macro th_set_carry_for_lsr(op1,shift_count) {
t_op:4 = thopcode1; t_op:4 = thopcode1;
coprocessor_moveto2(t_cpn,t_op,Rt1215,Rn0003,thCRm); coprocessor_moveto2(t_cpn,t_op,Rt1215,Rn0003,thCRm);
} }
@endif # CDE
:mov^CheckInIT_ZN^ItCond Rd0810,Immed8 is TMode=1 & ItCond & op11=4 & Rd0810 & Immed8 & CheckInIT_ZN :mov^CheckInIT_ZN^ItCond Rd0810,Immed8 is TMode=1 & ItCond & op11=4 & Rd0810 & Immed8 & CheckInIT_ZN
{ {
@ -2652,7 +2693,7 @@ macro th_set_carry_for_lsr(op1,shift_count) {
Rd0811 = (zext(Immed16) << 16) | (Rd0811 & 0xffff); Rd0811 = (zext(Immed16) << 16) | (Rd0811 & 0xffff);
} }
@ifndef CDE
:mrc^ItCond thcpn,thc0507,Rt1215,thCRn,thCRm,thopcode2 is TMode=1 & ItCond & op8=0xee & thc0507 & thc0404=1 & thCRn; Rt1215 & thcpn & thopcode2 & thc0404=1 & thCRm :mrc^ItCond thcpn,thc0507,Rt1215,thCRn,thCRm,thopcode2 is TMode=1 & ItCond & op8=0xee & thc0507 & thc0404=1 & thCRn; Rt1215 & thcpn & thopcode2 & thc0404=1 & thCRm
{ {
build ItCond; build ItCond;
@ -2661,6 +2702,15 @@ macro th_set_carry_for_lsr(op1,shift_count) {
t_op2:4 = thopcode2; t_op2:4 = thopcode2;
Rt1215 = coprocessor_movefromRt(t_cpn,t_op1,t_op2,thCRn,thCRm); Rt1215 = coprocessor_movefromRt(t_cpn,t_op1,t_op2,thCRn,thCRm);
} }
:mrc^ItCond thcpn,thc0507,"APSR_nzcv",thCRn,thCRm,thopcode2 is TMode=1 & ItCond & op8=0xee & thc0507 & thc0404=1 & thCRn; Rt1215=15 & thcpn & thopcode2 & thc0404=1 & thCRm
{
build ItCond;
t_cpn:4 = thcpn;
t_op1:4 = thc0507;
t_op2:4 = thopcode2;
local tmp:4 = coprocessor_movefromRt(t_cpn,t_op1,t_op2,thCRn,thCRm);
writeAPSR_nzcv(tmp);
}
:mrc2^ItCond thcpn,thc0507,Rt1215,thCRn,thCRm,thopcode2 is TMode=1 & ItCond & op8=0xfe & thc0507 & thc0404=1 & thCRn; Rt1215 & thcpn & thopcode2 & thc0404=1 & thCRm :mrc2^ItCond thcpn,thc0507,Rt1215,thCRn,thCRm,thopcode2 is TMode=1 & ItCond & op8=0xfe & thc0507 & thc0404=1 & thCRn; Rt1215 & thcpn & thopcode2 & thc0404=1 & thCRm
{ {
@ -2670,6 +2720,15 @@ macro th_set_carry_for_lsr(op1,shift_count) {
t_op2:4 = thopcode2; t_op2:4 = thopcode2;
Rt1215 = coprocessor_movefromRt(t_cpn,t_op1,t_op2,thCRn,thCRm); Rt1215 = coprocessor_movefromRt(t_cpn,t_op1,t_op2,thCRn,thCRm);
} }
:mrc2^ItCond thcpn,thc0507,"APSR_nzcv",thCRn,thCRm,thopcode2 is TMode=1 & ItCond & op8=0xfe & thc0507 & thc0404=1 & thCRn; Rt1215=15 & thcpn & thopcode2 & thc0404=1 & thCRm
{
build ItCond;
t_cpn:4 = thcpn;
t_op1:4 = thc0507;
t_op2:4 = thopcode2;
local tmp:4 = coprocessor_movefromRt(t_cpn,t_op1,t_op2,thCRn,thCRm);
writeAPSR_nzcv(tmp);
}
:mrrc^ItCond thcpn,thopcode1,Rt1215,Rn0003,thCRm is TMode=1 & ItCond & op4=0xec5 & Rn0003; Rt1215 & thcpn & thopcode1 & thCRm :mrrc^ItCond thcpn,thopcode1,Rt1215,Rn0003,thCRm is TMode=1 & ItCond & op4=0xec5 & Rn0003; Rt1215 & thcpn & thopcode1 & thCRm
{ {
@ -2688,22 +2747,7 @@ macro th_set_carry_for_lsr(op1,shift_count) {
Rt1215 = coprocessor_movefromRt(t_cpn,t_op,thCRm); Rt1215 = coprocessor_movefromRt(t_cpn,t_op,thCRm);
Rn0003 = coprocessor_movefromRt2(t_cpn,t_op,thCRm); Rn0003 = coprocessor_movefromRt2(t_cpn,t_op,thCRm);
} }
@endif #CDE
macro readAPSR(r) {
# TODO: GE bits have not been included
r = r | zext( (NG<<4) | (ZR<<3) | (CY<<2) | (OV<<1) | (Q) ) << 27;
}
macro writeAPSR(r) {
# TODO: GE bits have not been included
local tmp = r >> 27 & 0x1f;
Q = ((tmp ) & 0x1) != 0;
OV = ((tmp >> 1) & 0x1) != 0;
CY = ((tmp >> 2) & 0x1) != 0;
ZR = ((tmp >> 3) & 0x1) != 0;
NG = ((tmp >> 4) & 0x1) != 0;
}
@if defined(VERSION_7M) @if defined(VERSION_7M)
define pcodeop getMainStackPointer; define pcodeop getMainStackPointer;
@ -2722,7 +2766,7 @@ mrsipsr: is thc0000=0 { }
mrsepsr: "e" is thc0101=1 { } mrsepsr: "e" is thc0101=1 { }
mrsepsr: is thc0101=0 { } mrsepsr: is thc0101=0 { }
mrsapsr: is thc0202=1 { } mrsapsr: is thc0202=1 { }
mrsapsr: "a" is thc0202=0 & Rd0811 { readAPSR(Rd0811); } mrsapsr: "a" is thc0202=0 & Rd0811 { readAPSR_nzcvq(Rd0811); }
mrspsr: mrsipsr^mrsepsr^mrsapsr^"psr" is mrsipsr & mrsepsr & mrsapsr & Rd0811 { mrspsr: mrsipsr^mrsepsr^mrsapsr^"psr" is mrsipsr & mrsepsr & mrsapsr & Rd0811 {
Rd0811 = 0; Rd0811 = 0;
@ -2820,7 +2864,7 @@ control: "control" is epsilon {}
{ {
build ItCond; build ItCond;
tmp:4 = 0; tmp:4 = 0;
readAPSR(tmp); readAPSR_nzcvq(tmp);
Rd0811 = tmp; Rd0811 = tmp;
} }
@ -2840,7 +2884,7 @@ msrepsr: is thc0101=0 { }
msrapsr: is thc0202=1 { } msrapsr: is thc0202=1 { }
msrapsr: "a" is thc0202=0 & Rn0003 { msrapsr: "a" is thc0202=0 & Rn0003 {
cpsr = cpsr | (Rn0003 & 0xf8000000); cpsr = cpsr | (Rn0003 & 0xf8000000);
writeAPSR(cpsr); writeAPSR_nzcvq(cpsr);
} }
msrpsr: msripsr^msrepsr^msrapsr^"psr" is msripsr & msrepsr & msrapsr { msrpsr: msripsr^msrepsr^msrapsr^"psr" is msripsr & msrepsr & msrapsr {
@ -2955,7 +2999,7 @@ thcpsrmask: cpsr^thpsrmask is thpsrmask & cpsr { export thpsrmask; }
build ItCond; build ItCond;
build thcpsrmask; build thcpsrmask;
cpsr = (cpsr& ~thcpsrmask) | (Rn0003 & thcpsrmask); cpsr = (cpsr& ~thcpsrmask) | (Rn0003 & thcpsrmask);
writeAPSR(cpsr); writeAPSR_nzcvq(cpsr);
} }
thspsrmask: spsr^thpsrmask is thpsrmask & spsr { export thpsrmask; } thspsrmask: spsr^thpsrmask is thpsrmask & spsr { export thpsrmask; }
@ -3773,7 +3817,7 @@ macro th_set_carry_for_ror(result, count) {
:sdiv^ItCond Rd0811,Rn0003,Rm0003 is TMode=1 & ItCond & op4=0xfb9 & Rn0003; op12=0xf & Rd0811 & thc0407=0xf & Rm0003 :sdiv^ItCond Rd0811,Rn0003,Rm0003 is TMode=1 & ItCond & op4=0xfb9 & Rn0003; op12=0xf & Rd0811 & thc0407=0xf & Rm0003
{ {
build ItCond; build ItCond;
local result = Rn0003 / Rm0003; local result = Rn0003 s/ Rm0003;
Rd0811 = result; Rd0811 = result;
} }
@ -4259,7 +4303,7 @@ thumbEndianNess: "BE" is op0=0xb658 { export 1:1; }
@endif # VERSION_6 @endif # VERSION_6
@if defined(VERSION_6T2) || defined(VERSION_7) @if defined(VERSION_6T2) || defined(VERSION_7)
@ifndef CDE
:stc^ItCond thcpn,thCRd,taddrmode5 is (TMode=1 & ItCond & op9=0x76 & thN6=0 & thL4=0; thCRd & thcpn) & taddrmode5 :stc^ItCond thcpn,thCRd,taddrmode5 is (TMode=1 & ItCond & op9=0x76 & thN6=0 & thL4=0; thCRd & thcpn) & taddrmode5
{ {
build ItCond; build ItCond;
@ -4291,6 +4335,7 @@ thumbEndianNess: "BE" is op0=0xb658 { export 1:1; }
t_cpn:4 = thcpn; t_cpn:4 = thcpn;
coprocessor_storelong(t_cpn,thCRd,taddrmode5); coprocessor_storelong(t_cpn,thCRd,taddrmode5);
} }
@endif # CDE
:stm^ItCond Rn0003,thstrlist_inc is TMode=1 & ItCond & op11=0x1d & thc0910=0 & sop0608=2 & thwbit=0 & thc0404=0 & Rn0003; thc1515=0 & thc1313=0 & thstrlist_inc :stm^ItCond Rn0003,thstrlist_inc is TMode=1 & ItCond & op11=0x1d & thc0910=0 & sop0608=2 & thwbit=0 & thc0404=0 & Rn0003; thc1515=0 & thc1313=0 & thstrlist_inc
{ {

View file

@ -0,0 +1,223 @@
@if defined(CDE)
# ARMv8-M Custom Datapath Extension
acc: "a" is thc1212=1 { local tmp:1 = 1; export *[const]:1 tmp; }
acc: "" is thc1212=0 { local tmp:1 = 0; export *[const]:1 tmp; }
vacc: "a" is thv_c2828=1 { local tmp:1 = 1; export *[const]:1 tmp; }
vacc: "" is thv_c2828=0 { local tmp:1 = 0; export *[const]:1 tmp; }
cx1_imm: val is thc0005; thop2 & thopcode3 [val=(thc0005 << 7) | (thop2 << 6) | thopcode3;] {export *[const]:4 val; }
cx2_imm: val is thc0405; thop2 & thopcode3 [val=(thc0405 << 7) | (thop2 << 6) | thopcode3;] {export *[const]:4 val; }
cx3_imm: val is thop1; thop2 & thop3 [val=(thop1 << 3) | (thop2 << 2) | thop3;] {export *[const]:4 val; }
vcx1_imm: val is thv_c2424 & thv_c1619 & thv_c0707 & thv_c0005 [val = (thv_c2424 << 11) |(thv_c1619 << 7) | (thv_c0707 << 6) | thv_c0005;] {export *[const]:4 val; }
vcx2_imm: val is thv_c2424 & thv_c1619 & thv_c0707 & thv_c0404 [val = (thv_c2424 << 6 ) |(thv_c1619 << 2) | (thv_c0707 << 1) | thv_c0404;] {export *[const]:4 val; }
vcx3_imm: val is thv_c2424 & thv_c2021 & thv_c0404 [val = (thv_c2424 << 3 ) |(thv_c2021 << 1) | thv_c0404;] {export *[const]:4 val; }
fvcx1_imm: val is thv_c1619 & thv_c0707 & thv_c0005 [val = (thv_c1619 << 7) | (thv_c0707 << 6) | thv_c0005;] {export *[const]:4 val; }
fvcx2_imm: val is thv_c1619 & thv_c0707 & thv_c0404 [val = (thv_c1619 << 2) | (thv_c0707 << 1) | thv_c0404;] {export *[const]:4 val; }
fvcx3_imm: val is thv_c2021 & thv_c0404 [val = (thv_c2021 << 1) | thv_c0404;] {export *[const]:4 val; }
cx_coRd: Ra1215 is Ra1215 { export Ra1215; }
cx_coRd:"APSR_nzcv" is Ra1215=15 { tmp:4 = 0; readAPSR_nzcv(tmp); export tmp; }
cx_coRn: Rn0003 is Rn0003 { export Rn0003; }
cx_coRn:"APSR_nzcv" is Rn0003=15 { tmp:4 = 0; readAPSR_nzcv(tmp); export tmp; }
cx_coRm: Ra1215 is Ra1215 { export Ra1215; }
cx_coRm:"APSR_nzcv" is Ra1215=15 { tmp:4 = 0; readAPSR_nzcv(tmp); export tmp; }
cx_coRd0: Rd0003 is Rd0003 { export Rd0003; }
cx_coRd0:"APSR_nzcv" is Rd0003=15 { tmp:4 = 0; readAPSR_nzcv(tmp); export tmp; }
# Pseudo-ops
define pcodeop cx1; # Rd = cx1(Coprocessor #, operation, Rd, accumulator, size)
define pcodeop cx2; # Rd = cx2(Coprocessor #, operation, Rd, Rn, accumulator, size)
define pcodeop cx3; # Rd = cx3(Coprocessor #, operation, Rd, Rn, Rm, accumulator, size)
define pcodeop vcx1; # Rd = vcx1(Coprocessor #, operation, Rd, accumulator, size, vectored)
define pcodeop vcx2; # Rd = vcx2(Coprocessor #, operation, Rd, Rn, accumulator, size, vectored)
define pcodeop vcx3; # Rd = vcx3(Coprocessor #, operation, Rd, Rn, Rm, accumulator, size, vectored)
:cx1^acc^ItCond thcop, cx_coRd, cx1_imm is TMode=1 & ItCond & (op13=7 & acc & thc0811=0xe & thc0607=0; cx_coRd & thc1111=0 & thcop & thc0606=0) & cx1_imm
{
build ItCond;
t_cpn:4 = thcop;
t_op1:4 = cx1_imm;
t_acc:1 = acc;
cx_coRd = cx1(t_cpn, t_op1, cx_coRd, t_acc, 32:1);
}
:cx1^acc^ItCond thcop, cx_coRd, cx1_imm is TMode=1 & ItCond & (op13=7 & acc & thc0811=0xe & thc0607=0; (cx_coRd & Ra1215=15) & thc1111=0 & thcop & thc0606=0) & cx1_imm
{
build ItCond;
t_cpn:4 = thcop;
t_op1:4 = cx1_imm;
t_acc:1 = acc;
cx_coRd = cx1(t_cpn, t_op1, cx_coRd, t_acc, 32:1);
writeAPSR_nzcv(cx_coRd);
}
:cx1d^acc^ItCond thcop, Ra1215, Rd1215hi, cx1_imm is TMode=1 & ItCond & (op13=7 & acc & thc0811=0xe & thc0607=0; Ra1215 & Rd1215hi & thc1111=0 & thcop & thc0606=1) & cx1_imm
{
build ItCond;
t_cpn:4 = thcop;
t_op1:4 = cx1_imm;
t_acc:1 = acc;
result:8 = cx1(t_cpn, t_op1, Ra1215, Rd1215hi, t_acc, 64:1);
Ra1215 = result(0);
Rd1215hi = result(4);
}
:cx2^acc^ItCond thcop, cx_coRd, cx_coRn, cx2_imm is TMode=1 & ItCond & (op13=7 & acc & thc0811=0xe & thc0607=1 & cx_coRn; cx_coRd & thc1111=0 & thcop & thc0606=0) & cx2_imm
{
build ItCond;
t_cpn:4 = thcop;
t_op1:4 = cx2_imm;
t_acc:1 = acc;
cx_coRd = cx2(t_cpn, t_op1, cx_coRd, cx_coRn, t_acc, 32:1);
}
:cx2^acc^ItCond thcop, cx_coRd, cx_coRn, cx2_imm is TMode=1 & ItCond & (op13=7 & acc & thc0811=0xe & thc0607=1 & cx_coRn; (cx_coRd & Ra1215=15) & thc1111=0 & thcop & thc0606=0) & cx2_imm
{
build ItCond;
t_cpn:4 = thcop;
t_op1:4 = cx2_imm;
t_acc:1 = acc;
cx_coRd = cx2(t_cpn, t_op1, cx_coRd, cx_coRn, t_acc, 32:1);
writeAPSR_nzcv(cx_coRd);
}
:cx2d^acc^ItCond thcop, Ra1215, Rd1215hi, cx_coRn, cx2_imm is TMode=1 & ItCond & (op13=7 & acc & thc0811=0xe & thc0607=1 & cx_coRn; Ra1215 & Rd1215hi & thc1111=0 & thcop & thc0606=1) & cx2_imm
{
build ItCond;
t_cpn:4 = thcop;
t_op1:4 = cx2_imm;
t_acc:1 = acc;
result:8 = cx2(t_cpn, t_op1, Ra1215, Rd1215hi, cx_coRn, t_acc, 64:1);
Ra1215 = result(0);
Rd1215hi = result(4);
}
:cx3^acc^ItCond thcop, cx_coRd0, cx_coRn, cx_coRm, cx3_imm is TMode=1 & ItCond & (op13=7 & acc & thc0811=0xe & thc0707=1 & cx_coRn; cx_coRm & thc1111=0 & thcop & thc0606=0 & cx_coRd0) & cx3_imm
{
build ItCond;
t_cpn:4 = thcop;
t_op1:4 = cx3_imm;
t_acc:1 = acc;
cx_coRd0 = cx3(t_cpn, t_op1, cx_coRd0, cx_coRn, cx_coRm, t_acc, 32:1);
}
:cx3^acc^ItCond thcop, cx_coRd0, cx_coRn, cx_coRm, cx3_imm is TMode=1 & ItCond & (op13=7 & acc & thc0811=0xe & thc0707=1 & cx_coRn; cx_coRm & thc1111=0 & thcop & thc0606=0 & (cx_coRd0 & Rd0003=15)) & cx3_imm
{
build ItCond;
t_cpn:4 = thcop;
t_op1:4 = cx3_imm;
t_acc:1 = acc;
cx_coRd0 = cx3(t_cpn, t_op1, cx_coRd0, cx_coRn, cx_coRm, t_acc, 32:1);
writeAPSR_nzcv(cx_coRd0);
}
:cx3d^acc^ItCond thcop, Rd0003, Rd0003hi, cx_coRn, cx_coRm, cx3_imm is TMode=1 & ItCond & (op13=7 & acc & thc0811=0xe & thc0707=1 & cx_coRn; cx_coRm & thc1111=0 & thcop & thc0606=1 & Rd0003 & Rd0003hi) & cx3_imm
{
build ItCond;
t_cpn:4 = thcop;
t_op1:4 = cx3_imm;
t_acc:1 = acc;
result:8 = cx3(t_cpn, t_op1, Rd0003, Rd0003hi, cx_coRn, cx_coRm, t_acc, 64:1);
Rd0003 = result(0);
Rd0003hi = result(4);
}
# Vector CDE instructions - Requires Armv8.1-M MVE
:vcx1^vacc^ItCond thv_cpn, Qd, vcx1_imm is TMode=1 & ItCond & thv_c2931=7 & vacc & thv_c2527=6 & thv_c2323=0 & thv_c2021=2 & thv_c1111=0 & thv_cpn & thv_c0606=1 & Qd & vcx1_imm
{
build ItCond;
t_cpn:4 = thv_cpn;
t_op1:4 = vcx1_imm;
t_acc:1 = vacc;
t_vec:1 = 1;
Qd = vcx1(t_cpn, t_op1, Qd, t_acc, 32:1, t_vec);
}
:vcx2^vacc^ItCond thv_cpn, Qd, Qm, vcx2_imm is TMode=1 & ItCond & thv_c2931=7 & vacc & thv_c2527=6 & thv_c2323=0 & thv_c2021=3 & thv_c1111=0 & thv_cpn & thv_c0606=1 & Qm & Qd & vcx2_imm
{
build ItCond;
t_cpn:4 = thv_cpn;
t_op1:4 = vcx2_imm;
t_acc:1 = vacc;
t_vec:1 = 1;
Qd = vcx2(t_cpn, t_op1, Qd, Qm, t_acc, 32:1, t_vec);
}
:vcx3^vacc^ItCond thv_cpn, Qd, Qn, Qm, vcx3_imm is TMode=1 & ItCond & thv_c2931=7 & vacc & thv_c2527=6 & thv_c2323=1 & thv_c1111=0 & thv_cpn & thv_c0606=1 & Qm & Qn & Qd & vcx3_imm
{
build ItCond;
t_cpn:4 = thv_cpn;
t_op1:4 = vcx3_imm;
t_acc:1 = vacc;
t_vec:1 = 1;
Qd = vcx3(t_cpn, t_op1, Qd, Qn, Qm, t_acc, 32:1, t_vec);
}
# Floating-point CDE instructions - Requires Armv8.1-M MVE
:vcx1^vacc^ItCond thv_cpn, Sd, fvcx1_imm is TMode=1 & ItCond & thv_c2931=7 & vacc & thv_c2527=6 & thv_c2424=0 & thv_c2323=0 & thv_c2021=2 & thv_c1111=0 & thv_cpn & thv_c0606=0 & Sd & fvcx1_imm
{
build ItCond;
t_cpn:4 = thv_cpn;
t_op1:4 = fvcx1_imm;
t_acc:1 = vacc;
t_vec:1 = 0;
Sd = vcx1(t_cpn, t_op1, Sd, t_acc, 32:1, t_vec);
}
:vcx1^vacc^ItCond thv_cpn, Dd, fvcx1_imm is TMode=1 & ItCond & thv_c2931=7 & vacc & thv_c2527=6 & thv_c2424=1 & thv_c2323=0 & thv_c2021=2 & thv_c1111=0 & thv_cpn & thv_c0606=0 & Dd & fvcx1_imm
{
build ItCond;
t_cpn:4 = thv_cpn;
t_op1:4 = fvcx1_imm;
t_acc:1 = vacc;
t_vec:1 = 0;
Dd = vcx1(t_cpn, t_op1, Dd, t_acc, 64:1, t_vec);
}
:vcx2^vacc^ItCond thv_cpn, Sd, Sm, fvcx2_imm is TMode=1 & ItCond & thv_c2931=7 & vacc & thv_c2527=6 & thv_c2424=0 & thv_c2323=0 & thv_c2021=3 & thv_c1111=0 & thv_cpn & thv_c0606=0 & Sm & Sd & fvcx2_imm
{
build ItCond;
t_cpn:4 = thv_cpn;
t_op1:4 = fvcx2_imm;
t_acc:1 = vacc;
t_vec:1 = 0;
Sd = vcx2(t_cpn, t_op1, Sd, Sm, t_acc, 32:1, t_vec);
}
:vcx2^vacc^ItCond thv_cpn, Dd, Dm, fvcx2_imm is TMode=1 & ItCond & thv_c2931=7 & vacc & thv_c2527=6 & thv_c2424=1 & thv_c2323=0 & thv_c2021=3 & thv_c1111=0 & thv_cpn & thv_c0606=0 & Dm & Dd & fvcx2_imm
{
build ItCond;
t_cpn:4 = thv_cpn;
t_op1:4 = fvcx2_imm;
t_acc:1 = vacc;
t_vec:1 = 0;
Dd = vcx2(t_cpn, t_op1, Dd, Dm, t_acc, 64:1, t_vec);
}
:vcx3^vacc^ItCond thv_cpn, Sd, Sn, Sm, fvcx3_imm is TMode=1 & ItCond & thv_c2931=7 & vacc & thv_c2527=6 & thv_c2424=0 & thv_c2323=1 & thv_c1111=0 & thv_cpn & thv_c0606=0 & Sm & Sn & Sd & fvcx3_imm
{
build ItCond;
t_cpn:4 = thv_cpn;
t_op1:4 = fvcx3_imm;
t_acc:1 = vacc;
t_vec:1 = 0;
Sd = vcx3(t_cpn, t_op1, Sd, Sn, Sm, t_acc, 32:1, t_vec);
}
:vcx3^vacc^ItCond thv_cpn, Dd, Dn, Dm, fvcx3_imm is TMode=1 & ItCond & thv_c2931=7 & vacc & thv_c2527=6 & thv_c2424=1 & thv_c2323=1 & thv_c1111=0 & thv_cpn & thv_c0606=0 & Dm & Dn & Dd & fvcx3_imm
{
build ItCond;
t_cpn:4 = thv_cpn;
t_op1:4 = fvcx3_imm;
t_acc:1 = vacc;
t_vec:1 = 0;
Dd = vcx3(t_cpn, t_op1, Dd, Dn, Dm, t_acc, 64:1, t_vec);
}
@endif # CDE

View file

@ -313,6 +313,7 @@ define token instrArm (32)
thv_Rm=(16,19) thv_Rm=(16,19)
thv_Rt2=(24,27) thv_Rt2=(24,27)
thv_immed=(16,23) thv_immed=(16,23)
thv_cpn=(8,10)
# Arbitrary bit fields for 32-bit Little Endian Thumb # Arbitrary bit fields for 32-bit Little Endian Thumb
@ -330,15 +331,16 @@ define token instrArm (32)
thv_c2831=(12,15) thv_c2831=(12,15)
thv_c2828=(12,12) thv_c2828=(12,12)
thv_c2627=(10,11) thv_c2627=(10,11)
thv_c2531=(9,15)
thv_c2527=(9,11) thv_c2527=(9,11)
thv_c2525=(9,9) thv_c2525=(9,9)
thv_c2431=(8,15)
thv_c2427=(8,11) thv_c2427=(8,11)
thv_c2424=(8,8) thv_c2424=(8,8)
thv_c2331=(7,15) thv_c2331=(7,15)
thv_c2327=(7,11) thv_c2327=(7,11)
thv_c2324=(7,8) thv_c2324=(7,8)
thv_c2323=(7,7) thv_c2323=(7,7)
thv_c2223=(6,7)
thv_c2222=(6,6) thv_c2222=(6,6)
thv_c2131=(5,15) thv_c2131=(5,15)
thv_c2127=(5,11) thv_c2127=(5,11)
@ -415,6 +417,7 @@ define token instrArm (32)
thv_c0008=(16,24) thv_c0008=(16,24)
thv_c0007=(16,23) thv_c0007=(16,23)
thv_c0006=(16,22) thv_c0006=(16,22)
thv_c0005=(16,21)
thv_c0004=(16,20) thv_c0004=(16,20)
thv_c0003=(16,19) thv_c0003=(16,19)
thv_c0001=(16,17) thv_c0001=(16,17)
@ -477,6 +480,7 @@ define token instrArm (32)
thv_Rm=(0,3) thv_Rm=(0,3)
thv_Rt2=(8,11) thv_Rt2=(8,11)
thv_immed=(0,7) thv_immed=(0,7)
thv_cpn=(24,26)
# Arbitrary bit fields for 32-bit Big Endian Thumb # Arbitrary bit fields for 32-bit Big Endian Thumb
thv_bit31=(31,31) thv_bit31=(31,31)
@ -493,15 +497,16 @@ define token instrArm (32)
thv_c2831=(28,31) thv_c2831=(28,31)
thv_c2828=(28,28) thv_c2828=(28,28)
thv_c2627=(26,27) thv_c2627=(26,27)
thv_c2531=(25,31)
thv_c2527=(25,27) thv_c2527=(25,27)
thv_c2525=(25,25) thv_c2525=(25,25)
thv_c2431=(24,31)
thv_c2427=(24,27) thv_c2427=(24,27)
thv_c2424=(24,24) thv_c2424=(24,24)
thv_c2331=(23,31) thv_c2331=(23,31)
thv_c2327=(23,27) thv_c2327=(23,27)
thv_c2324=(23,24) thv_c2324=(23,24)
thv_c2323=(23,23) thv_c2323=(23,23)
thv_c2223=(22,23)
thv_c2222=(22,22) thv_c2222=(22,22)
thv_c2131=(21,31) thv_c2131=(21,31)
thv_c2127=(21,27) thv_c2127=(21,27)
@ -578,6 +583,7 @@ define token instrArm (32)
thv_c0008=(0,8) thv_c0008=(0,8)
thv_c0007=(0,7) thv_c0007=(0,7)
thv_c0006=(0,6) thv_c0006=(0,6)
thv_c0005=(0,5)
thv_c0004=(0,4) thv_c0004=(0,4)
thv_c0003=(0,3) thv_c0003=(0,3)
thv_c0001=(0,1) thv_c0001=(0,1)
@ -594,6 +600,7 @@ attach variables [ CRd CRn CRm ] [ cr0 cr1 cr2 cr3 cr4 cr5 cr6 cr7 cr8 cr9 cr10
attach variables [ thv_Rd thv_Rn thv_Rt thv_Rt2 ] [ r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp lr pc ]; attach variables [ thv_Rd thv_Rn thv_Rt thv_Rt2 ] [ r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp lr pc ];
attach names [ cpn ] [ p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 ]; attach names [ cpn ] [ p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 ];
attach names [ thv_cpn ] [ p0 p1 p2 p3 p4 p5 p6 p7 ];
attach names [ ibOption ] [ opt0 opt1 opt2 opt3 opt4 opt5 opt6 opt7 opt8 opt9 opt10 opt11 opt12 opt13 opt14 SY ]; attach names [ ibOption ] [ opt0 opt1 opt2 opt3 opt4 opt5 opt6 opt7 opt8 opt9 opt10 opt11 opt12 opt13 opt14 SY ];
attach names [ dbOption ] [ opt0 opt1 OSHST OSH opt4 opt5 NSHST NSH opt8 opt9 ISHST ISH opt12 opt13 ST SY ]; attach names [ dbOption ] [ opt0 opt1 OSHST OSH opt4 opt5 NSHST NSH opt8 opt9 ISHST ISH opt12 opt13 ST SY ];
@ -4907,7 +4914,7 @@ macro BitReverse_arm(val) {
:sdiv^COND RdHi,RnLo,RmHi is $(AMODE) & ARMcond=1 & COND & c2027=0x71 & RdHi & c1215=0xf & RmHi & c0407=0x1 & RnLo :sdiv^COND RdHi,RnLo,RmHi is $(AMODE) & ARMcond=1 & COND & c2027=0x71 & RdHi & c1215=0xf & RmHi & c0407=0x1 & RnLo
{ {
build COND; build COND;
local result = RnLo / RmHi; local result = RnLo s/ RmHi;
RdHi = result; RdHi = result;
} }

View file

@ -0,0 +1,40 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class ARM_v8m_O0_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "ARM:LE:32:Cortex8m";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public ARM_v8m_O0_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "ARM_v8m_GCC_O0";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(ARM_v8m_O0_EmulatorTest.class);
}
}

View file

@ -0,0 +1,40 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class ARM_v8m_O3_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "ARM:LE:32:Cortex8m";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public ARM_v8m_O3_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "ARM_v8m_GCC_O3";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(ARM_v8m_O3_EmulatorTest.class);
}
}