Skip to content

Add support for MSR/MRS (banked register) for 32-bit ARM architectures #8013

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion Ghidra/Processors/ARM/data/languages/ARM.sinc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ define register offset=0x0020 size=4 [ r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11
define register offset=0x0060 size=1 [ NG ZR CY OV tmpNG tmpZR tmpCY tmpOV shift_carry TB Q GE1 GE2 GE3 GE4 ];
define register offset=0x0070 size=4 [ cpsr spsr ];
define register offset=0x0080 size=4 [ mult_addr ]; # Special internal register for dealing with multiple stores/loads
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=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)
Expand Down Expand Up @@ -75,6 +74,22 @@ define register offset=0x0200 size=4 [ cr0 cr1 cr2 cr3 cr4 cr5 cr6 cr7 cr8 cr9 c

@endif # SIMD

@if defined(VERSION_7)
# 0x400-0x500 is marked as volatile in the .pspec; update it there if this
# space is moved or expanded
# 33 registers x 4 bytes/register = 0x84 bytes consumed
define register offset=0x0400 size=4 [ r8_usr r9_usr r10_usr r11_usr r12_usr sp_usr lr_usr
r8_fiq r9_fiq r10_fiq r11_fiq r12_fiq sp_fiq lr_fiq
sp_irq lr_irq
sp_svc lr_svc
sp_mon lr_mon
sp_abt lr_abt
sp_hyp elr_hyp
sp_und lr_und
spsr_fiq spsr_irq spsr_svc spsr_mon spsr_abt spsr_hyp spsr_und ];

@endif # defined(VERSION_7)

# Define context bits
# WARNING: when adjusting context keep compiler packing in mind
# and make sure fields do not span a 32-bit boundary before or
Expand Down Expand Up @@ -189,6 +204,11 @@ define pcodeop ReverseBitOrder;
define pcodeop SendEvent;
define pcodeop setEndianState;

define pcodeop UnkBankedRegRead;
define pcodeop UnkBankedSpsrRead;
define pcodeop UnkBankedRegWrite;
define pcodeop UnkBankedSpsrWrite;

# Copies ISAModeSwitch to TMode
define pcodeop setISAMode;

Expand Down
144 changes: 143 additions & 1 deletion Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ define token instr2 (16)

define token instrThumb (16)
op4=(4,15)
op5=(5,15)
op6=(6,15)
op7=(7,15)
op8=(8,15)
Expand Down Expand Up @@ -149,6 +150,12 @@ define token instrThumb (16)
sysm37=(3,7)
sysm02=(0,2)

mrs_banked_m1=(0,3)
mrs_banked_m=(4,4)

msr_banked_m1=(8,11)
msr_banked_m=(4,4)


thc0001=(0,1)
thc0002=(0,2)
Expand Down Expand Up @@ -2973,7 +2980,142 @@ define pcodeop setStackMode;
# TODO: should we set sp ?
}

@endif
@endif # defined(VERSION_7M)

@if defined(VERSION_7)

BankedSysmThumb: banked_sysm is op5=0x79f & thc0003 ; thc0404
[ banked_sysm = (thc0404 << 4) $or thc0003; ]
{
export *[const]:4 banked_sysm;
}

BankedSysmThumb: banked_sysm is op5=0x79c ; thc0811 & thc0404
[ banked_sysm = (thc0404 << 4) $or thc0811; ]
{
export *[const]:4 banked_sysm;
}

# MRS/MSR (banked register)
# See https://developer.arm.com/documentation/ddi0597/2024-12/Base-Instructions/MSR--Banked-register---Move-general-purpose-register-to-Banked-or-Special-register-

# MRS, SPSR = 0, M = 0
BankedRegThumb: r8_usr is r8_usr & op4=0xf3e & mrs_banked_m1=0b0000 ; mrs_banked_m=0 { export r8_usr; }
BankedRegThumb: r9_usr is r9_usr & op4=0xf3e & mrs_banked_m1=0b0001 ; mrs_banked_m=0 { export r9_usr; }
BankedRegThumb: r10_usr is r10_usr & op4=0xf3e & mrs_banked_m1=0b0010 ; mrs_banked_m=0 { export r10_usr; }
BankedRegThumb: r11_usr is r11_usr & op4=0xf3e & mrs_banked_m1=0b0011 ; mrs_banked_m=0 { export r11_usr; }
BankedRegThumb: r12_usr is r12_usr & op4=0xf3e & mrs_banked_m1=0b0100 ; mrs_banked_m=0 { export r12_usr; }
BankedRegThumb: sp_usr is sp_usr & op4=0xf3e & mrs_banked_m1=0b0101 ; mrs_banked_m=0 { export sp_usr; }
BankedRegThumb: lr_usr is lr_usr & op4=0xf3e & mrs_banked_m1=0b0110 ; mrs_banked_m=0 { export lr_usr; }

BankedRegThumb: r8_fiq is r8_fiq & op4=0xf3e & mrs_banked_m1=0b1000 ; mrs_banked_m=0 { export r8_fiq; }
BankedRegThumb: r9_fiq is r9_fiq & op4=0xf3e & mrs_banked_m1=0b1001 ; mrs_banked_m=0 { export r9_fiq; }
BankedRegThumb: r10_fiq is r10_fiq & op4=0xf3e & mrs_banked_m1=0b1010 ; mrs_banked_m=0 { export r10_fiq; }
BankedRegThumb: r11_fiq is r11_fiq & op4=0xf3e & mrs_banked_m1=0b1011 ; mrs_banked_m=0 { export r11_fiq; }
BankedRegThumb: r12_fiq is r12_fiq & op4=0xf3e & mrs_banked_m1=0b1100 ; mrs_banked_m=0 { export r12_fiq; }
BankedRegThumb: sp_fiq is sp_fiq & op4=0xf3e & mrs_banked_m1=0b1101 ; mrs_banked_m=0 { export sp_fiq; }
BankedRegThumb: lr_fiq is lr_fiq & op4=0xf3e & mrs_banked_m1=0b1110 ; mrs_banked_m=0 { export lr_fiq; }

# MSR, SPSR = 0, M = 0
BankedRegThumb: r8_usr is r8_usr & op4=0xf38 ; msr_banked_m1=0b0000 & msr_banked_m=0 { export r8_usr; }
BankedRegThumb: r9_usr is r9_usr & op4=0xf38 ; msr_banked_m1=0b0001 & msr_banked_m=0 { export r9_usr; }
BankedRegThumb: r10_usr is r10_usr & op4=0xf38 ; msr_banked_m1=0b0010 & msr_banked_m=0 { export r10_usr; }
BankedRegThumb: r11_usr is r11_usr & op4=0xf38 ; msr_banked_m1=0b0011 & msr_banked_m=0 { export r11_usr; }
BankedRegThumb: r12_usr is r12_usr & op4=0xf38 ; msr_banked_m1=0b0100 & msr_banked_m=0 { export r12_usr; }
BankedRegThumb: sp_usr is sp_usr & op4=0xf38 ; msr_banked_m1=0b0101 & msr_banked_m=0 { export sp_usr; }
BankedRegThumb: lr_usr is lr_usr & op4=0xf38 ; msr_banked_m1=0b0110 & msr_banked_m=0 { export lr_usr; }

BankedRegThumb: r8_fiq is r8_fiq & op4=0xf38 ; msr_banked_m1=0b1000 & msr_banked_m=0 { export r8_fiq; }
BankedRegThumb: r9_fiq is r9_fiq & op4=0xf38 ; msr_banked_m1=0b1001 & msr_banked_m=0 { export r9_fiq; }
BankedRegThumb: r10_fiq is r10_fiq & op4=0xf38 ; msr_banked_m1=0b1010 & msr_banked_m=0 { export r10_fiq; }
BankedRegThumb: r11_fiq is r11_fiq & op4=0xf38 ; msr_banked_m1=0b1011 & msr_banked_m=0 { export r11_fiq; }
BankedRegThumb: r12_fiq is r12_fiq & op4=0xf38 ; msr_banked_m1=0b1100 & msr_banked_m=0 { export r12_fiq; }
BankedRegThumb: sp_fiq is sp_fiq & op4=0xf38 ; msr_banked_m1=0b1101 & msr_banked_m=0 { export sp_fiq; }
BankedRegThumb: lr_fiq is lr_fiq & op4=0xf38 ; msr_banked_m1=0b1110 & msr_banked_m=0 { export lr_fiq; }

# MRS, SPSR = 0, M = 1
BankedRegThumb: lr_irq is lr_irq & op4=0xf3e & mrs_banked_m1=0b0000 ; mrs_banked_m=1 { export lr_irq; }
BankedRegThumb: sp_irq is sp_irq & op4=0xf3e & mrs_banked_m1=0b0001 ; mrs_banked_m=1 { export sp_irq; }
BankedRegThumb: lr_svc is lr_svc & op4=0xf3e & mrs_banked_m1=0b0010 ; mrs_banked_m=1 { export lr_svc; }
BankedRegThumb: sp_svc is sp_svc & op4=0xf3e & mrs_banked_m1=0b0011 ; mrs_banked_m=1 { export sp_svc; }
BankedRegThumb: lr_abt is lr_abt & op4=0xf3e & mrs_banked_m1=0b0100 ; mrs_banked_m=1 { export lr_abt; }
BankedRegThumb: sp_abt is sp_abt & op4=0xf3e & mrs_banked_m1=0b0101 ; mrs_banked_m=1 { export sp_abt; }
BankedRegThumb: lr_und is lr_und & op4=0xf3e & mrs_banked_m1=0b0110 ; mrs_banked_m=1 { export lr_und; }
BankedRegThumb: sp_und is sp_und & op4=0xf3e & mrs_banked_m1=0b0111 ; mrs_banked_m=1 { export sp_und; }

BankedRegThumb: lr_mon is lr_mon & op4=0xf3e & mrs_banked_m1=0b1100 ; mrs_banked_m=1 { export lr_mon; }
BankedRegThumb: sp_mon is sp_mon & op4=0xf3e & mrs_banked_m1=0b1101 ; mrs_banked_m=1 { export sp_mon; }
BankedRegThumb: elr_hyp is elr_hyp & op4=0xf3e & mrs_banked_m1=0b1110 ; mrs_banked_m=1 { export elr_hyp; }
BankedRegThumb: sp_hyp is sp_hyp & op4=0xf3e & mrs_banked_m1=0b1111 ; mrs_banked_m=1 { export sp_hyp; }

# MSR, SPSR = 0, M = 1
BankedRegThumb: lr_irq is lr_irq & op4=0xf38 ; msr_banked_m1=0b0000 & msr_banked_m=1 { export lr_irq; }
BankedRegThumb: sp_irq is sp_irq & op4=0xf38 ; msr_banked_m1=0b0001 & msr_banked_m=1 { export sp_irq; }
BankedRegThumb: lr_svc is lr_svc & op4=0xf38 ; msr_banked_m1=0b0010 & msr_banked_m=1 { export lr_svc; }
BankedRegThumb: sp_svc is sp_svc & op4=0xf38 ; msr_banked_m1=0b0011 & msr_banked_m=1 { export sp_svc; }
BankedRegThumb: lr_abt is lr_abt & op4=0xf38 ; msr_banked_m1=0b0100 & msr_banked_m=1 { export lr_abt; }
BankedRegThumb: sp_abt is sp_abt & op4=0xf38 ; msr_banked_m1=0b0101 & msr_banked_m=1 { export sp_abt; }
BankedRegThumb: lr_und is lr_und & op4=0xf38 ; msr_banked_m1=0b0110 & msr_banked_m=1 { export lr_und; }
BankedRegThumb: sp_und is sp_und & op4=0xf38 ; msr_banked_m1=0b0111 & msr_banked_m=1 { export sp_und; }

BankedRegThumb: lr_mon is lr_mon & op4=0xf38 ; msr_banked_m1=0b1100 & msr_banked_m=1 { export lr_mon; }
BankedRegThumb: sp_mon is sp_mon & op4=0xf38 ; msr_banked_m1=0b1101 & msr_banked_m=1 { export sp_mon; }
BankedRegThumb: elr_hyp is elr_hyp & op4=0xf38 ; msr_banked_m1=0b1110 & msr_banked_m=1 { export elr_hyp; }
BankedRegThumb: sp_hyp is sp_hyp & op4=0xf38 ; msr_banked_m1=0b1111 & msr_banked_m=1 { export sp_hyp; }

# Fallback: unknown registers
BankedRegThumb: "banked_reg_sysm("^BankedSysmThumb^")" is (op4=0xf3e ; op0) & BankedSysmThumb { tmp:4 = UnkBankedRegRead(BankedSysmThumb:1); export tmp; }
BankedRegThumb: "banked_reg_sysm("^BankedSysmThumb^")" is (op4=0xf38 & thc0404=0 & Rn0003 ; op0) & BankedSysmThumb { tmp:4 = UnkBankedRegWrite(BankedSysmThumb:1, Rn0003); export tmp; }

# MRS, SPSR = 1
BankedSpsrThumb: spsr_fiq is spsr_fiq & op4=0xf3f & mrs_banked_m1=0b1110 ; mrs_banked_m=0 { export spsr_fiq; }
BankedSpsrThumb: spsr_irq is spsr_irq & op4=0xf3f & mrs_banked_m1=0b0000 ; mrs_banked_m=1 { export spsr_irq; }
BankedSpsrThumb: spsr_svc is spsr_svc & op4=0xf3f & mrs_banked_m1=0b0010 ; mrs_banked_m=1 { export spsr_svc; }
BankedSpsrThumb: spsr_abt is spsr_abt & op4=0xf3f & mrs_banked_m1=0b0100 ; mrs_banked_m=1 { export spsr_abt; }
BankedSpsrThumb: spsr_und is spsr_und & op4=0xf3f & mrs_banked_m1=0b0110 ; mrs_banked_m=1 { export spsr_und; }
BankedSpsrThumb: spsr_mon is spsr_mon & op4=0xf3f & mrs_banked_m1=0b1100 ; mrs_banked_m=1 { export spsr_mon; }
BankedSpsrThumb: spsr_hyp is spsr_hyp & op4=0xf3f & mrs_banked_m1=0b1110 ; mrs_banked_m=1 { export spsr_hyp; }

# MSR, SPSR = 1
BankedSpsrThumb: spsr_fiq is spsr_fiq & op4=0xf39 ; msr_banked_m1=0b1110 & msr_banked_m=0 { export spsr_fiq; }
BankedSpsrThumb: spsr_irq is spsr_irq & op4=0xf39 ; msr_banked_m1=0b0000 & msr_banked_m=1 { export spsr_irq; }
BankedSpsrThumb: spsr_svc is spsr_svc & op4=0xf39 ; msr_banked_m1=0b0010 & msr_banked_m=1 { export spsr_svc; }
BankedSpsrThumb: spsr_abt is spsr_abt & op4=0xf39 ; msr_banked_m1=0b0100 & msr_banked_m=1 { export spsr_abt; }
BankedSpsrThumb: spsr_und is spsr_und & op4=0xf39 ; msr_banked_m1=0b0110 & msr_banked_m=1 { export spsr_und; }
BankedSpsrThumb: spsr_mon is spsr_mon & op4=0xf39 ; msr_banked_m1=0b1100 & msr_banked_m=1 { export spsr_mon; }
BankedSpsrThumb: spsr_hyp is spsr_hyp & op4=0xf39 ; msr_banked_m1=0b1110 & msr_banked_m=1 { export spsr_hyp; }

# Fallback: unknown registers
BankedSpsrThumb: "banked_spsr_sysm("^BankedSysmThumb^")" is (op4=0xf3f ; op0) & BankedSysmThumb { tmp:4 = UnkBankedSpsrRead(BankedSysmThumb:1); export tmp; }
BankedSpsrThumb: "banked_spsr_sysm("^BankedSysmThumb^")" is (op4=0xf39 & Rn0003 ; op0) & BankedSysmThumb { tmp:4 = UnkBankedSpsrWrite(BankedSysmThumb:1, Rn0003); export tmp; }


:mrs^ItCond Rd0811,BankedRegThumb is TMode=1 & ItCond & (op4=0xf3e; op12=0x8 & Rd0811 & thc0507=0x1 & thc0003=0x0) & BankedRegThumb
{
build ItCond;
Rd0811 = BankedRegThumb;
}

:mrs^ItCond Rd0811,BankedSpsrThumb is TMode=1 & ItCond & (op4=0xf3f; op12=0x8 & Rd0811 & thc0507=0x1 & thc0003=0x0) & BankedSpsrThumb
{
build ItCond;
Rd0811 = BankedSpsrThumb;
}

:msr^ItCond BankedRegThumb,Rn0003 is TMode=1 & ItCond & (op4=0xf38 & Rn0003; op12=0x8 & thc0507=0x1 & thc0003=0x0) & BankedRegThumb
{
build ItCond;
BankedRegThumb = Rn0003;
}

:msr^ItCond BankedSpsrThumb,Rn0003 is TMode=1 & ItCond & (op4=0xf39 & Rn0003; op12=0x8 & thc0507=0x1 & thc0003=0x0) & BankedSpsrThumb
{
build ItCond;
BankedSpsrThumb = Rn0003;
}


@endif # defined(VERSION_7)

thpsrmask: is th_psrmask=0 { export 0:4; }
thpsrmask: "_c" is th_psrmask=1 { export 0xff:4; }
Expand Down
86 changes: 86 additions & 0 deletions Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ define token instrArm (32)
x=(5,5)
r=(5,5)
y=(6,6)
banked_m1=(16,19)
banked_m=(8,8)

# Advanced SIMD and VFP instruction fields
D22=(22,22)
Expand Down Expand Up @@ -4142,6 +4144,66 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate
Rd = coprocessor_movefromRt(t_cpn,t_op1,t_opc2,CRn,CRm);
}

BankedSysmArm: banked_sysm is banked_m & banked_m1
[ banked_sysm = (banked_m << 4) $or banked_m1; ]
{
export *[const]:4 banked_sysm;
}

# MRS/MSR (banked register)
# See https://developer.arm.com/documentation/ddi0597/2024-12/Base-Instructions/MSR--Banked-register---Move-general-purpose-register-to-Banked-or-Special-register-
#
# M1/M are in the same places for MRS/MSR instructions, so no need to
# distinguish between them

# SPSR = 0, M = 0
BankedRegArm: r8_usr is r8_usr & banked_m=0 & banked_m1=0b0000 { export r8_usr; }
BankedRegArm: r9_usr is r9_usr & banked_m=0 & banked_m1=0b0001 { export r9_usr; }
BankedRegArm: r10_usr is r10_usr & banked_m=0 & banked_m1=0b0010 { export r10_usr; }
BankedRegArm: r11_usr is r11_usr & banked_m=0 & banked_m1=0b0011 { export r11_usr; }
BankedRegArm: r12_usr is r12_usr & banked_m=0 & banked_m1=0b0100 { export r12_usr; }
BankedRegArm: sp_usr is sp_usr & banked_m=0 & banked_m1=0b0101 { export sp_usr; }
BankedRegArm: lr_usr is lr_usr & banked_m=0 & banked_m1=0b0110 { export lr_usr; }

BankedRegArm: r8_fiq is r8_fiq & banked_m=0 & banked_m1=0b1000 { export r8_fiq; }
BankedRegArm: r9_fiq is r9_fiq & banked_m=0 & banked_m1=0b1001 { export r9_fiq; }
BankedRegArm: r10_fiq is r10_fiq & banked_m=0 & banked_m1=0b1010 { export r10_fiq; }
BankedRegArm: r11_fiq is r11_fiq & banked_m=0 & banked_m1=0b1011 { export r11_fiq; }
BankedRegArm: r12_fiq is r12_fiq & banked_m=0 & banked_m1=0b1100 { export r12_fiq; }
BankedRegArm: sp_fiq is sp_fiq & banked_m=0 & banked_m1=0b1101 { export sp_fiq; }
BankedRegArm: lr_fiq is lr_fiq & banked_m=0 & banked_m1=0b1110 { export lr_fiq; }

# SPSR = 0, M = 0
BankedRegArm: lr_irq is lr_irq & banked_m=1 & banked_m1=0b0000 { export lr_irq; }
BankedRegArm: sp_irq is sp_irq & banked_m=1 & banked_m1=0b0001 { export sp_irq; }
BankedRegArm: lr_svc is lr_svc & banked_m=1 & banked_m1=0b0010 { export lr_svc; }
BankedRegArm: sp_svc is sp_svc & banked_m=1 & banked_m1=0b0011 { export sp_svc; }
BankedRegArm: lr_abt is lr_abt & banked_m=1 & banked_m1=0b0100 { export lr_abt; }
BankedRegArm: sp_abt is sp_abt & banked_m=1 & banked_m1=0b0101 { export sp_abt; }
BankedRegArm: lr_und is lr_und & banked_m=1 & banked_m1=0b0110 { export lr_und; }
BankedRegArm: sp_und is sp_und & banked_m=1 & banked_m1=0b0111 { export sp_und; }

BankedRegArm: lr_mon is lr_mon & banked_m=1 & banked_m1=0b1100 { export lr_mon; }
BankedRegArm: sp_mon is sp_mon & banked_m=1 & banked_m1=0b1101 { export sp_mon; }
BankedRegArm: elr_hyp is elr_hyp & banked_m=1 & banked_m1=0b1110 { export elr_hyp; }
BankedRegArm: sp_hyp is sp_hyp & banked_m=1 & banked_m1=0b1111 { export sp_hyp; }

# Fallback: unknown registers
BankedRegArm: "banked_reg_sysm("^BankedSysmArm^")" is c2027=0x10 & BankedSysmArm { tmp:4 = UnkBankedRegRead(BankedSysmArm:1); export tmp; }
BankedRegArm: "banked_reg_sysm("^BankedSysmArm^")" is c2027=0x12 & RnLo & BankedSysmArm { tmp:4 = UnkBankedRegWrite(BankedSysmArm:1, RnLo); export tmp; }

# MRS/MSR (banked register), spsr=1
BankedSpsrArm: spsr_fiq is spsr_fiq & banked_m=0 & banked_m1=0b1110 { export spsr_fiq; }
BankedSpsrArm: spsr_irq is spsr_irq & banked_m=1 & banked_m1=0b0000 { export spsr_irq; }
BankedSpsrArm: spsr_svc is spsr_svc & banked_m=1 & banked_m1=0b0010 { export spsr_svc; }
BankedSpsrArm: spsr_abt is spsr_abt & banked_m=1 & banked_m1=0b0100 { export spsr_abt; }
BankedSpsrArm: spsr_und is spsr_und & banked_m=1 & banked_m1=0b0110 { export spsr_und; }
BankedSpsrArm: spsr_mon is spsr_mon & banked_m=1 & banked_m1=0b1100 { export spsr_mon; }
BankedSpsrArm: spsr_hyp is spsr_hyp & banked_m=1 & banked_m1=0b1110 { export spsr_hyp; }

# Fallback: unknown registers
BankedSpsrArm: "banked_spsr_sysm("^BankedSysmArm^")" is c2027=0x14 & BankedSysmArm { tmp:4 = UnkBankedSpsrRead(BankedSysmArm:1); export tmp; }
BankedSpsrArm: "banked_spsr_sysm("^BankedSysmArm^")" is c2027=0x16 & RnLo & BankedSysmArm { tmp:4 = UnkBankedSpsrWrite(BankedSysmArm:1, RnLo); export tmp; }

:mrs^COND Rd,cpsr is $(AMODE) & ARMcond=1 & COND & c2027=16 & c1619=15 & Rd & offset_12=0 & cpsr
{
Expand All @@ -4156,6 +4218,18 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate
Rd = spsr;
}

:mrs^COND Rd,BankedRegArm is $(AMODE) & ARMcond=1 & COND & c2027=0x10 & Rd & c0911=1 & c0007=0 & BankedRegArm
{
build COND;
Rd = BankedRegArm;
}

:mrs^COND Rd,BankedSpsrArm is $(AMODE) & ARMcond=1 & COND & c2027=0x14 & Rd & c0911=1 & c0007=0 & BankedSpsrArm
{
build COND;
Rd = BankedSpsrArm;
}

:msr^COND cpsrmask,shift1 is $(AMODE) & ARMcond=1 & COND & c2027=50 & cpsrmask & c1215=15 & c2627=0 & shift1
{
build COND;
Expand Down Expand Up @@ -4193,6 +4267,18 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate
spsr = (spsr& ~spsrmask) | (rm & spsrmask);
}

:msr^COND BankedRegArm,RnLo is $(AMODE) & ARMcond=1 & COND & c2027=0x12 & c0915=0x79 & c0407=0 & RnLo & BankedRegArm
{
build COND;
BankedRegArm = RnLo;
}

:msr^COND BankedSpsrArm,RnLo is $(AMODE) & ARMcond=1 & COND & c2027=0x16 & c0915=0x79 & c0407=0 & RnLo & BankedSpsrArm
{
build COND;
BankedSpsrArm = RnLo;
}

:mul^COND^SBIT_ZN rn,rm,rs is $(AMODE) & ARMcond=1 & COND & c2527=0 & c2124=0 & SBIT_ZN & rn & c1215=0 & rs & c0407=9 & rm
{
build COND;
Expand Down
4 changes: 4 additions & 0 deletions Ghidra/Processors/ARM/data/languages/ARMt.pspec
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
<symbol name="H_FIQ" address="ram:0xFFFF001c" entry="true"/>
</default_symbols>

<volatile outputop="cWrite" inputop="cRead">
<range space="register" first="0x400" last="0x4ff"/>
</volatile>

<register_data>
<register name="q0" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q1" group="NEON" vector_lane_sizes="1,2,4"/>
Expand Down
4 changes: 4 additions & 0 deletions Ghidra/Processors/ARM/data/languages/ARMtTHUMB.pspec
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
<symbol name="H_FIQ" address="ram:0xFFFF001c" entry="true"/>
</default_symbols>

<volatile outputop="cWrite" inputop="cRead">
<range space="register" first="0x400" last="0x4ff"/>
</volatile>

<register_data>
<register name="q0" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q1" group="NEON" vector_lane_sizes="1,2,4"/>
Expand Down