|
|
1.1 root 1: ;;- Machine description Acorn RISC Machine for GNU compiler
2: ;; Copyright (C) 1991 Free Software Foundation, Inc.
3: ;; Contributed by Pieter `Tiggr' Schoenmakers ([email protected])
4: ;; and Martin Simmons (@harleqn.co.uk).
5:
6: ;; This file is part of GNU CC.
7:
8: ;; GNU CC is free software; you can redistribute it and/or modify
9: ;; it under the terms of the GNU General Public License as published by
10: ;; the Free Software Foundation; either version 2, or (at your option)
11: ;; any later version.
12:
13: ;; GNU CC is distributed in the hope that it will be useful,
14: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16: ;; GNU General Public License for more details.
17:
18: ;; You should have received a copy of the GNU General Public License
19: ;; along with GNU CC; see the file COPYING. If not, write to
20: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21:
22: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23:
24: ;; Every template must be output by arm_output_asm_insn, since this keeps
25: ;; track of the offset of labels within the text segment. This is needed to
26: ;; to be able to (correctly) output instructions for loading a value from a
27: ;; function's constant pool, since different instructions are needed when the
28: ;; constant pool is more than 4095 bytes away from the PC.
29:
30: ;; Addition insns.
31:
32: (define_insn "adddi3"
33: [(set (match_operand:DI 0 "di_operand" "=r")
34: (plus:DI (match_operand:DI 1 "di_operand" "%r")
35: (match_operand:DI 2 "di_operand" "r")))]
36: ""
37: "*
38: arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands);
39: return (arm_output_asm_insn (\"adc\\t%R0, %R1, %R2\", operands));
40: ")
41:
42: (define_insn "addsi3"
43: [(set (match_operand:SI 0 "register_operand" "=r,r")
44: (plus:SI (match_operand:SI 1 "register_operand" "r,r")
45: (match_operand:SI 2 "general_operand" "r,n")))]
46: ""
47: "*
48: switch (which_alternative)
49: {
50: case 0:
51: return (arm_output_asm_insn (\"add\\t%0, %1, %2\", operands));
52: case 1:
53: return (output_add_immediate (operands));
54: }
55: ")
56:
57: (define_insn "addsf3"
58: [(set (match_operand:SF 0 "register_operand" "=f")
59: (plus:SF (match_operand:SF 1 "register_operand" "f")
60: (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
61: ""
62: "*
63: return (arm_output_asm_insn (\"adfs\\t%0, %1, %2\", operands));
64: ")
65:
66: (define_insn "adddf3"
67: [(set (match_operand:DF 0 "register_operand" "=f")
68: (plus:DF (match_operand:DF 1 "register_operand" "f")
69: (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
70: ""
71: "*
72: return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
73: ")
74:
75: (define_insn "subdi3"
76: [(set (match_operand:DI 0 "di_operand" "=r")
77: (minus:DI (match_operand:DI 1 "di_operand" "%r")
78: (match_operand:DI 2 "di_operand" "r")))]
79: ""
80: "*
81: arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
82: return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %R2\", operands));
83: ")
84:
85: (define_insn "subsi3"
86: [(set (match_operand:SI 0 "register_operand" "=r,r,r")
87: (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
88: (match_operand:SI 2 "general_operand" "r,n,r")))]
89: ""
90: "*
91: switch (which_alternative)
92: {
93: case 0:
94: return (arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands));
95: case 1:
96: operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2]));
97: return (output_add_immediate (operands));
98: case 2:
99: return (arm_output_asm_insn (\"rsb\\t%0, %2, %1\", operands));
100: }
101: ")
102:
103: (define_insn "subsf3"
104: [(set (match_operand:SF 0 "register_operand" "=f,f")
105: (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
106: (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
107: ""
108: "*
109: switch (which_alternative)
110: {
111: case 0:
112: return (arm_output_asm_insn (\"sufs\\t%0, %1, %2\", operands));
113: case 1:
114: return (arm_output_asm_insn (\"rsfs\\t%0, %2, %1\", operands));
115: }
116: ")
117:
118: (define_insn "subdf3"
119: [(set (match_operand:DF 0 "register_operand" "=f,f")
120: (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
121: (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
122: ""
123: "*
124: switch (which_alternative)
125: {
126: case 0:
127: return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands));
128: case 2:
129: return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands));
130: }
131: ")
132:
133: ;; Multiplication insns
134:
135: ;; The `&' is too strict, but at least generates correct code.
136: (define_insn "mulsi3"
137: [(set (match_operand:SI 0 "register_operand" "=&r")
138: (mult:SI (match_operand:SI 1 "register_operand" "%r")
139: (match_operand:SI 2 "register_operand" "r")))]
140: ""
141: "*
142: if (REGNO (operands[0]) == REGNO (operands[1]))
143: return (arm_output_asm_insn (\"mul\\t%0, %2, %1\", operands));
144: else
145: return (arm_output_asm_insn (\"mul\\t%0, %1, %2\", operands));
146: ")
147:
148: ;; Unnamed templates to match MLA instruction.
149:
150: (define_insn ""
151: [(set (match_operand:SI 0 "register_operand" "=&r")
152: (plus:SI
153: (mult:SI (match_operand:SI 1 "register_operand" "%r")
154: (match_operand:SI 2 "register_operand" "r"))
155: (match_operand:SI 3 "register_operand" "r")))]
156: ""
157: "*
158: if (REGNO (operands[0]) == REGNO (operands[1]))
159: return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands));
160: else
161: return (arm_output_asm_insn (\"mla\\t%0, %1, %2, %3\", operands));
162: ")
163:
164: (define_insn ""
165: [(set (match_operand:SI 0 "register_operand" "=&r")
166: (plus:SI
167: (match_operand:SI 3 "register_operand" "r")
168: (mult:SI (match_operand:SI 1 "register_operand" "%r")
169: (match_operand:SI 2 "register_operand" "r"))))]
170: ""
171: "*
172: if (REGNO (operands[0]) == REGNO (operands[1]))
173: return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands));
174: else
175: return (arm_output_asm_insn (\"mla\\t%0, %1, %2, %3\", operands));
176: ")
177:
178: (define_insn "mulsf3"
179: [(set (match_operand:SF 0 "register_operand" "=f")
180: (mult:SF (match_operand:SF 1 "register_operand" "f")
181: (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
182: ""
183: "*return (arm_output_asm_insn (\"mufs\\t%0, %1, %2\", operands));")
184:
185: (define_insn "muldf3"
186: [(set (match_operand:DF 0 "register_operand" "=f")
187: (mult:DF (match_operand:DF 1 "register_operand" "f")
188: (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
189: ""
190: "*
191: return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));
192: ")
193:
194: ;; Division insns
195:
196: (define_insn "divsf3"
197: [(set (match_operand:SF 0 "register_operand" "=f,f")
198: (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
199: (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
200: ""
201: "*
202: switch (which_alternative)
203: {
204: case 0:
205: return (arm_output_asm_insn (\"dvfs\\t%0, %1, %2\", operands));
206: case 1:
207: return (arm_output_asm_insn (\"rdfs\\t%0, %2, %1\", operands));
208: }
209: ")
210:
211: (define_insn "divdf3"
212: [(set (match_operand:DF 0 "register_operand" "=f,f")
213: (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
214: (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
215: ""
216: "*
217: switch (which_alternative)
218: {
219: case 0:
220: return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands));
221: case 1:
222: return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands));
223: }
224: ")
225:
226: ;; Modulo insns
227:
228: (define_insn "modsf3"
229: [(set (match_operand:SF 0 "register_operand" "=f")
230: (mod:SF (match_operand:SF 1 "register_operand" "f")
231: (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
232: ""
233: "*
234: return (arm_output_asm_insn (\"rmfs\\t%0, %1, %2\", operands));
235: ")
236:
237: (define_insn "moddf3"
238: [(set (match_operand:DF 0 "register_operand" "=f")
239: (mod:DF (match_operand:DF 1 "register_operand" "f")
240: (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
241: ""
242: "*
243: return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));
244: ")
245:
246: ;; Boolean and,ior,xor insns
247:
248: (define_insn "anddi3"
249: [(set (match_operand:DI 0 "di_operand" "=r")
250: (and:DI (match_operand:DI 1 "di_operand" "%r")
251: (match_operand:DI 2 "di_operand" "r")))]
252: ""
253: "*
254: arm_output_asm_insn (\"and\\t%0, %1, %2\", operands);
255: return (arm_output_asm_insn (\"and\\t%R0, %R1, %R2\", operands));
256: ")
257:
258: (define_insn "andsi3"
259: [(set (match_operand:SI 0 "register_operand" "=r")
260: (and:SI (match_operand:SI 1 "register_operand" "r")
261: (match_operand:SI 2 "arm_rhs_operand" "rI")))]
262: ""
263: "*
264: return (arm_output_asm_insn (\"and\\t%0, %1, %2\", operands));
265: ")
266:
267: (define_insn "andcbsi3"
268: [(set (match_operand:SI 0 "register_operand" "=r")
269: (and:SI (match_operand:SI 1 "register_operand" "r")
270: (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
271: ""
272: "*
273: return (arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands));
274: ")
275:
276: (define_insn "iordi3"
277: [(set (match_operand:DI 0 "di_operand" "=r")
278: (ior:DI (match_operand:DI 1 "di_operand" "%r")
279: (match_operand:DI 2 "di_operand" "r")))]
280: ""
281: "*
282: arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands);
283: return (arm_output_asm_insn (\"orr\\t%R0, %R1, %R2\", operands));
284: ")
285:
286: (define_insn "iorsi3"
287: [(set (match_operand:SI 0 "register_operand" "=r,r")
288: (ior:SI (match_operand:SI 1 "register_operand" "r,r")
289: (match_operand:SI 2 "nonmemory_operand" "r,n")))]
290: ""
291: "*
292: switch (which_alternative)
293: {
294: case 0:
295: return (arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands));
296: case 1:
297: return (output_multi_immediate (operands,
298: \"orr\\t%0, %1, %2\", \"orr\\t%0, %0, %2\",
299: 2, INTVAL (operands[2])));
300: }
301: ")
302:
303: (define_insn "xorsi3"
304: [(set (match_operand:SI 0 "register_operand" "=r,r")
305: (xor:SI (match_operand:SI 1 "register_operand" "r,r")
306: (match_operand:SI 2 "nonmemory_operand" "r,n")))]
307: ""
308: "*
309: switch (which_alternative)
310: {
311: case 0:
312: return (arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands));
313: case 1:
314: return (output_multi_immediate (operands,
315: \"eor\\t%0, %1, %2\", \"eor\\t%0, %0, %2\",
316: 2, INTVAL (operands[2])));
317: }
318: ")
319:
320: ;; Shift and rotation insns
321:
322: (define_insn "ashlsi3"
323: [(set (match_operand:SI 0 "register_operand" "=r")
324: (ashift:SI (match_operand:SI 1 "register_operand" "r")
325: (match_operand:SI 2 "general_operand" "rn")))]
326: ""
327: "*
328: return (output_shifted_move (ASHIFT, operands));
329: ")
330:
331: (define_insn "ashrsi3"
332: [(set (match_operand:SI 0 "register_operand" "=r")
333: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
334: (match_operand:SI 2 "general_operand" "rn")))]
335: ""
336: "*
337: return (output_shifted_move (ASHIFTRT, operands));
338: ")
339:
340: ;; lshlsi3 is not defined because shift counts cannot be negative
341: ;; An unnamed pattern is needed for expansion of zero_extend.
342:
343: (define_insn ""
344: [(set (match_operand:SI 0 "register_operand" "=r")
345: (lshift:SI (match_operand:SI 1 "register_operand" "r")
346: (match_operand:SI 2 "general_operand" "rn")))]
347: ""
348: "*
349: return (output_shifted_move (LSHIFT, operands));
350: ")
351:
352: (define_insn "lshrsi3"
353: [(set (match_operand:SI 0 "register_operand" "=r")
354: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
355: (match_operand:SI 2 "general_operand" "rn")))]
356: ""
357: "*
358: return (output_shifted_move (LSHIFTRT, operands));
359: ")
360:
361: ;; rotlsi3 is not defined yet to see what happens
362:
363: (define_insn "rotrsi3"
364: [(set (match_operand:SI 0 "register_operand" "=r,r")
365: (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
366: (match_operand:SI 2 "general_operand" "r,n")))]
367: ""
368: "*
369: switch (which_alternative)
370: {
371: case 0:
372: return (arm_output_asm_insn (\"mov\\t%0, %1,ror %2\", operands));
373: case 1:
374: if (INTVAL(operands[2]) > 31)
375: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 32);
376: return (arm_output_asm_insn (\"mov\\t%0, %1,ror%2\", operands));
377: }
378: ")
379:
380: ;; Unary arithmetic insns
381:
382: (define_insn "negdi2"
383: [(set (match_operand:DI 0 "di_operand" "=r")
384: (neg:DI (match_operand:DI 1 "di_operand" "r")))]
385: ""
386: "*
387: arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands);
388: return (arm_output_asm_insn (\"rsc\\t%R0, %R1, #0\", operands));
389: ")
390:
391: (define_insn "negsi2"
392: [(set (match_operand:SI 0 "register_operand" "=r")
393: (neg:SI (match_operand:SI 1 "register_operand" "r")))]
394: ""
395: "*
396: return (arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands));
397: ")
398:
399: (define_insn "negsf2"
400: [(set (match_operand:SF 0 "register_operand" "=f")
401: (neg:SF (match_operand:SF 1 "register_operand" "f")))]
402: ""
403: "*
404: return (arm_output_asm_insn (\"mnfs\\t%0, %1\", operands));
405: ")
406:
407: (define_insn "negdf2"
408: [(set (match_operand:DF 0 "register_operand" "=f")
409: (neg:DF (match_operand:DF 1 "register_operand" "f")))]
410: ""
411: "*
412: return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands));
413: ")
414:
415: (define_insn "abssf2"
416: [(set (match_operand:SF 0 "register_operand" "=f")
417: (abs:SF (match_operand:SF 1 "register_operand" "f")))]
418: ""
419: "*
420: return (arm_output_asm_insn (\"abss\\t%0, %1\", operands));
421: ")
422:
423: (define_insn "absdf2"
424: [(set (match_operand:DF 0 "register_operand" "=f")
425: (abs:DF (match_operand:DF 1 "register_operand" "f")))]
426: ""
427: "*
428: return (arm_output_asm_insn (\"absd\\t%0, %1\", operands));
429: ")
430:
431: (define_insn "sqrtsf2"
432: [(set (match_operand:SF 0 "register_operand" "=f")
433: (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
434: ""
435: "*
436: return (arm_output_asm_insn (\"sqts\\t%0, %1\", operands));
437: ")
438:
439: (define_insn "sqrtdf2"
440: [(set (match_operand:DF 0 "register_operand" "=f")
441: (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
442: ""
443: "*
444: return (arm_output_asm_insn (\"sqtd\\t%0, %1\", operands));
445: ")
446:
447: (define_insn "one_cmplsi2"
448: [(set (match_operand:SI 0 "register_operand" "=r")
449: (not:SI (match_operand:SI 1 "register_operand" "r")))]
450: ""
451: "*
452: return (arm_output_asm_insn (\"mvn\\t%0, %1\", operands));
453: ")
454:
455: ;; Fixed <--> Floating conversion insns
456:
457: (define_insn "floatsisf2"
458: [(set (match_operand:SF 0 "register_operand" "=f")
459: (float:SF (match_operand:SI 1 "register_operand" "r")))]
460: ""
461: "*
462: return (arm_output_asm_insn (\"flts\\t%0, %1\", operands));
463: ")
464:
465: (define_insn "floatsidf2"
466: [(set (match_operand:DF 0 "register_operand" "=f")
467: (float:DF (match_operand:SI 1 "register_operand" "r")))]
468: ""
469: "*
470: return (arm_output_asm_insn (\"fltd\\t%0, %1\", operands));
471: ")
472:
473: ;; Truncation insns
474:
475: (define_insn "truncsiqi2"
476: [(set (match_operand:QI 0 "general_operand" "=mr")
477: (truncate:QI (match_operand:SI 1 "register_operand" "r")))]
478: ""
479: "*
480: if (GET_CODE (operands[0]) == MEM)
481: return (arm_output_asm_insn (\"strb\\t%1, %0\\t@ truncsiqi2\", operands));
482: else
483: return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ truncsiqi2\", operands));
484: ")
485:
486: (define_insn "trunchiqi2"
487: [(set (match_operand:QI 0 "general_operand" "=mr")
488: (truncate:QI (match_operand:HI 1 "register_operand" "r")))]
489: ""
490: "*
491: if (GET_CODE(operands[0]) == MEM)
492: return (arm_output_asm_insn (\"strb\\t%1, %0\\t@ trunchiqi2\", operands));
493: else
494: return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ trunchiqi2\", operands));
495: ")
496:
497: ;; Mode is changed to SI below
498:
499: (define_expand "truncsihi2"
500: [(set (match_operand:SI 0 "register_operand" "")
501: (ashift:SI (match_operand:HI 1 "register_operand" "")
502: (const_int 16)))
503: (set (match_dup 0)
504: (ashiftrt:SI (match_dup 0) (const_int 16)))]
505: ""
506: "
507: if (GET_CODE (operands[1]) == SUBREG)
508: operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
509: SUBREG_WORD (operands[1]));
510: else
511: operands[1] = gen_rtx(SUBREG, SImode, operands[1], 0);
512: ")
513:
514: (define_insn "truncdfsf2"
515: [(set (match_operand:SF 0 "register_operand" "=f")
516: (float_truncate:SF
517: (match_operand:DF 1 "register_operand" "f")))]
518: ""
519: "*
520: return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands));
521: ")
522:
1.1.1.2 ! root 523: ;; Zero extension instructions.
1.1 root 524:
525: (define_expand "zero_extendhisi2"
526: [(set (match_operand:SI 0 "register_operand" "")
527: (ashift:SI (match_operand:HI 1 "register_operand" "")
528: (const_int 16)))
529: (set (match_dup 0)
530: (lshiftrt:SI (match_dup 0) (const_int 16)))]
531: ""
532: "
533: if (GET_CODE (operands[1]) == SUBREG)
534: operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
535: SUBREG_WORD (operands[1]));
536: else
537: operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
538: ")
539:
540: (define_insn "zero_extendqihi2"
541: [(set (match_operand:HI 0 "register_operand" "=r")
542: (zero_extend:HI
543: (match_operand:QI 1 "register_operand" "r")))]
544: ""
545: "*
546: return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqihi2\", operands));
547: ")
548:
549: (define_insn "zero_extendqisi2"
550: [(set (match_operand:SI 0 "register_operand" "=r,r")
551: (zero_extend:SI
552: (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
553: ""
554: "*
555: switch (which_alternative)
556: {
557: case 0:
558: return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqisi2\", operands));
559: case 1:
560: return (arm_output_asm_insn (\"ldrb\\t%0, %1\\t@ zero_extendqisi2\", operands));
561: }
562: ")
563:
564: ;; Note that the ones starting from HImode come before those for QImode so
565: ;; that a constant operand will match HImode, not QImode.
566:
567: (define_expand "extendhisi2"
568: [(set (match_operand:SI 0 "register_operand" "")
569: (ashift:SI (match_operand:HI 1 "register_operand" "")
570: (const_int 16)))
571: (set (match_dup 0)
572: (ashiftrt:SI (match_dup 0) (const_int 16)))]
573: ""
574: "
575: if (GET_CODE (operands[1]) == SUBREG)
576: operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
577: SUBREG_WORD (operands[1]));
578: else
579: operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
580: ")
581:
582: ;; XXX Is this ever used?
583:
584: (define_insn "extendqihi2"
585: [(set (match_operand:HI 0 "register_operand" "=r")
586: (sign_extend:SI
587: (match_operand:QI 1 "register_operand" "r")))]
588: ""
589: "*
590: arm_output_asm_insn (\"mov\\t%0, %1, lsl#24\\t@ extendqihi\", operands);
591: return (arm_output_asm_insn (\"mov\\t%0, %0, asr#24\", operands));
592: ")
593:
594:
595: (define_expand "extendqisi2"
596: [(set (match_operand:SI 0 "register_operand" "")
597: (ashift:SI (match_operand:QI 1 "register_operand" "")
598: (const_int 24)))
599: (set (match_dup 0)
600: (ashiftrt:SI (match_dup 0) (const_int 24)))]
601: ""
602: "
603: if (GET_CODE (operands[1]) == SUBREG)
604: operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
605: SUBREG_WORD(operands[1]));
606: else
607: operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
608: ")
609:
610: (define_insn "extendsfdf2"
611: [(set (match_operand:DF 0 "register_operand" "=f")
612: (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
613: ""
614: "*
615: return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands));
616: ")
617:
618: ;; Move insns (including loads and stores)
619:
620: ;; XXX Just some ideas about movti.
621:
622: ;;(define_expand "loadti"
623: ;; [(set (match_operand:TI 0 "register_operand" "")
624: ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
625: ;; "" "")
626:
627: ;;(define_expand "storeti"
628: ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
629: ;; (match_operand:TI 1 "register_operand" ""))]
630: ;; "" "")
631:
632: ;;(define_expand "movti"
633: ;; [(set (match_operand:TI 0 "general_operand" "")
634: ;; (match_operand:TI 1 "general_operand" ""))]
635: ;; ""
636: ;; "
637: ;;{
638: ;; rtx insn;
639: ;;
640: ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
641: ;; operands[1] = copy_to_reg (operands[1]);
642: ;; if (GET_CODE (operands[0]) == MEM)
643: ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
644: ;; else if (GET_CODE (operands[1]) == MEM)
645: ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
646: ;; else
647: ;; FAIL;
648: ;;
649: ;; emit_insn (insn);
650: ;; DONE;
651: ;;}")
652:
653: ;; Recognise garbage generated above.
654:
655: ;;(define_insn ""
656: ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
657: ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
658: ;; ""
659: ;; "*
660: ;; {
661: ;; register mem = (which_alternative < 3);
662: ;; register char *template;
663: ;;
664: ;; operands[mem] = XEXP (operands[mem], 0);
665: ;; switch (which_alternative)
666: ;; {
667: ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
668: ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
669: ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
670: ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
671: ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
672: ;; case 5: template = \"stmia\\t%0, %M1\"; break;
673: ;; }
674: ;; return (arm_output_asm_insn (template, operands));
675: ;; }")
676:
677:
678: (define_insn "movdi"
679: [(set (match_operand:DI 0 "di_operand" "=r,r,r,o,r")
680: (match_operand:DI 1 "di_operand" "r,n,o,r,F"))]
681: ""
682: "*
683: return (output_move_double (operands));
684: ")
685:
686: (define_insn "movsi"
687: [(set (match_operand:SI 0 "general_operand" "=r,r,r,m")
688: (match_operand:SI 1 "general_operand" "r,n,m,r"))]
689: ""
690: "*
691: switch (which_alternative)
692: {
693: case 0:
694: return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
695: case 1:
696: return (output_mov_immediate (operands));
697: case 2:
698: if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
699: && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
700: return (arm_output_llc (operands));
701: else
702: return (arm_output_asm_insn (\"ldr\\t%0, %1\", operands));
703: case 3:
704: return (arm_output_asm_insn (\"str\\t%1, %0\", operands));
705: }
706: ")
707:
708: ;; XXX The movhi stuff isn't as correct or as nice as it could be...
709:
710: ;; Subroutine to load a half word into a register from memory.
711: ;; Operand 0 is the destination register (HImode).
712: ;; Operand 1 is the source address (SImode).
713: ;; Operand 2 is a temporary (SImode).
714:
715: ;;(define_expand "loadhi"
716: ;; [;; load the whole word (ARM realigns it if not on word boundary)
717: ;; (set (match_operand:SI 2 "register_operand" "")
718: ;; (mem:SI (match_operand:SI 1 "address_operand" "")))
719: ;; ;; quietly forget the upper 16 bits
720: ;; (set (match_operand:HI 0 "register_operand" "")
721: ;; (subreg:HI (match_dup 2) 0))]
722: ;; ""
723: ;; ""
724: ;;)
725:
726: ;; Load op0 from mem:op1. Subroutine in case we're reloading and the normal
727: ;; loadhi is not allowed.
728:
729: ;;(define_expand "reloadhi"
730: ;; [(set (reg:SI 10)
731: ;; (mem:SI (match_operand:SI 1 "address_operand" "")))
732: ;; (set (match_operand:HI 0 "register_operand" "")
733: ;; (subreg:HI (reg:SI 10) 0))]
734: ;; "" "")
735:
736: ;; Store op0 into mem:op1. Subroutine in case we're reloading and the normal
737: ;; storehi is not allowed.
738:
739: (define_expand "restorehi"
740: [(set (mem:QI (match_operand:SI 1 "address_operand" ""))
741: (truncate:QI (match_operand:HI 0 "register_operand" "")))
742: (set (reg:HI 10)
743: (ashiftrt:HI (match_dup 0) (const_int 8)))
744: (set (mem:QI (plus:SI (match_dup 1) (const_int 1)))
745: (truncate:QI (reg:HI 10)))]
746: "" "")
747:
748: ;; Subroutine to store a half word from a register into memory.
749: ;; Operand 0 is the source register (HImode)
750: ;; Operand 1 is the destination address (SImode)
751: ;; Operand 2 is a temporary (SImode).
752: ;; Operand 3 is a temporary (SImode).
753: ;; Operand 4 is a temporary (SImode).
754: ;; Operand 5 is a local temporary (SImode).
755:
756: (define_expand "storehi"
757: [;; compute the address into a register
758: (set (match_operand:SI 2 "register_operand" "")
759: (match_operand:SI 1 "address_operand" ""))
760: ;; get the half word into a full word register
761: (set (match_operand:SI 3 "register_operand" "")
762: (match_dup 5))
763: ;; store the low byte
764: (set (mem:QI (match_dup 2))
765: (truncate:QI (match_dup 3)))
766: ;; extract the high byte
767: (set (match_operand:SI 4 "register_operand" "")
768: (ashiftrt:SI (match_dup 3) (const_int 8)))
769: ;; store the high byte
770: (set (mem:QI (plus (match_dup 2) (const_int 1)))
771: (truncate:QI (match_dup 4)))]
772: ""
773: "
774: if (GET_CODE(operands[0]) == SUBREG)
775: operands[5] = gen_rtx(SUBREG, SImode, SUBREG_REG(operands[0]),
776: SUBREG_WORD(operands[0]));
777: else
778: operands[5] = gen_rtx(SUBREG, SImode, operands[0], 0);
779:
780: ")
781:
782: ;; Subroutine to store a half word integer constant into memory.
783: ;; Operand 0 is the constant
784: ;; Operand 1 is the destination address (SImode)
785: ;; Operand 2 is a temporary (SImode).
786: ;; Operand 3 is a temporary (QImode).
787: ;; Operand 4 is a temporary (QImode).
788: ;; Operand 5 is a local CONST_INT.
789: ;; Operand 6 is a local CONST_INT.
790:
791: (define_expand "storeinthi"
792: [;; compute the address into a register
793: (set (match_operand:SI 2 "register_operand" "")
794: (match_operand:SI 1 "address_operand" ""))
795: ;; load the low byte
796: (set (match_operand:QI 3 "register_operand" "")
797: (match_dup 5))
798: ;; store the low byte
799: (set (mem:QI (match_dup 2))
800: (match_dup 3))
801: ;; load the high byte
802: (set (match_operand:QI 4 "register_operand" "")
803: (match_dup 6))
804: ;; store the high byte
805: (set (mem:QI (plus (match_dup 2) (const_int 1)))
806: (match_dup 4))]
807: ""
808: "
809: {
810: int value = INTVAL(operands[0]);
811:
812: operands[5] = gen_rtx(CONST_INT, VOIDmode, value & 255);
813: operands[6] = gen_rtx(CONST_INT, VOIDmode,(value>>8) & 255);
814: }
815: ")
816:
817: (define_expand "movhi"
818: [(set (match_operand:HI 0 "general_operand" "")
819: (match_operand:HI 1 "general_operand" ""))]
820: ""
821: "
822: {
823: rtx insn;
824:
825: if (reload_in_progress || reload_completed)
826: {
827: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == REG)
828: insn = gen_restorehi (operands[1], XEXP (operands[0], 0));
829: else
830: insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
831: }
832: else
833: {
834: if (GET_CODE (operands[0]) == MEM)
835: {
836: if (GET_CODE (operands[1]) == MEM)
837: operands[1] = copy_to_reg (operands[1]);
838:
839: if (GET_CODE (operands[1]) == CONST_INT)
840: {
841: insn = gen_storeinthi (operands[1], XEXP (operands[0], 0),
842: gen_reg_rtx (SImode),
843: gen_reg_rtx (QImode),
844: gen_reg_rtx (QImode));
845: }
846: else
847: {
848: insn = gen_storehi (operands[1], XEXP (operands[0], 0),
849: gen_reg_rtx (SImode),
850: gen_reg_rtx (SImode),
851: gen_reg_rtx (SImode));
852: }
853: }
854: #if 0
855: else if (GET_CODE (operands[1]) == MEM)
856: {
857: insn = gen_loadhi (operands[0], XEXP (operands[1], 0),
858: gen_reg_rtx (SImode));
859: }
860: #endif
861: else
862: insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
863: }
864:
865: emit_insn (insn);
866: DONE;
867: }")
868:
869: ;; Pattern to recognise insn generated default case above
870:
871: (define_insn ""
872: [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
873: (match_operand:HI 1 "general_operand" "r,n,m,r"))]
874: ""
875: "*
876: switch (which_alternative)
877: {
878: case 0: return (arm_output_asm_insn (\"mov\\t%0, %1\\t@movhi\", operands));
879: case 1: return (output_mov_immediate (operands));
880: case 2: return (arm_output_asm_insn (\"ldr\\t%0, %1\\t@movhi\", operands));
881: case 3: return (arm_output_asm_insn (\"str\\t%1, %0\\t@movhi\", operands));
882: }
883: ")
884:
885: (define_insn "movqi"
886: [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
887: (match_operand:QI 1 "general_operand" "r,n,m,r"))]
888: ""
889: "*
890: switch (which_alternative)
891: {
892: case 0:
893: return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
894: case 1:
895: return (output_mov_immediate (operands));
896: case 2:
897: return (arm_output_asm_insn (\"ldrb\\t%0, %1\", operands));
898: case 3:
899: return (arm_output_asm_insn (\"strb\\t%1, %0\", operands));
900: }
901:
902: ")
903:
904: (define_insn "movsf"
905: [(set (match_operand:SF 0 "general_operand" "=f,f,m,f,r,r")
906: (match_operand:SF 1 "general_operand" "fG,m,f,r,f,r"))]
907: ""
908: "*
909: switch (which_alternative)
910: {
911: case 0:
912: return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands));
913: case 1:
914: return (arm_output_asm_insn (\"ldfs\\t%0, %1\", operands));
915: case 2:
916: return (arm_output_asm_insn (\"stfs\\t%1, %0\", operands));
917: case 3:
918: arm_output_asm_insn(\"stmfd\\tsp!, {%1}\", operands);
919: return (arm_output_asm_insn (\"ldfs\\t%0, [sp],#4\", operands));
920: case 4:
921: arm_output_asm_insn(\"stfs\\t%1, [sp,#-4]!\", operands);
922: return (arm_output_asm_insn (\"ldmfd\\tsp!, {%0}\", operands));
923: case 5:
924: return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
925: }
926: ")
927:
928: (define_insn "movdf"
929: [(set (match_operand:DF 0 "general_operand" "=f,f,m,f,r,r")
930: (match_operand:DF 1 "general_operand" "fG,m,f,r,f,r"))]
931: ""
932: "*
933: switch (which_alternative)
934: {
935: case 0: return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands));
936: case 1: return (arm_output_asm_insn (\"ldfd\\t%0, %1\", operands));
937: case 2: return (arm_output_asm_insn (\"stfd\\t%1, %0\", operands));
938: case 3: return (output_mov_double_fpu_from_arm (operands));
939: case 4: return (output_mov_double_arm_from_fpu (operands));
940: case 5: return (output_move_double (operands));
941: }
942: ")
943:
944: ;; Comparison and test insns
945:
946: (define_insn "cmpsi"
947: [(set (cc0)
948: (compare (match_operand:SI 0 "register_operand" "r")
949: (match_operand:SI 1 "arm_rhs_operand" "rI")))]
950: ""
951: "*
952: return (arm_output_asm_insn (\"cmp\\t%0, %1\", operands));
953: ")
954:
955: (define_insn "tstsi"
956: [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
957: ""
958: "*
959: return (arm_output_asm_insn (\"cmp\\t%0, #0\", operands));
960: ")
961:
962: (define_insn ""
963: [(set (cc0)
964: (compare (match_operand:SI 0 "register_operand" "r")
965: (neg:SI (match_operand:SI 1 "arm_rhs_operand" "rI"))))]
966: ""
967: "*
968: return (arm_output_asm_insn (\"cmn\\t%0, %1\", operands));
969: ")
970:
971: (define_insn "cmpsf"
972: [(set (cc0)
973: (compare (match_operand:SF 0 "register_operand" "f")
974: (match_operand:SF 1 "fpu_rhs_operand" "fG")))]
975: ""
976: "*
977: return (arm_output_asm_insn (\"cmf\\t%0, %1\", operands));
978: ")
979:
980: (define_insn "cmpdf"
981: [(set (cc0)
982: (compare (match_operand:DF 0 "register_operand" "f")
983: (match_operand:DF 1 "fpu_rhs_operand" "fG")))]
984: ""
985: "*
986: return (arm_output_asm_insn (\"cmf\\t%0, %1\", operands));
987: ")
988:
989: ;; Conditional branch insns
990:
991: (define_insn "beq"
992: [(set (pc)
993: (if_then_else (eq (cc0) (const_int 0))
994: (label_ref (match_operand 0 "" ""))
995: (pc)))]
996: ""
997: "*
998: return (arm_output_asm_insn (\"beq\\t%l0\", operands));
999: ")
1000:
1001: (define_insn "bne"
1002: [(set (pc)
1003: (if_then_else (ne (cc0) (const_int 0))
1004: (label_ref (match_operand 0 "" ""))
1005: (pc)))]
1006: ""
1007: "*
1008: return (arm_output_asm_insn (\"bne\\t%l0\", operands));
1009: ")
1010:
1011: (define_insn "bgt"
1012: [(set (pc)
1013: (if_then_else (gt (cc0) (const_int 0))
1014: (label_ref (match_operand 0 "" ""))
1015: (pc)))]
1016: ""
1017: "*
1018: return (arm_output_asm_insn (\"bgt\\t%l0\", operands));
1019: ")
1020:
1021: (define_insn "ble"
1022: [(set (pc)
1023: (if_then_else (le (cc0) (const_int 0))
1024: (label_ref (match_operand 0 "" ""))
1025: (pc)))]
1026: ""
1027: "*
1028: return (arm_output_asm_insn (\"ble\\t%l0\", operands));
1029: ")
1030:
1031: (define_insn "bge"
1032: [(set (pc)
1033: (if_then_else (ge (cc0) (const_int 0))
1034: (label_ref (match_operand 0 "" ""))
1035: (pc)))]
1036: ""
1037: "*
1038: return (arm_output_asm_insn (\"bge\\t%l0\", operands));
1039: ")
1040:
1041: (define_insn "blt"
1042: [(set (pc)
1043: (if_then_else (lt (cc0) (const_int 0))
1044: (label_ref (match_operand 0 "" ""))
1045: (pc)))]
1046: ""
1047: "*
1048: return (arm_output_asm_insn (\"blt\\t%l0\", operands));
1049: ")
1050:
1051: (define_insn "bgtu"
1052: [(set (pc)
1053: (if_then_else (gtu (cc0) (const_int 0))
1054: (label_ref (match_operand 0 "" ""))
1055: (pc)))]
1056: ""
1057: "*
1058: return (arm_output_asm_insn (\"bhi\\t%l0\", operands));
1059: ")
1060:
1061: (define_insn "bleu"
1062: [(set (pc)
1063: (if_then_else (leu (cc0) (const_int 0))
1064: (label_ref (match_operand 0 "" ""))
1065: (pc)))]
1066: ""
1067: "*
1068: return (arm_output_asm_insn (\"bls\\t%l0\", operands));
1069: ")
1070:
1071: (define_insn "bgeu"
1072: [(set (pc)
1073: (if_then_else (geu (cc0) (const_int 0))
1074: (label_ref (match_operand 0 "" ""))
1075: (pc)))]
1076: ""
1077: "*
1078: return (arm_output_asm_insn (\"bhs\\t%l0\", operands));
1079: ")
1080:
1081: (define_insn "bltu"
1082: [(set (pc)
1083: (if_then_else (ltu (cc0) (const_int 0))
1084: (label_ref (match_operand 0 "" ""))
1085: (pc)))]
1086: ""
1087: "*
1088: return (arm_output_asm_insn (\"blo\\t%l0\", operands));
1089: ")
1090:
1091: ;; Inverted conditional branch insns
1092:
1093: (define_insn ""
1094: [(set (pc)
1095: (if_then_else (eq (cc0) (const_int 0))
1096: (pc)
1097: (label_ref (match_operand 0 "" ""))))]
1098: ""
1099: "*
1100: return (arm_output_asm_insn (\"bne\\t%l0\", operands));
1101: ")
1102:
1103: (define_insn ""
1104: [(set (pc)
1105: (if_then_else (ne (cc0) (const_int 0))
1106: (pc)
1107: (label_ref (match_operand 0 "" ""))))]
1108: ""
1109: "*
1110: return (arm_output_asm_insn (\"beq\\t%l0\", operands));
1111: ")
1112:
1113: (define_insn ""
1114: [(set (pc)
1115: (if_then_else (gt (cc0) (const_int 0))
1116: (pc)
1117: (label_ref (match_operand 0 "" ""))))]
1118: ""
1119: "*
1120: return (arm_output_asm_insn (\"ble\\t%l0\", operands));
1121: ")
1122:
1123: (define_insn ""
1124: [(set (pc)
1125: (if_then_else (le (cc0) (const_int 0))
1126: (pc)
1127: (label_ref (match_operand 0 "" ""))))]
1128: ""
1129: "*
1130: return (arm_output_asm_insn (\"bgt\\t%l0\", operands));
1131: ")
1132:
1133: (define_insn ""
1134: [(set (pc)
1135: (if_then_else (ge (cc0) (const_int 0))
1136: (pc)
1137: (label_ref (match_operand 0 "" ""))))]
1138: ""
1139: "*
1140: return (arm_output_asm_insn (\"blt\\t%l0\", operands));
1141: ")
1142:
1143: (define_insn ""
1144: [(set (pc)
1145: (if_then_else (lt (cc0) (const_int 0))
1146: (pc)
1147: (label_ref (match_operand 0 "" ""))))]
1148: ""
1149: "*
1150: return (arm_output_asm_insn (\"bge\\t%l0\", operands));
1151: ")
1152:
1153: (define_insn ""
1154: [(set (pc)
1155: (if_then_else (gtu (cc0) (const_int 0))
1156: (pc)
1157: (label_ref (match_operand 0 "" ""))))]
1158: ""
1159: "*
1160: return (arm_output_asm_insn (\"bls\\t%l0\", operands));
1161: ")
1162:
1163: (define_insn ""
1164: [(set (pc)
1165: (if_then_else (leu (cc0) (const_int 0))
1166: (pc)
1167: (label_ref (match_operand 0 "" ""))))]
1168: ""
1169: "*
1170: return (arm_output_asm_insn (\"bhi\\t%l0\", operands));
1171: ")
1172:
1173: (define_insn ""
1174: [(set (pc)
1175: (if_then_else (geu (cc0) (const_int 0))
1176: (pc)
1177: (label_ref (match_operand 0 "" ""))))]
1178: ""
1179: "*
1180: return (arm_output_asm_insn (\"blo\\t%l0\", operands));
1181: ")
1182:
1183: (define_insn ""
1184: [(set (pc)
1185: (if_then_else (ltu (cc0) (const_int 0))
1186: (pc)
1187: (label_ref (match_operand 0 "" ""))))]
1188: ""
1189: "*
1190: return (arm_output_asm_insn (\"bhs\\t%l0\", operands));
1191: ")
1192:
1193: ;; Jump and linkage insns
1194: ;; `return' is still a jump-to-epilogue...
1195:
1196: (define_insn "jump"
1197: [(set (pc)
1198: (label_ref (match_operand 0 "" "")))]
1199: ""
1200: "*
1201: return (arm_output_asm_insn (\"b\\t%l0\", operands));
1202: ")
1203:
1204: (define_insn "call"
1205: [(call (match_operand 0 "memory_operand" "m")
1206: (match_operand 1 "general_operand" "g"))
1207: (clobber (reg:SI 14))]
1208: ""
1209: "*
1210: return (output_call (operands));
1211: ")
1212:
1213: (define_insn "call_value"
1214: [(set (match_operand 0 "" "rf")
1215: (call (match_operand 1 "memory_operand" "m")
1216: (match_operand 2 "general_operand" "g")))
1217: (clobber (reg:SI 14))]
1218: ""
1219: "*
1220: return (output_call (&operands[1]));
1221: ")
1222:
1223: ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
1224: ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
1225:
1226: (define_insn ""
1227: [(call (mem:SI (match_operand:SI 0 "" "i"))
1228: (match_operand:SI 1 "general_operand" "g"))
1229: (clobber (reg:SI 14))]
1230: "GET_CODE (operands[0]) == SYMBOL_REF"
1231: "*
1232: return (arm_output_asm_insn (\"bl\\t%a0\", operands));
1233: ")
1234:
1235: (define_insn ""
1236: [(set (match_operand 0 "register_operand" "=rf")
1237: (call (mem:SI (match_operand:SI 1 "" "i"))
1238: (match_operand:SI 2 "general_operand" "g")))
1239: (clobber (reg:SI 14))]
1240: "GET_CODE(operands[1]) == SYMBOL_REF"
1241: "*
1242: return (arm_output_asm_insn (\"bl\\t%a1\", operands));
1243: ")
1244:
1245: (define_insn "tablejump"
1246: [(set (pc)
1247: (match_operand:SI 0 "register_operand" "r"))
1248: (use (label_ref (match_operand 1 "" "")))]
1249: ""
1250: "*
1251: return (arm_output_asm_insn (\"mov\\tpc, %0\\t@ table jump, label %l1\", operands));
1252: ")
1253:
1254: (define_insn "indirect_jump"
1255: [(set (pc)
1256: (match_operand:SI 0 "register_operand" "r"))]
1257: ""
1258: "*
1259: return (arm_output_asm_insn (\"mov\\tpc, %0\\t@ indirect jump\", operands));
1260: ")
1261:
1262: ;; Misc insns
1263:
1264: (define_insn "nop"
1265: [(const_int 0)]
1266: ""
1267: "*
1268: return (arm_output_asm_insn (\"mov\\tr0, r0\\t@ nop\", operands));
1269: ")
1270:
1271: ;; Patterns to allow combination of arithmetic, cond code and shifts
1272:
1273: ;(define_insn ""
1274: ; [(set (match_operand:SI 0 "register_operand" "=r")
1275: ; (match_operator:SI 1 "shiftable_operator"
1276: ; [(match_operand:SI 2 "register_operand" "r")
1277: ; (match_operator:SI 3 "shift_operator"
1278: ; [(match_operand:SI 4 "register_operand" "r")
1279: ; (match_operand:SI 5 "nonmemory_operand" "rn")])]))]
1280: ; ""
1281: ; "*
1282: ; return (output_arithmetic_with_shift (operands, FALSE, FALSE));
1283: ; "
1284: ;)
1285:
1286: ;(define_insn ""
1287: ; [(set (match_operand:SI 0 "register_operand" "=r")
1288: ; (match_operator:SI 1 "shiftable_operator"
1289: ; [(match_operator:SI 3 "shift_operator"
1290: ; [(match_operand:SI 4 "register_operand" "r")
1291: ; (match_operand:SI 5 "nonmemory_operand" "rI")])
1292: ; (match_operand:SI 2 "register_operand" "r")]))]
1293: ; ""
1294: ; "*
1295: ; return (output_arithmetic_with_shift (operands, TRUE, FALSE));
1296: ;")
1297:
1298: ;; Patterns to allow combination of arithmetic and multiplication
1299:
1300: ;(define_insn ""
1301: ; [(set (match_operand:SI 0 "register_operand" "=r")
1302: ; (match_operator:SI 1 "shiftable_operator"
1303: ; [(match_operand:SI 2 "register_operand" "r")
1304: ; (mult:SI
1305: ; (match_operand:SI 3 "register_operand" "r")
1306: ; (match_operand:SI 4 "power_of_two_operand" "n"))]))]
1307: ; ""
1308: ; "*
1309: ; return (output_arithmetic_with_immediate_multiply (operands, FALSE));
1310: ;")
1311:
1312: ; Uncomment this to show combiner problem (see ../COMBINER-PROBLEM).
1313: ;(define_insn ""
1314: ; [(set (match_operand:SI 0 "register_operand" "=r")
1315: ; (match_operator:SI 1 "shiftable_operator"
1316: ; [(mult:SI
1317: ; (match_operand:SI 3 "register_operand" "r")
1318: ; (match_operand:SI 4 "power_of_two_operand" "n"))
1319: ; (match_operand:SI 2 "register_operand" "r")]))]
1320: ; ""
1321: ; "*
1322: ; return (output_arithmetic_with_immediate_multiply (operands, TRUE));
1323: ;")
1324:
1325: ;; Peephole optimizations.
1326:
1327: ;; When testing a bitset smaller than 9 bits for (un)equality, a
1328: ;; shift/and/cmp/b{eq,ne} sequence can be replaced by one tst and the same
1329: ;; branch sequence.
1330:
1331: ;;(define_peephole
1332: ;; [(set (match_operand:SI 0 "register_operand" "=r")
1333: ;; (lshiftrt:SI (match_dup 0)
1334: ;; (match_operand 1 "immediate_operand" "")))
1335: ;; (set (match_dup 0)
1336: ;; (and:SI (match_dup 0)
1337: ;; (match_operand 2 "immediate_operand" "")))
1338: ;; (set (cc0) (match_dup 0))
1339: ;; (set (pc)
1340: ;; (if_then_else (ne (cc0) (const_int 0))
1341: ;; (label_ref (match_operand 3 "" ""))
1342: ;; (pc)))]
1343: ;; "dead_or_set_p (PREV_INSN (insn), operands[0])
1344: ;; && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT
1345: ;; && const_ok_for_arm (INTVAL (operands[2]) << INTVAL (operands[1]))"
1346: ;; "*
1347: ;; operands[2] = gen_rtx (CONST_INT, VOIDmode,
1348: ;; INTVAL (operands[2]) << INTVAL (operands[1]));
1349: ;; arm_output_asm_insn (\"tst\\t%0, %2\\t\\t@ ph test bitfield\", operands);
1350: ;; return (arm_output_asm_insn (\"bne\\t%l3\", operands));
1351: ;;")
1352:
1353: ;;(define_peephole
1354: ;; [(set (match_operand:SI 0 "register_operand" "=r")
1355: ;; (lshiftrt:SI (match_dup 0)
1356: ;; (match_operand 1 "immediate_operand" "")))
1357: ;; (set (match_dup 0)
1358: ;; (and:SI (match_dup 0)
1359: ;; (match_operand 2 "immediate_operand" "")))
1360: ;; (set (cc0) (match_dup 0))
1361: ;; (set (pc)
1362: ;; (if_then_else (ne (cc0) (const_int 0))
1363: ;; (pc)
1364: ;; (label_ref (match_operand 3 "" ""))))]
1365: ;; "dead_or_set_p (prev_real_insn (insn), operands[0])
1366: ;; && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT
1367: ;; && const_ok_for_arm (INTVAL (operands[2]) << INTVAL (operands[1]))"
1368: ;; "*
1369: ;; operands[2] = gen_rtx (CONST_INT, VOIDmode,
1370: ;; INTVAL (operands[2]) << INTVAL (operands[1]));
1371: ;; arm_output_asm_insn (\"tst\\t%0, %2\\t\\t@ ph test bitfield\", operands);
1372: ;; return (arm_output_asm_insn (\"beq\\t%l3\", operands));
1373: ;;")
1374:
1375: ;; This allows negative constants to be compared since GCC appears not to try
1376: ;; converting them with a NEG.
1377:
1378: ;;(define_peephole
1379: ;; [(set (match_operand:SI 2 "register_operand" "=r")
1380: ;; (match_operand:SI 1 "immediate_operand" "n"))
1381: ;; (set (cc0)
1382: ;; (compare (match_operand:SI 0 "register_operand" "r")
1383: ;; (match_dup 1)))]
1384: ;; "const_ok_for_arm (-INTVAL (operands[1]))
1385: ;; && dead_or_set_p (prev_real_insn (insn), operands[0])"
1386: ;; "*
1387: ;; operands[1] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1]));
1388: ;; return (arm_output_asm_insn (\"cmn\\t%0, %1\\t\\t@ ph negate comparison\", operands));
1389: ;;")
1390:
1391: ;; Local variables:
1392: ;; mode:emacs-lisp
1393: ;; eval: (setq comment-start ";; ")
1394: ;; eval: (setq comment-end "")
1395: ;; eval: (setq comment-start-skip ";;+ *")
1396: ;; eval: (set-syntax-table (copy-sequence (syntax-table)))
1397: ;; eval: (modify-syntax-entry ?[ "(]")
1398: ;; eval: (modify-syntax-entry ?] ")[")
1399: ;; eval: (modify-syntax-entry ?{ "(}")
1400: ;; eval: (modify-syntax-entry ?} "){")
1401: ;; End:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.