|
|
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"
1.1.1.3 ! root 33: [(set (match_operand:DI 0 "di_operand" "=&r")
1.1 root 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")
1.1.1.3 ! root 44: (plus:SI (match_operand:SI 1 "register_operand" "r,r")
! 45: (match_operand:SI 2 "general_operand" "r,n")))]
1.1 root 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")
1.1.1.3 ! root 59: (plus:SF (match_operand:SF 1 "register_operand" "f")
! 60: (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
1.1 root 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")
1.1.1.3 ! root 68: (plus:DF (match_operand:DF 1 "register_operand" "f")
! 69: (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
1.1 root 70: ""
71: "*
72: return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
73: ")
74:
75: (define_insn "subdi3"
1.1.1.3 ! root 76: [(set (match_operand:DI 0 "di_operand" "=&r")
1.1 root 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")
1.1.1.3 ! root 87: (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
! 88: (match_operand:SI 2 "general_operand" "r,n,r")))]
1.1 root 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")
1.1.1.3 ! root 105: (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
! 106: (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
1.1 root 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")
1.1.1.3 ! root 120: (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
1.1 root 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")
1.1.1.3 ! root 138: (mult:SI (match_operand:SI 1 "register_operand" "%r")
! 139: (match_operand:SI 2 "register_operand" "r")))]
1.1 root 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")
1.1.1.3 ! root 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")))]
1.1 root 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")
1.1.1.3 ! root 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"))))]
1.1 root 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")
1.1.1.3 ! root 180: (mult:SF (match_operand:SF 1 "register_operand" "f")
! 181: (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
1.1 root 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")
1.1.1.3 ! root 187: (mult:DF (match_operand:DF 1 "register_operand" "f")
! 188: (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
1.1 root 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")
1.1.1.3 ! root 198: (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
! 199: (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
1.1 root 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")
1.1.1.3 ! root 213: (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
! 214: (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
1.1 root 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")
1.1.1.3 ! root 230: (mod:SF (match_operand:SF 1 "register_operand" "f")
! 231: (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
1.1 root 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")
1.1.1.3 ! root 239: (mod:DF (match_operand:DF 1 "register_operand" "f")
! 240: (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
1.1 root 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"
1.1.1.3 ! root 249: [(set (match_operand:DI 0 "di_operand" "=&r")
1.1 root 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")
1.1.1.3 ! root 260: (and:SI (match_operand:SI 1 "register_operand" "r")
! 261: (match_operand:SI 2 "arm_rhs_operand" "rI")))]
1.1 root 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")
1.1.1.3 ! root 269: (and:SI (match_operand:SI 1 "register_operand" "r")
! 270: (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
1.1 root 271: ""
272: "*
273: return (arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands));
274: ")
275:
276: (define_insn "iordi3"
1.1.1.3 ! root 277: [(set (match_operand:DI 0 "di_operand" "=&r")
1.1 root 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")
1.1.1.3 ! root 288: (ior:SI (match_operand:SI 1 "register_operand" "r,r")
! 289: (match_operand:SI 2 "nonmemory_operand" "r,n")))]
1.1 root 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")
1.1.1.3 ! root 305: (xor:SI (match_operand:SI 1 "register_operand" "r,r")
! 306: (match_operand:SI 2 "nonmemory_operand" "r,n")))]
1.1 root 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\",
1.1.1.3 ! root 316: 2, INTVAL (operands[2])));
1.1 root 317: }
318: ")
319:
320: ;; Shift and rotation insns
321:
322: (define_insn "ashlsi3"
323: [(set (match_operand:SI 0 "register_operand" "=r")
1.1.1.3 ! root 324: (ashift:SI (match_operand:SI 1 "register_operand" "r")
! 325: (match_operand:SI 2 "general_operand" "rn")))]
1.1 root 326: ""
327: "*
328: return (output_shifted_move (ASHIFT, operands));
329: ")
330:
331: (define_insn "ashrsi3"
332: [(set (match_operand:SI 0 "register_operand" "=r")
1.1.1.3 ! root 333: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
! 334: (match_operand:SI 2 "general_operand" "rn")))]
1.1 root 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")
1.1.1.3 ! root 345: (lshift:SI (match_operand:SI 1 "register_operand" "r")
! 346: (match_operand:SI 2 "general_operand" "rn")))]
1.1 root 347: ""
348: "*
349: return (output_shifted_move (LSHIFT, operands));
350: ")
351:
352: (define_insn "lshrsi3"
353: [(set (match_operand:SI 0 "register_operand" "=r")
1.1.1.3 ! root 354: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
! 355: (match_operand:SI 2 "general_operand" "rn")))]
1.1 root 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")
1.1.1.3 ! root 365: (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
! 366: (match_operand:SI 2 "general_operand" "r,n")))]
1.1 root 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)
1.1.1.3 ! root 375: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 32);
1.1 root 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"
1.1.1.3 ! root 383: [(set (match_operand:DI 0 "di_operand" "=&r")
! 384: (neg:DI (match_operand:DI 1 "di_operand" "r")))]
1.1 root 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")
1.1.1.3 ! root 393: (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1.1 root 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")
1.1.1.3 ! root 401: (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1.1 root 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")
1.1.1.3 ! root 409: (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1.1 root 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")
1.1.1.3 ! root 417: (abs:SF (match_operand:SF 1 "register_operand" "f")))]
1.1 root 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")
1.1.1.3 ! root 425: (abs:DF (match_operand:DF 1 "register_operand" "f")))]
1.1 root 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")
1.1.1.3 ! root 433: (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
1.1 root 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")
1.1.1.3 ! root 441: (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
1.1 root 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")
1.1.1.3 ! root 449: (not:SI (match_operand:SI 1 "register_operand" "r")))]
1.1 root 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")
1.1.1.3 ! root 459: (float:SF (match_operand:SI 1 "register_operand" "r")))]
1.1 root 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")
1.1.1.3 ! root 467: (float:DF (match_operand:SI 1 "register_operand" "r")))]
1.1 root 468: ""
469: "*
470: return (arm_output_asm_insn (\"fltd\\t%0, %1\", operands));
471: ")
472:
1.1.1.3 ! root 473: ;; Truncation insns
1.1 root 474:
475: (define_insn "truncdfsf2"
476: [(set (match_operand:SF 0 "register_operand" "=f")
1.1.1.3 ! root 477: (float_truncate:SF
! 478: (match_operand:DF 1 "register_operand" "f")))]
1.1 root 479: ""
480: "*
481: return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands));
482: ")
483:
1.1.1.2 root 484: ;; Zero extension instructions.
1.1 root 485:
486: (define_expand "zero_extendhisi2"
1.1.1.3 ! root 487: [(set (match_dup 2)
1.1 root 488: (ashift:SI (match_operand:HI 1 "register_operand" "")
489: (const_int 16)))
1.1.1.3 ! root 490: (set (match_operand:SI 0 "register_operand" "")
! 491: (lshiftrt:SI (match_dup 2)
! 492: (const_int 16)))]
1.1 root 493: ""
494: "
1.1.1.3 ! root 495: { operands[1] = gen_lowpart (SImode, operands[1]);
! 496: operands[2] = gen_reg_rtx (SImode); }")
1.1 root 497:
498: (define_insn "zero_extendqihi2"
499: [(set (match_operand:HI 0 "register_operand" "=r")
1.1.1.3 ! root 500: (zero_extend:HI
1.1 root 501: (match_operand:QI 1 "register_operand" "r")))]
502: ""
503: "*
504: return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqihi2\", operands));
505: ")
506:
507: (define_insn "zero_extendqisi2"
508: [(set (match_operand:SI 0 "register_operand" "=r,r")
1.1.1.3 ! root 509: (zero_extend:SI
1.1 root 510: (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
511: ""
512: "*
513: switch (which_alternative)
514: {
515: case 0:
516: return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqisi2\", operands));
517: case 1:
518: return (arm_output_asm_insn (\"ldrb\\t%0, %1\\t@ zero_extendqisi2\", operands));
519: }
520: ")
521:
522: (define_expand "extendhisi2"
1.1.1.3 ! root 523: [(set (match_dup 2)
1.1 root 524: (ashift:SI (match_operand:HI 1 "register_operand" "")
525: (const_int 16)))
1.1.1.3 ! root 526: (set (match_operand:SI 0 "register_operand" "")
! 527: (ashiftrt:SI (match_dup 2)
! 528: (const_int 16)))]
1.1 root 529: ""
530: "
1.1.1.3 ! root 531: { operands[1] = gen_lowpart (SImode, operands[1]);
! 532: operands[2] = gen_reg_rtx (SImode); }")
1.1 root 533:
1.1.1.3 ! root 534: (define_expand "extendqihi2"
! 535: [(set (match_dup 2)
! 536: (ashift:SI (match_operand:QI 1 "register_operand" "")
! 537: (const_int 24)))
! 538: (set (match_operand:HI 0 "register_operand" "")
! 539: (ashiftrt:SI (match_dup 2)
! 540: (const_int 24)))]
1.1 root 541: ""
1.1.1.3 ! root 542: "
! 543: { operands[0] = gen_lowpart (SImode, operands[0]);
! 544: operands[1] = gen_lowpart (SImode, operands[1]);
! 545: operands[2] = gen_reg_rtx (SImode); }")
1.1 root 546:
547: (define_expand "extendqisi2"
1.1.1.3 ! root 548: [(set (match_dup 2)
1.1 root 549: (ashift:SI (match_operand:QI 1 "register_operand" "")
550: (const_int 24)))
1.1.1.3 ! root 551: (set (match_operand:SI 0 "register_operand" "")
! 552: (ashiftrt:SI (match_dup 2)
! 553: (const_int 24)))]
1.1 root 554: ""
555: "
1.1.1.3 ! root 556: { operands[1] = gen_lowpart (SImode, operands[1]);
! 557: operands[2] = gen_reg_rtx (SImode); }")
1.1 root 558:
559: (define_insn "extendsfdf2"
560: [(set (match_operand:DF 0 "register_operand" "=f")
1.1.1.3 ! root 561: (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
1.1 root 562: ""
563: "*
564: return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands));
565: ")
566:
567: ;; Move insns (including loads and stores)
568:
569: ;; XXX Just some ideas about movti.
570:
571: ;;(define_expand "loadti"
572: ;; [(set (match_operand:TI 0 "register_operand" "")
573: ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
574: ;; "" "")
575:
576: ;;(define_expand "storeti"
577: ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
578: ;; (match_operand:TI 1 "register_operand" ""))]
579: ;; "" "")
580:
581: ;;(define_expand "movti"
582: ;; [(set (match_operand:TI 0 "general_operand" "")
583: ;; (match_operand:TI 1 "general_operand" ""))]
584: ;; ""
585: ;; "
586: ;;{
587: ;; rtx insn;
588: ;;
589: ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
590: ;; operands[1] = copy_to_reg (operands[1]);
591: ;; if (GET_CODE (operands[0]) == MEM)
592: ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
593: ;; else if (GET_CODE (operands[1]) == MEM)
594: ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
595: ;; else
596: ;; FAIL;
597: ;;
598: ;; emit_insn (insn);
599: ;; DONE;
600: ;;}")
601:
602: ;; Recognise garbage generated above.
603:
604: ;;(define_insn ""
605: ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
606: ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
607: ;; ""
608: ;; "*
609: ;; {
610: ;; register mem = (which_alternative < 3);
611: ;; register char *template;
612: ;;
613: ;; operands[mem] = XEXP (operands[mem], 0);
614: ;; switch (which_alternative)
615: ;; {
616: ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
617: ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
618: ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
619: ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
620: ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
621: ;; case 5: template = \"stmia\\t%0, %M1\"; break;
622: ;; }
623: ;; return (arm_output_asm_insn (template, operands));
624: ;; }")
625:
626:
627: (define_insn "movdi"
628: [(set (match_operand:DI 0 "di_operand" "=r,r,r,o,r")
1.1.1.3 ! root 629: (match_operand:DI 1 "di_operand" "r,n,o,r,F"))]
1.1 root 630: ""
631: "*
632: return (output_move_double (operands));
633: ")
634:
635: (define_insn "movsi"
636: [(set (match_operand:SI 0 "general_operand" "=r,r,r,m")
1.1.1.3 ! root 637: (match_operand:SI 1 "general_operand" "r,n,m,r"))]
1.1 root 638: ""
639: "*
640: switch (which_alternative)
641: {
642: case 0:
643: return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
644: case 1:
645: return (output_mov_immediate (operands));
646: case 2:
647: if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1.1.1.3 ! root 648: && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
1.1 root 649: return (arm_output_llc (operands));
650: else
1.1.1.3 ! root 651: return (arm_output_asm_insn (\"ldr\\t%0, %1\", operands));
1.1 root 652: case 3:
653: return (arm_output_asm_insn (\"str\\t%1, %0\", operands));
654: }
655: ")
656:
657: ;; XXX The movhi stuff isn't as correct or as nice as it could be...
658:
659: ;; Subroutine to load a half word into a register from memory.
660: ;; Operand 0 is the destination register (HImode).
661: ;; Operand 1 is the source address (SImode).
662: ;; Operand 2 is a temporary (SImode).
663:
664: ;;(define_expand "loadhi"
665: ;; [;; load the whole word (ARM realigns it if not on word boundary)
666: ;; (set (match_operand:SI 2 "register_operand" "")
667: ;; (mem:SI (match_operand:SI 1 "address_operand" "")))
668: ;; ;; quietly forget the upper 16 bits
669: ;; (set (match_operand:HI 0 "register_operand" "")
670: ;; (subreg:HI (match_dup 2) 0))]
671: ;; ""
672: ;; ""
673: ;;)
674:
675: ;; Load op0 from mem:op1. Subroutine in case we're reloading and the normal
676: ;; loadhi is not allowed.
677:
678: ;;(define_expand "reloadhi"
679: ;; [(set (reg:SI 10)
680: ;; (mem:SI (match_operand:SI 1 "address_operand" "")))
681: ;; (set (match_operand:HI 0 "register_operand" "")
682: ;; (subreg:HI (reg:SI 10) 0))]
683: ;; "" "")
684:
685: ;; Store op0 into mem:op1. Subroutine in case we're reloading and the normal
686: ;; storehi is not allowed.
687:
688: (define_expand "restorehi"
1.1.1.3 ! root 689: [(set (mem:QI (match_operand 1 "" ""))
! 690: (match_dup 2))
! 691: (set (reg:SI 10)
! 692: (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
1.1 root 693: (set (mem:QI (plus:SI (match_dup 1) (const_int 1)))
1.1.1.3 ! root 694: (reg:QI 10))]
! 695: ""
! 696: "
! 697: {
! 698: operands[2] = gen_lowpart (QImode, operands[0]);
! 699: operands[0] = gen_lowpart (SImode, operands[0]);
! 700: }")
1.1 root 701:
702: ;; Subroutine to store a half word from a register into memory.
703: ;; Operand 0 is the source register (HImode)
1.1.1.3 ! root 704: ;; Operand 1 is the destination address in a register (SImode)
1.1 root 705:
706: (define_expand "storehi"
1.1.1.3 ! root 707: [;; store the low byte
! 708: (set (mem:QI (match_operand 1 "" "")) (match_dup 3))
1.1 root 709: ;; extract the high byte
1.1.1.3 ! root 710: (set (match_dup 2)
! 711: (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
1.1 root 712: ;; store the high byte
1.1.1.3 ! root 713: (set (mem:QI (plus (match_dup 1) (const_int 1)))
! 714: (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
1.1 root 715: ""
716: "
1.1.1.3 ! root 717: { operands[3] = gen_lowpart (QImode, operands[0]);
! 718: operands[0] = gen_lowpart (SImode, operands[0]);
! 719: operands[2] = gen_reg_rtx (SImode); }")
1.1 root 720:
721: ;; Subroutine to store a half word integer constant into memory.
722: ;; Operand 0 is the constant
1.1.1.3 ! root 723: ;; Operand 1 is the destination address in a register (SImode)
1.1 root 724:
725: (define_expand "storeinthi"
1.1.1.3 ! root 726: [;; store the low byte
! 727: (set (mem:QI (match_operand 1 "" "")) (match_operand 0 "" ""))
1.1 root 728: ;; store the high byte
1.1.1.3 ! root 729: (set (mem:QI (plus (match_dup 1) (const_int 1)))
! 730: (match_dup 2))]
1.1 root 731: ""
732: "
733: {
1.1.1.3 ! root 734: int value = INTVAL (operands[0]);
1.1 root 735:
1.1.1.3 ! root 736: operands[0] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode, value & 255));
! 737: operands[2] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode,(value>>8) & 255));
1.1 root 738: }
739: ")
740:
741: (define_expand "movhi"
742: [(set (match_operand:HI 0 "general_operand" "")
1.1.1.3 ! root 743: (match_operand:HI 1 "general_operand" ""))]
1.1 root 744: ""
745: "
746: {
747: rtx insn;
748:
749: if (reload_in_progress || reload_completed)
750: {
751: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == REG)
752: insn = gen_restorehi (operands[1], XEXP (operands[0], 0));
753: else
754: insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
755: }
756: else
757: {
758: if (GET_CODE (operands[0]) == MEM)
759: {
760: if (GET_CODE (operands[1]) == CONST_INT)
761: {
1.1.1.3 ! root 762: insn = gen_storeinthi (operands[1], force_reg (SImode, XEXP (operands[0], 0)));
1.1 root 763: }
764: else
765: {
1.1.1.3 ! root 766: if (GET_CODE (operands[1]) == MEM)
! 767: operands[1] = copy_to_reg (operands[1]);
! 768: insn = gen_storehi (operands[1], force_reg (SImode, XEXP (operands[0], 0)));
1.1 root 769: }
770: }
771: #if 0
772: else if (GET_CODE (operands[1]) == MEM)
773: {
774: insn = gen_loadhi (operands[0], XEXP (operands[1], 0),
775: gen_reg_rtx (SImode));
776: }
777: #endif
778: else
779: insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
780: }
781:
782: emit_insn (insn);
783: DONE;
784: }")
785:
786: ;; Pattern to recognise insn generated default case above
787:
788: (define_insn ""
789: [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
1.1.1.3 ! root 790: (match_operand:HI 1 "general_operand" "r,n,m,r"))]
1.1 root 791: ""
792: "*
793: switch (which_alternative)
794: {
795: case 0: return (arm_output_asm_insn (\"mov\\t%0, %1\\t@movhi\", operands));
796: case 1: return (output_mov_immediate (operands));
797: case 2: return (arm_output_asm_insn (\"ldr\\t%0, %1\\t@movhi\", operands));
798: case 3: return (arm_output_asm_insn (\"str\\t%1, %0\\t@movhi\", operands));
799: }
800: ")
801:
802: (define_insn "movqi"
803: [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
1.1.1.3 ! root 804: (match_operand:QI 1 "general_operand" "r,n,m,r"))]
1.1 root 805: ""
806: "*
807: switch (which_alternative)
808: {
809: case 0:
810: return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
811: case 1:
812: return (output_mov_immediate (operands));
813: case 2:
814: return (arm_output_asm_insn (\"ldrb\\t%0, %1\", operands));
815: case 3:
816: return (arm_output_asm_insn (\"strb\\t%1, %0\", operands));
817: }
818: ")
819:
820: (define_insn "movsf"
821: [(set (match_operand:SF 0 "general_operand" "=f,f,m,f,r,r")
1.1.1.3 ! root 822: (match_operand:SF 1 "general_operand" "fG,m,f,r,f,r"))]
1.1 root 823: ""
824: "*
825: switch (which_alternative)
826: {
827: case 0:
828: return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands));
829: case 1:
830: return (arm_output_asm_insn (\"ldfs\\t%0, %1\", operands));
831: case 2:
832: return (arm_output_asm_insn (\"stfs\\t%1, %0\", operands));
833: case 3:
834: arm_output_asm_insn(\"stmfd\\tsp!, {%1}\", operands);
835: return (arm_output_asm_insn (\"ldfs\\t%0, [sp],#4\", operands));
836: case 4:
837: arm_output_asm_insn(\"stfs\\t%1, [sp,#-4]!\", operands);
838: return (arm_output_asm_insn (\"ldmfd\\tsp!, {%0}\", operands));
839: case 5:
840: return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
841: }
842: ")
843:
844: (define_insn "movdf"
845: [(set (match_operand:DF 0 "general_operand" "=f,f,m,f,r,r")
1.1.1.3 ! root 846: (match_operand:DF 1 "general_operand" "fG,m,f,r,f,r"))]
1.1 root 847: ""
848: "*
849: switch (which_alternative)
850: {
851: case 0: return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands));
852: case 1: return (arm_output_asm_insn (\"ldfd\\t%0, %1\", operands));
853: case 2: return (arm_output_asm_insn (\"stfd\\t%1, %0\", operands));
854: case 3: return (output_mov_double_fpu_from_arm (operands));
855: case 4: return (output_mov_double_arm_from_fpu (operands));
856: case 5: return (output_move_double (operands));
857: }
858: ")
859:
860: ;; Comparison and test insns
861:
862: (define_insn "cmpsi"
863: [(set (cc0)
1.1.1.3 ! root 864: (compare (match_operand:SI 0 "register_operand" "r")
1.1 root 865: (match_operand:SI 1 "arm_rhs_operand" "rI")))]
866: ""
867: "*
868: return (arm_output_asm_insn (\"cmp\\t%0, %1\", operands));
869: ")
870:
871: (define_insn "tstsi"
872: [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
873: ""
874: "*
875: return (arm_output_asm_insn (\"cmp\\t%0, #0\", operands));
876: ")
877:
878: (define_insn ""
879: [(set (cc0)
1.1.1.3 ! root 880: (compare (match_operand:SI 0 "register_operand" "r")
! 881: (neg:SI (match_operand:SI 1 "arm_rhs_operand" "rI"))))]
1.1 root 882: ""
883: "*
884: return (arm_output_asm_insn (\"cmn\\t%0, %1\", operands));
885: ")
886:
887: (define_insn "cmpsf"
888: [(set (cc0)
1.1.1.3 ! root 889: (compare (match_operand:SF 0 "register_operand" "f")
1.1 root 890: (match_operand:SF 1 "fpu_rhs_operand" "fG")))]
891: ""
892: "*
893: return (arm_output_asm_insn (\"cmf\\t%0, %1\", operands));
894: ")
895:
896: (define_insn "cmpdf"
897: [(set (cc0)
1.1.1.3 ! root 898: (compare (match_operand:DF 0 "register_operand" "f")
1.1 root 899: (match_operand:DF 1 "fpu_rhs_operand" "fG")))]
900: ""
901: "*
902: return (arm_output_asm_insn (\"cmf\\t%0, %1\", operands));
903: ")
904:
905: ;; Conditional branch insns
906:
907: (define_insn "beq"
908: [(set (pc)
1.1.1.3 ! root 909: (if_then_else (eq (cc0) (const_int 0))
! 910: (label_ref (match_operand 0 "" ""))
! 911: (pc)))]
1.1 root 912: ""
913: "*
914: return (arm_output_asm_insn (\"beq\\t%l0\", operands));
915: ")
916:
917: (define_insn "bne"
918: [(set (pc)
1.1.1.3 ! root 919: (if_then_else (ne (cc0) (const_int 0))
! 920: (label_ref (match_operand 0 "" ""))
! 921: (pc)))]
1.1 root 922: ""
923: "*
924: return (arm_output_asm_insn (\"bne\\t%l0\", operands));
925: ")
926:
927: (define_insn "bgt"
928: [(set (pc)
1.1.1.3 ! root 929: (if_then_else (gt (cc0) (const_int 0))
! 930: (label_ref (match_operand 0 "" ""))
! 931: (pc)))]
1.1 root 932: ""
933: "*
934: return (arm_output_asm_insn (\"bgt\\t%l0\", operands));
935: ")
936:
937: (define_insn "ble"
938: [(set (pc)
1.1.1.3 ! root 939: (if_then_else (le (cc0) (const_int 0))
! 940: (label_ref (match_operand 0 "" ""))
! 941: (pc)))]
1.1 root 942: ""
943: "*
944: return (arm_output_asm_insn (\"ble\\t%l0\", operands));
945: ")
946:
947: (define_insn "bge"
948: [(set (pc)
1.1.1.3 ! root 949: (if_then_else (ge (cc0) (const_int 0))
! 950: (label_ref (match_operand 0 "" ""))
! 951: (pc)))]
1.1 root 952: ""
953: "*
954: return (arm_output_asm_insn (\"bge\\t%l0\", operands));
955: ")
956:
957: (define_insn "blt"
958: [(set (pc)
1.1.1.3 ! root 959: (if_then_else (lt (cc0) (const_int 0))
! 960: (label_ref (match_operand 0 "" ""))
! 961: (pc)))]
1.1 root 962: ""
963: "*
964: return (arm_output_asm_insn (\"blt\\t%l0\", operands));
965: ")
966:
967: (define_insn "bgtu"
968: [(set (pc)
1.1.1.3 ! root 969: (if_then_else (gtu (cc0) (const_int 0))
! 970: (label_ref (match_operand 0 "" ""))
! 971: (pc)))]
1.1 root 972: ""
973: "*
974: return (arm_output_asm_insn (\"bhi\\t%l0\", operands));
975: ")
976:
977: (define_insn "bleu"
978: [(set (pc)
1.1.1.3 ! root 979: (if_then_else (leu (cc0) (const_int 0))
! 980: (label_ref (match_operand 0 "" ""))
! 981: (pc)))]
1.1 root 982: ""
983: "*
984: return (arm_output_asm_insn (\"bls\\t%l0\", operands));
985: ")
986:
987: (define_insn "bgeu"
988: [(set (pc)
1.1.1.3 ! root 989: (if_then_else (geu (cc0) (const_int 0))
! 990: (label_ref (match_operand 0 "" ""))
! 991: (pc)))]
1.1 root 992: ""
993: "*
994: return (arm_output_asm_insn (\"bhs\\t%l0\", operands));
995: ")
996:
997: (define_insn "bltu"
998: [(set (pc)
1.1.1.3 ! root 999: (if_then_else (ltu (cc0) (const_int 0))
! 1000: (label_ref (match_operand 0 "" ""))
! 1001: (pc)))]
1.1 root 1002: ""
1003: "*
1004: return (arm_output_asm_insn (\"blo\\t%l0\", operands));
1005: ")
1006:
1007: ;; Inverted conditional branch insns
1008:
1009: (define_insn ""
1010: [(set (pc)
1.1.1.3 ! root 1011: (if_then_else (eq (cc0) (const_int 0))
! 1012: (pc)
! 1013: (label_ref (match_operand 0 "" ""))))]
1.1 root 1014: ""
1015: "*
1016: return (arm_output_asm_insn (\"bne\\t%l0\", operands));
1017: ")
1018:
1019: (define_insn ""
1020: [(set (pc)
1.1.1.3 ! root 1021: (if_then_else (ne (cc0) (const_int 0))
! 1022: (pc)
! 1023: (label_ref (match_operand 0 "" ""))))]
1.1 root 1024: ""
1025: "*
1026: return (arm_output_asm_insn (\"beq\\t%l0\", operands));
1027: ")
1028:
1029: (define_insn ""
1030: [(set (pc)
1.1.1.3 ! root 1031: (if_then_else (gt (cc0) (const_int 0))
! 1032: (pc)
! 1033: (label_ref (match_operand 0 "" ""))))]
1.1 root 1034: ""
1035: "*
1036: return (arm_output_asm_insn (\"ble\\t%l0\", operands));
1037: ")
1038:
1039: (define_insn ""
1040: [(set (pc)
1.1.1.3 ! root 1041: (if_then_else (le (cc0) (const_int 0))
! 1042: (pc)
! 1043: (label_ref (match_operand 0 "" ""))))]
1.1 root 1044: ""
1045: "*
1046: return (arm_output_asm_insn (\"bgt\\t%l0\", operands));
1047: ")
1048:
1049: (define_insn ""
1050: [(set (pc)
1.1.1.3 ! root 1051: (if_then_else (ge (cc0) (const_int 0))
! 1052: (pc)
! 1053: (label_ref (match_operand 0 "" ""))))]
1.1 root 1054: ""
1055: "*
1056: return (arm_output_asm_insn (\"blt\\t%l0\", operands));
1057: ")
1058:
1059: (define_insn ""
1060: [(set (pc)
1.1.1.3 ! root 1061: (if_then_else (lt (cc0) (const_int 0))
! 1062: (pc)
! 1063: (label_ref (match_operand 0 "" ""))))]
1.1 root 1064: ""
1065: "*
1066: return (arm_output_asm_insn (\"bge\\t%l0\", operands));
1067: ")
1068:
1069: (define_insn ""
1070: [(set (pc)
1.1.1.3 ! root 1071: (if_then_else (gtu (cc0) (const_int 0))
! 1072: (pc)
! 1073: (label_ref (match_operand 0 "" ""))))]
1.1 root 1074: ""
1075: "*
1076: return (arm_output_asm_insn (\"bls\\t%l0\", operands));
1077: ")
1078:
1079: (define_insn ""
1080: [(set (pc)
1.1.1.3 ! root 1081: (if_then_else (leu (cc0) (const_int 0))
! 1082: (pc)
! 1083: (label_ref (match_operand 0 "" ""))))]
1.1 root 1084: ""
1085: "*
1086: return (arm_output_asm_insn (\"bhi\\t%l0\", operands));
1087: ")
1088:
1089: (define_insn ""
1090: [(set (pc)
1.1.1.3 ! root 1091: (if_then_else (geu (cc0) (const_int 0))
! 1092: (pc)
! 1093: (label_ref (match_operand 0 "" ""))))]
1.1 root 1094: ""
1095: "*
1096: return (arm_output_asm_insn (\"blo\\t%l0\", operands));
1097: ")
1098:
1099: (define_insn ""
1100: [(set (pc)
1.1.1.3 ! root 1101: (if_then_else (ltu (cc0) (const_int 0))
! 1102: (pc)
! 1103: (label_ref (match_operand 0 "" ""))))]
1.1 root 1104: ""
1105: "*
1106: return (arm_output_asm_insn (\"bhs\\t%l0\", operands));
1107: ")
1108:
1109: ;; Jump and linkage insns
1110: ;; `return' is still a jump-to-epilogue...
1111:
1112: (define_insn "jump"
1113: [(set (pc)
1.1.1.3 ! root 1114: (label_ref (match_operand 0 "" "")))]
1.1 root 1115: ""
1116: "*
1117: return (arm_output_asm_insn (\"b\\t%l0\", operands));
1118: ")
1119:
1120: (define_insn "call"
1121: [(call (match_operand 0 "memory_operand" "m")
1.1.1.3 ! root 1122: (match_operand 1 "general_operand" "g"))
1.1 root 1123: (clobber (reg:SI 14))]
1124: ""
1125: "*
1126: return (output_call (operands));
1127: ")
1128:
1129: (define_insn "call_value"
1.1.1.3 ! root 1130: [(set (match_operand 0 "" "=rf")
! 1131: (call (match_operand 1 "memory_operand" "m")
! 1132: (match_operand 2 "general_operand" "g")))
1.1 root 1133: (clobber (reg:SI 14))]
1134: ""
1135: "*
1136: return (output_call (&operands[1]));
1137: ")
1138:
1139: ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
1140: ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
1141:
1142: (define_insn ""
1143: [(call (mem:SI (match_operand:SI 0 "" "i"))
1.1.1.3 ! root 1144: (match_operand:SI 1 "general_operand" "g"))
1.1 root 1145: (clobber (reg:SI 14))]
1146: "GET_CODE (operands[0]) == SYMBOL_REF"
1147: "*
1148: return (arm_output_asm_insn (\"bl\\t%a0\", operands));
1149: ")
1150:
1151: (define_insn ""
1152: [(set (match_operand 0 "register_operand" "=rf")
1.1.1.3 ! root 1153: (call (mem:SI (match_operand:SI 1 "" "i"))
! 1154: (match_operand:SI 2 "general_operand" "g")))
1.1 root 1155: (clobber (reg:SI 14))]
1156: "GET_CODE(operands[1]) == SYMBOL_REF"
1157: "*
1158: return (arm_output_asm_insn (\"bl\\t%a1\", operands));
1159: ")
1160:
1161: (define_insn "tablejump"
1162: [(set (pc)
1.1.1.3 ! root 1163: (match_operand:SI 0 "register_operand" "r"))
1.1 root 1164: (use (label_ref (match_operand 1 "" "")))]
1165: ""
1166: "*
1167: return (arm_output_asm_insn (\"mov\\tpc, %0\\t@ table jump, label %l1\", operands));
1168: ")
1169:
1170: (define_insn "indirect_jump"
1171: [(set (pc)
1.1.1.3 ! root 1172: (match_operand:SI 0 "register_operand" "r"))]
1.1 root 1173: ""
1174: "*
1175: return (arm_output_asm_insn (\"mov\\tpc, %0\\t@ indirect jump\", operands));
1176: ")
1177:
1178: ;; Misc insns
1179:
1180: (define_insn "nop"
1181: [(const_int 0)]
1182: ""
1183: "*
1184: return (arm_output_asm_insn (\"mov\\tr0, r0\\t@ nop\", operands));
1185: ")
1186:
1187: ;; Patterns to allow combination of arithmetic, cond code and shifts
1188:
1189: ;(define_insn ""
1190: ; [(set (match_operand:SI 0 "register_operand" "=r")
1191: ; (match_operator:SI 1 "shiftable_operator"
1192: ; [(match_operand:SI 2 "register_operand" "r")
1193: ; (match_operator:SI 3 "shift_operator"
1194: ; [(match_operand:SI 4 "register_operand" "r")
1195: ; (match_operand:SI 5 "nonmemory_operand" "rn")])]))]
1196: ; ""
1197: ; "*
1198: ; return (output_arithmetic_with_shift (operands, FALSE, FALSE));
1199: ; "
1200: ;)
1201:
1202: ;(define_insn ""
1203: ; [(set (match_operand:SI 0 "register_operand" "=r")
1204: ; (match_operator:SI 1 "shiftable_operator"
1205: ; [(match_operator:SI 3 "shift_operator"
1206: ; [(match_operand:SI 4 "register_operand" "r")
1207: ; (match_operand:SI 5 "nonmemory_operand" "rI")])
1208: ; (match_operand:SI 2 "register_operand" "r")]))]
1209: ; ""
1210: ; "*
1211: ; return (output_arithmetic_with_shift (operands, TRUE, FALSE));
1212: ;")
1213:
1214: ;; Patterns to allow combination of arithmetic and multiplication
1215:
1216: ;(define_insn ""
1217: ; [(set (match_operand:SI 0 "register_operand" "=r")
1218: ; (match_operator:SI 1 "shiftable_operator"
1219: ; [(match_operand:SI 2 "register_operand" "r")
1220: ; (mult:SI
1221: ; (match_operand:SI 3 "register_operand" "r")
1222: ; (match_operand:SI 4 "power_of_two_operand" "n"))]))]
1223: ; ""
1224: ; "*
1225: ; return (output_arithmetic_with_immediate_multiply (operands, FALSE));
1226: ;")
1227:
1228: ; Uncomment this to show combiner problem (see ../COMBINER-PROBLEM).
1229: ;(define_insn ""
1230: ; [(set (match_operand:SI 0 "register_operand" "=r")
1231: ; (match_operator:SI 1 "shiftable_operator"
1232: ; [(mult:SI
1233: ; (match_operand:SI 3 "register_operand" "r")
1234: ; (match_operand:SI 4 "power_of_two_operand" "n"))
1235: ; (match_operand:SI 2 "register_operand" "r")]))]
1236: ; ""
1237: ; "*
1238: ; return (output_arithmetic_with_immediate_multiply (operands, TRUE));
1239: ;")
1240:
1241: ;; Peephole optimizations.
1242:
1243: ;; When testing a bitset smaller than 9 bits for (un)equality, a
1244: ;; shift/and/cmp/b{eq,ne} sequence can be replaced by one tst and the same
1245: ;; branch sequence.
1246:
1247: ;;(define_peephole
1248: ;; [(set (match_operand:SI 0 "register_operand" "=r")
1249: ;; (lshiftrt:SI (match_dup 0)
1250: ;; (match_operand 1 "immediate_operand" "")))
1251: ;; (set (match_dup 0)
1252: ;; (and:SI (match_dup 0)
1253: ;; (match_operand 2 "immediate_operand" "")))
1254: ;; (set (cc0) (match_dup 0))
1255: ;; (set (pc)
1256: ;; (if_then_else (ne (cc0) (const_int 0))
1257: ;; (label_ref (match_operand 3 "" ""))
1258: ;; (pc)))]
1259: ;; "dead_or_set_p (PREV_INSN (insn), operands[0])
1260: ;; && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT
1261: ;; && const_ok_for_arm (INTVAL (operands[2]) << INTVAL (operands[1]))"
1262: ;; "*
1263: ;; operands[2] = gen_rtx (CONST_INT, VOIDmode,
1264: ;; INTVAL (operands[2]) << INTVAL (operands[1]));
1265: ;; arm_output_asm_insn (\"tst\\t%0, %2\\t\\t@ ph test bitfield\", operands);
1266: ;; return (arm_output_asm_insn (\"bne\\t%l3\", operands));
1267: ;;")
1268:
1269: ;;(define_peephole
1270: ;; [(set (match_operand:SI 0 "register_operand" "=r")
1271: ;; (lshiftrt:SI (match_dup 0)
1272: ;; (match_operand 1 "immediate_operand" "")))
1273: ;; (set (match_dup 0)
1274: ;; (and:SI (match_dup 0)
1275: ;; (match_operand 2 "immediate_operand" "")))
1276: ;; (set (cc0) (match_dup 0))
1277: ;; (set (pc)
1278: ;; (if_then_else (ne (cc0) (const_int 0))
1279: ;; (pc)
1280: ;; (label_ref (match_operand 3 "" ""))))]
1281: ;; "dead_or_set_p (prev_real_insn (insn), operands[0])
1282: ;; && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT
1283: ;; && const_ok_for_arm (INTVAL (operands[2]) << INTVAL (operands[1]))"
1284: ;; "*
1285: ;; operands[2] = gen_rtx (CONST_INT, VOIDmode,
1286: ;; INTVAL (operands[2]) << INTVAL (operands[1]));
1287: ;; arm_output_asm_insn (\"tst\\t%0, %2\\t\\t@ ph test bitfield\", operands);
1288: ;; return (arm_output_asm_insn (\"beq\\t%l3\", operands));
1289: ;;")
1290:
1291: ;; This allows negative constants to be compared since GCC appears not to try
1292: ;; converting them with a NEG.
1293:
1294: ;;(define_peephole
1295: ;; [(set (match_operand:SI 2 "register_operand" "=r")
1296: ;; (match_operand:SI 1 "immediate_operand" "n"))
1297: ;; (set (cc0)
1298: ;; (compare (match_operand:SI 0 "register_operand" "r")
1299: ;; (match_dup 1)))]
1300: ;; "const_ok_for_arm (-INTVAL (operands[1]))
1301: ;; && dead_or_set_p (prev_real_insn (insn), operands[0])"
1302: ;; "*
1303: ;; operands[1] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1]));
1304: ;; return (arm_output_asm_insn (\"cmn\\t%0, %1\\t\\t@ ph negate comparison\", operands));
1305: ;;")
1306:
1307: ;; Local variables:
1308: ;; mode:emacs-lisp
1309: ;; eval: (setq comment-start ";; ")
1310: ;; eval: (setq comment-end "")
1311: ;; eval: (setq comment-start-skip ";;+ *")
1312: ;; eval: (set-syntax-table (copy-sequence (syntax-table)))
1313: ;; eval: (modify-syntax-entry ?[ "(]")
1314: ;; eval: (modify-syntax-entry ?] ")[")
1315: ;; eval: (modify-syntax-entry ?{ "(}")
1316: ;; eval: (modify-syntax-entry ?} "){")
1317: ;; End:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.