Pristine Ack-5.5
[Ack-5.5.git] / mach / arm / ncg / table
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  ****************************************************************************/
8
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)
21
22 #define illegal(a)    !legal(a)
23 #define minlegal(a)    (a < 0) && neglegal(a)
24 #define minillegal(a)  (a < 0) && !neglegal(a)
25
26 EM_WSIZE=4
27 EM_PSIZE=4
28 EM_BSIZE=8
29
30 PROPERTIES
31
32 GENREG                  /* All 16 user registers */
33 REG                     /* Allocatable registers */
34 PCPSR                   /* PSW and PC */
35 SREG
36 STACKPOINTER
37 LOCALBASE
38 LINKREGISTER
39
40 REGISTERS
41
42 R0,R1,R2,R3,R8,R9,R10                   :GENREG, REG .
43 R4,R5,R6,R7                             :GENREG regvar(reg_any).
44 R11                                     :GENREG, SREG  .
45 SP("R12")                               :STACKPOINTER .
46 LB("R13")                               :LOCALBASE .
47 LR("R14")                               :LINKREGISTER .
48 PC("R15")                               :PCPSR .
49
50 TOKENS
51
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  .
63
64 imS             = { GENREG reg; ADDR S; INT shift;} 4 
65                         reg "," S "#" shift  .
66 regS            = { GENREG reg; ADDR S; GENREG sreg;} 4 
67                         reg "," S " "sreg  .
68 regind          = { GENREG reg; } 4 
69                         "[" reg "]" .
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 
95                         "[" reg "],#" ind .
96 regconst        = { GENREG reg; INT  ind; } 4 
97                         reg ",#" ind  .
98
99 regplusreg      = {GENREG reg1; GENREG reg2;} 4
100                         reg1 "," reg2 .
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
106                         reg1 "," reg2 .
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 .
111
112 REGlist1        = {REG reg1; } 4 
113                         "{" reg1 "}" .
114 reglist1        = {GENREG reg1; } 4 
115                         "{" reg1 "}" .
116 lb_reglist1     = {LOCALBASE reg1; } 4 
117                         "{" reg1 "}" .
118 sp_reglist1     = {STACKPOINTER reg1; } 4 
119                         "{" reg1 "}" .
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 "}" .
128
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 .
137
138 LOCAL           = { INT ind;} 4 ">>> BUG IN LOCAL".
139 stack           = { GENREG r;} 4 "R12<,{" r "}".
140
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.
151
152
153 SETS
154
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 +
164                   regexp + REGlist1 .
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.
178
179 INSTRUCTIONS
180
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) .
192
193 LDR              REG+LOCALBASE+GENREG+address:wo, address:rw    cost(4,4) .
194 LDR              LOCAL+GENREG:rw,
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) .
200
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) .
205
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,
213                                         rhs:ro                  cost(4,1).
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,
245                                         rhs:ro                  cost(4,1).
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) .
250 SUB              LOCAL+GENREG:rw,
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) .
261
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).                       */
265
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).
271
272
273 MOVES
274
275 from GENREG+STACKPOINTER+LOCALBASE+PCPSR to
276      GENREG+STACKPOINTER+LOCALBASE+PCPSR
277         gen MOV %2, %1
278
279 from fitcon+GENREG+REG to LOCAL inreg(%ind)==reg_any
280         gen MOV %2, %1
281
282 from LOCAL inreg(%ind)==reg_any to REG+GENREG
283         gen MOV %2, %1
284
285 /* illegal immediate operands */
286
287 from const4 minlegal(%num+1) to GENREG+LOCAL
288 gen MVN %2, {fitcon, 0-%1.num-1}
289
290 from const4 (minlegal(%num)) to GENREG+LOCAL
291 gen MOV %2, {fitcon, 0-%1.num}
292     RSB %2, %2, {fitcon, 0}
293
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}
299
300 from regconst (%ind > 0) && legal(%ind) to LOCAL inreg(%ind)==reg_any
301         gen ADD %2, %1
302
303 from regconst minlegal(%ind) to LOCAL inreg(%ind)==reg_any
304         gen SUB %2, %1.reg, {fitcon, 0-%1.ind}
305
306 from lb_local legal(%ind) to GENREG
307 gen LDR %2, {lb_regrel, LB, %1.ind}
308
309 from lb_local to GENREG
310 gen move {const4, %1.ind}, R11
311     LDR %2, {lb_regregrel, LB, R11}
312
313 from GENREG to lb_local legal(%ind)
314 gen STR %1, {lb_regrel, LB, %2.ind}
315
316 from GENREG to lb_local
317 gen move {const4, %2.ind}, R11
318     STR %1, {lb_regregrel, LB, R11}
319
320 from GENREG to address
321         gen STR %1, %2
322
323 from address to GENREG+LOCALBASE
324         gen LDR %2, %1
325
326 from GENREG to autoid
327         gen STMFD %2, {reglist1, %1}
328
329 from autoid to GENREG
330         gen LDMFD %1, {reglist1, %2}
331
332 from REGcon to GENREG+LOCALBASE
333         gen MOV %2, %1
334
335
336 from addr_external to GENREG
337           gen ADR %2, %1
338
339 /* strictly speaking, the following move is impossible.
340  * what it really means is: move from reg to address!
341  */
342 from GENREG to addr_external
343           gen ADR R11,%2
344               STR %1,{regind,R11}
345
346
347
348 TESTS
349
350 to test GENREG
351 gen CMP %1, {fitcon, 0}
352
353
354 STACKINGRULES
355
356 from LOCAL to STACK
357         gen STMFD {stack, regvar(%1.ind)}
358
359 from REG to STACK
360         gen STMFD {autoid, SP}, {REGlist1, %1}
361
362 from GENREG to STACK
363         gen STMFD {autoid, SP}, {reglist1, %1}
364
365 from LOCALBASE to STACK
366         gen STMFD {autoid, SP}, {lb_reglist1, %1}
367
368 from STACKPOINTER to STACK
369         gen STMFD {autoid, SP}, {sp_reglist1, %1}
370
371 from REGcon to STACK
372         gen move %1, R11
373             STMFD {autoid, SP}, {reglist1, R11}
374
375 from const4 to STACK
376         gen move %1, R11
377             STMFD {autoid, SP}, {reglist1, R11}
378
379 from addr_local legal(%ind) to STACK
380         gen ADD R11, LB, {fitcon, %1.ind}
381             STMFD {autoid, SP}, {reglist1, R11}
382
383 from addr_local to STACK
384         gen move {const4, %1.ind}, R11
385             ADD R11, LB, R11
386             STMFD {autoid, SP}, {reglist1, R11}
387
388 from naddr_local legal(%ind) to STACK
389         gen SUB R11, LB, {fitcon, %1.ind}
390             STMFD {autoid, SP}, {reglist1, R11}
391
392 from naddr_local to STACK
393         gen move {const4, %1.ind}, R11
394             SUB R11, LB, R11
395             STMFD {autoid, SP}, {reglist1, R11}
396
397 from addr_external to STACK
398         gen ADR R11, %1
399             STMFD {autoid, SP}, {reglist1, R11}
400
401 from regconst (%ind > 0) && legal(%ind) to STACK
402         gen ADD R11, %1.reg, {fitcon,%1.ind}
403             STMFD {autoid, SP}, {reglist1, R11}
404
405 from regconst to STACK
406         gen move {const4, %1.ind}, R11
407             ADD R11, R11, %1.reg
408             STMFD {autoid, SP}, {reglist1, R11}
409
410 from regplusreg to STACK
411         gen ADD R11, %1.reg1, %1.reg2
412             STMFD {autoid, SP}, {reglist1, R11}
413
414 from regminreg to STACK
415         gen SUB R11, %1.reg1, %1.reg2
416             STMFD {autoid, SP}, {reglist1, R11}
417
418 from regplusiSreg to STACK
419         gen ADD R11, %1.reg1, {imS, %1.reg2, %1.S, %1.shift}
420             STMFD {autoid, SP}, {reglist1, R11}
421
422 from regminiSreg to STACK
423         gen SUB R11, %1.reg1, {imS, %1.reg2, %1.S, %1.shift}
424             STMFD {autoid, SP}, {reglist1, R11}
425
426 from regplusrSreg to STACK
427         gen ADD R11, %1.reg1, {regS, %1.reg2, %1.S, %1.sreg}
428             STMFD {autoid, SP}, {reglist1, R11}
429
430 from regminrSreg to STACK
431         gen SUB R11, %1.reg1, {regS, %1.reg2, %1.S, %1.sreg}
432             STMFD {autoid, SP}, {reglist1, R11}
433
434 from address to STACK
435         gen move %1, R11
436             STMFD {autoid, SP}, {reglist1, R11}
437
438 COERCIONS
439
440 from LOCAL
441 uses GENREG
442 gen MOV %a, %1                                  yields %a
443
444 from lb_local legal(%ind)
445 uses GENREG
446 gen LDR %a, {lb_regrel, LB, %ind}               yields %a
447
448 from lb_local
449 uses GENREG
450 gen move {const4, %ind}, R11 
451     LDR %a, {lb_regregrel, LB, R11}             yields %a
452
453 from const4 %num < 0
454 uses GENREG
455         gen move {const4, 0-%num}, %a
456             RSB %a, %a, {fitcon, 0}             yields %a
457
458 from const4 illegal(%num)
459 uses GENREG
460         gen move %1, %a                         yields %a
461
462 from const4                                     yields {fitcon, %num}
463
464 from STACK
465 uses GENREG
466         gen LDMFD {autoid, SP}, {reglist1, %a}  yields %a
467
468 from address
469 uses GENREG
470         gen move %1, %a                         yields %a
471
472 from REGcon
473 uses GENREG
474         gen move %1, %a                         yields %a
475
476 from addr_external
477 uses GENREG
478         gen move %1, %a
479                                                 yields %a
480
481 from addr_local legal(%ind)
482 uses GENREG
483         gen ADD %a, LB, {fitcon, %ind}          yields %a
484
485 from addr_local
486 uses GENREG
487         gen move {const4, %ind}, %a
488             ADD %a, LB, %a                      yields %a
489
490 from naddr_local legal(%ind)
491 uses GENREG
492         gen SUB %a, LB, {fitcon, %ind}          yields %a
493
494 from naddr_local
495 uses GENREG
496         gen move {const4, %ind}, %a
497             SUB %a, LB, %a                      yields %a
498
499 from regconst (%ind > 0) && legal(%ind)
500 uses GENREG
501         gen ADD %a, %1                          yields %a
502
503 from regconst minlegal(%ind)
504 uses GENREG
505         gen SUB %a, %reg, {fitcon, 0-%ind}      yields %a
506
507 from regconst minillegal(%ind)
508 uses GENREG
509         gen move {const4, 0-%ind}, %a
510             SUB %a, %a, %reg                    yields %a
511
512 from regconst
513 uses GENREG
514         gen move {const4, %ind}, %a
515             ADD %a, %a, %reg                    yields %a
516
517 from regplusreg
518 uses GENREG
519         gen ADD %a, %reg1, %reg2
520                                                 yields %a
521
522 from regminreg
523 uses GENREG
524         gen SUB %a, %reg1, %reg2
525                                                 yields %a
526
527 from regplusiSreg
528 uses GENREG
529         gen ADD %a, %reg1, {imS, %reg2, %S, %shift}
530                                                 yields %a
531
532 from regminiSreg
533 uses GENREG
534         gen SUB %a, %reg1, {imS, %reg2, %S, %shift}
535                                                 yields %a
536
537 from regplusrSreg
538 uses GENREG
539         gen ADD %a, %reg1, {regS, %reg2, %S, %sreg}
540                                                 yields %a
541
542 from regminrSreg
543 uses GENREG
544         gen SUB %a, %reg1, {regS, %reg2, %S, %sreg}
545                                                 yields %a
546
547
548 PATTERNS
549
550 /************************************************************************
551  *                                                                      *
552  * GROUP 0 :    Register variables                                      *
553  *                                                                      *
554  ************************************************************************/
555
556 /* Simple load and store */
557 pat lol                 inreg($1)==reg_any
558     yields {LOCAL, $1}
559
560 pat lil                 inreg($1)==reg_any
561     yields {regind, regvar($1)}
562
563 pat stl                 inreg($1)==reg_any
564 with exact const4
565 kills local %ind==$1
566 gen move %1, {LOCAL, $1}
567 with exact fitcon
568 kills local %ind==$1
569 gen MOV {LOCAL, $1}, %1
570 with rhs-constant
571 kills local %ind==$1
572         gen MOV {LOCAL, $1}, %1
573 with mem4+absolute
574 kills local %ind==$1
575         gen LDR {LOCAL, $1}, %1
576 with regminreg
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
582 with negshifts
583 kills local %ind == $1
584         gen SUB {LOCAL, $1}, %1
585
586 pat stl $1==1 && inreg($1)==reg_any
587 with rhs
588     kills local %ind==$1
589     gen LDR_B {LOCAL, $1}, %1
590
591 pat sil                 inreg($1)==reg_any
592 with GENREG
593     kills /*all_except_con*/ address
594     gen move %1, {regind, regvar($1)}
595
596
597 /* Increment, decrement, zero                                           */
598 pat inl                 inreg($1)==reg_any
599     kills local %ind==$1
600     gen ADD {LOCAL, $1}, {LOCAL, $1}, {fitcon, 1}
601
602 pat del                 inreg($1)==reg_any
603     kills local %ind==$1
604     gen SUB {LOCAL, $1}, {LOCAL, $1}, {fitcon, 1}
605
606 pat zrl                 inreg($1)==reg_any
607     kills local %ind==$1
608     gen MOV {LOCAL, $1}, {fitcon, 0}
609
610 pat lol inc stl         inreg($1)==reg_any && inreg($3)==reg_any
611     kills local %ind==$3
612     gen ADD {LOCAL, $3}, {LOCAL, $1}, {fitcon, 1}
613
614 pat lol dec stl         inreg($1)==reg_any && inreg($3)==reg_any
615     kills local %ind==$3
616     gen SUB {LOCAL, $3}, {LOCAL, $1}, {fitcon, 1}
617
618 pat lol ngi stl         inreg($1)==reg_any && inreg($3)==reg_any
619     kills local %ind==$3
620     gen RSB {LOCAL, $3}, {LOCAL, $1}, {fitcon, 0}
621
622 /* Procedure :  load register, op xx, store register */
623 proc lol_op_stl example lol adi stl
624 with rhs
625     kills local %ind==$3
626     gen rxx* {LOCAL, $3}, {LOCAL, $1}, %1
627
628 pat lol adi stl         inreg($1)==reg_any && inreg($3)==reg_any && $2==4
629     call lol_op_stl("ADD")
630
631 pat lol adu stl         leaving lol $1 adi $2 stl $3
632
633 pat lol sbi stl         inreg($1)==reg_any && inreg($3)==reg_any && $2==4
634     call lol_op_stl("RSB")
635
636 pat lol sbu stl         leaving lol $1 sbi $2 stl $3
637
638 pat lol and stl         inreg($1)==reg_any && inreg($3)==reg_any && $2==4
639     call lol_op_stl("AND")
640
641 pat lol ior stl         inreg($1)==reg_any && inreg($3)==reg_any && $2==4
642     call lol_op_stl("ORR")
643
644 pat lol xor stl         inreg($1)==reg_any && inreg($3)==reg_any && $2==4
645     call lol_op_stl("EOR")
646
647 /* Procedure : load register, load constant, op xx, store register */
648 proc lol_loc_op_stl example lol loc adi stl
649     kills local %ind==$4
650     gen rxx* {LOCAL, $4}, {LOCAL, $1}, {const4, $2}
651
652 pat lol loc adi stl     inreg($1)==reg_any && inreg($4)==reg_any && $3==4
653     call lol_loc_op_stl("ADD")
654
655 pat lol loc adu stl     leaving lol $1 loc $2 adi $3 stl $4
656
657 pat lol loc sbi stl     inreg($1)==reg_any && inreg($4)==reg_any && $3==4
658     call lol_loc_op_stl("SUB")
659
660 pat lol loc sbu stl     leaving lol $1 loc $2 sbi $3 stl $4
661
662 pat lol loc and stl     inreg($1)==reg_any && inreg($4)==reg_any && $3==4
663     call lol_loc_op_stl("AND")
664
665 pat lol loc ior stl     inreg($1)==reg_any && inreg($4)==reg_any && $3==4
666     call lol_loc_op_stl("ORR")
667
668 pat lol loc xor stl     inreg($1)==reg_any && inreg($4)==reg_any && $3==4
669     call lol_loc_op_stl("EOR")
670
671 pat lol dup inreg($1)==reg_any && $2==4 leaving lol $1 lol $1
672
673 /* Procedure : load register, load register, op xx, store register      */
674 proc lol_lol_op_stl example lol lol adi stl
675     kills local %ind==$4
676     gen rrx* {LOCAL, $4}, {LOCAL, $1}, {LOCAL, $2}
677
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")
681
682 pat lol lol adu stl     leaving lol $1 lol $2 adi $3 stl $4
683
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")
687
688 pat lol lol sbu stl     leaving lol $1 lol $2 sbi $3 stl $4
689
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")
693
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")
697
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")
701
702 /* Shifts                                                               */
703 pat lol loc sli stl     inreg($1)==reg_any && inreg($4)==reg_any && $3==4
704     kills local %ind==$4
705     gen MOV {LOCAL, $4}, {reglslcon, regvar($1), $2}
706
707 pat lol loc slu stl     leaving lol $1 loc $2 sli $3 stl $4
708
709 pat lol loc sri stl     inreg($1)==reg_any && inreg($4)==reg_any && $3==4
710     kills local %ind==$4
711     gen MOV {LOCAL, $4}, {regasrcon, regvar($1), $2}
712
713 pat lol loc sru stl     inreg($1)==reg_any && inreg($4)==reg_any && $3==4
714     kills local %ind==$4
715     gen MOV {LOCAL, $4}, {reglsrcon, regvar($1), $2}
716
717 pat lol lol sli stl     inreg($1)==reg_any && inreg($2)==reg_any &&
718                         inreg($4)==reg_any && $3==4
719     kills local %ind==$4
720     gen MOV {LOCAL, $4}, {reglslreg, regvar($1), regvar($2)}
721
722 pat lol lol slu stl     leaving lol $1 lol $2 sli $3 stl $4
723
724 pat lol lol sri stl     inreg($1)==reg_any && inreg($2)==reg_any &&
725                         inreg($4)==reg_any && $3==4
726     kills local %ind==$4
727     gen MOV {LOCAL, $4}, {regasrreg, regvar($1), regvar($2)}
728
729 pat lol lol sru stl     inreg($1)==reg_any && inreg($2)==reg_any &&
730                         inreg($4)==reg_any && $3==4
731     kills local %ind==$4
732     gen MOV {LOCAL, $4}, {reglsrreg, regvar($1), regvar($2)}
733
734 /* Rotates                                                              */
735 pat lol loc ror stl     inreg($1)==reg_any && inreg($4)==reg_any && $3==4
736     kills local %ind==$4
737     gen MOV {LOCAL, $4}, {regrorcon, regvar($1), $2}
738
739 pat lol lol ror stl     inreg($1)==reg_any && inreg($2)==reg_any && 
740                         inreg($4)==reg_any && $3==4
741     kills local %ind==$4
742     gen MOV {LOCAL, $4}, {regrorreg, regvar($1), regvar($2)}
743
744 pat lol loc rol stl     inreg($1)==reg_any && inreg($4)==reg_any && $3==4
745     kills local %ind==$4
746     gen MOV {LOCAL, $4}, {regrorcon, regvar($1), 32-$2}
747
748 pat lol lol ror stl     inreg($1)==reg_any && inreg($2)==reg_any &&
749                         inreg($4)==reg_any && $3==4
750     kills local %ind==$4
751     gen RSB R11, {LOCAL, $2}, {fitcon, 32}
752         MOV {LOCAL, $4}, {regrorregr, regvar($1), R11}
753
754 /* code for *p++ and *p-- (integers) */
755 pat lol lol adp stl loi $1==$2 && $2==$4 && $5==4 && inreg($1)==reg_any
756 kills GENREG
757 uses GENREG
758 gen LDR %a, {regrelpi, regvar($1), $5}                  yields %a
759
760 pat lol lol adp stl sti $1==$2 && $2==$4 && $5==4 && inreg($1)==reg_any
761 with GENREG
762 kills GENREG
763 gen STR %1, {regrelpi, regvar($1), $5}
764
765 /* code for *p++ and *p-- (bytes)*/
766 pat lol lol adp stl loi $1==$2 && $2==$4 && $5==1 && inreg($1)==reg_any
767 kills GENREG
768 uses GENREG
769 gen LDR_B %a, {regrelpi, regvar($1), $5}                yields %a
770
771 pat lol lol adp stl sti $1==$2 && $2==$4 && $5==1 && inreg($1)==reg_any
772 with GENREG
773 kills GENREG
774 gen STR_B %1, {regrelpi, regvar($1), $5}
775
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
778 kills GENREG
779 uses GENREG,GENREG
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
784
785 pat lil dup adp sil sti $1==$4 && $2==4 && $5==4 && inreg($1)==reg_any
786 with GENREG
787 kills GENREG
788 uses GENREG,GENREG
789 gen LDR %a, {regind, regvar($1)}
790     ADD %b, %a, {fitcon, $3}
791     STR %b, {regind, regvar($1)}
792     STR %1, {regind, %a}
793
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
796 kills GENREG
797 uses GENREG,GENREG
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
802
803 pat lil dup adp sil sti $1==$4 && $2==4 && $5==1 && inreg($1)==reg_any
804 with GENREG
805 kills GENREG
806 uses GENREG,GENREG
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}
811
812 /************************************************************************
813  *                                                                      *
814  * GROUP I :    Load Instructions                                       *
815  *                                                                      *
816  ************************************************************************/
817
818 pat loc $1 < 0                                          yields {const4, $1}
819
820 pat loc legal($1)                                       yields {fitcon, $1}
821
822 pat loc                                                 yields {const4, $1}
823
824 pat ldc leaving loc 18 trp
825
826 pat lol                                                 yields {lb_local, $1}
827
828 pat loe                                                 yields {absolute, $1}
829
830 pat lil leaving lol $1 loi 4
831
832 pat lof
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}
837
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
841
842 pat lae                         yields {addr_external, $1}
843 pat lae loi lae sti $2==$4      leaving lae $1 lae $3 blm $2
844
845 pat lxl $1==0                   yields LB
846
847 pat lxl $1==1                   yields {lb_local,8}
848
849 pat lxl $1>1
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
855
856 pat lxa $1==0                   yields {addr_local,8}
857
858 pat lxa $1==1
859 uses GENREG={lb_local,8}                yields {regconst,%a,8}
860
861
862 pat lxa $1>1
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}
868
869 pat loi $1==1
870 with GENREG
871 uses GENREG
872 gen LDR_B %a, {regind, %1}                                      yields %a
873 with exact naddr_local
874 uses GENREG
875 gen LDR_B %a, {lb_local, 0-%1.ind}                              yields %a
876 with exact addr_local
877 uses GENREG
878 gen LDR_B %a, {lb_local, %1.ind}                                yields %a
879 with exact addr_external
880 uses GENREG
881 gen LDR_B %a, {absolute, %1.add}                                yields %a
882 with exact regconst
883 uses GENREG
884 gen LDR_B %a, {regrel, %1.reg, %1.ind}                          yields %a
885 with exact regplusreg
886 uses GENREG
887 gen LDR_B %a, {regregrel, %1.reg1, %1.reg2}                     yields %a
888 with exact regminreg
889 uses GENREG
890 gen LDR_B %a, {regminregrel, %1.reg1, %1.reg2}                  yields %a
891 with exact regplusiSreg
892 uses GENREG
893 gen LDR_B %a, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}   yields %a
894 with exact regminiSreg
895 uses GENREG
896 gen LDR_B %a, {regminiSregrel,%1.reg1,%1.S,%1.shift,%1.reg2}    yields %a
897
898 with exact regplusrSreg
899 uses GENREG,GENREG
900 gen move {regS,%1.reg2,%1.S,%1.sreg}, %b
901     LDR_B %a, {regregrel, %1.reg1, %b}                          yields %a
902
903 with exact regminrSreg
904 uses GENREG
905 gen LDR_B %a, {regminrSregrel,%1.reg1,%1.S,%1.sreg,%1.reg2}     yields %a
906
907 pat loi $1==2
908 with GENREG
909 uses GENREG, GENREG
910 gen LDR_B %a, {regind, %1}
911     LDR_B %b, {regrel, %1, 1}
912     ADD %a,%a,{imS,%b,"LSL",8}  yields %a
913
914 pat loi $1==4
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,
923                                                     %1.shift,%1.reg2}
924 with exact regminiSreg          yields {regminiSregrel,%1.reg1,%1.S,
925                                                        %1.shift,%1.reg2}
926 with exact regplusrSreg
927 uses GENREG,GENREG
928 gen move {regS,%1.reg2,%1.S,%1.sreg}, %b
929     LDR %a, {regregrel, %1.reg1, %b}            yields %a
930
931 with exact regminrSreg                          yields {regminrSregrel,%1.reg1,
932                                                           %1.S,%1.sreg,%1.reg2}
933
934 pat loi $1==8
935 with GENREG
936 uses GENREG, GENREG
937 gen LDMIA %1, {reglist2, %a, %b}                yields %b %a
938
939 pat loi defined($1)
940 with GENREG STACK
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}
946     BGT {label, "1b"}
947
948 pat loi loc and $1==2 && $2>0 && $2<256  leaving loi 1 loc $2 and $3
949
950 pat loi loc loc cii $1==2 && $2==2 && $3==4
951 with GENREG
952 uses GENREG,GENREG
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
957
958 pat los
959 with STACK
960 kills ALL
961 gen BAL_L {label, ".los"}
962
963 pat ldl                         yields {lb_local, $1+4}
964                                         {lb_local, $1}
965
966 pat lde                         yields {absolute, $1+4}
967                                        {absolute, $1}
968
969 pat ldf
970 with GENREG                     yields {regrel, %1, $1+4}
971                                        {regrel, %1, $1}
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}
978
979 pat lpi                                 yields {addr_external,$1}
980
981 /************************************************************************
982  *                                                                      *
983  * GROUP II :   Store Instructions                                      *
984  *                                                                      *
985  ************************************************************************/
986
987 pat stl
988 with GENREG
989 kills address-(absolute+lb_local), lb_local %ind-4 < $1 && %ind+4 > $1
990         gen move %1, {lb_local, $1}
991
992 pat stl lol $1==$2              leaving dup 4 stl $1
993
994 pat ste
995 with GENREG
996 kills address
997         gen move %1, {absolute, $1}
998
999 pat ste loe $1==$2
1000         leaving dup 4 ste $1
1001
1002 pat sil leaving lol $1 sti 4
1003
1004 pat stf
1005 with GENREG GENREG
1006 kills address
1007         gen move %2, {regrel, %1, $1}
1008 with addr_local GENREG
1009 kills address
1010         gen move %2, {lb_local, %1.ind + $1}
1011 with addr_external GENREG
1012 kills address
1013         gen move %2, {absolute, %1.add + $1}
1014 with regconst GENREG
1015 kills address
1016         gen move %2, {regrel, %1.reg, $1+%1.ind}
1017
1018 pat sti $1==1
1019 with GENREG GENREG
1020 kills address
1021         gen STR_B %2, {regind, %1}
1022 with  addr_local GENREG
1023 kills address
1024         gen STR_B %2, {lb_local, %1.ind}
1025 with  addr_external GENREG
1026 kills address
1027         gen STR_B %2, {absolute, %1.add}
1028 with  regconst GENREG
1029 kills address
1030         gen STR_B %2, {regrel, %1.reg, %1.ind}
1031 with  regplusreg GENREG
1032 kills address
1033         gen STR_B %2, {regregrel, %1.reg1, %1.reg2}
1034 with  regminreg GENREG
1035 kills address
1036         gen STR_B %2, {regminregrel, %1.reg1, %1.reg2}
1037 with  regplusiSreg GENREG
1038 kills address
1039         gen STR_B %2, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
1040 with  regminiSreg GENREG
1041 kills address
1042         gen STR_B %2, {regminiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
1043
1044 with  regplusrSreg GENREG
1045 kills address
1046 uses GENREG
1047 gen move {regS, %1.reg2, %1.S, %1.sreg}, %a
1048     STR_B %2, {regregrel, %1.reg1, %a}
1049
1050 with  regminrSreg GENREG
1051 kills address
1052         gen STR_B %2, {regminrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}
1053
1054 pat sti $1==2
1055 with GENREG GENREG
1056 kills address
1057 /*uses GENREG
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}
1062 */
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
1067 kills address
1068 gen STR_B %2, {regind, %1}
1069     STR_B %2, {regrel, %1, 1}
1070 */
1071 pat sti $1==4
1072 with GENREG GENREG
1073 kills address
1074         gen move %2, {regind, %1}
1075 with addr_local GENREG
1076 kills address
1077         gen move %2, {lb_local, %1.ind}
1078 with addr_external GENREG
1079 kills address
1080         gen move %2, {absolute, %1.add}
1081 with regconst GENREG
1082 kills address
1083         gen move %2, {regrel, %1.reg, %1.ind}
1084 with  regplusreg GENREG
1085 kills address
1086         gen move %2, {regregrel, %1.reg1, %1.reg2}
1087 with  regminreg GENREG
1088 kills address
1089         gen move %2, {regminregrel, %1.reg1, %1.reg2}
1090 with  regplusiSreg GENREG
1091 kills address
1092         gen move %2, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
1093 with  regminiSreg GENREG
1094 kills address
1095         gen move %2, {regminiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
1096 with  regplusrSreg GENREG
1097 kills address
1098 uses GENREG
1099 gen move {regS, %1.reg2, %1.S, %1.sreg}, %a
1100     STR %2, {regregrel, %1.reg1, %a}
1101 with  regminrSreg GENREG
1102 kills address
1103         gen move %2, {regminrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}
1104
1105 pat sti defined($1) && legal($1)
1106 with GENREG STACK
1107 kills address
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}
1113         BGT {label,"1B"}
1114         ADD SP, SP, {fitcon, $1}
1115
1116 pat sti defined($1)
1117 with GENREG STACK
1118 kills address
1119 uses GENREG={const4, $1}, GENREG
1120 gen     move %a, %b
1121         LABEL {label, "1:"}
1122         SUB_S %a, %a, {fitcon, 4}
1123         move {st_regregrel, SP, %a}, R11
1124         move R11, {regregrel, %1, %a}
1125         BGT {label,"1B"}
1126         ADD SP, SP, %b
1127
1128 pat sts
1129 with STACK
1130 kills ALL
1131 gen BAL_L {label, ".sts"}
1132
1133 pat sdl
1134 with GENREG GENREG
1135 kills address-absolute
1136 gen     move %1, {lb_local,$1}
1137         move %2, {lb_local,$1+4}
1138
1139 pat sde
1140 with GENREG GENREG
1141 kills address
1142 gen     move %1, {absolute, $1}
1143         move %2, {absolute, $1+4}
1144
1145 pat sdf
1146 with GENREG GENREG GENREG
1147 kills address
1148 gen     move %2, {regrel, %1, $1}
1149         move %3, {regrel, %1, $1+4}
1150
1151 /************************************************************************
1152  *                                                                      *
1153  * GROUP III :  Integer Arithmetic                                      *
1154  *                                                                      *
1155  ************************************************************************/
1156
1157 pat adi $1==4
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,
1162                                                         %2.shift, %2.reg}
1163 with imS GENREG                         yields {regplusiSreg,%2, %1.S,
1164                                                         %1.shift, %1.reg}
1165 with GENREG regS                        yields {regplusrSreg,%1, %2.S,
1166                                                         %2.sreg, %2.reg}
1167 with regS GENREG                        yields {regplusrSreg,%2, %1.S,
1168                                                         %1.sreg, %1.reg}
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}
1173
1174 pat sbi $1==4
1175 with GENREG GENREG                      yields {regminreg, %2, %1}
1176 with imS GENREG                         yields {regminiSreg,%2,%1.S,
1177                                                         %1.shift,%1.reg}
1178 with regS GENREG                        yields {regminrSreg,%2,%1.S,
1179                                                         %1.sreg,%1.reg}
1180 with GENREG fitcon
1181 uses GENREG
1182 gen RSB  %a, %1, %2                     yields %a
1183 with fitcon GENREG
1184 gen SUB %2, %2, %1                      yields %2
1185 with GENREG const4
1186 uses GENREG
1187 gen move %2, %a
1188     RSB  %1, %1, %a                     yields %1
1189 with const4 GENREG
1190 uses GENREG
1191 gen move %1, %a
1192     SUB  %a, %2, %a                     yields %a
1193 with GENREG REGcon
1194 uses GENREG
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}
1198
1199 pat loc mli $1<0 && $2==4               leaving loc 0-$1
1200                                                 mli 4
1201                                                 ngi 4
1202
1203 pat loc mli $1==2 && $2==4
1204 with GENREG                             yields {imS, %1, "LSL", 1}
1205
1206 pat loc mli $1==4 && $2==4
1207 with GENREG                             yields {imS, %1, "LSL", 2}
1208
1209 pat loc mli $1==8 && $2==4
1210 with GENREG                             yields {imS, %1, "LSL", 3}
1211
1212 pat loc mli $1==16 && $2==4
1213 with GENREG                             yields {imS, %1, "LSL", 4}
1214
1215 pat loc mli $1==32 && $2==4
1216 with GENREG                             yields {imS, %1, "LSL", 5}
1217
1218 pat loc mli $1==3 && $2==4
1219 with GENREG                             yields {regplusiSreg,%1,"LSL",1,%1}
1220
1221 pat loc mli $1==5 && $2==4
1222 with GENREG                             yields {regplusiSreg,%1,"LSL",2,%1}
1223
1224 pat loc mli $1==6 && $2==4
1225 with GENREG
1226 uses GENREG
1227 gen MOV %a, {imS,%1,"LSL",2}
1228     ADD %a, %a, {imS,%1,"LSL",1}        yields %a
1229
1230 pat loc mli $1==7 && $2==4
1231 with GENREG
1232 uses GENREG
1233 gen RSB %a, %1, {imS, %1, "LSL", 3}     yields %a
1234
1235 pat loc mli $1==9 && $2==4
1236 with GENREG                             yields {regplusiSreg,%1,"LSL",3,%1}
1237
1238 pat loc mli $1==10 && $2==4
1239 with GENREG
1240 uses GENREG
1241 gen MOV %a,{imS, %1, "LSL", 1}
1242     ADD %a, %a, {imS, %1, "LSL", 3}     yields %a
1243
1244 pat loc mli $1==12 && $2==4
1245 with GENREG
1246 uses GENREG
1247 gen move {imS, %1, "LSL", 3}, %a        yields {regplusiSreg,%a,"LSR",1,%a}
1248
1249 pat mli $1==4
1250 with STACK
1251 kills ALL
1252 gen     BAL_L {label, ".mli"}           yields R0
1253
1254 pat loc dvi $1<0 && $2==4               leaving loc 0-$1
1255                                                 dvi 4
1256
1257 pat dvi $1==4
1258 with STACK
1259 kills ALL
1260 gen     BAL_L {label, ".dvi"}           yields R3
1261
1262 pat rmi $1==4
1263 with STACK
1264 kills ALL
1265 gen     BAL_L {label, ".dvi"}           yields R2
1266
1267 pat ngi $1==4
1268 with GENREG
1269 uses GENREG
1270 gen     RSB %a, %1, {fitcon, 0}         yields %a
1271
1272 pat sli $1==4
1273 with fitcon GENREG                      yields {imS, %2, "LSL", %1.num}
1274 with GENREG GENREG                      yields {regS, %2, "LSL", %1}
1275
1276 pat loc sri $1==0 && $2==4
1277 with address+REGcon                     yields %1
1278
1279 pat sri $1==4
1280 with fitcon GENREG                      yields {imS, %2, "ASR", %1.num}
1281 with GENREG GENREG                      yields {regS, %2, "ASR", %1}
1282
1283
1284 /************************************************************************
1285  *                                                                      *
1286  * GROUP IV :   Unsigned Arithmetic                                     *
1287  *                                                                      *
1288  ************************************************************************/
1289
1290 pat adu                                 leaving adi $1
1291
1292 pat sbu                                 leaving sbi $1
1293
1294 pat loc mlu $1<11 && $1>0 && $2==4      leaving loc $1
1295                                                 mli 4
1296
1297 pat mlu $1==4
1298 with STACK
1299 kills ALL
1300 gen     BAL_L {label, ".mlu"}           yields R0
1301
1302 pat loc dvu $1<33 && $1>0 && $2==4      leaving loc $1
1303                                                 dvi 4
1304
1305 pat dvu $1==4
1306 with STACK
1307 kills ALL
1308 gen     BAL_L {label, ".dvu"}           yields R3
1309
1310 pat rmu $1==4
1311 with STACK
1312 kills ALL
1313 gen     BAL_L {label, ".dvu"}           yields R2
1314
1315 pat slu $1==4
1316 with GENREG GENREG                      yields {regS, %2, "LSL", %1}
1317 with const4+fitcon GENREG               yields {imS, %2, "LSL", %1.num}
1318
1319 pat sru $1==4
1320 with GENREG GENREG                      yields {regS, %2, "LSR", %1}
1321 with const4+fitcon GENREG               yields {imS, %2, "LSR", %1.num}
1322
1323 /************************************************************************
1324  *                                                                      *
1325  * GROUP V :    Floating Point Arithmetic                               *
1326  *                                                                      *
1327  ************************************************************************/
1328
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"
1343
1344 /************************************************************************
1345  *                                                                      *
1346  * GROUP VI :   Pointer Arithmetic                                      *
1347  *                                                                      *
1348  ************************************************************************/
1349
1350 pat adp
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}
1355
1356 pat ads $1==4                           leaving adi 4
1357
1358 pat sbs $1==4                           leaving sbi 4
1359
1360 /************************************************************************
1361  *                                                                      *
1362  * GROUP VII :  Increment/Decrement/Zero                                *
1363  *                                                                      *
1364  ************************************************************************/
1365
1366 pat inc
1367 with GENREG                             yields {regconst, %1, 1}
1368 with exact regconst                     yields {regconst, %1.reg, %1.ind+1}
1369
1370 pat inl
1371 kills address-absolute
1372 uses GENREG={lb_local,$1}
1373 gen ADD %a,%a,{fitcon,1}
1374     move %a,{lb_local,$1}
1375
1376 pat ine
1377 kills address
1378 uses GENREG={absolute,$1}
1379 gen ADD %a,%a,{fitcon,1}
1380     move %a,{absolute,$1}
1381
1382 pat dec
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}
1386
1387 pat del
1388 kills address-absolute
1389 uses GENREG={lb_local,$1}
1390 gen SUB %a,%a,{fitcon,1}
1391     move %a,{lb_local,$1}
1392
1393 pat dee
1394 kills address
1395 uses GENREG={absolute,$1}
1396 gen SUB %a,%a,{fitcon,1}
1397     move %a,{absolute,$1}
1398
1399 pat zrl
1400 kills address-absolute
1401 uses GENREG={fitcon,0}
1402 gen move %a,{lb_local,$1}
1403
1404 pat zre
1405 kills address
1406 uses GENREG={fitcon,0}
1407 gen move %a,{absolute,$1}
1408
1409 pat zrf leaving zer $1
1410
1411 pat zer $1==4                           yields {fitcon,0}
1412
1413 pat zer $1==8                           yields {fitcon,0} {fitcon,0}
1414
1415 pat zer $1==12                          yields {fitcon,0} {fitcon,0} {fitcon,0}
1416
1417 pat zer defined($1)
1418 with STACK
1419 kills ALL
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}
1424     BNE {label,"1B"}
1425
1426 /************************************************************************
1427  *                                                                      *
1428  * GROUP VIII : Convert                                                 *
1429  *                                                                      *
1430  ************************************************************************/
1431
1432 /* sign extension short -> integer */
1433 pat loc loc cii $1==2 && $2==4
1434 with GENREG
1435 uses GENREG
1436 gen MOV %a, {imS, %1, "LSL", 16}
1437     MOV %a, {imS, %a, "ASR", 16}                yields %a
1438
1439 /* sign extension byte -> integer */
1440 pat loc loc cii $1==1 && $2==4
1441 with GENREG
1442 uses GENREG
1443 gen MOV %a, {imS, %1, "LSL", 24}
1444     MOV %a, {imS, %a, "ASR", 24}                yields %a
1445
1446 pat loc loc cii ($1 > 2)
1447
1448 pat cui
1449 with address +REGcon address + REGcon
1450
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"
1453
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"
1456
1457 pat loc loc cfi leaving loc $1 loc $2 cal ".cfi" asp 8+($1-4)
1458
1459 pat loc loc cfu leaving loc $1 loc $2 cal ".cfu" asp 8+($1-4)
1460
1461 pat loc loc cff $1==8 && $2==4 leaving cal ".cff4" asp 4
1462
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"
1465
1466 pat ciu
1467 with address +REGcon address + REGcon
1468
1469 pat cuu
1470 with address +REGcon address + REGcon
1471
1472 /************************************************************************
1473  *                                                                      *
1474  * GROUP IX :   Logical                                                 *
1475  *                                                                      *
1476  ************************************************************************/
1477
1478 pat and $1==4
1479 with REGcon GENREG
1480 uses GENREG
1481 gen AND %a, %2, %1                      yields %a
1482 with GENREG REGcon
1483 uses GENREG
1484 gen AND %a, %1, %2                      yields %a
1485
1486 pat ior $1==4
1487 with REGcon GENREG
1488 uses GENREG
1489 gen ORR %a, %2, %1                      yields %a
1490 with GENREG REGcon
1491 uses GENREG
1492 gen ORR %a, %1, %2                      yields %a
1493
1494 pat xor $1==4
1495 with REGcon GENREG
1496 uses GENREG
1497 gen EOR %a, %2, %1                      yields %a
1498 with GENREG REGcon
1499 uses GENREG
1500 gen EOR %a, %1, %2                      yields %a
1501
1502 pat com $1==4
1503 with REGcon
1504 uses GENREG
1505 gen MVN %a,%1                           yields %a
1506
1507 pat ror $1==4
1508 with constant GENREG                    yields {imS, %2, "ROR", %1.num}
1509 with GENREG GENREG                      yields {regS, %2, "ROR", %1}
1510
1511 pat rol $1==4
1512 with constant GENREG                    yields {imS, %2, "ROR", 32-%1.num}
1513 with GENREG GENREG
1514 uses GENREG
1515 gen RSB %a, %1, {fitcon,32}             yields {regS, %2, "ROR", %a}
1516
1517 pat and $1>4
1518 with STACK
1519 kills ALL
1520 uses GENREG,GENREG,GENREG,GENREG
1521 gen move {const4,$1}, %b
1522     move SP, %a
1523     ADD SP, SP, %b
1524     LABEL {label, "1:"}
1525     SUB_S %b, %b, {fitcon, 4}
1526     move {st_regregrel, SP,%b}, %c
1527     move {regregrel, %a, %b}, %d
1528     AND %c, %c, %d
1529     move %c, {st_regregrel, SP, %b}
1530     BNE {label, "1B"}
1531
1532 pat ior $1>4
1533 with STACK
1534 kills ALL
1535 uses GENREG,GENREG,GENREG,GENREG
1536 gen move {const4,$1}, %b
1537     move SP, %a
1538     ADD SP, SP, %b
1539     LABEL {label, "1:"}
1540     SUB_S %b, %b, {fitcon, 4}
1541     move {st_regregrel, SP,%b}, %c
1542     move {regregrel, %a, %b}, %d
1543     ORR %c, %c, %d
1544     move %c, {st_regregrel, SP, %b}
1545     BNE {label, "1B"}
1546
1547 pat ior !defined($1)
1548 with STACK
1549 kills ALL
1550 uses GENREG,GENREG,GENREG,GENREG
1551 gen LDMFD {autoid, SP}, {reglist1, %b}
1552     move SP, %a
1553     ADD SP, SP, %b
1554     LABEL {label, "1:"}
1555     SUB_S %b, %b, {fitcon, 4}
1556     move {st_regregrel, SP, %b}, %c
1557     move {regregrel, %a, %b}, %d
1558     ORR %c, %c, %d
1559     move %c, {st_regregrel, SP, %b}
1560     BNE {label, "1B"}
1561
1562
1563 pat xor $1>4
1564 with STACK
1565 kills ALL
1566 uses GENREG,GENREG,GENREG,GENREG
1567 gen move {const4,$1}, %b
1568     move SP, %a
1569     ADD SP, SP, %b
1570     LABEL {label, "1:"}
1571     SUB_S %b, %b, {fitcon, 4}
1572     move {st_regregrel, SP,%b}, %c
1573     move {regregrel, %a, %b}, %d
1574     EOR %c, %c, %d
1575     move %c, {st_regregrel, SP, %b}
1576     BNE {label, "1B"}
1577
1578 pat com $1>4
1579 with STACK
1580 kills ALL
1581 uses GENREG,GENREG,GENREG
1582 gen move {const4,$1}, %b
1583     LABEL {label, "1:"}
1584     SUB_S %b, %b, {fitcon, 4}
1585     move {st_regregrel, SP, %b}, %c
1586     MVN %c, %c
1587     move %c, {st_regregrel, SP, %b}
1588     BNE {label, "1B"}
1589
1590 /************************************************************************
1591  *                                                                      *
1592  * GROUP X:     Sets                                                    *
1593  *                                                                      *
1594  ************************************************************************/
1595
1596 pat loc loc inn !defined($3)            leaving loc $1 inn $2
1597
1598 pat loc inn $2==4 && $1>=0 && $1<32
1599 with GENREG
1600 uses GENREG={fitcon,1},GENREG
1601 gen AND %b, %1, {imS,%a,"LSL",$1}       yields %b
1602
1603 pat loc inn $2==4 && $1<0
1604 with GENREG
1605 gen move {fitcon,0}, %1                 yields %1
1606
1607 pat loc inn $2==4 && $1>31              leaving loc 2 trp
1608
1609 pat loc inn !defined($2)                leaving inn $1
1610
1611 pat inn defined($1)
1612 with GENREG STACK
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
1618     AND_S %b, %b, %c
1619     MOV_NE %b, {fitcon, 1}
1620     ADD SP, SP, {const4, $1}            yields %b
1621
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
1629     AND_S %b, %b, %c
1630     MOV_NE %b, {fitcon, 1}
1631     ADD SP, SP, %1                      yields %b
1632
1633 pat loc set !defined($2)                leaving set $1
1634
1635 pat set $1==4
1636 with const4
1637 uses GENREG={fitcon,1}                  yields {imS,%a,"LSL",%1.num}
1638 with GENREG
1639 uses GENREG={fitcon,1}                  yields {regS,%a,"LSL",%1}
1640
1641 pat set $1>4
1642 with GENREG STACK
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}
1647     BGT {label, "2B"}
1648     CMP %1, {fitcon, 0}
1649     BMI {label, "1F"}
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}
1654     LABEL {label, "1:"}
1655
1656 pat set !defined($1)
1657 with STACK
1658 kills ALL
1659 uses GENREG={fitcon,1}, GENREG={fitcon,0}, GENREG, GENREG
1660 gen LDMFD {autoid, SP}, {reglist1, %c}
1661     LDMFD {autoid, SP}, {reglist1, %d}
1662     LABEL {label, "2:"}
1663     STMFD {autoid, SP}, {reglist1, %b}
1664     SUB_S %c, %c, {fitcon,4}
1665     BGT {label, "2B"}
1666     CMP %d, {fitcon, 0}
1667     BMI {label, "1F"}
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}
1672     LABEL {label, "1:"}
1673
1674 /************************************************************************
1675  *                                                                      *
1676  * GROUP XI :   Array Instructions                                      *
1677  *                                                                      *
1678  ************************************************************************/
1679
1680 pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)==0       leaving adi 4
1681
1682 pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)>0 && legal(rom($1,1))
1683 with GENREG
1684 uses GENREG
1685 gen SUB %a,%1,{fitcon,rom($1,1)}                yields %a
1686                                                 leaving adi 4
1687 with exact regconst                             yields {regconst, %1.reg,
1688                                                         %1.ind-rom($1,1)}
1689                                                 leaving adi 4
1690
1691 pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)!=0
1692 with GENREG
1693 uses GENREG={const4, 0-rom($1,1)}
1694 gen ADD %a,%1,%a                                yields %a
1695                                                 leaving adi 4
1696 with exact regconst                             yields {regconst, %1.reg,
1697                                                         %1.ind-rom($1,1)}
1698                                                 leaving adi 4
1699
1700 pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)==0
1701 with GENREG                                     yields {imS, %1,"LSL",  2}
1702                                                 leaving adi 4
1703
1704 pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)>0 && legal(rom($1,1))
1705 with GENREG
1706 uses GENREG
1707 gen SUB %a,%1,{fitcon, rom($1,1)}               yields {imS, %a,"LSL", 2}
1708                                                 leaving adi 4
1709
1710 pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)!=0
1711 with GENREG
1712 uses GENREG={const4, 0-rom($1,1)}
1713 gen ADD %a,%1,%a                                yields {imS, %a,"LSL", 2}
1714                                                 leaving adi 4
1715
1716 pat lae aar $2==4 && rom($1,1)==0
1717                                                 leaving loc rom($1,3)
1718                                                         mli 4 adi 4
1719
1720 pat lae aar $2==4 && rom($1,1)>0 && legal(rom($1,1))
1721 with GENREG
1722 uses GENREG
1723 gen SUB %a,%1,{fitcon,rom($1,1)}                yields %a
1724                                                 leaving loc rom($1,3)
1725                                                         mli 4 adi 4
1726
1727 pat lae aar $2==4 && rom($1,1)!=0
1728 with GENREG
1729 uses GENREG={const4, 0-rom($1,1)}
1730 gen ADD %a,%1,%a                                yields %a
1731                                                 leaving loc rom($1,3)
1732                                                         mli 4 adi 4
1733
1734 pat aar $1==4
1735 with GENREG GENREG
1736 uses GENREG
1737 gen move {regind, %1}, %a
1738     SUB %2, %2, %a                              yields %2 {regrel, %1, 8}
1739                                                 leaving mli 4 adi 4
1740
1741 pat lae sar $2==4 && defined(rom($1,3))         leaving lae $1 aar 4
1742                                                         sti rom($1,3)
1743
1744 pat lae lar $2==4 && defined(rom($1,3))         leaving lae $1 aar 4
1745                                                         loi rom($1,3)
1746
1747 pat loc aar !defined($2)                        leaving aar $1
1748
1749 pat lae loc sar !defined($3) && $2==4 && defined(rom($1,3))
1750                                                 leaving lae $1 aar 4
1751                                                         sti rom($1,3)
1752
1753 pat lae loc lar !defined($3) && $2==4 && defined(rom($1,3))
1754                                                 leaving lae $1 aar 4
1755                                                         loi rom($1,3)
1756
1757 /* next two: dynamic arrays in modula2 - not tested */
1758
1759 pat lal sar $2==4 leaving lal $1 aar 4 lal $1 adp 8 loi 4 sts
1760
1761 pat lal lar $2==4 leaving lal $1 aar 4 lal $1 adp 8 loi 4 los
1762
1763 /************************************************************************
1764  *                                                                      *
1765  * GROUP XII :  Compare Instructions                                    *
1766  *                                                                      *
1767  ************************************************************************/
1768
1769 pat cmi
1770 with GENREG REGcon
1771 uses reusing %1, GENREG=%1
1772 gen RSB_S %a, %1, %2                            yields %a
1773 with REGcon GENREG
1774 uses reusing %2, GENREG=%2
1775 gen SUB_S %a, %2, %1                            yields %a
1776
1777 pat cmu $1==4
1778 with GENREG REGcon
1779 uses GENREG
1780 gen CMP %1, %2
1781     MOV_HI %a, {fitcon, 0-1}
1782     MOV_LS %a, {fitcon, 1}
1783     MOV_EQ %a, {fitcon, 0}                      yields %a
1784 with REGcon GENREG
1785 uses GENREG
1786 gen CMP %2, %1
1787     MOV_HI %a, {fitcon, 1}
1788     MOV_LS %a, {fitcon, 0-1}
1789     MOV_EQ %a, {fitcon, 0}                      yields %a
1790
1791 pat cmp                                         leaving cmu 4
1792
1793 pat cmf $1==4   leaving cal ".cmf4" asp 8 lfr 4
1794 pat cmf $1==8   leaving cal ".cmf8" asp 16 lfr 4
1795
1796 pat loc cms !defined($2)                        leaving cms $1
1797
1798 pat cms $1==4
1799 with GENREG REGcon
1800 gen EOR_S %1, %1, %2                            yields %1
1801 with REGcon GENREG
1802 gen EOR_S %2, %2, %1                            yields %2
1803
1804 pat cms $1!=4
1805 with STACK
1806 kills ALL
1807 uses GENREG = {const4, $1}, GENREG, GENREG, GENREG, GENREG
1808 gen move %a, %e
1809     ADD %b, %a, SP
1810     LABEL {label, "1:"}
1811     SUB_S %a, %a, {fitcon, 4}
1812     BLT {label, "2F"}
1813     move {st_regregrel, SP, %a}, %c
1814     move {regregrel, %b, %a}, %d
1815     EOR_S %c, %c, %d
1816     BEQ {label, "1B"}
1817     LABEL {label, "2:"}
1818     ADD SP, %b, %e                              yields %c
1819
1820 pat cms !defined($1)
1821 with GENREG STACK
1822 uses GENREG, GENREG, GENREG, GENREG
1823 gen move %1, %d
1824     ADD %a, %1, SP
1825     LABEL {label, "1:"}
1826     SUB_S %1, %1, {fitcon, 4}
1827     BLT {label, "2F"}
1828     move {st_regregrel, SP, %1}, %b
1829     move {regregrel, %a, %1}, %c
1830     EOR_S %b, %b, %c
1831     BEQ {label, "1B"}
1832     LABEL {label, "2:"}
1833     ADD SP, %a, %d                              yields %b
1834
1835 pat tlt
1836 with GENREG
1837 uses reusing %1, GENREG=%1
1838 gen test %1
1839     MOV_LT %a, {fitcon,1}
1840     MOV_GE %a, {fitcon,0}                       yields %a
1841
1842 pat tle
1843 with  GENREG
1844 uses reusing %1, GENREG=%1
1845 gen test %1
1846     MOV_LE %a, {fitcon,1}
1847     MOV_GT %a, {fitcon,0}                       yields %a
1848
1849 pat teq
1850 with GENREG
1851 uses reusing %1, GENREG=%1
1852 gen test %1
1853     MOV_EQ %a, {fitcon,1}
1854     MOV_NE %a, {fitcon,0}                       yields %a
1855
1856 pat tne
1857 with  GENREG
1858 uses reusing %1, GENREG=%1
1859 gen test %1
1860     MOV_NE %a, {fitcon,1}
1861     MOV_EQ %a, {fitcon,0}                       yields %a
1862
1863 pat tge
1864 with  GENREG
1865 uses reusing %1, GENREG=%1
1866 gen test %1
1867     MOV_GE %a, {fitcon,1}
1868     MOV_LT %a, {fitcon,0}                       yields %a
1869
1870 pat tgt
1871 with GENREG
1872 uses reusing %1, GENREG=%1
1873 gen test %1
1874     MOV_GT %a, {fitcon,1}
1875     MOV_LE %a, {fitcon,0}                       yields %a
1876
1877 /************************************************************************
1878  *                                                                      *
1879  * GROUP XIII : Branch Instructions                                     *
1880  *                                                                      *
1881  ************************************************************************/
1882
1883 pat bra
1884 with STACK
1885 kills ALL
1886         gen BAL {label, $1}
1887
1888 pat bne
1889 with REGcon GENREG STACK
1890         gen CMP %2, %1
1891             BNE {label, $1}
1892 with GENREG REGcon STACK
1893         gen CMP %1, %2
1894             BNE {label, $1}
1895
1896 pat beq
1897 with REGcon GENREG STACK
1898         gen CMP %2, %1
1899             BEQ {label, $1}
1900 with GENREG REGcon STACK
1901         gen CMP %1, %2
1902             BEQ {label, $1}
1903
1904 pat blt
1905 with REGcon GENREG STACK
1906         gen CMP %2, %1
1907             BLT {label, $1}
1908
1909 pat ble
1910 with REGcon GENREG STACK
1911         gen CMP %2, %1
1912             BLE {label, $1}
1913
1914 pat bgt
1915 with REGcon GENREG STACK
1916         gen CMP %2, %1
1917             BGT {label, $1}
1918
1919 pat bge
1920 with REGcon GENREG STACK
1921         gen CMP %2, %1
1922             BGE {label, $1}
1923
1924 pat zlt
1925 with GENREG STACK
1926 gen test %1
1927     BLT {label, $1}
1928
1929 pat zle
1930 with GENREG STACK
1931 gen test %1
1932     BLE {label, $1}
1933
1934 pat zeq
1935 with GENREG STACK
1936 gen test %1
1937     BEQ {label, $1}
1938
1939 pat zne
1940 with GENREG STACK
1941 gen test %1
1942     BNE {label, $1}
1943
1944 pat zge
1945 with GENREG STACK
1946 gen test %1
1947     BGE {label, $1}
1948
1949 pat zgt
1950 with  GENREG STACK
1951 gen test %1
1952     BGT {label, $1}
1953
1954 /************************************************************************
1955  *                                                                      *
1956  * GROUP XIV :  Procedure Call                                          *
1957  *                                                                      *
1958  ************************************************************************/
1959
1960 pat cal
1961 with STACK
1962 kills ALL
1963 gen BAL_L {label, $1}
1964
1965 pat cai
1966 with GENREG STACK
1967 kills ALL
1968 gen /* the trick is to set up R14 properly */
1969     ADR LR, {label, "1F"}
1970     MOV PC, %1
1971     LABEL {label, "1:"}
1972
1973 pat lfr $1==4                           yields R0
1974
1975 pat lfr $1==8                           yields R1 R0
1976
1977 pat lfr $1==12                          yields R2 R1 R0
1978
1979 pat ret $1==0
1980 with STACK
1981 kills ALL
1982 gen return
1983     MOV SP, LB
1984     LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
1985
1986 pat ret $1==4
1987 with address STACK
1988 kills ALL
1989 gen move %1, R0
1990     return
1991     move LB, SP
1992     LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
1993 with REGcon STACK
1994 kills ALL
1995 gen move %1, R0
1996     return
1997     move LB, SP
1998     LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
1999
2000 pat ret $1==8
2001 with REGcon REGcon STACK
2002 kills ALL
2003 gen move %1, R0
2004     move %2, R1
2005     return
2006     move LB, SP
2007     LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
2008
2009 pat ret $1==12
2010 with REGcon REGcon REGcon STACK
2011 kills ALL
2012 gen move %1, R0
2013     move %2, R1
2014     move %3, R2
2015     return
2016     move LB, SP
2017     LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
2018
2019
2020 /************************************************************************
2021  *                                                                      *
2022  * GROUP XV :   Miscellaneous                                           *
2023  *                                                                      *
2024  ************************************************************************/
2025
2026 pat asp legal($1)
2027 with STACK
2028 kills ALL
2029 gen ADD SP, SP, {fitcon, $1}
2030
2031 pat asp
2032 with STACK
2033 kills ALL
2034 uses GENREG={const4, $1}
2035 gen ADD SP, SP, %a
2036
2037 pat ass $1==4
2038 with REGcon STACK
2039 gen ADD SP, SP, %1
2040
2041 pat blm $1==0
2042 with address+REGcon address+REGcon
2043
2044 pat blm $1==1
2045 with GENREG GENREG
2046 kills address
2047 uses GENREG
2048 gen LDR_B %a, {regind, %2}
2049     STR_B %a, {regind, %1}
2050
2051 pat blm $1==4
2052 with GENREG GENREG
2053 kills address
2054 uses GENREG
2055 gen move {regind, %2}, %a
2056     move %a, {regind, %1}
2057
2058 pat blm $1>4
2059 with GENREG GENREG
2060 kills address
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}
2066     BGE {label,"1B"}
2067
2068 pat bls $1==4
2069 with GENREG GENREG GENREG
2070 kills address
2071 uses 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}
2076     BGT {label,"1B"}
2077
2078 pat csa $1==4
2079 with STACK
2080 kills ALL
2081 gen BAL_L {label, "_Csa"}
2082     move R2, PC
2083
2084 pat csb $1==4
2085 with STACK
2086 kills ALL
2087 gen BAL_L {label, "_Csb"}
2088     move R3, PC
2089
2090 pat dch leaving loi 4
2091
2092 pat dup $1==4
2093 with address+REGcon                     yields %1 %1
2094
2095 pat dup $1==8
2096 with address+REGcon address+REGcon      yields %2 %1 %2 %1
2097
2098 pat dup $1>8
2099 with STACK
2100 kills ALL
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}
2106     BGT {label, "1B"}
2107
2108 pat dus
2109 with GENREG STACK
2110 uses GENREG, GENREG
2111 gen SUB %b, %1, {fitcon, 4}
2112     LABEL {label, "1:"}
2113     move {st_regregrel, SP, %b}, %a
2114     STMFD {autoid, SP}, {reglist1, %a}
2115     SUB_S %1, %1, {fitcon, 4}
2116     BGT {label, "1B"}
2117
2118 pat exg $1==4
2119 with address+REGcon address+REGcon              yields %1 %2
2120
2121 pat exg $1==8
2122 with address+REGcon address+REGcon
2123      address+REGcon address+REGcon              yields %2 %1 %4 %3
2124
2125 pat exg $1>8
2126 with STACK
2127 kills ALL
2128 uses GENREG, GENREG, GENREG={const4, $1-4}, GENREG, GENREG={const4, $1}
2129 gen ADD %d, SP, %e
2130     LABEL {label, "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}
2136     BGE {label, "1B"}
2137
2138 pat fil
2139 uses GENREG
2140 gen move {addr_external,$1}, %a
2141     move %a, {addr_external, "_Filna"}
2142
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
2149     MOV  LB, %c
2150     MOV  SP, %b
2151     MOV  PC, %a
2152
2153 pat lin
2154 kills address
2155 uses GENREG={const4,$1}
2156 gen move %a,{addr_external,"_Lineno"}
2157
2158 pat lni
2159 kills address
2160 uses GENREG
2161 gen move {addr_external,"_Lineno"}, %a
2162     LDR %a, {regind, %a}
2163     ADD %a,%a,{fitcon,1}
2164     move %a,{addr_external,"_Lineno"}
2165
2166 pat lor $1==0                           yields LB
2167
2168 pat lor $1==1
2169 with STACK
2170 kills ALL                               yields SP
2171
2172 pat lor $1==2                           yields {absolute, "_RegHp"}
2173
2174 pat lpb                                 leaving adp 8
2175
2176 pat nop
2177 kills ALL
2178 gen MOV_NV R0,R0
2179
2180 pat rck
2181 with GENREG REGcon  STACK 
2182 uses GENREG,GENREG
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.
2188      */
2189     move %2,%b
2190     STMFD {autoid, SP}, {reglist1, %b}
2191     CMP %a, %2
2192     BGT {label, "_RckTrap"}
2193     move {regrel, %1, 4}, %a
2194     CMP %a, %2
2195     BLT {label, "_RckTrap"}
2196
2197 pat lim
2198 with STACK
2199 kills ALL
2200 uses GENREG
2201 gen move {addr_external, "_IgnoreMask"}, %a
2202     STMFD {autoid, SP}, {reglist1, %a}
2203
2204 pat mon
2205 with STACK
2206 kills ALL
2207 gen BAL_L {label, "_EmMon"}
2208
2209 pat rtt
2210             leaving ret 0
2211
2212 pat sig
2213 with STACK
2214 kills ALL
2215 uses GENREG,GENREG
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}
2221
2222 pat sim
2223 with STACK
2224 kills ALL
2225 uses GENREG
2226 gen LDMFD {autoid, SP}, {reglist1, %a}
2227     move %a, {addr_external, "_IgnoreMask"}
2228
2229 pat trp
2230 with STACK
2231 kills ALL
2232 gen BAL_L {label, "_EmTrp"}
2233
2234 pat str $1==0
2235 with address
2236 gen move %1, LB
2237 with REGcon
2238 gen move %1, LB
2239
2240 pat str $1==1
2241 with address
2242 gen MOV SP, %1
2243 with REGcon
2244 gen MOV SP, %1
2245
2246 pat str $1==2
2247 with GENREG
2248 gen move %1, {absolute, "_RegHp"}
2249
2250 /***********************************************************************/
2251
2252 /* code for *p++ and *p-- (integers)*/
2253 pat lol dup adp stl loi $1==$4 && $2==4 && $5==4
2254 kills GENREG
2255 uses GENREG, GENREG
2256 gen move {lb_local, $1}, %a
2257     LDR %b, {regrelpi, %a, $5}
2258     STR %a, {lb_local, $1}              yields %b
2259
2260 pat lol dup adp stl sti $1==$4 && $2==4 && $5==4
2261 with GENREG
2262 kills GENREG
2263 uses GENREG
2264 gen move {lb_local,$1}, %a
2265     STR %1, {regrelpi, %a, $5}
2266     STR %a, {lb_local, $1}
2267
2268 /* code for *p++ and *p-- (bytes)*/
2269 pat lol dup adp stl loi $1==$4 && $2==4 && $5==1
2270 kills GENREG
2271 uses GENREG, GENREG
2272 gen move {lb_local, $1}, %a
2273     LDR_B %b, {regrelpi, %a, $5}
2274     STR %a, {lb_local, $1}              yields %b
2275
2276 pat lol dup adp stl sti $1==$4 && $2==4 && $5==1
2277 with GENREG
2278 kills GENREG
2279 uses GENREG
2280 gen move {lb_local,$1}, %a
2281     STR_B %1, {regrelpi, %a, $5}
2282     STR %a, {lb_local, $1}
2283
2284 /* code for *pp->p++ and *pp->p-- (integers)*/
2285 pat lil dup adp sil loi $1==$4 && $2==4 && $5==4
2286 kills GENREG
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
2293
2294 pat lil dup adp sil sti $1==$4 && $2==4 && $5==4
2295 with GENREG
2296 kills GENREG
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}
2303
2304 /* code for *pp->p++ and *pp->p-- (bytes)*/
2305 pat lil dup adp sil loi $1==$4 && $2==4 && $5==1
2306 kills GENREG
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
2313
2314 pat lil dup adp sil sti $1==$4 && $2==4 && $5==1
2315 with GENREG
2316 kills GENREG
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}
2323
2324
2325 /* global array access of the form x[y-1] */
2326
2327 pat lol loc mli loc sbi $2==$4 && $3==4 && $5==4
2328     leaving lol $1 dec 4 loc $2 mli 4
2329
2330 /* x[i] = y with large array elements */
2331
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
2336
2337 /* prevent double push/pull of $1 */
2338
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
2343
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
2348
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
2353
2354 /*
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
2359 */