162 lines
4.4 KiB
C
162 lines
4.4 KiB
C
; ARM6 PSR transfer macros
|
|
|
|
; Condition code symbols
|
|
|
|
Cond_EQ * 0 :SHL: 28
|
|
Cond_NE * 1 :SHL: 28
|
|
Cond_CS * 2 :SHL: 28
|
|
Cond_HS * Cond_CS
|
|
Cond_CC * 3 :SHL: 28
|
|
Cond_LO * Cond_CC
|
|
Cond_MI * 4 :SHL: 28
|
|
Cond_PL * 5 :SHL: 28
|
|
Cond_VS * 6 :SHL: 28
|
|
Cond_VC * 7 :SHL: 28
|
|
Cond_HI * 8 :SHL: 28
|
|
Cond_LS * 9 :SHL: 28
|
|
Cond_GE * 10 :SHL: 28
|
|
Cond_LT * 11 :SHL: 28
|
|
Cond_GT * 12 :SHL: 28
|
|
Cond_LE * 13 :SHL: 28
|
|
Cond_AL * 14 :SHL: 28
|
|
Cond_ * Cond_AL
|
|
Cond_NV * 15 :SHL: 28
|
|
|
|
; New positions of I and F bits in 32-bit PSR
|
|
|
|
I32_bit * 1 :SHL: 7
|
|
F32_bit * 1 :SHL: 6
|
|
IF32_26Shift * 26-6
|
|
|
|
; Processor mode numbers
|
|
|
|
USR26_mode * 2_00000
|
|
FIQ26_mode * 2_00001
|
|
IRQ26_mode * 2_00010
|
|
SVC26_mode * 2_00011
|
|
USR32_mode * 2_10000
|
|
FIQ32_mode * 2_10001
|
|
IRQ32_mode * 2_10010
|
|
SVC32_mode * 2_10011
|
|
ABT32_mode * 2_10111
|
|
UND32_mode * 2_11011
|
|
|
|
; New register names
|
|
|
|
r13_abort RN 13
|
|
r14_abort RN 14
|
|
lr_abort RN 14
|
|
|
|
r13_undef RN 13
|
|
r14_undef RN 14
|
|
lr_undef RN 14
|
|
|
|
MACRO
|
|
mrs $cond, $rd, $psrs
|
|
LCLA psrtype
|
|
psrtype SETA -1
|
|
[ "$psrs" = "CPSR" :LOR: "$psrs" = "CPSR_all"
|
|
psrtype SETA 0 :SHL: 22
|
|
]
|
|
[ "$psrs" = "SPSR" :LOR: "$psrs" = "SPSR_all"
|
|
psrtype SETA 1 :SHL: 22
|
|
]
|
|
ASSERT psrtype <> -1
|
|
ASSERT $rd <> 15
|
|
& Cond_$cond :OR: 2_00000001000011110000000000000000 :OR: psrtype :OR: ($rd :SHL: 12)
|
|
MEND
|
|
|
|
MACRO
|
|
msr $cond, $psrl, $op2a, $op2b
|
|
LCLA psrtype
|
|
LCLS op2as
|
|
LCLA op
|
|
LCLA shift
|
|
psrtype SETA -1
|
|
[ "$psrl" = "CPSR" :LOR: "$psrl" = "CPSR_all"
|
|
psrtype SETA (0:SHL:22) :OR: (1:SHL:19) :OR: (1:SHL:16)
|
|
]
|
|
[ "$psrl" = "CPSR_flg"
|
|
psrtype SETA (0:SHL:22) :OR: (1:SHL:19) :OR: (0:SHL:16)
|
|
]
|
|
[ "$psrl" = "CPSR_ctl"
|
|
psrtype SETA (0:SHL:22) :OR: (0:SHL:19) :OR: (1:SHL:16)
|
|
]
|
|
[ "$psrl" = "SPSR" :LOR: "$psrl" = "SPSR_all"
|
|
psrtype SETA (1:SHL:22) :OR: (1:SHL:19) :OR: (1:SHL:16)
|
|
]
|
|
[ "$psrl" = "SPSR_flg"
|
|
psrtype SETA (1:SHL:22) :OR: (1:SHL:19) :OR: (0:SHL:16)
|
|
]
|
|
[ "$psrl" = "SPSR_ctl"
|
|
psrtype SETA (1:SHL:22) :OR: (0:SHL:19) :OR: (1:SHL:16)
|
|
]
|
|
ASSERT psrtype <> -1
|
|
[ ("$op2a" :LEFT: 1) = "#"
|
|
; Immediate operand
|
|
|
|
op2as SETS "$op2a" :RIGHT: ((:LEN: "$op2a")-1)
|
|
op SETA $op2as
|
|
|
|
[ "$op2b" = ""
|
|
; Rotate not specified in immediate operand
|
|
shift SETA 0
|
|
WHILE (op :AND: &FFFFFF00)<>0 :LAND: shift<16
|
|
op SETA ((op:SHR:30):AND:3):OR:(op:SHL:2)
|
|
shift SETA shift + 1
|
|
WEND
|
|
ASSERT (op :AND: &FFFFFF00)=0
|
|
|
|
|
; Rotate of immediate operand specified explicitly
|
|
ASSERT (($op2b):AND:&FFFFFFE1)=0
|
|
shift SETA ($opt2b):SHR:1
|
|
]
|
|
op SETA (shift :SHL: 8) :OR: op :OR: (1:SHL:25)
|
|
|
|
|
|
|
; Not an immediate operand
|
|
[ "$op2b" = ""
|
|
; Unshifted register
|
|
op SETA ($op2a) :OR: (0:SHL:25)
|
|
|
|
|
! 1, "Shifted register not yet implemented in this macro!"
|
|
]
|
|
]
|
|
& Cond_$cond :OR: 2_00000001001000001111000000000000 :OR: op :OR: psrtype
|
|
MEND
|
|
|
|
; SetMode newmode, reg1, regoldpsr
|
|
;
|
|
; Sets processor mode to constant value newmode
|
|
; using register reg1 as a temporary.
|
|
; If regoldpsr is specified, then this register
|
|
; on exit holds the old PSR before the mode change
|
|
; reg1 on exit always holds the new PSR after the mode change
|
|
|
|
; MACRO
|
|
; SetMode $newmode, $reg1, $regoldpsr
|
|
; [ "$regoldpsr"=""
|
|
; mrs AL, $reg1, CPSR_all
|
|
; BIC $reg1, $reg1, #&1F
|
|
; ORR $reg1, $reg1, #$newmode
|
|
; msr AL, CPSR_all, $reg1
|
|
; |
|
|
; mrs AL, $regoldpsr, CPSR_all
|
|
; BIC $reg1, $regoldpsr, #&1F
|
|
; ORR $reg1, $reg1, #$newmode
|
|
; msr AL, CPSR_all, $reg1
|
|
; ]
|
|
; MEND
|
|
|
|
MACRO
|
|
mrc $cond, $coproc, $op, $rd, $crn, $crm, $info
|
|
& Cond_$cond :OR: 2_00001110000100000000000000010000 :OR: ($coproc :SHL: 8) :OR: ($op :SHL: 21) :OR: ($rd :SHL: 12) :OR: ($crn :SHL: 16) :OR: $crm :OR: ($info :SHL: 5)
|
|
MEND
|
|
|
|
MACRO
|
|
mcr $cond, $coproc, $op, $rd, $crn, $crm, $info
|
|
& Cond_$cond :OR: 2_00001110000000000000000000010000 :OR: ($coproc :SHL: 8) :OR: ($op :SHL: 21) :OR: ($rd :SHL: 12) :OR: ($crn :SHL: 16) :OR: $crm :OR: ($info :SHL: 5)
|
|
MEND
|
|
|
|
END
|