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