1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
; 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
|