1 /****************************************************************************
2 * ACK backend for Acorn Risc Machine *
3 * First version: A.N.Other, Vrije Universiteit, Amsterdam *
4 * Completed by: Albert Koelmans, University of Newcastle *
5 * Register variables by Jonathan Hardwick *
6 * With help from: Andy Michael and Ceriel Jacobs *
7 ****************************************************************************/
9 #define legal(a) ((a&~0xFF)==0||(a&~0x3FC)==0||(a&~0xFF0)==0||\
10 (a&~0x3FC0)==0||(a&~0xFF00)==0||(a&~0x3FC00)==0||\
11 (a&~0xFF000)==0||(a&~0x3FC000)==0||(a&~0xFF0000)==0||\
12 (a&~0x3FC0000)==0||(a&~0xFF00000)==0||(a&~0x3FC00000)==0||\
13 (a&~0xFF000000)==0||(a&~0xFC000003)==0||(a&~0xF000000F)==0||\
14 (a&~0xC000003F)==0||(~a&~0xFF)==0)
15 #define neglegal(a) (((0-a)&~0xFF)==0||((0-a)&~0x3FC)==0||((0-a)&~0xFF0)==0||\
16 ((0-a)&~0x3FC0)==0||((0-a)&~0xFF00)==0||((0-a)&~0x3FC00)==0||\
17 ((0-a)&~0xFF000)==0||((0-a)&~0x3FC000)==0||((0-a)&~0xFF0000)==0||\
18 ((0-a)&~0x3FC0000)==0||((0-a)&~0xFF00000)==0||((0-a)&~0x3FC00000)==0||\
19 ((0-a)&~0xFF000000)==0||((0-a)&~0xFC000003)==0||((0-a)&~0xF000000F)==0||\
20 ((0-a)&~0xC000003F)==0||(~(0-a)&~0xFF)==0)
22 #define illegal(a) !legal(a)
23 #define minlegal(a) (a < 0) && neglegal(a)
24 #define minillegal(a) (a < 0) && !neglegal(a)
32 GENREG /* All 16 user registers */
33 REG /* Allocatable registers */
34 PCPSR /* PSW and PC */
42 R0,R1,R2,R3,R8,R9,R10 :GENREG, REG .
43 R4,R5,R6,R7 :GENREG regvar(reg_any).
45 SP("R12") :STACKPOINTER .
46 LB("R13") :LOCALBASE .
47 LR("R14") :LINKREGISTER .
52 const4 = { INT num; } 4 cost(0,4) "#" num .
53 fitcon = { INT num; } 4 cost(0,4) "#" num .
54 lb_local = { INT ind; } 4 "[R13,#" ind "]" .
55 addr_local = { INT ind; } 4 .
56 naddr_local = { INT ind; } 4 .
57 absolute = { ADDR add; } 4 add .
58 addr_external = { ADDR add; } 4 add .
59 label = { ADDR add; } 4 add .
60 autoid = { STACKPOINTER reg; } 4 reg "<" .
61 regexp = { INT exp;} 4 exp .
62 register = { GENREG exp;} 4 exp .
64 imS = { GENREG reg; ADDR S; INT shift;} 4
66 regS = { GENREG reg; ADDR S; GENREG sreg;} 4
68 regind = { GENREG reg; } 4
70 REGrel = { REG reg; ADDR ind; } 4
71 "[" reg ",#" ind "]" .
72 regrel = { GENREG reg; ADDR ind; } 4
73 "[" reg ",#" ind "]" .
74 st_regrel = { STACKPOINTER reg; ADDR ind; } 4
75 "[" reg ",#" ind "]" .
76 lb_regrel = { LOCALBASE reg; ADDR ind; } 4
77 "[" reg ",#" ind "]" .
78 regregrel = { GENREG reg1; GENREG reg2; } 4
79 "[" reg1 "," reg2 "]" .
80 st_regregrel = { STACKPOINTER reg1; GENREG reg2; } 4
81 "[" reg1 "," reg2 "]" .
82 lb_regregrel = { LOCALBASE reg1; GENREG reg2; } 4
83 "[" reg1 "," reg2 "]" .
84 regminregrel = { GENREG reg1; GENREG reg2; } 4
85 "[" reg1 ",-" reg2 "]" .
86 regiSregrel = { GENREG reg1; ADDR S; INT shift; GENREG reg2; } 4
87 "[" reg1 "," reg2 "," S "#" shift "]" .
88 st_regiSregrel = { STACKPOINTER reg1; ADDR S; INT shift; GENREG reg2; } 4
89 "[" reg1 "," reg2 "," S "#" shift "]" .
90 regminiSregrel = { GENREG reg1; ADDR S; INT shift; GENREG reg2; } 4
91 "[" reg1 ",-" reg2 "," S "#" shift "]" .
92 regminrSregrel = { GENREG reg1; ADDR S; GENREG sreg; GENREG reg2; } 4
93 "[" reg1 ",-" reg2 "," S " " sreg "]" .
94 regrelpi = { GENREG reg; ADDR ind; } 4
96 regconst = { GENREG reg; INT ind; } 4
99 regplusreg = {GENREG reg1; GENREG reg2;} 4
101 regplusiSreg = {GENREG reg1; ADDR S; INT shift; GENREG reg2;} 4
102 reg1 "," reg2 "," S "#" shift .
103 regplusrSreg = {GENREG reg1; ADDR S; GENREG sreg; GENREG reg2;} 4
104 reg1 "," reg2 "," S "," sreg .
105 regminreg = {GENREG reg1; GENREG reg2;} 4
107 regminiSreg = {GENREG reg1; ADDR S; INT shift; GENREG reg2;} 4
108 reg1 "," reg2 "," S "#" shift .
109 regminrSreg = {GENREG reg1; ADDR S; GENREG sreg; GENREG reg2;} 4
110 reg1 "," reg2 "," S "," sreg .
112 REGlist1 = {REG reg1; } 4
114 reglist1 = {GENREG reg1; } 4
116 lb_reglist1 = {LOCALBASE reg1; } 4
118 sp_reglist1 = {STACKPOINTER reg1; } 4
120 reglist2 = {GENREG reg1; GENREG reg2; } 8
121 "{" reg1 "," reg2 "}" .
122 lb_pc_reglist2 = {LOCALBASE reg1; PCPSR reg2; } 8
123 "{" reg1 "," reg2 "}" .
124 reglist3 = {GENREG reg1; GENREG reg2; GENREG reg3; } 12
125 "{" reg1 "," reg2 "," reg3 "}" .
126 reglist4 = {GENREG reg1; GENREG reg2; GENREG reg3; GENREG reg4; } 16
127 "{" reg1 "," reg2 "," reg3 "," reg4 "}" .
129 /* the next 5 are not currently used - perhaps later */
130 regrelwb = { GENREG reg; ADDR ind; } 4 "[" reg ",#" ind "]<" .
131 regregrelwb = { GENREG reg1; GENREG reg2; } 4 "[" reg1 "," reg2 "]<" .
132 regiSregrelwb = { GENREG reg1; ADDR S; INT shift; GENREG reg2; } 4
133 "[" reg1 "," reg2 "," S "#" shift "]<" .
134 regrSregrelwb = { GENREG reg1; ADDR S; GENREG sreg; GENREG reg2; } 4
135 "[" reg1 "," reg2 "," S " " sreg "]<" .
136 regregrelpi = { GENREG reg1; GENREG reg2; } 4 "[" reg1 "]," reg2 .
138 LOCAL = { INT ind;} 4 ">>> BUG IN LOCAL".
139 stack = { GENREG r;} 4 "R12<,{" r "}".
141 /* tokens to put shifts and rotates into opcodes */
142 reglslcon = {GENREG target; INT shift;} 4 target ",LSL#" shift.
143 reglsrcon = {GENREG target; INT shift;} 4 target ",LSR#" shift.
144 regasrcon = {GENREG target; INT shift;} 4 target ",ASR#" shift.
145 regrorcon = {GENREG target; INT shift;} 4 target ",ROR#" shift.
146 reglslreg = {GENREG target; GENREG shift;} 4 cost(0,1) target ",LSL " shift.
147 reglsrreg = {GENREG target; GENREG shift;} 4 cost(0,1) target ",LSR " shift.
148 regasrreg = {GENREG target; GENREG shift;} 4 cost(0,1) target ",ASR " shift.
149 regrorreg = {GENREG target; GENREG shift;} 4 cost(0,1) target ",ROR " shift.
150 regrorregr = {GENREG target; GENREG shift;} 4 cost(0,1) target ",ROR " shift.
155 address = absolute + regind + regrel + regrelwb + regregrel +
156 st_regrel + st_regregrel + st_regiSregrel +
157 lb_regrel + lb_regregrel +
158 regiSregrel + regiSregrelwb + regrSregrelwb +
159 regminregrel + regminiSregrel + regminrSregrel +
160 regregrelwb + regrelpi + regregrelpi + lb_local .
161 REGcon = GENREG + imS + regS + fitcon .
162 reglist = reglist1 + reglist2 + reglist3 + reglist4 +
163 lb_reglist1 + sp_reglist1 + lb_pc_reglist2 +
165 constant = fitcon + const4 .
166 local = lb_local + LOCAL.
167 regshift = reglslreg + reglsrreg + regasrreg + regrorreg + regrorregr +
168 reglslcon + reglsrcon + regasrcon + regrorcon.
169 rhs = GENREG + constant + regshift + LOCAL.
170 mem4 = regregrel + regrel + lb_local.
171 extern = addr_external + absolute + label.
172 all_except_con = mem4 + extern + local.
173 any_data = all_except_con + rhs.
174 any_data_except_local = any_data - LOCAL.
175 posshifts = regplusiSreg+regplusrSreg.
176 negshifts = regminiSreg+regminrSreg.
177 shifts = posshifts+negshifts.
181 BAL label cost(4,4) .
182 BAL_L "BAL.L" label cost(4,4) .
183 BAL_LEQ "BAL.L.EQ" label cost(4,4) .
184 BNV label cost(4,4) .
185 BNE label cost(4,4) .
186 BEQ label cost(4,4) .
187 BMI label cost(4,4) .
188 BGT label cost(4,4) .
189 BLT label cost(4,4) .
190 BLE label cost(4,4) .
191 BGE label cost(4,4) .
193 LDR REG+LOCALBASE+GENREG+address:wo, address:rw cost(4,4) .
195 mem4+absolute+addr_external:ro cost(4,4) .
196 STR GENREG+REG:ro, REGrel+address:rw cost(4,4) .
197 LDR_B "LDR.B" REG+GENREG:wo, address:rw cost(4,4) .
198 LDR_B LOCAL:rw, rhs+mem4:ro cost(4,4) .
199 STR_B "STR.B" GENREG+REG:ro, address:rw cost(4,4) .
201 LDMFD autoid:rw, reglist:wo cost(4,7) .
202 STMFD autoid:rw, reglist:ro cost(4,7) .
203 STMFD stack cost(4,4) .
204 LDMIA GENREG:rw, reglist:wo cost(4,7) .
206 ADC REG+GENREG:wo, REG+GENREG:ro, REGcon:ro cost(4,1) .
207 ADD GENREG+REG:wo, GENREG:ro, REGcon+const4:ro cost(4,1) .
208 ADD GENREG+STACKPOINTER:wo, GENREG+STACKPOINTER:ro,
209 STACKPOINTER+REGcon+const4:ro cost(4,1) .
210 ADD LOCAL+GENREG+REG:wo,
211 regconst+shifts+regminreg+regplusreg:ro cost(4,1) .
212 ADD LOCAL+GENREG:rw, LOCALBASE+GENREG+LOCAL:ro,
214 ADD_NE "ADD.NE" GENREG+REG:wo, GENREG:ro, REGcon+const4:ro cost(4,1) .
215 AND REG+GENREG:wo, GENREG:ro, GENREG+REGcon:ro cost(4,1) .
216 AND_S "AND.S" GENREG+REG:wo, GENREG:ro, REGcon:ro cost(4,1) .
217 BIC REG+GENREG:wo, GENREG:ro, REGcon:ro cost(4,1) .
218 CMN GENREG+REG:ro, REGcon:ro kills :cc cost(4,1) .
219 CMP REG+GENREG:ro, REGcon:ro kills :cc cost(4,1) .
220 EOR GENREG+REG:wo, GENREG:ro, GENREG+REGcon:ro cost(4,1) .
221 EOR_S "EOR.S" REG+GENREG:wo:cc, GENREG:ro, REGcon:ro cost(4,1) .
222 MOV REG:wo, REGcon+const4:ro cost(4,1) .
223 MOV REG:rw, LOCAL:ro cost(4,1).
224 MOV LOCALBASE+PCPSR+STACKPOINTER+GENREG:rw,
225 REGcon+address+LOCALBASE+PCPSR+
226 STACKPOINTER+GENREG+LOCAL:ro cost(4,1).
227 MOV LOCAL+GENREG:rw, GENREG+rhs+register+REG:ro cost(4,1).
228 MOV LOCALBASE+GENREG:wo, REGcon+const4:ro cost(4,1) .
229 MOV_MI "MOV.MI" REG+GENREG:wo, REGcon+const4:ro cost(4,1) .
230 MOV_HI "MOV.HI" GENREG+REG:wo, REGcon+const4:ro cost(4,1) .
231 MOV_LS "MOV.LS" REG+GENREG:wo, REGcon+const4:ro cost(4,1) .
232 MOV_LT "MOV.LT" GENREG+REG:wo, REGcon+const4:ro cost(4,1) .
233 MOV_LE "MOV.LE" REG+GENREG:wo, REGcon+const4:ro cost(4,1) .
234 MOV_EQ "MOV.EQ" GENREG+REG:wo, REGcon+const4:ro cost(4,1) .
235 MOV_NE "MOV.NE" REG+GENREG:wo, REGcon+const4:ro cost(4,1) .
236 MOV_GE "MOV.GE" REG+GENREG:wo, REGcon+const4:ro cost(4,1) .
237 MOV_GT "MOV.GT" REG+GENREG:wo, REGcon+const4:ro cost(4,1) .
238 MOV_NV "MOV.NV" GENREG+REG:wo, REGcon+const4:ro cost(4,1) .
239 MOV_S "MOV.S" GENREG+REG:wo, REGcon+const4+regind:ro
240 kills :cc cost(4,1) .
241 MVN LOCAL+GENREG+REG:wo, REGcon:ro cost(4,1) .
242 ORR REG+GENREG:wo, GENREG:ro, GENREG+REGcon:ro cost(4,1) .
243 ORR REG+GENREG+LOCAL:wo, imS:ro cost(4,1) .
244 RSB REG+GENREG+LOCAL:rw, REG+GENREG+LOCAL:ro,
246 RSB GENREG+REG:wo, GENREG:ro, REGcon:ro cost(4,1) .
247 RSB_S "RSB.S" REG+GENREG:wo:cc, GENREG:ro, REGcon:ro cost(4,1) .
248 RSC GENREG+REG:wo, GENREG:ro, REGcon:ro cost(4,1) .
249 SBC REG+GENREG:wo, GENREG:ro, REGcon:ro cost(4,1) .
251 regconst+shifts+regplusreg+regminreg:ro cost(4,1).
252 SUB LOCAL:rw, LOCAL:ro, rhs:ro cost(4,1).
253 SUB LOCAL+REG+GENREG:wo, LOCALBASE+GENREG:ro,
254 constant+REGcon:ro cost(4,1) .
255 SUB_S "SUB.S" REG+GENREG:wo:cc, GENREG:ro, REGcon:ro cost(4,1) .
256 TEQ GENREG+REG:ro, REGcon:ro kills :cc cost(4,1) .
257 TST REG+GENREG:ro, REGcon:ro kills :cc cost(4,1) .
258 ADR REG+LINKREGISTER+GENREG:wo,
259 addr_external+label:ro cost(4,1) .
260 LABEL "" label kills :cc cost(4,1) .
262 /* Dummy instructions for ncgg procedures : lxx is logical operator, */
263 /* mxx is conditional move, bxx is conditional branch, rxx is arith- */
264 /* metical operator on register variable (LOCAL). */
266 lxx "lxx : bug in cg" REG:rw, REG:ro, rhs:ro cost(4,1).
267 mxx "mxx : bug in cg" REG:rw, rhs:ro cost(4,1).
268 bxx "bxx : bug in cg" addr_external cost(4,4).
269 rxx "rxx : bug in cg" LOCAL:rw, LOCAL:ro, rhs:ro cost(4,1).
270 rrx "rrx : bug in cg" LOCAL:rw, LOCAL:ro, LOCAL:ro cost(4,1).
275 from GENREG+STACKPOINTER+LOCALBASE+PCPSR to
276 GENREG+STACKPOINTER+LOCALBASE+PCPSR
279 from fitcon+GENREG+REG to LOCAL inreg(%ind)==reg_any
282 from LOCAL inreg(%ind)==reg_any to REG+GENREG
285 /* illegal immediate operands */
287 from const4 minlegal(%num+1) to GENREG+LOCAL
288 gen MVN %2, {fitcon, 0-%1.num-1}
290 from const4 (minlegal(%num)) to GENREG+LOCAL
291 gen MOV %2, {fitcon, 0-%1.num}
292 RSB %2, %2, {fitcon, 0}
294 from const4 to GENREG+LOCAL /* general case */
295 gen MOV %2, { fitcon, %1.num & 0xFF}
296 ADD %2, %2, { fitcon, %1.num & 0xFF00}
297 ADD %2, %2, { fitcon, %1.num & 0xFF0000}
298 ADD %2, %2, { fitcon, %1.num & 0xFF000000}
300 from regconst (%ind > 0) && legal(%ind) to LOCAL inreg(%ind)==reg_any
303 from regconst minlegal(%ind) to LOCAL inreg(%ind)==reg_any
304 gen SUB %2, %1.reg, {fitcon, 0-%1.ind}
306 from lb_local legal(%ind) to GENREG
307 gen LDR %2, {lb_regrel, LB, %1.ind}
309 from lb_local to GENREG
310 gen move {const4, %1.ind}, R11
311 LDR %2, {lb_regregrel, LB, R11}
313 from GENREG to lb_local legal(%ind)
314 gen STR %1, {lb_regrel, LB, %2.ind}
316 from GENREG to lb_local
317 gen move {const4, %2.ind}, R11
318 STR %1, {lb_regregrel, LB, R11}
320 from GENREG to address
323 from address to GENREG+LOCALBASE
326 from GENREG to autoid
327 gen STMFD %2, {reglist1, %1}
329 from autoid to GENREG
330 gen LDMFD %1, {reglist1, %2}
332 from REGcon to GENREG+LOCALBASE
336 from addr_external to GENREG
339 /* strictly speaking, the following move is impossible.
340 * what it really means is: move from reg to address!
342 from GENREG to addr_external
351 gen CMP %1, {fitcon, 0}
357 gen STMFD {stack, regvar(%1.ind)}
360 gen STMFD {autoid, SP}, {REGlist1, %1}
363 gen STMFD {autoid, SP}, {reglist1, %1}
365 from LOCALBASE to STACK
366 gen STMFD {autoid, SP}, {lb_reglist1, %1}
368 from STACKPOINTER to STACK
369 gen STMFD {autoid, SP}, {sp_reglist1, %1}
373 STMFD {autoid, SP}, {reglist1, R11}
377 STMFD {autoid, SP}, {reglist1, R11}
379 from addr_local legal(%ind) to STACK
380 gen ADD R11, LB, {fitcon, %1.ind}
381 STMFD {autoid, SP}, {reglist1, R11}
383 from addr_local to STACK
384 gen move {const4, %1.ind}, R11
386 STMFD {autoid, SP}, {reglist1, R11}
388 from naddr_local legal(%ind) to STACK
389 gen SUB R11, LB, {fitcon, %1.ind}
390 STMFD {autoid, SP}, {reglist1, R11}
392 from naddr_local to STACK
393 gen move {const4, %1.ind}, R11
395 STMFD {autoid, SP}, {reglist1, R11}
397 from addr_external to STACK
399 STMFD {autoid, SP}, {reglist1, R11}
401 from regconst (%ind > 0) && legal(%ind) to STACK
402 gen ADD R11, %1.reg, {fitcon,%1.ind}
403 STMFD {autoid, SP}, {reglist1, R11}
405 from regconst to STACK
406 gen move {const4, %1.ind}, R11
408 STMFD {autoid, SP}, {reglist1, R11}
410 from regplusreg to STACK
411 gen ADD R11, %1.reg1, %1.reg2
412 STMFD {autoid, SP}, {reglist1, R11}
414 from regminreg to STACK
415 gen SUB R11, %1.reg1, %1.reg2
416 STMFD {autoid, SP}, {reglist1, R11}
418 from regplusiSreg to STACK
419 gen ADD R11, %1.reg1, {imS, %1.reg2, %1.S, %1.shift}
420 STMFD {autoid, SP}, {reglist1, R11}
422 from regminiSreg to STACK
423 gen SUB R11, %1.reg1, {imS, %1.reg2, %1.S, %1.shift}
424 STMFD {autoid, SP}, {reglist1, R11}
426 from regplusrSreg to STACK
427 gen ADD R11, %1.reg1, {regS, %1.reg2, %1.S, %1.sreg}
428 STMFD {autoid, SP}, {reglist1, R11}
430 from regminrSreg to STACK
431 gen SUB R11, %1.reg1, {regS, %1.reg2, %1.S, %1.sreg}
432 STMFD {autoid, SP}, {reglist1, R11}
434 from address to STACK
436 STMFD {autoid, SP}, {reglist1, R11}
442 gen MOV %a, %1 yields %a
444 from lb_local legal(%ind)
446 gen LDR %a, {lb_regrel, LB, %ind} yields %a
450 gen move {const4, %ind}, R11
451 LDR %a, {lb_regregrel, LB, R11} yields %a
455 gen move {const4, 0-%num}, %a
456 RSB %a, %a, {fitcon, 0} yields %a
458 from const4 illegal(%num)
460 gen move %1, %a yields %a
462 from const4 yields {fitcon, %num}
466 gen LDMFD {autoid, SP}, {reglist1, %a} yields %a
470 gen move %1, %a yields %a
474 gen move %1, %a yields %a
481 from addr_local legal(%ind)
483 gen ADD %a, LB, {fitcon, %ind} yields %a
487 gen move {const4, %ind}, %a
488 ADD %a, LB, %a yields %a
490 from naddr_local legal(%ind)
492 gen SUB %a, LB, {fitcon, %ind} yields %a
496 gen move {const4, %ind}, %a
497 SUB %a, LB, %a yields %a
499 from regconst (%ind > 0) && legal(%ind)
501 gen ADD %a, %1 yields %a
503 from regconst minlegal(%ind)
505 gen SUB %a, %reg, {fitcon, 0-%ind} yields %a
507 from regconst minillegal(%ind)
509 gen move {const4, 0-%ind}, %a
510 SUB %a, %a, %reg yields %a
514 gen move {const4, %ind}, %a
515 ADD %a, %a, %reg yields %a
519 gen ADD %a, %reg1, %reg2
524 gen SUB %a, %reg1, %reg2
529 gen ADD %a, %reg1, {imS, %reg2, %S, %shift}
534 gen SUB %a, %reg1, {imS, %reg2, %S, %shift}
539 gen ADD %a, %reg1, {regS, %reg2, %S, %sreg}
544 gen SUB %a, %reg1, {regS, %reg2, %S, %sreg}
550 /************************************************************************
552 * GROUP 0 : Register variables *
554 ************************************************************************/
556 /* Simple load and store */
557 pat lol inreg($1)==reg_any
560 pat lil inreg($1)==reg_any
561 yields {regind, regvar($1)}
563 pat stl inreg($1)==reg_any
566 gen move %1, {LOCAL, $1}
569 gen MOV {LOCAL, $1}, %1
572 gen MOV {LOCAL, $1}, %1
575 gen LDR {LOCAL, $1}, %1
577 kills local %ind == $1
578 gen SUB {LOCAL, $1}, %1
579 with regplusreg+posshifts
580 kills local %ind == $1
581 gen ADD {LOCAL, $1}, %1
583 kills local %ind == $1
584 gen SUB {LOCAL, $1}, %1
586 pat stl $1==1 && inreg($1)==reg_any
589 gen LDR_B {LOCAL, $1}, %1
591 pat sil inreg($1)==reg_any
593 kills /*all_except_con*/ address
594 gen move %1, {regind, regvar($1)}
597 /* Increment, decrement, zero */
598 pat inl inreg($1)==reg_any
600 gen ADD {LOCAL, $1}, {LOCAL, $1}, {fitcon, 1}
602 pat del inreg($1)==reg_any
604 gen SUB {LOCAL, $1}, {LOCAL, $1}, {fitcon, 1}
606 pat zrl inreg($1)==reg_any
608 gen MOV {LOCAL, $1}, {fitcon, 0}
610 pat lol inc stl inreg($1)==reg_any && inreg($3)==reg_any
612 gen ADD {LOCAL, $3}, {LOCAL, $1}, {fitcon, 1}
614 pat lol dec stl inreg($1)==reg_any && inreg($3)==reg_any
616 gen SUB {LOCAL, $3}, {LOCAL, $1}, {fitcon, 1}
618 pat lol ngi stl inreg($1)==reg_any && inreg($3)==reg_any
620 gen RSB {LOCAL, $3}, {LOCAL, $1}, {fitcon, 0}
622 /* Procedure : load register, op xx, store register */
623 proc lol_op_stl example lol adi stl
626 gen rxx* {LOCAL, $3}, {LOCAL, $1}, %1
628 pat lol adi stl inreg($1)==reg_any && inreg($3)==reg_any && $2==4
629 call lol_op_stl("ADD")
631 pat lol adu stl leaving lol $1 adi $2 stl $3
633 pat lol sbi stl inreg($1)==reg_any && inreg($3)==reg_any && $2==4
634 call lol_op_stl("RSB")
636 pat lol sbu stl leaving lol $1 sbi $2 stl $3
638 pat lol and stl inreg($1)==reg_any && inreg($3)==reg_any && $2==4
639 call lol_op_stl("AND")
641 pat lol ior stl inreg($1)==reg_any && inreg($3)==reg_any && $2==4
642 call lol_op_stl("ORR")
644 pat lol xor stl inreg($1)==reg_any && inreg($3)==reg_any && $2==4
645 call lol_op_stl("EOR")
647 /* Procedure : load register, load constant, op xx, store register */
648 proc lol_loc_op_stl example lol loc adi stl
650 gen rxx* {LOCAL, $4}, {LOCAL, $1}, {const4, $2}
652 pat lol loc adi stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
653 call lol_loc_op_stl("ADD")
655 pat lol loc adu stl leaving lol $1 loc $2 adi $3 stl $4
657 pat lol loc sbi stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
658 call lol_loc_op_stl("SUB")
660 pat lol loc sbu stl leaving lol $1 loc $2 sbi $3 stl $4
662 pat lol loc and stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
663 call lol_loc_op_stl("AND")
665 pat lol loc ior stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
666 call lol_loc_op_stl("ORR")
668 pat lol loc xor stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
669 call lol_loc_op_stl("EOR")
671 pat lol dup inreg($1)==reg_any && $2==4 leaving lol $1 lol $1
673 /* Procedure : load register, load register, op xx, store register */
674 proc lol_lol_op_stl example lol lol adi stl
676 gen rrx* {LOCAL, $4}, {LOCAL, $1}, {LOCAL, $2}
678 pat lol lol adi stl inreg($1)==reg_any && inreg($2)==reg_any &&
679 inreg($4)==reg_any && $3==4
680 call lol_lol_op_stl("ADD")
682 pat lol lol adu stl leaving lol $1 lol $2 adi $3 stl $4
684 pat lol lol sbi stl inreg($1)==reg_any && inreg($2)==reg_any &&
685 inreg($4)==reg_any && $3==4
686 call lol_lol_op_stl("SUB")
688 pat lol lol sbu stl leaving lol $1 lol $2 sbi $3 stl $4
690 pat lol lol and stl inreg($1)==reg_any && inreg($2)==reg_any &&
691 inreg($4)==reg_any && $3==4
692 call lol_lol_op_stl("AND")
694 pat lol lol ior stl inreg($1)==reg_any && inreg($2)==reg_any &&
695 inreg($4)==reg_any && $3==4
696 call lol_lol_op_stl("ORR")
698 pat lol lol xor stl inreg($1)==reg_any && inreg($2)==reg_any &&
699 inreg($4)==reg_any && $3==4
700 call lol_lol_op_stl("EOR")
703 pat lol loc sli stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
705 gen MOV {LOCAL, $4}, {reglslcon, regvar($1), $2}
707 pat lol loc slu stl leaving lol $1 loc $2 sli $3 stl $4
709 pat lol loc sri stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
711 gen MOV {LOCAL, $4}, {regasrcon, regvar($1), $2}
713 pat lol loc sru stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
715 gen MOV {LOCAL, $4}, {reglsrcon, regvar($1), $2}
717 pat lol lol sli stl inreg($1)==reg_any && inreg($2)==reg_any &&
718 inreg($4)==reg_any && $3==4
720 gen MOV {LOCAL, $4}, {reglslreg, regvar($1), regvar($2)}
722 pat lol lol slu stl leaving lol $1 lol $2 sli $3 stl $4
724 pat lol lol sri stl inreg($1)==reg_any && inreg($2)==reg_any &&
725 inreg($4)==reg_any && $3==4
727 gen MOV {LOCAL, $4}, {regasrreg, regvar($1), regvar($2)}
729 pat lol lol sru stl inreg($1)==reg_any && inreg($2)==reg_any &&
730 inreg($4)==reg_any && $3==4
732 gen MOV {LOCAL, $4}, {reglsrreg, regvar($1), regvar($2)}
735 pat lol loc ror stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
737 gen MOV {LOCAL, $4}, {regrorcon, regvar($1), $2}
739 pat lol lol ror stl inreg($1)==reg_any && inreg($2)==reg_any &&
740 inreg($4)==reg_any && $3==4
742 gen MOV {LOCAL, $4}, {regrorreg, regvar($1), regvar($2)}
744 pat lol loc rol stl inreg($1)==reg_any && inreg($4)==reg_any && $3==4
746 gen MOV {LOCAL, $4}, {regrorcon, regvar($1), 32-$2}
748 pat lol lol ror stl inreg($1)==reg_any && inreg($2)==reg_any &&
749 inreg($4)==reg_any && $3==4
751 gen RSB R11, {LOCAL, $2}, {fitcon, 32}
752 MOV {LOCAL, $4}, {regrorregr, regvar($1), R11}
754 /* code for *p++ and *p-- (integers) */
755 pat lol lol adp stl loi $1==$2 && $2==$4 && $5==4 && inreg($1)==reg_any
758 gen LDR %a, {regrelpi, regvar($1), $5} yields %a
760 pat lol lol adp stl sti $1==$2 && $2==$4 && $5==4 && inreg($1)==reg_any
763 gen STR %1, {regrelpi, regvar($1), $5}
765 /* code for *p++ and *p-- (bytes)*/
766 pat lol lol adp stl loi $1==$2 && $2==$4 && $5==1 && inreg($1)==reg_any
769 gen LDR_B %a, {regrelpi, regvar($1), $5} yields %a
771 pat lol lol adp stl sti $1==$2 && $2==$4 && $5==1 && inreg($1)==reg_any
774 gen STR_B %1, {regrelpi, regvar($1), $5}
776 /* code for *pp->p++ and *pp->p-- (integers) */
777 pat lil dup adp sil loi $1==$4 && $2==4 && $5==4 && inreg($1)==reg_any
780 gen LDR %a, {regind, regvar($1)}
781 ADD %b, %a, {fitcon, $3}
782 STR %b, {regind, regvar($1)}
783 LDR %b, {regind, %a} yields %b
785 pat lil dup adp sil sti $1==$4 && $2==4 && $5==4 && inreg($1)==reg_any
789 gen LDR %a, {regind, regvar($1)}
790 ADD %b, %a, {fitcon, $3}
791 STR %b, {regind, regvar($1)}
794 /* code for *pp->p++ and *pp->p-- (bytes) */
795 pat lil dup adp sil loi $1==$4 && $2==4 && $5==1 && inreg($1)==reg_any
798 gen LDR %a, {regind, regvar($1)}
799 ADD %b, %a, {fitcon, $3}
800 STR %b, {regind, regvar($1)}
801 LDR_B %b, {regind, %a} yields %b
803 pat lil dup adp sil sti $1==$4 && $2==4 && $5==1 && inreg($1)==reg_any
807 gen LDR %a, {regind, regvar($1)}
808 ADD %b, %a, {fitcon, $3}
809 STR %b, {regind, regvar($1)}
810 STR_B %1, {regind, %a}
812 /************************************************************************
814 * GROUP I : Load Instructions *
816 ************************************************************************/
818 pat loc $1 < 0 yields {const4, $1}
820 pat loc legal($1) yields {fitcon, $1}
822 pat loc yields {const4, $1}
824 pat ldc leaving loc 18 trp
826 pat lol yields {lb_local, $1}
828 pat loe yields {absolute, $1}
830 pat lil leaving lol $1 loi 4
833 with GENREG yields {regrel, %1, $1}
834 with exact addr_local yields {lb_local, %1.ind+$1}
835 with exact addr_external yields {absolute, %1.add+$1}
836 with exact regconst yields {regrel, %1.reg, $1+%1.ind}
838 pat lal $1 > 0 yields {addr_local, $1}
839 pat lal $1 < 0 yields {naddr_local, 0-$1}
840 pat lal $1 == 0 yields LB
842 pat lae yields {addr_external, $1}
843 pat lae loi lae sti $2==$4 leaving lae $1 lae $3 blm $2
845 pat lxl $1==0 yields LB
847 pat lxl $1==1 yields {lb_local,8}
850 uses GENREG={const4, $1}, GENREG=LB
851 gen LABEL {label, "1:"}
852 move {regrel, %b, 8}, %b
853 SUB_S %a, %a, {fitcon,1}
854 BNE {label,"1B"} yields %b
856 pat lxa $1==0 yields {addr_local,8}
859 uses GENREG={lb_local,8} yields {regconst,%a,8}
863 uses GENREG={const4, $1}, GENREG=LB
864 gen LABEL {label, "1:"}
865 move {regrel, %b, 8}, %b
866 SUB_S %a, %a, {fitcon,1}
867 BNE {label,"1B"} yields {regconst, %b, 8}
872 gen LDR_B %a, {regind, %1} yields %a
873 with exact naddr_local
875 gen LDR_B %a, {lb_local, 0-%1.ind} yields %a
876 with exact addr_local
878 gen LDR_B %a, {lb_local, %1.ind} yields %a
879 with exact addr_external
881 gen LDR_B %a, {absolute, %1.add} yields %a
884 gen LDR_B %a, {regrel, %1.reg, %1.ind} yields %a
885 with exact regplusreg
887 gen LDR_B %a, {regregrel, %1.reg1, %1.reg2} yields %a
890 gen LDR_B %a, {regminregrel, %1.reg1, %1.reg2} yields %a
891 with exact regplusiSreg
893 gen LDR_B %a, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2} yields %a
894 with exact regminiSreg
896 gen LDR_B %a, {regminiSregrel,%1.reg1,%1.S,%1.shift,%1.reg2} yields %a
898 with exact regplusrSreg
900 gen move {regS,%1.reg2,%1.S,%1.sreg}, %b
901 LDR_B %a, {regregrel, %1.reg1, %b} yields %a
903 with exact regminrSreg
905 gen LDR_B %a, {regminrSregrel,%1.reg1,%1.S,%1.sreg,%1.reg2} yields %a
910 gen LDR_B %a, {regind, %1}
911 LDR_B %b, {regrel, %1, 1}
912 ADD %a,%a,{imS,%b,"LSL",8} yields %a
915 with GENREG yields {regind, %1}
916 with exact addr_local yields {lb_local, %1.ind}
917 with exact naddr_local yields {lb_local, 0-%1.ind}
918 with exact addr_external yields {absolute, %1.add}
919 with exact regconst yields {regrel, %1.reg, %1.ind}
920 with exact regplusreg yields {regregrel, %1.reg1, %1.reg2}
921 with exact regminreg yields {regminregrel, %1.reg1, %1.reg2}
922 with exact regplusiSreg yields {regiSregrel,%1.reg1,%1.S,
924 with exact regminiSreg yields {regminiSregrel,%1.reg1,%1.S,
926 with exact regplusrSreg
928 gen move {regS,%1.reg2,%1.S,%1.sreg}, %b
929 LDR %a, {regregrel, %1.reg1, %b} yields %a
931 with exact regminrSreg yields {regminrSregrel,%1.reg1,
932 %1.S,%1.sreg,%1.reg2}
937 gen LDMIA %1, {reglist2, %a, %b} yields %b %a
941 uses GENREG = {const4, $1}
942 gen LABEL {label, "1:"}
943 SUB_S %a, %a, {fitcon, 4}
944 move {regregrel, %1, %a}, R11
945 STMFD {autoid, SP}, {reglist1, R11}
948 pat loi loc and $1==2 && $2>0 && $2<256 leaving loi 1 loc $2 and $3
950 pat loi loc loc cii $1==2 && $2==2 && $3==4
953 gen LDR_B %a, {regind, %1}
954 LDR_B %b, {regrel, %1, 1}
955 MOV %b, {imS, %b, "LSL", 24}
956 ORR %a, %a, {imS, %b, "ASR", 16} yields %a
961 gen BAL_L {label, ".los"}
963 pat ldl yields {lb_local, $1+4}
966 pat lde yields {absolute, $1+4}
970 with GENREG yields {regrel, %1, $1+4}
972 with exact addr_local yields {lb_local, %1.ind+$1+4}
973 {lb_local, %1.ind+$1}
974 with exact addr_external yields {absolute, %1.add+$1+4}
975 {absolute, %1.add+$1}
976 with exact regconst yields {regrel, %1.reg, $1+%1.ind+4}
977 {regrel, %1.reg, $1+%1.ind}
979 pat lpi yields {addr_external,$1}
981 /************************************************************************
983 * GROUP II : Store Instructions *
985 ************************************************************************/
989 kills address-(absolute+lb_local), lb_local %ind-4 < $1 && %ind+4 > $1
990 gen move %1, {lb_local, $1}
992 pat stl lol $1==$2 leaving dup 4 stl $1
997 gen move %1, {absolute, $1}
1000 leaving dup 4 ste $1
1002 pat sil leaving lol $1 sti 4
1007 gen move %2, {regrel, %1, $1}
1008 with addr_local GENREG
1010 gen move %2, {lb_local, %1.ind + $1}
1011 with addr_external GENREG
1013 gen move %2, {absolute, %1.add + $1}
1014 with regconst GENREG
1016 gen move %2, {regrel, %1.reg, $1+%1.ind}
1021 gen STR_B %2, {regind, %1}
1022 with addr_local GENREG
1024 gen STR_B %2, {lb_local, %1.ind}
1025 with addr_external GENREG
1027 gen STR_B %2, {absolute, %1.add}
1028 with regconst GENREG
1030 gen STR_B %2, {regrel, %1.reg, %1.ind}
1031 with regplusreg GENREG
1033 gen STR_B %2, {regregrel, %1.reg1, %1.reg2}
1034 with regminreg GENREG
1036 gen STR_B %2, {regminregrel, %1.reg1, %1.reg2}
1037 with regplusiSreg GENREG
1039 gen STR_B %2, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
1040 with regminiSreg GENREG
1042 gen STR_B %2, {regminiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
1044 with regplusrSreg GENREG
1047 gen move {regS, %1.reg2, %1.S, %1.sreg}, %a
1048 STR_B %2, {regregrel, %1.reg1, %a}
1050 with regminrSreg GENREG
1052 gen STR_B %2, {regminrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}
1058 gen move {imS, %2, "LSR", 8}, %a
1059 SUB %2, %2, {imS, %a, "LSL", 8}
1060 STR_B %2, {regind, %1}
1061 STR_B %a, {regrel, %1, 1}
1063 gen STR_B %2, {regind, %1}
1064 MOV %2, {imS, %2, "LSR", 8}
1065 STR_B %2, {regrel, %1, 1}
1066 /*with GENREG fitcon %2.num==0
1068 gen STR_B %2, {regind, %1}
1069 STR_B %2, {regrel, %1, 1}
1074 gen move %2, {regind, %1}
1075 with addr_local GENREG
1077 gen move %2, {lb_local, %1.ind}
1078 with addr_external GENREG
1080 gen move %2, {absolute, %1.add}
1081 with regconst GENREG
1083 gen move %2, {regrel, %1.reg, %1.ind}
1084 with regplusreg GENREG
1086 gen move %2, {regregrel, %1.reg1, %1.reg2}
1087 with regminreg GENREG
1089 gen move %2, {regminregrel, %1.reg1, %1.reg2}
1090 with regplusiSreg GENREG
1092 gen move %2, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
1093 with regminiSreg GENREG
1095 gen move %2, {regminiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
1096 with regplusrSreg GENREG
1099 gen move {regS, %1.reg2, %1.S, %1.sreg}, %a
1100 STR %2, {regregrel, %1.reg1, %a}
1101 with regminrSreg GENREG
1103 gen move %2, {regminrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}
1105 pat sti defined($1) && legal($1)
1108 uses GENREG={fitcon, $1}
1109 gen LABEL {label, "1:"}
1110 SUB_S %a, %a, {fitcon, 4}
1111 move {st_regregrel, SP, %a}, R11
1112 move R11, {regregrel, %1, %a}
1114 ADD SP, SP, {fitcon, $1}
1119 uses GENREG={const4, $1}, GENREG
1122 SUB_S %a, %a, {fitcon, 4}
1123 move {st_regregrel, SP, %a}, R11
1124 move R11, {regregrel, %1, %a}
1131 gen BAL_L {label, ".sts"}
1135 kills address-absolute
1136 gen move %1, {lb_local,$1}
1137 move %2, {lb_local,$1+4}
1142 gen move %1, {absolute, $1}
1143 move %2, {absolute, $1+4}
1146 with GENREG GENREG GENREG
1148 gen move %2, {regrel, %1, $1}
1149 move %3, {regrel, %1, $1+4}
1151 /************************************************************************
1153 * GROUP III : Integer Arithmetic *
1155 ************************************************************************/
1158 with GENREG constant yields {regconst, %1, %2.num}
1159 with constant GENREG yields {regconst, %2, %1.num}
1160 with GENREG GENREG yields {regplusreg, %1, %2}
1161 with GENREG imS yields {regplusiSreg,%1, %2.S,
1163 with imS GENREG yields {regplusiSreg,%2, %1.S,
1165 with GENREG regS yields {regplusrSreg,%1, %2.S,
1167 with regS GENREG yields {regplusrSreg,%2, %1.S,
1169 with exact addr_local constant yields {addr_local, %1.ind+%2.num}
1170 with exact constant addr_local yields {addr_local, %2.ind+%1.num}
1171 with exact addr_external constant yields {addr_external, %1.add+%2.num}
1172 with exact constant addr_external yields {addr_external, %2.add+%1.num}
1175 with GENREG GENREG yields {regminreg, %2, %1}
1176 with imS GENREG yields {regminiSreg,%2,%1.S,
1178 with regS GENREG yields {regminrSreg,%2,%1.S,
1182 gen RSB %a, %1, %2 yields %a
1184 gen SUB %2, %2, %1 yields %2
1188 RSB %1, %1, %a yields %1
1192 SUB %a, %2, %a yields %a
1195 gen RSB %a, %1, %2 yields %a
1196 /*with constant GENREG yields {regconst, %2, 0-%1.num}*/
1197 with exact constant addr_local yields {addr_local, %2.ind-%1.num}
1199 pat loc mli $1<0 && $2==4 leaving loc 0-$1
1203 pat loc mli $1==2 && $2==4
1204 with GENREG yields {imS, %1, "LSL", 1}
1206 pat loc mli $1==4 && $2==4
1207 with GENREG yields {imS, %1, "LSL", 2}
1209 pat loc mli $1==8 && $2==4
1210 with GENREG yields {imS, %1, "LSL", 3}
1212 pat loc mli $1==16 && $2==4
1213 with GENREG yields {imS, %1, "LSL", 4}
1215 pat loc mli $1==32 && $2==4
1216 with GENREG yields {imS, %1, "LSL", 5}
1218 pat loc mli $1==3 && $2==4
1219 with GENREG yields {regplusiSreg,%1,"LSL",1,%1}
1221 pat loc mli $1==5 && $2==4
1222 with GENREG yields {regplusiSreg,%1,"LSL",2,%1}
1224 pat loc mli $1==6 && $2==4
1227 gen MOV %a, {imS,%1,"LSL",2}
1228 ADD %a, %a, {imS,%1,"LSL",1} yields %a
1230 pat loc mli $1==7 && $2==4
1233 gen RSB %a, %1, {imS, %1, "LSL", 3} yields %a
1235 pat loc mli $1==9 && $2==4
1236 with GENREG yields {regplusiSreg,%1,"LSL",3,%1}
1238 pat loc mli $1==10 && $2==4
1241 gen MOV %a,{imS, %1, "LSL", 1}
1242 ADD %a, %a, {imS, %1, "LSL", 3} yields %a
1244 pat loc mli $1==12 && $2==4
1247 gen move {imS, %1, "LSL", 3}, %a yields {regplusiSreg,%a,"LSR",1,%a}
1252 gen BAL_L {label, ".mli"} yields R0
1254 pat loc dvi $1<0 && $2==4 leaving loc 0-$1
1260 gen BAL_L {label, ".dvi"} yields R3
1265 gen BAL_L {label, ".dvi"} yields R2
1270 gen RSB %a, %1, {fitcon, 0} yields %a
1273 with fitcon GENREG yields {imS, %2, "LSL", %1.num}
1274 with GENREG GENREG yields {regS, %2, "LSL", %1}
1276 pat loc sri $1==0 && $2==4
1277 with address+REGcon yields %1
1280 with fitcon GENREG yields {imS, %2, "ASR", %1.num}
1281 with GENREG GENREG yields {regS, %2, "ASR", %1}
1284 /************************************************************************
1286 * GROUP IV : Unsigned Arithmetic *
1288 ************************************************************************/
1290 pat adu leaving adi $1
1292 pat sbu leaving sbi $1
1294 pat loc mlu $1<11 && $1>0 && $2==4 leaving loc $1
1300 gen BAL_L {label, ".mlu"} yields R0
1302 pat loc dvu $1<33 && $1>0 && $2==4 leaving loc $1
1308 gen BAL_L {label, ".dvu"} yields R3
1313 gen BAL_L {label, ".dvu"} yields R2
1316 with GENREG GENREG yields {regS, %2, "LSL", %1}
1317 with const4+fitcon GENREG yields {imS, %2, "LSL", %1.num}
1320 with GENREG GENREG yields {regS, %2, "LSR", %1}
1321 with const4+fitcon GENREG yields {imS, %2, "LSR", %1.num}
1323 /************************************************************************
1325 * GROUP V : Floating Point Arithmetic *
1327 ************************************************************************/
1329 pat adf $1==4 leaving cal ".adf4" asp 4
1330 pat adf $1==8 leaving cal ".adf8" asp 8
1331 pat sbf $1==4 leaving cal ".sbf4" asp 4
1332 pat sbf $1==8 leaving cal ".sbf8" asp 8
1333 pat mlf $1==4 leaving cal ".mlf4" asp 4
1334 pat mlf $1==8 leaving cal ".mlf8" asp 8
1335 pat dvf $1==4 leaving cal ".dvf4" asp 4
1336 pat dvf $1==8 leaving cal ".dvf8" asp 8
1337 pat ngf $1==4 leaving cal ".ngf4"
1338 pat ngf $1==8 leaving cal ".ngf8"
1339 pat fif $1==4 leaving lor 1 cal ".fif4" asp 4
1340 pat fif $1==8 leaving lor 1 cal ".fif8" asp 4
1341 pat fef $1==4 leaving lor 1 adp 0-4 cal ".fef4"
1342 pat fef $1==8 leaving lor 1 adp 0-4 cal ".fef8"
1344 /************************************************************************
1346 * GROUP VI : Pointer Arithmetic *
1348 ************************************************************************/
1351 with GENREG yields {regconst, %1, $1}
1352 with exact addr_local yields {addr_local, %1.ind+$1}
1353 with exact addr_external yields {addr_external, %1.add+$1}
1354 with exact regconst yields {regconst, %1.reg, %1.ind+$1}
1356 pat ads $1==4 leaving adi 4
1358 pat sbs $1==4 leaving sbi 4
1360 /************************************************************************
1362 * GROUP VII : Increment/Decrement/Zero *
1364 ************************************************************************/
1367 with GENREG yields {regconst, %1, 1}
1368 with exact regconst yields {regconst, %1.reg, %1.ind+1}
1371 kills address-absolute
1372 uses GENREG={lb_local,$1}
1373 gen ADD %a,%a,{fitcon,1}
1374 move %a,{lb_local,$1}
1378 uses GENREG={absolute,$1}
1379 gen ADD %a,%a,{fitcon,1}
1380 move %a,{absolute,$1}
1383 with GENREG yields {regconst, %1, 0-1}
1384 /*gen SUB %a, %1, {fitcon, 1}*/
1385 with exact regconst yields {regconst, %1.reg, %1.ind-1}
1388 kills address-absolute
1389 uses GENREG={lb_local,$1}
1390 gen SUB %a,%a,{fitcon,1}
1391 move %a,{lb_local,$1}
1395 uses GENREG={absolute,$1}
1396 gen SUB %a,%a,{fitcon,1}
1397 move %a,{absolute,$1}
1400 kills address-absolute
1401 uses GENREG={fitcon,0}
1402 gen move %a,{lb_local,$1}
1406 uses GENREG={fitcon,0}
1407 gen move %a,{absolute,$1}
1409 pat zrf leaving zer $1
1411 pat zer $1==4 yields {fitcon,0}
1413 pat zer $1==8 yields {fitcon,0} {fitcon,0}
1415 pat zer $1==12 yields {fitcon,0} {fitcon,0} {fitcon,0}
1420 uses GENREG={fitcon,0},GENREG={const4,$1}
1421 gen LABEL {label, "1:"}
1422 STMFD {autoid, SP}, {reglist1, %a}
1423 SUB_S %b,%b,{fitcon,4}
1426 /************************************************************************
1428 * GROUP VIII : Convert *
1430 ************************************************************************/
1432 /* sign extension short -> integer */
1433 pat loc loc cii $1==2 && $2==4
1436 gen MOV %a, {imS, %1, "LSL", 16}
1437 MOV %a, {imS, %a, "ASR", 16} yields %a
1439 /* sign extension byte -> integer */
1440 pat loc loc cii $1==1 && $2==4
1443 gen MOV %a, {imS, %1, "LSL", 24}
1444 MOV %a, {imS, %a, "ASR", 24} yields %a
1446 pat loc loc cii ($1 > 2)
1449 with address +REGcon address + REGcon
1451 pat loc loc cif $1==4 && $2==4 leaving loc 4 cal ".cif4" asp 4
1452 pat loc loc cif $1==4 && $2==8 leaving loc 4 cal ".cif8"
1454 pat loc loc cuf $1==4 && $2==4 leaving loc 4 cal ".cuf4" asp 4
1455 pat loc loc cuf $1==4 && $2==8 leaving loc 4 cal ".cuf8"
1457 pat loc loc cfi leaving loc $1 loc $2 cal ".cfi" asp 8+($1-4)
1459 pat loc loc cfu leaving loc $1 loc $2 cal ".cfu" asp 8+($1-4)
1461 pat loc loc cff $1==8 && $2==4 leaving cal ".cff4" asp 4
1463 /* this one expects a 4 byte hole on the stack */
1464 pat loc loc cff $1==4 && $2==8 leaving dup 4 cal ".cff8"
1467 with address +REGcon address + REGcon
1470 with address +REGcon address + REGcon
1472 /************************************************************************
1474 * GROUP IX : Logical *
1476 ************************************************************************/
1481 gen AND %a, %2, %1 yields %a
1484 gen AND %a, %1, %2 yields %a
1489 gen ORR %a, %2, %1 yields %a
1492 gen ORR %a, %1, %2 yields %a
1497 gen EOR %a, %2, %1 yields %a
1500 gen EOR %a, %1, %2 yields %a
1505 gen MVN %a,%1 yields %a
1508 with constant GENREG yields {imS, %2, "ROR", %1.num}
1509 with GENREG GENREG yields {regS, %2, "ROR", %1}
1512 with constant GENREG yields {imS, %2, "ROR", 32-%1.num}
1515 gen RSB %a, %1, {fitcon,32} yields {regS, %2, "ROR", %a}
1520 uses GENREG,GENREG,GENREG,GENREG
1521 gen move {const4,$1}, %b
1525 SUB_S %b, %b, {fitcon, 4}
1526 move {st_regregrel, SP,%b}, %c
1527 move {regregrel, %a, %b}, %d
1529 move %c, {st_regregrel, SP, %b}
1535 uses GENREG,GENREG,GENREG,GENREG
1536 gen move {const4,$1}, %b
1540 SUB_S %b, %b, {fitcon, 4}
1541 move {st_regregrel, SP,%b}, %c
1542 move {regregrel, %a, %b}, %d
1544 move %c, {st_regregrel, SP, %b}
1547 pat ior !defined($1)
1550 uses GENREG,GENREG,GENREG,GENREG
1551 gen LDMFD {autoid, SP}, {reglist1, %b}
1555 SUB_S %b, %b, {fitcon, 4}
1556 move {st_regregrel, SP, %b}, %c
1557 move {regregrel, %a, %b}, %d
1559 move %c, {st_regregrel, SP, %b}
1566 uses GENREG,GENREG,GENREG,GENREG
1567 gen move {const4,$1}, %b
1571 SUB_S %b, %b, {fitcon, 4}
1572 move {st_regregrel, SP,%b}, %c
1573 move {regregrel, %a, %b}, %d
1575 move %c, {st_regregrel, SP, %b}
1581 uses GENREG,GENREG,GENREG
1582 gen move {const4,$1}, %b
1584 SUB_S %b, %b, {fitcon, 4}
1585 move {st_regregrel, SP, %b}, %c
1587 move %c, {st_regregrel, SP, %b}
1590 /************************************************************************
1594 ************************************************************************/
1596 pat loc loc inn !defined($3) leaving loc $1 inn $2
1598 pat loc inn $2==4 && $1>=0 && $1<32
1600 uses GENREG={fitcon,1},GENREG
1601 gen AND %b, %1, {imS,%a,"LSL",$1} yields %b
1603 pat loc inn $2==4 && $1<0
1605 gen move {fitcon,0}, %1 yields %1
1607 pat loc inn $2==4 && $1>31 leaving loc 2 trp
1609 pat loc inn !defined($2) leaving inn $1
1613 uses GENREG={fitcon,1}, GENREG, GENREG
1614 gen AND %b, %1, {fitcon, 31}
1615 move {regS, %a, "LSL", %b}, %b
1616 move {imS, %1, "LSR", 5}, %1
1617 move {st_regiSregrel, SP, "LSL", 2, %1}, %c
1619 MOV_NE %b, {fitcon, 1}
1620 ADD SP, SP, {const4, $1} yields %b
1622 pat inn !defined($1)
1623 with GENREG GENREG STACK
1624 uses GENREG={fitcon,1}, GENREG, GENREG
1625 gen AND %b, %2, {fitcon, 31}
1626 move {regS, %a, "LSL", %b}, %b
1627 move {imS, %2, "LSR", 5}, %2
1628 move {st_regiSregrel, SP, "LSL", 2, %2}, %c
1630 MOV_NE %b, {fitcon, 1}
1631 ADD SP, SP, %1 yields %b
1633 pat loc set !defined($2) leaving set $1
1637 uses GENREG={fitcon,1} yields {imS,%a,"LSL",%1.num}
1639 uses GENREG={fitcon,1} yields {regS,%a,"LSL",%1}
1643 uses GENREG={fitcon,1}, GENREG={fitcon,0}, GENREG={const4,$1}
1644 gen LABEL {label, "2:"}
1645 STMFD {autoid, SP}, {reglist1, %b}
1646 SUB_S %c, %c, {fitcon,4}
1650 AND %b, %1, {fitcon, 31}
1651 move {regS, %a, "LSL", %b}, %b
1652 move {imS, %1, "LSR", 5}, %1
1653 move %b, {st_regiSregrel, SP, "LSL", 2, %1}
1656 pat set !defined($1)
1659 uses GENREG={fitcon,1}, GENREG={fitcon,0}, GENREG, GENREG
1660 gen LDMFD {autoid, SP}, {reglist1, %c}
1661 LDMFD {autoid, SP}, {reglist1, %d}
1663 STMFD {autoid, SP}, {reglist1, %b}
1664 SUB_S %c, %c, {fitcon,4}
1668 AND %b, %d, {fitcon, 31}
1669 move {regS, %a, "LSL", %b}, %b
1670 move {imS, %d, "LSR", 5}, %d
1671 move %b, {st_regiSregrel, SP, "LSL", 2, %d}
1674 /************************************************************************
1676 * GROUP XI : Array Instructions *
1678 ************************************************************************/
1680 pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)==0 leaving adi 4
1682 pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)>0 && legal(rom($1,1))
1685 gen SUB %a,%1,{fitcon,rom($1,1)} yields %a
1687 with exact regconst yields {regconst, %1.reg,
1691 pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)!=0
1693 uses GENREG={const4, 0-rom($1,1)}
1694 gen ADD %a,%1,%a yields %a
1696 with exact regconst yields {regconst, %1.reg,
1700 pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)==0
1701 with GENREG yields {imS, %1,"LSL", 2}
1704 pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)>0 && legal(rom($1,1))
1707 gen SUB %a,%1,{fitcon, rom($1,1)} yields {imS, %a,"LSL", 2}
1710 pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)!=0
1712 uses GENREG={const4, 0-rom($1,1)}
1713 gen ADD %a,%1,%a yields {imS, %a,"LSL", 2}
1716 pat lae aar $2==4 && rom($1,1)==0
1717 leaving loc rom($1,3)
1720 pat lae aar $2==4 && rom($1,1)>0 && legal(rom($1,1))
1723 gen SUB %a,%1,{fitcon,rom($1,1)} yields %a
1724 leaving loc rom($1,3)
1727 pat lae aar $2==4 && rom($1,1)!=0
1729 uses GENREG={const4, 0-rom($1,1)}
1730 gen ADD %a,%1,%a yields %a
1731 leaving loc rom($1,3)
1737 gen move {regind, %1}, %a
1738 SUB %2, %2, %a yields %2 {regrel, %1, 8}
1741 pat lae sar $2==4 && defined(rom($1,3)) leaving lae $1 aar 4
1744 pat lae lar $2==4 && defined(rom($1,3)) leaving lae $1 aar 4
1747 pat loc aar !defined($2) leaving aar $1
1749 pat lae loc sar !defined($3) && $2==4 && defined(rom($1,3))
1750 leaving lae $1 aar 4
1753 pat lae loc lar !defined($3) && $2==4 && defined(rom($1,3))
1754 leaving lae $1 aar 4
1757 /* next two: dynamic arrays in modula2 - not tested */
1759 pat lal sar $2==4 leaving lal $1 aar 4 lal $1 adp 8 loi 4 sts
1761 pat lal lar $2==4 leaving lal $1 aar 4 lal $1 adp 8 loi 4 los
1763 /************************************************************************
1765 * GROUP XII : Compare Instructions *
1767 ************************************************************************/
1771 uses reusing %1, GENREG=%1
1772 gen RSB_S %a, %1, %2 yields %a
1774 uses reusing %2, GENREG=%2
1775 gen SUB_S %a, %2, %1 yields %a
1781 MOV_HI %a, {fitcon, 0-1}
1782 MOV_LS %a, {fitcon, 1}
1783 MOV_EQ %a, {fitcon, 0} yields %a
1787 MOV_HI %a, {fitcon, 1}
1788 MOV_LS %a, {fitcon, 0-1}
1789 MOV_EQ %a, {fitcon, 0} yields %a
1791 pat cmp leaving cmu 4
1793 pat cmf $1==4 leaving cal ".cmf4" asp 8 lfr 4
1794 pat cmf $1==8 leaving cal ".cmf8" asp 16 lfr 4
1796 pat loc cms !defined($2) leaving cms $1
1800 gen EOR_S %1, %1, %2 yields %1
1802 gen EOR_S %2, %2, %1 yields %2
1807 uses GENREG = {const4, $1}, GENREG, GENREG, GENREG, GENREG
1811 SUB_S %a, %a, {fitcon, 4}
1813 move {st_regregrel, SP, %a}, %c
1814 move {regregrel, %b, %a}, %d
1818 ADD SP, %b, %e yields %c
1820 pat cms !defined($1)
1822 uses GENREG, GENREG, GENREG, GENREG
1826 SUB_S %1, %1, {fitcon, 4}
1828 move {st_regregrel, SP, %1}, %b
1829 move {regregrel, %a, %1}, %c
1833 ADD SP, %a, %d yields %b
1837 uses reusing %1, GENREG=%1
1839 MOV_LT %a, {fitcon,1}
1840 MOV_GE %a, {fitcon,0} yields %a
1844 uses reusing %1, GENREG=%1
1846 MOV_LE %a, {fitcon,1}
1847 MOV_GT %a, {fitcon,0} yields %a
1851 uses reusing %1, GENREG=%1
1853 MOV_EQ %a, {fitcon,1}
1854 MOV_NE %a, {fitcon,0} yields %a
1858 uses reusing %1, GENREG=%1
1860 MOV_NE %a, {fitcon,1}
1861 MOV_EQ %a, {fitcon,0} yields %a
1865 uses reusing %1, GENREG=%1
1867 MOV_GE %a, {fitcon,1}
1868 MOV_LT %a, {fitcon,0} yields %a
1872 uses reusing %1, GENREG=%1
1874 MOV_GT %a, {fitcon,1}
1875 MOV_LE %a, {fitcon,0} yields %a
1877 /************************************************************************
1879 * GROUP XIII : Branch Instructions *
1881 ************************************************************************/
1889 with REGcon GENREG STACK
1892 with GENREG REGcon STACK
1897 with REGcon GENREG STACK
1900 with GENREG REGcon STACK
1905 with REGcon GENREG STACK
1910 with REGcon GENREG STACK
1915 with REGcon GENREG STACK
1920 with REGcon GENREG STACK
1954 /************************************************************************
1956 * GROUP XIV : Procedure Call *
1958 ************************************************************************/
1963 gen BAL_L {label, $1}
1968 gen /* the trick is to set up R14 properly */
1969 ADR LR, {label, "1F"}
1973 pat lfr $1==4 yields R0
1975 pat lfr $1==8 yields R1 R0
1977 pat lfr $1==12 yields R2 R1 R0
1984 LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
1992 LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
1998 LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
2001 with REGcon REGcon STACK
2007 LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
2010 with REGcon REGcon REGcon STACK
2017 LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
2020 /************************************************************************
2022 * GROUP XV : Miscellaneous *
2024 ************************************************************************/
2029 gen ADD SP, SP, {fitcon, $1}
2034 uses GENREG={const4, $1}
2042 with address+REGcon address+REGcon
2048 gen LDR_B %a, {regind, %2}
2049 STR_B %a, {regind, %1}
2055 gen move {regind, %2}, %a
2056 move %a, {regind, %1}
2061 uses GENREG, GENREG={const4, $1-4}
2062 gen LABEL {label, "1:"}
2063 move {regregrel, %2, %b}, %a
2064 move %a, {regregrel, %1, %b}
2065 SUB_S %b, %b, {fitcon, 4}
2069 with GENREG GENREG GENREG
2072 gen LABEL {label, "1:"}
2073 SUB_S %1, %1, {fitcon, 4}
2074 move {regregrel, %3, %1}, %a
2075 move %a, {regregrel, %2, %1}
2081 gen BAL_L {label, "_Csa"}
2087 gen BAL_L {label, "_Csb"}
2090 pat dch leaving loi 4
2093 with address+REGcon yields %1 %1
2096 with address+REGcon address+REGcon yields %2 %1 %2 %1
2101 uses GENREG={const4,$1}, GENREG
2102 gen LABEL {label, "1:"}
2103 move {st_regrel, SP, $1-4}, %b
2104 STMFD {autoid, SP}, {reglist1, %b}
2105 SUB_S %a, %a, {fitcon, 4}
2111 gen SUB %b, %1, {fitcon, 4}
2113 move {st_regregrel, SP, %b}, %a
2114 STMFD {autoid, SP}, {reglist1, %a}
2115 SUB_S %1, %1, {fitcon, 4}
2119 with address+REGcon address+REGcon yields %1 %2
2122 with address+REGcon address+REGcon
2123 address+REGcon address+REGcon yields %2 %1 %4 %3
2128 uses GENREG, GENREG, GENREG={const4, $1-4}, GENREG, GENREG={const4, $1}
2131 move {st_regregrel, SP,%c}, %a
2132 move {regregrel,%d,%c}, %b
2133 move %a, {regregrel,%d,%c}
2134 move %b, {st_regregrel, SP,%c}
2135 SUB_S %c, %c, {fitcon, 4}
2140 gen move {addr_external,$1}, %a
2141 move %a, {addr_external, "_Filna"}
2143 pat gto /* this code does NOT restore registers */
2144 uses GENREG,GENREG,GENREG,GENREG
2145 gen move {addr_external, $1}, %d
2146 move {regind, %d}, %a
2147 move {regrel, %d, 4}, %b
2148 move {regrel, %d, 8}, %c
2155 uses GENREG={const4,$1}
2156 gen move %a,{addr_external,"_Lineno"}
2161 gen move {addr_external,"_Lineno"}, %a
2162 LDR %a, {regind, %a}
2163 ADD %a,%a,{fitcon,1}
2164 move %a,{addr_external,"_Lineno"}
2166 pat lor $1==0 yields LB
2172 pat lor $1==2 yields {absolute, "_RegHp"}
2174 pat lpb leaving adp 8
2181 with GENREG REGcon STACK
2183 gen move {regind, %1}, %a
2184 /* for some reason, the code generator expects the value
2185 * to be checked on top of the stack after checking, while
2186 * in fact it is held in %2. This causes mayhem later on, and
2187 * the following two lines rectify this.
2190 STMFD {autoid, SP}, {reglist1, %b}
2192 BGT {label, "_RckTrap"}
2193 move {regrel, %1, 4}, %a
2195 BLT {label, "_RckTrap"}
2201 gen move {addr_external, "_IgnoreMask"}, %a
2202 STMFD {autoid, SP}, {reglist1, %a}
2207 gen BAL_L {label, "_EmMon"}
2216 gen move {addr_external, "_TrpReg"}, %a
2217 LDR %a, {regind, %a}
2218 LDMFD {autoid, SP}, {reglist1, %b}
2219 move %b, {addr_external, "_TrpReg"}
2220 STMFD {autoid, SP}, {reglist1, %a}
2226 gen LDMFD {autoid, SP}, {reglist1, %a}
2227 move %a, {addr_external, "_IgnoreMask"}
2232 gen BAL_L {label, "_EmTrp"}
2248 gen move %1, {absolute, "_RegHp"}
2250 /***********************************************************************/
2252 /* code for *p++ and *p-- (integers)*/
2253 pat lol dup adp stl loi $1==$4 && $2==4 && $5==4
2256 gen move {lb_local, $1}, %a
2257 LDR %b, {regrelpi, %a, $5}
2258 STR %a, {lb_local, $1} yields %b
2260 pat lol dup adp stl sti $1==$4 && $2==4 && $5==4
2264 gen move {lb_local,$1}, %a
2265 STR %1, {regrelpi, %a, $5}
2266 STR %a, {lb_local, $1}
2268 /* code for *p++ and *p-- (bytes)*/
2269 pat lol dup adp stl loi $1==$4 && $2==4 && $5==1
2272 gen move {lb_local, $1}, %a
2273 LDR_B %b, {regrelpi, %a, $5}
2274 STR %a, {lb_local, $1} yields %b
2276 pat lol dup adp stl sti $1==$4 && $2==4 && $5==1
2280 gen move {lb_local,$1}, %a
2281 STR_B %1, {regrelpi, %a, $5}
2282 STR %a, {lb_local, $1}
2284 /* code for *pp->p++ and *pp->p-- (integers)*/
2285 pat lil dup adp sil loi $1==$4 && $2==4 && $5==4
2287 uses GENREG, GENREG, GENREG
2288 gen move {lb_local, $1}, %a
2289 LDR %b, {regind, %a}
2290 ADD %c, %b, {fitcon, $5}
2291 STR %c, {regind, %a}
2292 LDR %c, {regind, %b} yields %c
2294 pat lil dup adp sil sti $1==$4 && $2==4 && $5==4
2297 uses GENREG, GENREG, GENREG
2298 gen move {lb_local, $1}, %a
2299 LDR %b, {regind, %a}
2300 ADD %c, %b, {fitcon, $5}
2301 STR %c, {regind, %a}
2302 STR %1, {regind, %b}
2304 /* code for *pp->p++ and *pp->p-- (bytes)*/
2305 pat lil dup adp sil loi $1==$4 && $2==4 && $5==1
2307 uses GENREG, GENREG, GENREG
2308 gen move {lb_local, $1}, %a
2309 LDR %b, {regind, %a}
2310 ADD %c, %b, {fitcon, $5}
2311 STR %c, {regind, %a}
2312 LDR_B %c, {regind, %b} yields %c
2314 pat lil dup adp sil sti $1==$4 && $2==4 && $5==1
2317 uses GENREG, GENREG, GENREG
2318 gen move {lb_local, $1}, %a
2319 LDR %b, {regind, %a}
2320 ADD %c, %b, {fitcon, $5}
2321 STR %c, {regind, %a}
2322 STR_B %1, {regind, %b}
2325 /* global array access of the form x[y-1] */
2327 pat lol loc mli loc sbi $2==$4 && $3==4 && $5==4
2328 leaving lol $1 dec 4 loc $2 mli 4
2330 /* x[i] = y with large array elements */
2332 pat lae loi lae lol loc mli ads sti $2==$8 && $2 > 4
2333 leaving lae $1 lae $3 lol $4 loc $5 mli $6 ads $7 blm $8
2334 pat lae loi lae lol loc mlu ads sti $2==$8 && $2 > 4
2335 leaving lae $1 lae $3 lol $4 loc $5 mlu $6 ads $7 blm $8
2337 /* prevent double push/pull of $1 */
2339 pat lae lol loc mli ads
2340 leaving lol $2 loc $3 mli $4 lae $1 ads $5
2341 pat lae lol loc mlu ads
2342 leaving lol $2 loc $3 mlu $4 lae $1 ads $5
2344 pat lae lol loc mli ads lol loc mli ads $5==$9 && $4==$8
2345 leaving lol $2 loc $3 mli $4 lol $6 loc $7 mli $8 ads $5 lae $1 ads $9
2346 pat lae lol loc mlu ads lol loc mlu ads $5==$9 && $4==$8
2347 leaving lol $2 loc $3 mlu $4 lol $6 loc $7 mlu $8 ads $5 lae $1 ads $9
2349 pat lae lol adp loi loc mli ads
2350 leaving lol $2 adp $3 loi $4 loc $5 mli $6 lae $1 ads $7
2351 pat lae lol adp loi loc mlu ads
2352 leaving lol $2 adp $3 loi $4 loc $5 mlu $6 lae $1 ads $7
2355 pat lae loi lae lol adp loi loc mli ads sti $2==$10 && $2 > 4
2356 leaving lae $1 lae $3 lol $4 adp $5 loi $6 loc $7 mli $8 ads $9 blm $2
2357 pat lae loi lae lol adp loi loc mlu ads sti $2==$10 && $2 > 4
2358 leaving lae $1 lae $3 lol $4 adp $5 loi $6 loc $7 mlu $8 ads $9 blm $2