1 ! Copyright (C) 2007 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays generator generator.fixup kernel sequences words
4 namespaces math math.bitfields ;
7 : define-registers ( seq -- )
8 dup length [ "register" set-word-prop ] 2each ;
27 { R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 }
30 PREDICATE: register < word register >boolean ;
32 GENERIC: register ( register -- n )
33 M: word register "register" word-prop ;
34 M: f register drop 0 ;
36 : SL R10 ; inline : FP R11 ; inline : IP R12 ; inline
37 : SP R13 ; inline : LR R14 ; inline : PC R15 ; inline
46 #! Default value is BIN: 1110 AL (= always)
47 cond-code [ f ] change BIN: 1110 or ;
66 : (insn) ( n -- ) CC> 28 shift bitor , ;
68 : insn ( bitspec -- ) bitfield (insn) ; inline
70 ! Branching instructions
71 GENERIC# (B) 1 ( signed-imm-24 l -- )
73 M: integer (B) { 24 { 1 25 } { 0 26 } { 1 27 } 0 } insn ;
74 M: word (B) 0 swap (B) rc-relative-arm-3 rel-word ;
75 M: label (B) 0 swap (B) rc-relative-arm-3 label-fixup ;
77 : B 0 (B) ; : BL 1 (B) ;
79 ! Data processing instructions
80 SYMBOL: updates-cond-code
82 : S ( -- ) updates-cond-code on ;
84 : S> ( -- ? ) updates-cond-code [ f ] change ;
86 : sinsn ( bitspec -- )
87 bitfield S> [ 20 2^ bitor ] when (insn) ; inline
89 GENERIC# shift-imm/reg 2 ( shift-imm/Rs Rm shift -- n )
91 M: integer shift-imm/reg ( shift-imm Rm shift -- n )
92 { { 0 4 } 5 { register 0 } 7 } bitfield ;
94 M: register shift-imm/reg ( Rs Rm shift -- n )
103 GENERIC: shifter-op ( shifter-op -- n )
105 TUPLE: IMM immed rotate ;
109 dup IMM-immed swap IMM-rotate
110 { { 1 25 } 8 0 } bitfield ;
112 TUPLE: shifter Rm by shift ;
115 M: shifter shifter-op
116 dup shifter-by over shifter-Rm rot shifter-shift
119 : <LSL> ( Rm shift-imm/Rs -- shifter-op ) BIN: 00 <shifter> ;
120 : <LSR> ( Rm shift-imm/Rs -- shifter-op ) BIN: 01 <shifter> ;
121 : <ASR> ( Rm shift-imm/Rs -- shifter-op ) BIN: 10 <shifter> ;
122 : <ROR> ( Rm shift-imm/Rs -- shifter-op ) BIN: 11 <shifter> ;
123 : <RRX> ( Rm -- shifter-op ) 0 <ROR> ;
125 M: register shifter-op 0 <LSL> shifter-op ;
127 M: integer shifter-op 0 <IMM> shifter-op ;
129 : addr1 ( Rd Rn shifter-op opcode -- )
137 : AND BIN: 0000 addr1 ;
138 : EOR BIN: 0001 addr1 ;
139 : SUB BIN: 0010 addr1 ;
140 : RSB BIN: 0011 addr1 ;
141 : ADD BIN: 0100 addr1 ;
142 : ADC BIN: 0101 addr1 ;
143 : SBC BIN: 0110 addr1 ;
144 : RSC BIN: 0111 addr1 ;
145 : ORR BIN: 1100 addr1 ;
146 : BIC BIN: 1110 addr1 ;
148 : MOV f swap BIN: 1101 addr1 ;
149 : MVN f swap BIN: 1111 addr1 ;
151 ! These always update the condition code flags
152 : (CMP) >r f -rot r> S addr1 ;
154 : TST BIN: 1000 (CMP) ;
155 : TEQ BIN: 1001 (CMP) ;
156 : CMP BIN: 1010 (CMP) ;
157 : CMN BIN: 1011 (CMP) ;
159 ! Multiply instructions
160 : (MLA) ( Rd Rm Rs Rn a -- )
171 : MUL ( Rd Rm Rs -- ) f 0 (MLA) ;
172 : MLA ( Rd Rm Rs Rn -- ) 1 (MLA) ;
174 : (S/UMLAL) ( RdLo RdHi Rm Rs s a -- )
187 : SMLAL 1 1 (S/UMLAL) ; : SMULL 1 0 (S/UMLAL) ;
188 : UMLAL 0 1 (S/UMLAL) ; : UMULL 0 0 (S/UMLAL) ;
190 ! Miscellaneous arithmetic instructions
203 ! Status register acess instructions
205 ! Load and store instructions
206 GENERIC: addressing-mode-2 ( addressing-mode -- n )
208 TUPLE: addressing p u w ;
209 : <addressing> ( delegate p u w -- addressing )
215 } addressing construct ;
217 M: addressing addressing-mode-2
219 addressing-p addressing-u addressing-w delegate
220 } get-slots addressing-mode-2
221 { 0 21 23 24 } bitfield ;
223 M: integer addressing-mode-2 ;
225 M: object addressing-mode-2 shifter-op { { 1 25 } 0 } bitfield ;
228 : <+> 1 1 0 <addressing> ;
229 : <-> 1 0 0 <addressing> ;
232 : <!+> 1 1 1 <addressing> ;
233 : <!-> 1 0 1 <addressing> ;
236 : <+!> 0 1 0 <addressing> ;
237 : <-!> 0 0 0 <addressing> ;
239 : addr2 ( Rd Rn addressing-mode b l -- )
244 { addressing-mode-2 0 }
254 ! We might have to simulate these instructions since older ARM
255 ! chips don't have them.
259 GENERIC# (BX) 1 ( Rm l -- )
261 M: register (BX) ( Rm l -- )
273 M: word (BX) 0 swap (BX) rc-relative-arm-3 rel-word ;
275 M: label (BX) 0 swap (BX) rc-relative-arm-3 label-fixup ;
277 : BX have-BX? get [ 0 (BX) ] [ PC swap MOV ] if ;
279 : BLX have-BLX? get [ 1 (BX) ] [ LR PC MOV BX ] if ;
281 ! More load and store instructions
282 GENERIC: addressing-mode-3 ( addressing-mode -- n )
284 : b>n/n ( b -- n n ) dup -4 shift swap HEX: f bitand ;
286 M: addressing addressing-mode-3
287 [ addressing-p ] keep
288 [ addressing-u ] keep
289 [ addressing-w ] keep
290 delegate addressing-mode-3
291 { 0 21 23 24 } bitfield ;
293 M: integer addressing-mode-3
303 M: object addressing-mode-3
311 : addr3 ( Rn Rd addressing-mode h l s -- )
316 { addressing-mode-3 0 }
322 : LDRSB 0 1 1 addr3 ;
323 : LDRSH 1 1 1 addr3 ;
326 ! Load and store multiple instructions
328 ! Semaphore instructions
330 ! Exception-generating instructions