|
|
1.1 root 1: ;;- Machine description for SPUR chip for GNU C compiler
2: ;; Copyright (C) 1988 Free Software Foundation, Inc.
3:
4: ;; This file is part of GNU CC.
5:
6: ;; GNU CC is free software; you can redistribute it and/or modify
7: ;; it under the terms of the GNU General Public License as published by
8: ;; the Free Software Foundation; either version 2, or (at your option)
9: ;; any later version.
10:
11: ;; GNU CC is distributed in the hope that it will be useful,
12: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: ;; GNU General Public License for more details.
15:
16: ;; You should have received a copy of the GNU General Public License
17: ;; along with GNU CC; see the file COPYING. If not, write to
18: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19:
20:
21: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22:
23: ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
24: ;;- updates for most instructions.
25:
26: ;;- Operand classes for the register allocator:
27:
28: ;; Compare instructions.
29: ;; This pattern is used for generating an "insn"
30: ;; which does just a compare and sets a (fictitious) condition code.
31:
32: ;; The actual SPUR insns are compare-and-conditional-jump.
33: ;; The define_peephole's below recognize the combinations of
34: ;; compares and jumps, and output each pair as a single assembler insn.
35:
36: ;; This controls RTL generation and register allocation.
37: (define_insn "cmpsi"
38: [(set (cc0)
39: (compare (match_operand:SI 0 "register_operand" "rK")
40: (match_operand:SI 1 "nonmemory_operand" "rK")))]
41: ""
42: "*
43: {
44: cc_status.value1 = operands[0], cc_status.value2 = operands[1];
45: return \"\";
46: }")
47:
48: ;; We have to have this because cse can optimize the previous pattern
49: ;; into this one.
50:
51: (define_insn "tstsi"
52: [(set (cc0)
53: (match_operand:SI 0 "register_operand" "r"))]
54: ""
55: "*
56: {
57: cc_status.value1 = operands[0], cc_status.value2 = const0_rtx;
58: return \"\";
59: }")
60:
61:
62: ;; These control RTL generation for conditional jump insns
63: ;; and match them for register allocation.
64:
65: (define_insn "beq"
66: [(set (pc)
67: (if_then_else (eq (cc0)
68: (const_int 0))
69: (label_ref (match_operand 0 "" ""))
70: (pc)))]
71: ""
72: "* return output_compare (operands, \"eq\", \"eq\", \"ne\", \"ne\"); ")
73:
74: (define_insn "bne"
75: [(set (pc)
76: (if_then_else (ne (cc0)
77: (const_int 0))
78: (label_ref (match_operand 0 "" ""))
79: (pc)))]
80: ""
81: "* return output_compare (operands, \"ne\", \"ne\", \"eq\", \"eq\"); ")
82:
83: (define_insn "bgt"
84: [(set (pc)
85: (if_then_else (gt (cc0)
86: (const_int 0))
87: (label_ref (match_operand 0 "" ""))
88: (pc)))]
89: ""
90: "* return output_compare (operands, \"gt\", \"lt\", \"le\", \"ge\"); ")
91:
92: (define_insn "bgtu"
93: [(set (pc)
94: (if_then_else (gtu (cc0)
95: (const_int 0))
96: (label_ref (match_operand 0 "" ""))
97: (pc)))]
98: ""
99: "* return output_compare (operands, \"ugt\", \"ult\", \"ule\", \"uge\"); ")
100:
101: (define_insn "blt"
102: [(set (pc)
103: (if_then_else (lt (cc0)
104: (const_int 0))
105: (label_ref (match_operand 0 "" ""))
106: (pc)))]
107: ""
108: "* return output_compare (operands, \"lt\", \"gt\", \"ge\", \"le\"); ")
109:
110: (define_insn "bltu"
111: [(set (pc)
112: (if_then_else (ltu (cc0)
113: (const_int 0))
114: (label_ref (match_operand 0 "" ""))
115: (pc)))]
116: ""
117: "* return output_compare (operands, \"ult\", \"ugt\", \"uge\", \"ule\"); ")
118:
119: (define_insn "bge"
120: [(set (pc)
121: (if_then_else (ge (cc0)
122: (const_int 0))
123: (label_ref (match_operand 0 "" ""))
124: (pc)))]
125: ""
126: "* return output_compare (operands, \"ge\", \"le\", \"lt\", \"gt\"); ")
127:
128: (define_insn "bgeu"
129: [(set (pc)
130: (if_then_else (geu (cc0)
131: (const_int 0))
132: (label_ref (match_operand 0 "" ""))
133: (pc)))]
134: ""
135: "* return output_compare (operands, \"uge\", \"ule\", \"ult\", \"ugt\"); ")
136:
137: (define_insn "ble"
138: [(set (pc)
139: (if_then_else (le (cc0)
140: (const_int 0))
141: (label_ref (match_operand 0 "" ""))
142: (pc)))]
143: ""
144: "* return output_compare (operands, \"le\", \"ge\", \"gt\", \"lt\"); ")
145:
146: (define_insn "bleu"
147: [(set (pc)
148: (if_then_else (leu (cc0)
149: (const_int 0))
150: (label_ref (match_operand 0 "" ""))
151: (pc)))]
152: ""
153: "* return output_compare (operands, \"ule\", \"uge\", \"ugt\", \"ult\"); ")
154:
155: ;; These match inverted jump insns for register allocation.
156:
157: (define_insn ""
158: [(set (pc)
159: (if_then_else (eq (cc0)
160: (const_int 0))
161: (pc)
162: (label_ref (match_operand 0 "" ""))))]
163: ""
164: "* return output_compare (operands, \"ne\", \"ne\", \"eq\", \"eq\"); ")
165:
166: (define_insn ""
167: [(set (pc)
168: (if_then_else (ne (cc0)
169: (const_int 0))
170: (pc)
171: (label_ref (match_operand 0 "" ""))))]
172: ""
173: "* return output_compare (operands, \"eq\", \"eq\", \"ne\", \"ne\"); ")
174:
175: (define_insn ""
176: [(set (pc)
177: (if_then_else (gt (cc0)
178: (const_int 0))
179: (pc)
180: (label_ref (match_operand 0 "" ""))))]
181: ""
182: "* return output_compare (operands, \"le\", \"ge\", \"gt\", \"lt\"); ")
183:
184: (define_insn ""
185: [(set (pc)
186: (if_then_else (gtu (cc0)
187: (const_int 0))
188: (pc)
189: (label_ref (match_operand 0 "" ""))))]
190: ""
191: "* return output_compare (operands, \"ule\", \"uge\", \"ugt\", \"ult\"); ")
192:
193: (define_insn ""
194: [(set (pc)
195: (if_then_else (lt (cc0)
196: (const_int 0))
197: (pc)
198: (label_ref (match_operand 0 "" ""))))]
199: ""
200: "* return output_compare (operands, \"ge\", \"le\", \"lt\", \"gt\"); ")
201:
202: (define_insn ""
203: [(set (pc)
204: (if_then_else (ltu (cc0)
205: (const_int 0))
206: (pc)
207: (label_ref (match_operand 0 "" ""))))]
208: ""
209: "* return output_compare (operands, \"uge\", \"ule\", \"ult\", \"ugt\"); ")
210:
211: (define_insn ""
212: [(set (pc)
213: (if_then_else (ge (cc0)
214: (const_int 0))
215: (pc)
216: (label_ref (match_operand 0 "" ""))))]
217: ""
218: "* return output_compare (operands, \"lt\", \"gt\", \"ge\", \"le\"); ")
219:
220: (define_insn ""
221: [(set (pc)
222: (if_then_else (geu (cc0)
223: (const_int 0))
224: (pc)
225: (label_ref (match_operand 0 "" ""))))]
226: ""
227: "* return output_compare (operands, \"ult\", \"ugt\", \"uge\", \"ule\"); ")
228:
229: (define_insn ""
230: [(set (pc)
231: (if_then_else (le (cc0)
232: (const_int 0))
233: (pc)
234: (label_ref (match_operand 0 "" ""))))]
235: ""
236: "* return output_compare (operands, \"gt\", \"lt\", \"le\", \"ge\"); ")
237:
238: (define_insn ""
239: [(set (pc)
240: (if_then_else (leu (cc0)
241: (const_int 0))
242: (pc)
243: (label_ref (match_operand 0 "" ""))))]
244: ""
245: "* return output_compare (operands, \"ugt\", \"ult\", \"ule\", \"uge\"); ")
246:
247: ;; Move instructions
248:
249: (define_insn "movsi"
250: [(set (match_operand:SI 0 "general_operand" "=r,m")
251: (match_operand:SI 1 "general_operand" "rmi,rJ"))]
252: ""
253: "*
254: {
255: if (GET_CODE (operands[0]) == MEM)
256: return \"st_32 %r1,%0\";
257: if (GET_CODE (operands[1]) == MEM)
258: return \"ld_32 %0,%1\;nop\";
259: if (GET_CODE (operands[1]) == REG)
260: return \"add_nt %0,%1,$0\";
261: if (GET_CODE (operands[1]) == SYMBOL_REF && operands[1]->unchanging)
262: return \"add_nt %0,r24,$(%1-0b)\";
263: return \"add_nt %0,r0,%1\";
264: }")
265:
266: (define_insn ""
267: [(set (match_operand:SI 0 "register_operand" "=r")
268: (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
269: (match_operand:SI 2 "register_operand" "r"))))]
270: ""
271: "ld_32 %0,%1,%2\;nop")
272:
273: ;; Generate insns for moving single bytes.
274:
275: (define_expand "movqi"
276: [(set (match_operand:QI 0 "general_operand" "")
277: (match_operand:QI 1 "general_operand" ""))]
278: ""
279: "
280: {
281: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
282: operands[1] = copy_to_reg (operands[1]);
283:
284: if (GET_CODE (operands[1]) == MEM)
285: {
286: rtx tem = gen_reg_rtx (SImode);
287: rtx addr = force_reg (SImode, XEXP (operands[1], 0));
288: rtx subreg;
289:
290: emit_move_insn (tem, gen_rtx (MEM, SImode, addr));
291: if (GET_CODE (operands[0]) == SUBREG)
292: subreg = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[0]),
293: SUBREG_WORD (operands[0]));
294: else
295: subreg = gen_rtx (SUBREG, SImode, operands[0], 0);
296:
297: emit_insn (gen_rtx (SET, VOIDmode, subreg,
298: gen_rtx (ZERO_EXTRACT, SImode, tem,
299: gen_rtx (CONST_INT, VOIDmode, 8),
300: addr)));
301: }
302: else if (GET_CODE (operands[0]) == MEM)
303: {
304: rtx tem = gen_reg_rtx (SImode);
305: rtx addr = force_reg (SImode, XEXP (operands[0], 0));
306: rtx subreg;
307:
308: emit_move_insn (tem, gen_rtx (MEM, SImode, addr));
309: if (! CONSTANT_ADDRESS_P (operands[1]))
310: {
311: if (GET_CODE (operands[1]) == SUBREG)
312: subreg = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
313: SUBREG_WORD (operands[1]));
314: else
315: subreg = gen_rtx (SUBREG, SImode, operands[1], 0);
316: }
317:
318: emit_insn (gen_rtx (SET, VOIDmode,
319: gen_rtx (ZERO_EXTRACT, SImode, tem,
320: gen_rtx (CONST_INT, VOIDmode, 8),
321: addr),
322: subreg));
323: emit_move_insn (gen_rtx (MEM, SImode, addr), tem);
324: }
325: else
326: {
327: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
328: }
329: DONE;
330: }")
331:
332: ;; Recognize insns generated for moving single bytes.
333:
334: (define_insn ""
335: [(set (match_operand:QI 0 "general_operand" "=r,m")
336: (match_operand:QI 1 "general_operand" "rmi,r"))]
337: ""
338: "*
339: {
340: if (GET_CODE (operands[0]) == MEM)
341: return \"st_32 %1,%0\";
342: if (GET_CODE (operands[1]) == MEM)
343: return \"ld_32 %0,%1\;nop\";
344: if (GET_CODE (operands[1]) == REG)
345: return \"add_nt %0,%1,$0\";
346: return \"add_nt %0,r0,%1\";
347: }")
348:
349: (define_insn ""
350: [(set (match_operand:SI 0 "register_operand" "=r")
351: (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
352: (const_int 8)
353: (match_operand:SI 2 "nonmemory_operand" "rI")))]
354: ""
355: "extract %0,%1,%2")
356:
357: (define_insn ""
358: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
359: (const_int 8)
360: (match_operand:SI 1 "nonmemory_operand" "rI"))
361: (match_operand:SI 2 "nonmemory_operand" "ri"))]
362: ""
363: "wr_insert %1\;insert %0,%0,%2")
364:
365: ;; Constant propagation can optimize the previous pattern into this pattern.
366: ;[Not any more. It could when the position-operand contains a MULT.]
367:
368: ;(define_insn ""
369: ; [(set (zero_extract:QI (match_operand:SI 0 "register_operand" "+r")
370: ; (const_int 8)
371: ; (match_operand:SI 1 "immediate_operand" "I"))
372: ; (match_operand:QI 2 "register_operand" "r"))]
373: ; "GET_CODE (operands[1]) == CONST_INT
374: ; && INTVAL (operands[1]) % 8 == 0
375: ; && (unsigned) INTVAL (operands[1]) < 32"
376: ; "*
377: ;{
378: ; operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 8);
379: ; return \"wr_insert 0,0,%1\;insert %0,%0,%2\";
380: ;}")
381:
382: ;; The three define_expand patterns on this page
383: ;; serve as subroutines of "movhi".
384:
385: ;; Generate code to fetch an aligned halfword from memory.
386: ;; Operand 0 is the destination register (HImode).
387: ;; Operand 1 is the memory address (SImode).
388: ;; Operand 2 is a temporary (SImode).
389: ;; Operand 3 is a temporary (SImode).
390: ;; Operand 4 is a temporary (QImode).
391:
392: ;; Operand 5 is an internal temporary (HImode).
393:
394: (define_expand "loadhi"
395: [(set (match_operand:SI 2 "register_operand" "")
396: (mem:SI (match_operand:SI 1 "register_operand" "")))
397: ;; Extract the low byte.
398: (set (subreg:SI (match_dup 5) 0)
399: (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 1)))
400: ;; Form address of high byte.
401: (set (match_operand:SI 3 "register_operand" "")
402: (plus:SI (match_dup 1) (const_int 1)))
403: ;; Extract the high byte.
404: (set (subreg:SI (match_operand:QI 4 "register_operand" "") 0)
405: (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3)))
406: ;; Put the high byte in with the low one.
407: (set (zero_extract:SI (match_dup 5) (const_int 8) (const_int 1))
408: (subreg:SI (match_dup 4) 0))
409: (set (match_operand:HI 0 "register_operand" "") (match_dup 5))]
410: ""
411: "operands[5] = gen_reg_rtx (HImode);")
412:
413: ;; Generate code to store an aligned halfword into memory.
414: ;; Operand 0 is the destination address (SImode).
415: ;; Operand 1 is the source register (HImode, not constant).
416: ;; Operand 2 is a temporary (SImode).
417: ;; Operand 3 is a temporary (SImode).
418: ;; Operand 4 is a temporary (QImode).
419:
420: ;; Operand 5 is an internal variable made from operand 1.
421:
422: (define_expand "storehi"
423: [(set (match_operand:SI 2 "register_operand" "")
424: (mem:SI (match_operand:SI 0 "register_operand" "")))
425: ;; Insert the low byte.
426: (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 0))
427: (match_dup 5))
428: ;; Form address of high byte.
429: (set (match_operand:SI 3 "register_operand" "")
430: (plus:SI (match_dup 0) (const_int 1)))
431: ;; Extract the high byte from the source.
432: (set (subreg:SI (match_operand:QI 4 "register_operand" "") 0)
433: (zero_extract:SI (match_operand:HI 1 "register_operand" "")
434: (const_int 8) (const_int 1)))
435: ;; Store high byte into the memory word
436: (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3))
437: (subreg:SI (match_dup 4) 0))
438: ;; Put memory word back into memory.
439: (set (mem:SI (match_dup 0))
440: (match_dup 2))]
441: ""
442: "
443: {
444: if (GET_CODE (operands[1]) == SUBREG)
445: operands[5] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
446: SUBREG_WORD (operands[1]));
447: else
448: operands[5] = gen_rtx (SUBREG, SImode, operands[1], 0);
449: }")
450:
451: ;; Like storehi but operands[1] is a CONST_INT.
452:
453: (define_expand "storeinthi"
454: [(set (match_operand:SI 2 "register_operand" "")
455: (mem:SI (match_operand:SI 0 "register_operand" "")))
456: ;; Insert the low byte.
457: (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 0))
458: (match_dup 5))
459: ;; Form address of high byte.
460: (set (match_operand:SI 3 "register_operand" "")
461: (plus:SI (match_dup 0) (const_int 1)))
462: ;; Store high byte into the memory word
463: (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3))
464: (match_dup 6))
465: ;; Put memory word back into memory.
466: (set (mem:SI (match_dup 0))
467: (match_dup 2))]
468: ""
469: " operands[5] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 255);
470: operands[6] = gen_rtx (CONST_INT, VOIDmode,
471: (INTVAL (operands[1]) >> 8) & 255);
472: ")
473:
474: ;; Main entry for generating insns to move halfwords.
475:
476: (define_expand "movhi"
477: [(set (match_operand:HI 0 "general_operand" "")
478: (match_operand:HI 1 "general_operand" ""))]
479: ""
480: "
481: {
482: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
483: operands[1] = copy_to_reg (operands[1]);
484:
485: if (GET_CODE (operands[1]) == MEM)
486: {
487: rtx insn =
488: emit_insn (gen_loadhi (operands[0],
489: force_reg (SImode, XEXP (operands[1], 0)),
490: gen_reg_rtx (SImode), gen_reg_rtx (SImode),
491: gen_reg_rtx (QImode)));
492: /* Tell cse what value the loadhi produces, so it detect duplicates. */
493: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, operands[1],
494: REG_NOTES (insn));
495: }
496: else if (GET_CODE (operands[0]) == MEM)
497: {
498: if (GET_CODE (operands[1]) == CONST_INT)
499: emit_insn (gen_storeinthi (force_reg (SImode, XEXP (operands[0], 0)),
500: operands[1],
501: gen_reg_rtx (SImode), gen_reg_rtx (SImode),
502: gen_reg_rtx (QImode)));
503: else
504: {
505: if (CONSTANT_P (operands[1]))
506: operands[1] = force_reg (HImode, operands[1]);
507: emit_insn (gen_storehi (force_reg (SImode, XEXP (operands[0], 0)),
508: operands[1],
509: gen_reg_rtx (SImode), gen_reg_rtx (SImode),
510: gen_reg_rtx (QImode)));
511: }
512: }
513: else
514: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
515: DONE;
516: }")
517:
518: ;; Recognize insns generated for moving halfwords.
519: ;; (Note that the extract and insert patterns for single-byte moves
520: ;; are also involved in recognizing some of the insns used for this purpose.)
521:
522: (define_insn ""
523: [(set (match_operand:HI 0 "general_operand" "=r,m")
524: (match_operand:HI 1 "general_operand" "rmi,r"))]
525: ""
526: "*
527: {
528: if (GET_CODE (operands[0]) == MEM)
529: return \"st_32 %1,%0\";
530: if (GET_CODE (operands[1]) == MEM)
531: return \"ld_32 %0,%1\;nop\";
532: if (GET_CODE (operands[1]) == REG)
533: return \"add_nt %0,%1,$0\";
534: return \"add_nt %0,r0,%1\";
535: }")
536:
537: (define_insn ""
538: [(set (match_operand:SI 0 "register_operand" "=r")
539: (zero_extract:SI (match_operand:HI 1 "register_operand" "r")
540: (const_int 8)
541: (match_operand:SI 2 "nonmemory_operand" "rI")))]
542: ""
543: "extract %0,%1,%2")
544:
545: (define_insn ""
546: [(set (zero_extract:SI (match_operand:HI 0 "register_operand" "+r")
547: (const_int 8)
548: (match_operand:SI 1 "nonmemory_operand" "rI"))
549: (match_operand:SI 2 "nonmemory_operand" "ri"))]
550: ""
551: "wr_insert %1\;insert %0,%0,%2")
552:
553: ;; Constant propagation can optimize the previous pattern into this pattern.
554:
555: ;(define_insn ""
556: ; [(set (zero_extract:QI (match_operand:HI 0 "register_operand" "+r")
557: ; (const_int 8)
558: ; (match_operand:SI 1 "immediate_operand" "I"))
559: ; (match_operand:QI 2 "register_operand" "r"))]
560: ; "GET_CODE (operands[1]) == CONST_INT
561: ; && INTVAL (operands[1]) % 8 == 0
562: ; && (unsigned) INTVAL (operands[1]) < 32"
563: ; "*
564: ;{
565: ; operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 8);
566: ; return \"wr_insert 0,0,%1\;insert %0,%0,%2\";
567: ;}")
568:
569: ;; This pattern forces (set (reg:DF ...) (const_double ...))
570: ;; to be reloaded by putting the constant into memory.
571: ;; It must come before the more general movdf pattern.
572: (define_insn ""
573: [(set (match_operand:DF 0 "general_operand" "=&r,f,&o")
574: (match_operand:DF 1 "" "mG,m,G"))]
575: "GET_CODE (operands[1]) == CONST_DOUBLE"
576: "*
577: {
578: if (FP_REG_P (operands[0]))
579: return output_fp_move_double (operands);
580: if (operands[1] == CONST0_RTX (DFmode) && GET_CODE (operands[0]) == REG)
581: {
582: operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
583: return \"add_nt %0,r0,$0\;add_nt %1,r0,$0\";
584: }
585: if (operands[1] == CONST0_RTX (DFmode) && GET_CODE (operands[0]) == MEM)
586: {
587: operands[1] = adj_offsettable_operand (operands[0], 4);
588: return \"st_32 r0,%0\;st_32 r0,%1\";
589: }
590: return output_move_double (operands);
591: }
592: ")
593:
594: (define_insn "movdf"
595: [(set (match_operand:DF 0 "general_operand" "=r,&r,m,?f,?rm")
596: (match_operand:DF 1 "general_operand" "r,m,r,rfm,f"))]
597: ""
598: "*
599: {
600: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
601: return output_fp_move_double (operands);
602: return output_move_double (operands);
603: }
604: ")
605:
606: (define_insn "movdi"
607: [(set (match_operand:DI 0 "general_operand" "=r,&r,m,?f,?rm")
608: (match_operand:DI 1 "general_operand" "r,m,r,rfm,f"))]
609: ""
610: "*
611: {
612: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
613: return output_fp_move_double (operands);
614: return output_move_double (operands);
615: }
616: ")
617:
618: (define_insn "movsf"
619: [(set (match_operand:SF 0 "general_operand" "=rf,m")
620: (match_operand:SF 1 "general_operand" "rfm,rf"))]
621: ""
622: "*
623: {
624: if (FP_REG_P (operands[0]))
625: {
626: if (FP_REG_P (operands[1]))
627: return \"fmov %0,%1\";
628: if (GET_CODE (operands[1]) == REG)
629: {
630: rtx xoperands[2];
631: int offset = - get_frame_size () - 8;
632: xoperands[1] = operands[1];
633: xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset);
634: output_asm_insn (\"st_32 %1,r25,%0\", xoperands);
635: xoperands[1] = operands[0];
636: output_asm_insn (\"ld_sgl %1,r25,%0\;nop\", xoperands);
637: return \"\";
638: }
639: return \"ld_sgl %0,%1\;nop\";
640: }
641: if (FP_REG_P (operands[1]))
642: {
643: if (GET_CODE (operands[0]) == REG)
644: {
645: rtx xoperands[2];
646: int offset = - get_frame_size () - 8;
647: xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset);
648: xoperands[1] = operands[1];
649: output_asm_insn (\"st_sgl %1,r25,%0\", xoperands);
650: xoperands[1] = operands[0];
651: output_asm_insn (\"ld_32 %1,r25,%0\;nop\", xoperands);
652: return \"\";
653: }
654: return \"st_sgl %1,%0\";
655: }
656: if (GET_CODE (operands[0]) == MEM)
657: return \"st_32 %r1,%0\";
658: if (GET_CODE (operands[1]) == MEM)
659: return \"ld_32 %0,%1\;nop\";
660: if (GET_CODE (operands[1]) == REG)
661: return \"add_nt %0,%1,$0\";
662: return \"add_nt %0,r0,%1\";
663: }")
664:
665: ;;- truncation instructions
666: (define_insn "truncsiqi2"
667: [(set (match_operand:QI 0 "register_operand" "=r")
668: (truncate:QI
669: (match_operand:SI 1 "register_operand" "r")))]
670: ""
671: "add_nt %0,%1,$0")
672:
673: (define_insn "trunchiqi2"
674: [(set (match_operand:QI 0 "register_operand" "=r")
675: (truncate:QI
676: (match_operand:HI 1 "register_operand" "r")))]
677: ""
678: "add_nt %0,%1,$0")
679:
680: (define_insn "truncsihi2"
681: [(set (match_operand:HI 0 "register_operand" "=r")
682: (truncate:HI
683: (match_operand:SI 1 "register_operand" "r")))]
684: ""
685: "add_nt %0,%1,$0")
686:
687: ;;- zero extension instructions
688:
689: ;; Note that the one starting from HImode comes before those for QImode
690: ;; so that a constant operand will match HImode, not QImode.
691: (define_expand "zero_extendhisi2"
692: [(set (match_operand:SI 0 "register_operand" "")
693: (and:SI (match_operand:HI 1 "register_operand" "") ;Changed to SI below
694: ;; This constant is invalid, but reloading will handle it.
695: ;; It's useless to generate here the insns to construct it
696: ;; because constant propagation would simplify them anyway.
697: (match_dup 2)))]
698: ""
699: "
700: {
701: if (GET_CODE (operands[1]) == SUBREG)
702: operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
703: SUBREG_WORD (operands[1]));
704: else
705: operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
706:
707: operands[2] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, 65535));
708: }")
709:
710: (define_insn "zero_extendqihi2"
711: [(set (match_operand:HI 0 "register_operand" "=r")
712: (zero_extend:HI
713: (match_operand:QI 1 "register_operand" "r")))]
714: ""
715: "extract %0,%1,$0")
716:
717: (define_insn "zero_extendqisi2"
718: [(set (match_operand:SI 0 "register_operand" "=r")
719: (zero_extend:SI
720: (match_operand:QI 1 "register_operand" "r")))]
721: ""
722: "extract %0,%1,$0")
723:
724: ;;- sign extension instructions
725: ;; Note that the one starting from HImode comes before those for QImode
726: ;; so that a constant operand will match HImode, not QImode.
727:
728: (define_expand "extendhisi2"
729: [(set (match_dup 2)
730: (and:SI (match_operand:HI 1 "register_operand" "") ;Changed to SI below
731: (match_dup 4)))
732: (set (match_dup 3) (plus:SI (match_dup 2) (match_dup 5)))
733: (set (match_operand:SI 0 "register_operand" "")
734: (xor:SI (match_dup 3) (match_dup 5)))]
735: ""
736: "
737: {
738: if (GET_CODE (operands[1]) == SUBREG)
739: operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
740: SUBREG_WORD (operands[1]));
741: else
742: operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
743:
744: operands[2] = gen_reg_rtx (SImode);
745: operands[3] = gen_reg_rtx (SImode);
746: operands[4] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, 65535));
747: operands[5] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, -32768));
748: }")
749:
750: (define_expand "extendqihi2"
751: [(set (match_dup 2)
752: (and:HI (match_operand:QI 1 "register_operand" "") ;Changed to SI below
753: (const_int 255)))
754: (set (match_dup 3)
755: (plus:SI (match_dup 2) (const_int -128)))
756: (set (match_operand:HI 0 "register_operand" "")
757: (xor:SI (match_dup 3) (const_int -128)))]
758: ""
759: "
760: {
761: if (GET_CODE (operands[1]) == SUBREG)
762: operands[1] = gen_rtx (SUBREG, HImode, SUBREG_REG (operands[1]),
763: SUBREG_WORD (operands[1]));
764: else
765: operands[1] = gen_rtx (SUBREG, HImode, operands[1], 0);
766:
767: operands[2] = gen_reg_rtx (HImode);
768: operands[3] = gen_reg_rtx (HImode);
769: }")
770:
771: (define_expand "extendqisi2"
772: [(set (match_dup 2)
773: (and:SI (match_operand:QI 1 "register_operand" "") ;Changed to SI below
774: (const_int 255)))
775: (set (match_dup 3) (plus:SI (match_dup 2) (const_int -128)))
776: (set (match_operand:SI 0 "register_operand" "")
777: (xor:SI (match_dup 3) (const_int -128)))]
778: ""
779: "
780: {
781: if (GET_CODE (operands[1]) == SUBREG)
782: operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
783: SUBREG_WORD (operands[1]));
784: else
785: operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
786:
787: operands[2] = gen_reg_rtx (SImode);
788: operands[3] = gen_reg_rtx (SImode);
789: }")
790:
791: ;;- arithmetic instructions
792:
793: (define_insn "addsi3"
794: [(set (match_operand:SI 0 "register_operand" "=r")
795: (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r")
796: (match_operand:SI 2 "nonmemory_operand" "rI")))]
797: ""
798: "add %0,%1,%2")
799:
800: (define_insn ""
801: [(set (match_operand:SI 0 "register_operand" "=r")
802: (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r")
803: (match_operand:SI 2 "big_immediate_operand" "g")))]
804: "GET_CODE (operands[2]) == CONST_INT
805: && (unsigned) (INTVAL (operands[2]) + 0x8000000) < 0x10000000"
806: "*
807: {
808: return
809: output_add_large_offset (operands[0], operands[1], INTVAL (operands[2]));
810: }")
811:
812: (define_insn "subsi3"
813: [(set (match_operand:SI 0 "register_operand" "=r")
814: (minus:SI (match_operand:SI 1 "register_operand" "r")
815: (match_operand:SI 2 "nonmemory_operand" "rI")))]
816: ""
817: "sub %0,%1,%2")
818:
819: (define_insn "andsi3"
820: [(set (match_operand:SI 0 "register_operand" "=r")
821: (and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
822: (match_operand:SI 2 "nonmemory_operand" "rI")))]
823: ""
824: "and %0,%1,%2")
825:
826: (define_insn "iorsi3"
827: [(set (match_operand:SI 0 "register_operand" "=r")
828: (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
829: (match_operand:SI 2 "nonmemory_operand" "rI")))]
830: ""
831: "or %0,%1,%2")
832:
833: (define_insn "xorsi3"
834: [(set (match_operand:SI 0 "register_operand" "=r")
835: (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
836: (match_operand:SI 2 "nonmemory_operand" "rI")))]
837: ""
838: "xor %0,%1,%2")
839:
840: (define_insn "negsi2"
841: [(set (match_operand:SI 0 "register_operand" "=r")
842: (neg:SI (match_operand:SI 1 "nonmemory_operand" "rI")))]
843: ""
844: "sub %0,r0,%1")
845:
846: (define_insn "one_cmplsi2"
847: [(set (match_operand:SI 0 "register_operand" "=r")
848: (not:SI (match_operand:SI 1 "register_operand" "r")))]
849: ""
850: "xor %0,%1,$-1")
851:
852: ;; Floating point arithmetic instructions.
853:
854: (define_insn "adddf3"
855: [(set (match_operand:DF 0 "register_operand" "=f")
856: (plus:DF (match_operand:DF 1 "register_operand" "f")
857: (match_operand:DF 2 "register_operand" "f")))]
858: "TARGET_FPU"
859: "fadd %0,%1,%2")
860:
861: (define_insn "addsf3"
862: [(set (match_operand:SF 0 "register_operand" "=f")
863: (plus:SF (match_operand:SF 1 "register_operand" "f")
864: (match_operand:SF 2 "register_operand" "f")))]
865: "TARGET_FPU"
866: "fadd %0,%1,%2")
867:
868: (define_insn "subdf3"
869: [(set (match_operand:DF 0 "register_operand" "=f")
870: (minus:DF (match_operand:DF 1 "register_operand" "f")
871: (match_operand:DF 2 "register_operand" "f")))]
872: "TARGET_FPU"
873: "fsub %0,%1,%2")
874:
875: (define_insn "subsf3"
876: [(set (match_operand:SF 0 "register_operand" "=f")
877: (minus:SF (match_operand:SF 1 "register_operand" "f")
878: (match_operand:SF 2 "register_operand" "f")))]
879: "TARGET_FPU"
880: "fsub %0,%1,%2")
881:
882: (define_insn "muldf3"
883: [(set (match_operand:DF 0 "register_operand" "=f")
884: (mult:DF (match_operand:DF 1 "register_operand" "f")
885: (match_operand:DF 2 "register_operand" "f")))]
886: "TARGET_FPU"
887: "fmul %0,%1,%2")
888:
889: (define_insn "mulsf3"
890: [(set (match_operand:SF 0 "register_operand" "=f")
891: (mult:SF (match_operand:SF 1 "register_operand" "f")
892: (match_operand:SF 2 "register_operand" "f")))]
893: "TARGET_FPU"
894: "fmul %0,%1,%2")
895:
896: (define_insn "divdf3"
897: [(set (match_operand:DF 0 "register_operand" "=f")
898: (div:DF (match_operand:DF 1 "register_operand" "f")
899: (match_operand:DF 2 "register_operand" "f")))]
900: "TARGET_FPU"
901: "fdiv %0,%1,%2")
902:
903: (define_insn "divsf3"
904: [(set (match_operand:SF 0 "register_operand" "=f")
905: (div:SF (match_operand:SF 1 "register_operand" "f")
906: (match_operand:SF 2 "register_operand" "f")))]
907: "TARGET_FPU"
908: "fdiv %0,%1,%2")
909:
910: (define_insn "negdf2"
911: [(set (match_operand:DF 0 "register_operand" "=f")
912: (neg:DF (match_operand:DF 1 "nonmemory_operand" "f")))]
913: "TARGET_FPU"
914: "fneg %0,%1")
915:
916: (define_insn "negsf2"
917: [(set (match_operand:SF 0 "register_operand" "=f")
918: (neg:SF (match_operand:SF 1 "nonmemory_operand" "f")))]
919: "TARGET_FPU"
920: "fneg %0,%1")
921:
922: (define_insn "absdf2"
923: [(set (match_operand:DF 0 "register_operand" "=f")
924: (abs:DF (match_operand:DF 1 "nonmemory_operand" "f")))]
925: "TARGET_FPU"
926: "fabs %0,%1")
927:
928: (define_insn "abssf2"
929: [(set (match_operand:SF 0 "register_operand" "=f")
930: (abs:SF (match_operand:SF 1 "nonmemory_operand" "f")))]
931: "TARGET_FPU"
932: "fabs %0,%1")
933:
934: ;; Shift instructions
935:
936: (define_insn ""
937: [(set (match_operand:SI 0 "register_operand" "=r")
938: (ashift:SI (match_operand:SI 1 "register_operand" "r")
939: (match_operand:SI 2 "immediate_operand" "I")))]
940: "GET_CODE (operands[2]) == CONST_INT"
941: "*
942: {
943: unsigned int amount = INTVAL (operands[2]);
944:
945: switch (amount)
946: {
947: case 0:
948: return \"add_nt %0,%1,$0\";
949: case 1:
950: return \"sll %0,%1,$1\";
951: case 2:
952: return \"sll %0,%1,$2\";
953: default:
954: output_asm_insn (\"sll %0,%1,$3\", operands);
955:
956: for (amount -= 3; amount >= 3; amount -= 3)
957: output_asm_insn (\"sll %0,%0,$3\", operands);
958:
959: if (amount > 0)
960: output_asm_insn (amount == 1 ? \"sll %0,%0,$1\" : \"sll %0,%0,$2\",
961: operands);
962: return \"\";
963: }
964: }")
965:
966: (define_insn ""
967: [(set (match_operand:SI 0 "register_operand" "=r")
968: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
969: (match_operand:SI 2 "immediate_operand" "I")))]
970: "GET_CODE (operands[2]) == CONST_INT"
971: "*
972: {
973: unsigned int amount = INTVAL (operands[2]);
974:
975: if (amount == 0)
976: return \"add_nt %0,%1,$0\";
977: else
978: output_asm_insn (\"sra %0,%1,$1\", operands);
979:
980: for (amount -= 1; amount > 0; amount -= 1)
981: output_asm_insn (\"sra %0,%0,$1\", operands);
982:
983: return \"\";
984: }")
985:
986: (define_insn ""
987: [(set (match_operand:SI 0 "register_operand" "=r")
988: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
989: (match_operand:SI 2 "immediate_operand" "I")))]
990: "GET_CODE (operands[2]) == CONST_INT"
991: "*
992: {
993: unsigned int amount = INTVAL (operands[2]);
994:
995: if (amount == 0)
996: return \"add_nt %0,%1,$0\";
997: else
998: output_asm_insn (\"srl %0,%1,$1\", operands);
999:
1000: for (amount -= 1; amount > 0; amount -= 1)
1001: output_asm_insn (\"srl %0,%0,$1\", operands);
1002:
1003: return \"\";
1004: }")
1005:
1006: (define_expand "ashlsi3"
1007: [(set (match_operand:SI 0 "register_operand" "")
1008: (ashift:SI (match_operand:SI 1 "register_operand" "")
1009: (match_operand:SI 2 "nonmemory_operand" "")))]
1010: ""
1011: "
1012: {
1013: if (GET_CODE (operands[2]) != CONST_INT
1014: || (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands[2]) > 3))
1015: FAIL;
1016: }")
1017:
1018: (define_expand "lshlsi3"
1019: [(set (match_operand:SI 0 "register_operand" "")
1020: (ashift:SI (match_operand:SI 1 "register_operand" "")
1021: (match_operand:SI 2 "nonmemory_operand" "")))]
1022: ""
1023: "
1024: {
1025: if (GET_CODE (operands[2]) != CONST_INT
1026: || (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands[2]) > 3))
1027: FAIL;
1028: }")
1029:
1030: (define_expand "ashrsi3"
1031: [(set (match_operand:SI 0 "register_operand" "")
1032: (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1033: (match_operand:SI 2 "nonmemory_operand" "")))]
1034: ""
1035: "
1036: {
1037: if (GET_CODE (operands[2]) != CONST_INT
1038: || (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands[2]) > 1))
1039: FAIL;
1040: }")
1041:
1042: (define_expand "lshrsi3"
1043: [(set (match_operand:SI 0 "register_operand" "")
1044: (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1045: (match_operand:SI 2 "nonmemory_operand" "")))]
1046: ""
1047: "
1048: {
1049: if (GET_CODE (operands[2]) != CONST_INT
1050: || (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands[2]) > 1))
1051: FAIL;
1052: }")
1053:
1054: ;; Unconditional and other jump instructions
1055: (define_insn "jump"
1056: [(set (pc)
1057: (label_ref (match_operand 0 "" "")))]
1058: ""
1059: "jump %l0\;nop")
1060:
1061: (define_insn "tablejump"
1062: [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1063: (use (label_ref (match_operand 1 "" "")))]
1064: ""
1065: "jump_reg r0,%0\;nop")
1066:
1067: ;;- jump to subroutine
1068: (define_insn "call"
1069: [(call (match_operand:SI 0 "memory_operand" "m")
1070: (match_operand:SI 1 "general_operand" "g"))]
1071: ;;- Don't use operand 1 for most machines.
1072: ""
1073: "add_nt r2,%0\;call .+8\;jump_reg r0,r2\;nop")
1074:
1075: (define_insn "call_value"
1076: [(set (match_operand 0 "" "=g")
1077: (call (match_operand:SI 1 "memory_operand" "m")
1078: (match_operand:SI 2 "general_operand" "g")))]
1079: ;;- Don't use operand 1 for most machines.
1080: ""
1081: "add_nt r2,%1\;call .+8\;jump_reg r0,r2\;nop")
1082:
1083: ;; A memory ref with constant address is not normally valid.
1084: ;; But it is valid in a call insns. This pattern allows the
1085: ;; loading of the address to combine with the call.
1086: (define_insn ""
1087: [(call (mem:SI (match_operand:SI 0 "" "i"))
1088: (match_operand:SI 1 "general_operand" "g"))]
1089: ;;- Don't use operand 1 for most machines.
1090: "GET_CODE (operands[0]) == SYMBOL_REF"
1091: "call %0\;nop")
1092:
1093: (define_insn ""
1094: [(set (match_operand 0 "" "=g")
1095: (call (mem:SI (match_operand:SI 1 "" "i"))
1096: (match_operand:SI 2 "general_operand" "g")))]
1097: ;;- Don't use operand 1 for most machines.
1098: "GET_CODE (operands[1]) == SYMBOL_REF"
1099: "call %1\;nop")
1100:
1101: (define_insn "nop"
1102: [(const_int 0)]
1103: ""
1104: "nop")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.