|
|
1.1 root 1: ;; Mips.md Naive version of Machine Description for MIPS
2: ;; Contributed by A. Lichnewsky, [email protected]
1.1.1.3 root 3: ;; Changes by Michael Meissner, [email protected]
4: ;; Copyright (C) 1989, 1990 Free Software Foundation, Inc.
1.1 root 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 1, 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: ;;
23: ;;------------------------------------------------------------------------
24: ;;
25:
26: ;;
27: ;; ....................
28: ;;
29: ;; Peephole Optimizations for
30: ;;
31: ;; ARITHMETIC
32: ;;
33: ;; ....................
34: ;;
35: ;;- The following peepholes are
36: ;;- motivated by the fact that
37: ;;- stack movement result in some
38: ;;- cases in embarrassing sequences
39: ;;- of addiu SP,SP,int
40: ;;- addiu SP,SP,other_int
41:
42: ;;- --------------------
43: ;;- REMARK: this would be done better
44: ;;- by analysis of dependencies in
45: ;;- basic blocks, prior to REG ALLOC,
46: ;;- and simplification of trees:
47: ;;- (+ (+ REG const) const)
48: ;;- -> (+ REG newconst)
49: ;;- --------------------
1.1.1.3 root 50: ;;- Merged peephole code from
51: ;;- [email protected]
1.1 root 52:
53: (define_peephole
1.1.1.3 root 54: [(set (match_operand:SI 0 "register_operand" "=r")
55: (match_operator 1 "additive_op"
56: [(match_operand:SI 2 "register_operand" "r")
57: (match_operand:SI 3 "small_int" "I")]))
58: (set (match_operand:SI 4 "register_operand" "=r")
59: (match_operator 5 "additive_op"
60: [(match_dup 0)
61: (match_operand:SI 6 "small_int" "I")]))]
62: "(REGNO (operands[0]) == REGNO (operands[4])
63: || dead_or_set_p (insn, operands[0]))"
64: "*
65: {
66: int addend;
67: /* compute sum, with signs */
68: addend = INTVAL (operands[3]) * (GET_CODE (operands[1]) == PLUS ? 1 : -1);
69: addend += INTVAL (operands[6]) * (GET_CODE (operands[5]) == PLUS ? 1 : -1);
70: if (addend != 0)
71: {
72: operands[0] = gen_rtx (CONST_INT, VOIDmode, addend);
73: return \"addi%:\\t%4,%2,%0\";
74: }
75: /* value is zero; copy */
76: if (REGNO (operands[4]) != REGNO (operands[2]))
77: return \"add%:\\t%4,%2,$0\";
78: /* copying to self; punt */
79: return \" # null operation: additive operands cancel (%0,%2)\";
1.1 root 80: }")
81:
82: ;;
83: ;; ....................
84: ;;
85: ;; ARITHMETIC
86: ;;
87: ;; ....................
88: ;;
89:
90: (define_insn "adddf3"
1.1.1.3 root 91: [(set (match_operand:DF 0 "register_operand" "=f")
92: (plus:DF (match_operand:DF 1 "register_operand" "f")
93: (match_operand:DF 2 "register_operand" "f")))]
1.1 root 94: ""
95: "add.d\\t%0,%1,%2")
96:
97: (define_insn "addsf3"
1.1.1.3 root 98: [(set (match_operand:SF 0 "register_operand" "=f")
99: (plus:SF (match_operand:SF 1 "register_operand" "f")
100: (match_operand:SF 2 "register_operand" "f")))]
1.1 root 101: ""
102: "add.s\\t%0,%1,%2")
103:
1.1.1.3 root 104: ;; The following is generated when omiting the frame pointer
105: ;; and for referencing large auto arrays during optimization.
106:
107: (define_insn ""
1.1 root 108: [(set (match_operand:SI 0 "register_operand" "=r")
109: (plus:SI (match_operand:SI 1 "register_operand" "%r")
1.1.1.3 root 110: (match_operand:SI 2 "immediate_operand" "i")))]
111: "operands[1] == stack_pointer_rtx || operands[1] == frame_pointer_rtx"
1.1 root 112: "*
113: {
1.1.1.3 root 114: int number;
115: if (GET_CODE (operands[2]) != CONST_INT)
116: return \"add%:\\t%0,%1,%2\";
1.1 root 117:
1.1.1.3 root 118: number = INTVAL (operands[2]);
119: if (((unsigned) (number + 0x8000) > 0xffff))
1.1 root 120: {
1.1.1.3 root 121: operands[3] = gen_rtx (REG, SImode, 1); /* assembler temp. */
122: return \".set\\tnoat\\n\\tli\\t%3,%2\\n\\tadd%:\\t%0,%1,%3\\n\\t.set\\tat\";
1.1 root 123: }
124:
1.1.1.3 root 125: return (number < 0) ? \"sub%:\\t%0,%1,%n2\" : \"add%:\\t%0,%1,%2\";
1.1 root 126: }")
127:
1.1.1.3 root 128: (define_insn "addsi3"
129: [(set (match_operand:SI 0 "register_operand" "=r")
130: (plus:SI (match_operand:SI 1 "arith_operand" "%r")
131: (match_operand:SI 2 "arith_operand" "rI")))]
1.1 root 132: ""
133: "*
134: {
1.1.1.3 root 135: return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
136: ? \"sub%:\\t%0,%1,%n2\"
137: : \"add%:\\t%0,%1,%2\";
1.1 root 138: }")
1.1.1.3 root 139:
1.1 root 140:
141: ;;- All kinds of subtract instructions.
142:
143: (define_insn "subdf3"
1.1.1.3 root 144: [(set (match_operand:DF 0 "register_operand" "=f")
145: (minus:DF (match_operand:DF 1 "register_operand" "f")
146: (match_operand:DF 2 "register_operand" "f")))]
1.1 root 147: ""
148: "sub.d\\t%0,%1,%2")
149:
150: (define_insn "subsf3"
1.1.1.3 root 151: [(set (match_operand:SF 0 "register_operand" "=f")
152: (minus:SF (match_operand:SF 1 "register_operand" "f")
153: (match_operand:SF 2 "register_operand" "f")))]
1.1 root 154: ""
155: "sub.s\\t%0,%1,%2")
156:
1.1.1.3 root 157: ;; The following is generated when omiting the frame pointer
158: ;; and for referencing large auto arrays during optimization.
1.1 root 159:
1.1.1.3 root 160: (define_insn ""
161: [(set (match_operand:SI 0 "register_operand" "=r")
162: (minus:SI (match_operand:SI 1 "register_operand" "%r")
163: (match_operand:SI 2 "immediate_operand" "i")))]
164: "operands[1] == stack_pointer_rtx || operands[1] == frame_pointer_rtx"
1.1 root 165: "*
166: {
1.1.1.3 root 167: int number;
168: if (GET_CODE (operands[2]) != CONST_INT)
169: return \"sub%:\\t%0,%1,%2\";
170:
171: number = INTVAL (operands[2]);
172: if (((unsigned) (number + 0x8000) > 0xffff))
1.1 root 173: {
1.1.1.3 root 174: operands[3] = gen_rtx (REG, SImode, 1); /* assembler temp. */
175: return \".set\\tnoat\\n\\tli\\t%3,%2\\n\\tsub%:\\t%0,%1,%3\\n\\t.set\\tat\";
1.1 root 176: }
1.1.1.3 root 177:
178: return (number < 0) ? \"add%:\\t%0,%1,%n2\" : \"sub%:\\t%0,%1,%2\";
1.1 root 179: }")
180:
1.1.1.3 root 181: (define_insn "subsi3"
182: [(set (match_operand:SI 0 "register_operand" "=r")
183: (minus:SI (match_operand:SI 1 "register_operand" "r")
184: (match_operand:SI 2 "arith_operand" "rI")))]
1.1 root 185: ""
186: "*
187: {
1.1.1.3 root 188: return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
189: ? \"add%:\\t%0,%1,%n2\"
190: : \"sub%:\\t%0,%1,%2\";
1.1 root 191: }")
1.1.1.3 root 192:
1.1 root 193:
194: ;;- Multiply instructions.
195:
196: (define_insn "muldf3"
1.1.1.3 root 197: [(set (match_operand:DF 0 "register_operand" "=f")
198: (mult:DF (match_operand:DF 1 "register_operand" "f")
199: (match_operand:DF 2 "register_operand" "f")))]
1.1 root 200: ""
201: "mul.d\\t%0,%1,%2")
202:
203: (define_insn "mulsf3"
1.1.1.3 root 204: [(set (match_operand:SF 0 "register_operand" "=f")
205: (mult:SF (match_operand:SF 1 "register_operand" "f")
206: (match_operand:SF 2 "register_operand" "f")))]
1.1 root 207: ""
208: "mul.s\\t%0,%1,%2")
209:
210: (define_insn "mulsi3"
1.1.1.3 root 211: [(set (match_operand:SI 0 "register_operand" "=r")
212: (mult:SI (match_operand:SI 1 "arith_operand" "%r")
213: (match_operand:SI 2 "arith_operand" "rI")))]
1.1 root 214: ""
1.1.1.3 root 215: "mul\\t%0,%1,%2")
1.1 root 216:
217:
218: ;;- Divide instructions.
219:
220: (define_insn "divdf3"
1.1.1.3 root 221: [(set (match_operand:DF 0 "register_operand" "=f")
222: (div:DF (match_operand:DF 1 "register_operand" "f")
223: (match_operand:DF 2 "register_operand" "f")))]
1.1 root 224: ""
1.1.1.3 root 225: "div.d\\t%0,%1,%2")
1.1 root 226:
227: (define_insn "divsf3"
1.1.1.3 root 228: [(set (match_operand:SF 0 "register_operand" "=f")
229: (div:SF (match_operand:SF 1 "register_operand" "f")
230: (match_operand:SF 2 "register_operand" "f")))]
1.1 root 231: ""
232: "div.s\\t%0,%1,%2")
233:
1.1.1.3 root 234: (define_insn "divmodsi4"
235: [(set (match_operand:SI 0 "register_operand" "=r")
236: (div:SI (match_operand:SI 1 "register_operand" "r")
237: (match_operand:SI 2 "arith_operand" "rI")))
238: (set (match_operand:SI 3 "register_operand" "=r")
239: (mod:SI (match_dup 1)
240: (match_dup 2)))]
241: ""
242: "div\\t$0,%1,%2\\n\\tmflo\\t%0\\t\\t#quotient\\n\\tmfhi\\t%3\\t\\t#remainder")
243:
1.1 root 244: (define_insn "divsi3"
1.1.1.3 root 245: [(set (match_operand:SI 0 "register_operand" "=r")
246: (div:SI (match_operand:SI 1 "register_operand" "r")
247: (match_operand:SI 2 "arith_operand" "rI")))]
248: ""
249: "div\\t%0,%1,%2")
250:
251: (define_insn "udivmodsi4"
252: [(set (match_operand:SI 0 "register_operand" "=r")
253: (udiv:SI (match_operand:SI 1 "register_operand" "r")
254: (match_operand:SI 2 "arith_operand" "rI")))
255: (set (match_operand:SI 3 "register_operand" "=r")
256: (umod:SI (match_dup 1)
257: (match_dup 2)))]
258: ""
259: "divu\\t$0,%1,%2\\n\\tmflo\\t%0\\t\\t#quotient\\n\\tmfhi\\t%3\\t\\t#remainder")
260:
261: (define_insn "udivsi3"
262: [(set (match_operand:SI 0 "register_operand" "=r")
263: (udiv:SI (match_operand:SI 1 "register_operand" "r")
264: (match_operand:SI 2 "arith_operand" "rI")))]
265: ""
266: "divu\\t%0,%1,%2")
267:
268:
269: ;; Remainder instructions
270:
271:
272: (define_insn "modsi3"
273: [(set (match_operand:SI 0 "register_operand" "=r")
274: (mod:SI (match_operand:SI 1 "register_operand" "r")
275: (match_operand:SI 2 "arith_operand" "rI")))]
276: ""
277: "rem\\t%0,%1,%2")
278:
279: (define_insn "umodsi3"
280: [(set (match_operand:SI 0 "register_operand" "=r")
281: (umod:SI (match_operand:SI 1 "register_operand" "r")
282: (match_operand:SI 2 "arith_operand" "rI")))]
1.1 root 283: ""
1.1.1.3 root 284: "remu\\t%0,%1,%2")
285:
286:
287: ;; Absoluate value instructions -- Don't use the integer abs,
288: ;; since that signals an exception on -2147483648 (sigh).
1.1 root 289:
1.1.1.3 root 290: (define_insn "abssf2"
291: [(set (match_operand:SF 0 "register_operand" "=f")
292: (abs:SF (match_operand:SF 1 "register_operand" "f")))]
1.1 root 293: ""
1.1.1.3 root 294: "abs.s\\t%0,%1")
1.1 root 295:
1.1.1.3 root 296: (define_insn "absdf2"
297: [(set (match_operand:DF 0 "register_operand" "=f")
298: (abs:DF (match_operand:DF 1 "register_operand" "f")))]
1.1 root 299: ""
1.1.1.3 root 300: "abs.d\\t%0,%1")
1.1 root 301:
302: ;;
303: ;; ....................
304: ;;
305: ;; LOGICAL
306: ;;
307: ;; ....................
308: ;;
309:
310: (define_insn "anddi3"
1.1.1.3 root 311: [(set (match_operand:DI 0 "register_operand" "=&r")
312: (and:DI (match_operand:DI 1 "register_operand" "r")
313: (match_operand:DI 2 "register_operand" "r")))]
1.1 root 314: ""
1.1.1.3 root 315: "and\\t%0,%1,%2\;and\\t%D0,%D1,%D2")
1.1 root 316:
317: (define_insn "andsi3"
1.1.1.3 root 318: [(set (match_operand:SI 0 "register_operand" "=r")
319: (and:SI (match_operand:SI 1 "uns_arith_operand" "%r")
320: (match_operand:SI 2 "uns_arith_operand" "rK")))]
1.1 root 321: ""
322: "*
323: {
1.1.1.3 root 324: return (GET_CODE (operands[2]) == CONST_INT)
325: ? \"andi\\t%0,%1,%x2\"
326: : \"and\\t%0,%1,%2\";
327: }")
328:
329:
330: ;; Simple hack to recognize the "nor" instruction on the MIPS
331: ;; [rms: I don't think the following is actually required.]
332: ;; This must appear before the normal or patterns, so that the
333: ;; combiner will correctly fold things.
334:
335: (define_insn ""
336: [(set (match_operand:DI 0 "register_operand" "=r")
337: (not:DI (ior:DI (match_operand:DI 1 "register_operand" "r")
338: (match_operand:DI 2 "register_operand" "r"))))]
339: ""
340: "nor\\t%0,%1,%2\;nor\\t%D0,%D1,%D2")
341:
342: (define_insn ""
343: [(set (match_operand:SI 0 "register_operand" "=r")
344: (not:SI (ior:SI (match_operand:SI 1 "register_operand" "r")
345: (match_operand:SI 2 "register_operand" "r"))))]
1.1 root 346: ""
1.1.1.3 root 347: "nor\\t%0,%1,%2")
1.1 root 348:
349: (define_insn "iordi3"
1.1.1.3 root 350: [(set (match_operand:DI 0 "register_operand" "=&r")
351: (ior:DI (match_operand:DI 1 "register_operand" "r")
352: (match_operand:DI 2 "register_operand" "r")))]
1.1 root 353: ""
1.1.1.3 root 354: "or\\t%0,%1,%2\;or\\t%D0,%D1,%D2")
1.1 root 355:
356: (define_insn "iorsi3"
1.1.1.3 root 357: [(set (match_operand:SI 0 "register_operand" "=r")
358: (ior:SI (match_operand:SI 1 "uns_arith_operand" "%r")
359: (match_operand:SI 2 "uns_arith_operand" "rJ")))]
1.1 root 360: ""
361: "*
362: {
1.1.1.3 root 363: return (GET_CODE (operands[2]) == CONST_INT)
364: ? \"ori\\t%0,%1,%x2\"
365: : \"or\\t%0,%1,%2\";
1.1 root 366: }")
367:
368: (define_insn "xordi3"
1.1.1.3 root 369: [(set (match_operand:DI 0 "register_operand" "=&r")
370: (xor:DI (match_operand:DI 1 "register_operand" "r")
371: (match_operand:DI 2 "register_operand" "r")))]
1.1 root 372: ""
1.1.1.3 root 373: "xor\\t%0,%1,%2\;xor\\t%D0,%D1,%D2")
1.1 root 374:
375: (define_insn "xorsi3"
1.1.1.3 root 376: [(set (match_operand:SI 0 "register_operand" "=r")
377: (xor:SI (match_operand:SI 1 "uns_arith_operand" "%r")
378: (match_operand:SI 2 "uns_arith_operand" "rK")))]
1.1 root 379: ""
380: "*
381: {
1.1.1.3 root 382: return (GET_CODE (operands[2]) == CONST_INT)
383: ? \"xori\\t%0,%1,%x2\"
384: : \"xor\\t%0,%1,%2\";
1.1 root 385: }")
386:
387: ;;
388: ;; ....................
389: ;;
390: ;; TRUNCATION
391: ;;
392: ;; ....................
393:
394: ;; Extension and truncation insns.
395: ;; Those for integer source operand
396: ;; are ordered widest source type first.
397:
398:
399: (define_insn "truncsiqi2"
1.1.1.3 root 400: [(set (match_operand:QI 0 "register_operand" "=r")
401: (truncate:QI (match_operand:SI 1 "register_operand" "r")))]
1.1 root 402: ""
403: "andi\\t%0,%1,0xff\\t#truncsiqi2\\t %1 -> %0")
404:
405: (define_insn "truncsihi2"
1.1.1.3 root 406: [(set (match_operand:HI 0 "register_operand" "=r")
407: (truncate:HI (match_operand:SI 1 "register_operand" "r")))]
1.1 root 408: ""
409: "*
410: output_asm_insn (\"sll\\t%0,%1,0x10\\t#truncsihi2\\t %1 -> %0\",
411: operands);
412: return \"sra\\t%0,%0,0x10\\t#truncsihi2\\t %1 -> %0\";
413: ")
414:
415: (define_insn "trunchiqi2"
1.1.1.3 root 416: [(set (match_operand:QI 0 "register_operand" "=r")
417: (truncate:QI (match_operand:HI 1 "register_operand" "r")))]
1.1 root 418: ""
419: "andi\\t%0,%1,0xff\\t#trunchiqi2\\t %1 -> %0")
420:
421: (define_insn "truncdfsf2"
1.1.1.3 root 422: [(set (match_operand:SF 0 "register_operand" "=f")
423: (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
1.1 root 424: ""
425: "cvt.s.d\\t%0,%1\\t#truncdfsf2\\t %1 -> %0")
426:
427: ;;
428: ;; ....................
429: ;;
430: ;; ZERO EXTENSION
431: ;;
432: ;; ....................
433:
434: ;; Extension insns.
435: ;; Those for integer source operand
436: ;; are ordered widest source type first.
437:
438:
439:
440: (define_insn "zero_extendhisi2"
1.1.1.3 root 441: [(set (match_operand:SI 0 "register_operand" "=r,r")
1.1 root 442: (zero_extend:SI (match_operand:HI 1 "general_operand" "r,m")))]
443: ""
444: "*
445: {
446: if (which_alternative == 0)
447: {
448: output_asm_insn (\"sll\\t%0,%1,0x10\\t#zero_extendhisi2\\t %1 -> %0\",
449: operands);
450: return \"srl\\t%0,%0,0x10\\t#zero_extendhisi2\\t %1 -> %0\";
451: }
452: else
453: return \"lhu\\t%0,%1\\t#zero extendhisi2 %1 -> %0\";
454: }")
455:
456: (define_insn "zero_extendqihi2"
1.1.1.3 root 457: [(set (match_operand:HI 0 "register_operand" "=r")
458: (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1.1 root 459: ""
460: "*
461: output_asm_insn (\"sll\\t%0,%1,0x18\\t#zero_extendqihi2\\t %1 -> %0\",
462: operands);
463: return \"srl\\t%0,%0,0x18\\t#zero_extendqihi2\\t %1 -> %0\";
464: ")
465:
466:
467: (define_insn "zero_extendqisi2"
1.1.1.3 root 468: [(set (match_operand:SI 0 "register_operand" "=r,r")
1.1 root 469: (zero_extend:SI (match_operand:QI 1 "general_operand" "r,m")))]
470: ""
471: "*
472: {
473: if (which_alternative == 0)
474: {
475: return \"andi\\t%0,%1,0xff\\t#zero_extendqisi2\\t %1 -> %0\";
476: }
477: else
478: return \"lbu\\t%0,%1\\t#zero extendqisi2 %1 -> %0\";
479: }")
480:
481:
482: ;;
483: ;; ....................
484: ;;
485: ;; SIGN EXTENSION
486: ;;
487: ;; ....................
488:
489: ;; Extension insns.
490: ;; Those for integer source operand
491: ;; are ordered widest source type first.
492:
493:
494:
495: (define_insn "extendhisi2"
1.1.1.3 root 496: [(set (match_operand:SI 0 "register_operand" "=r,r")
1.1 root 497: (sign_extend:SI (match_operand:HI 1 "general_operand" "r,m")))]
498: ""
499: "*
500: {
501: if (which_alternative == 0)
502: {
503: output_asm_insn (\"sll\\t%0,%1,0x10\\t#sign extendhisi2\\t %1 -> %0\",
504: operands);
505: return \"sra\\t%0,%0,0x10\\t#sign extendhisi2\\t %1 -> %0\";
506: }
507: else
508: return \"lh\\t%0,%1\\t#sign extendhisi2 %1 -> %0\";
509: }")
510:
511: (define_insn "extendqihi2"
1.1.1.3 root 512: [(set (match_operand:HI 0 "register_operand" "=r")
513: (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1.1 root 514: ""
515: "*
516: output_asm_insn (\"sll\\t%0,%1,0x18\\t#sign extendqihi2\\t %1 -> %0\",
517: operands);
518: return \"sra\\t%0,%0,0x18\\t#sign extendqihi2\\t %1 -> %0\";
519: ")
520:
521:
522: (define_insn "extendqisi2"
1.1.1.3 root 523: [(set (match_operand:SI 0 "register_operand" "=r,r")
1.1 root 524: (sign_extend:SI (match_operand:QI 1 "general_operand" "r,m")))]
525: ""
526: "*
527: {
528: if (which_alternative == 0)
529: {
530: output_asm_insn (\"sll\\t%0,%1,0x18\\t#sign extendqisi2\\t %1 -> %0\",
531: operands);
532: return \"sra\\t%0,%0,0x18\\t#sign extendqisi2\\t %1 -> %0\";
533: }
534: else
535: return \"lb\\t%0,%1\\t#sign extendqisi2 %1 -> %0\";
536: }")
537:
538:
539: (define_insn "extendsfdf2"
1.1.1.3 root 540: [(set (match_operand:DF 0 "register_operand" "=f")
541: (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
1.1 root 542: ""
543: "cvt.d.s\\t%0,%1\\t#extendsfdf2\\t %1 -> %0")
544:
545:
546: ;;
547: ;; ....................
548: ;;
549: ;; CONVERSIONS
550: ;;
551: ;; ....................
552:
553:
1.1.1.3 root 554: (define_insn "fix_truncdfsi2_internal"
555: [(set (match_operand:DF 0 "register_operand" "=f")
556: (fix:DF (match_operand:DF 1 "register_operand" "f")))
557: (clobber (match_operand:SI 2 "register_operand" "r"))]
558: ""
559: "trunc.w.d %0,%1,%2")
560:
561: (define_insn ""
562: [(set (match_operand:SI 0 "register_operand" "=r")
563: (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
564: ""
565: "mfc1\\t%0,%1")
566:
567: (define_expand "fix_truncdfsi2"
568: [(set (match_operand:SI 0 "register_operand" "=r")
569: (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
570: ""
571: "
572: {
573: rtx reg1 = gen_reg_rtx (DFmode); /* fp reg that gets trunc result */
574: rtx reg2 = gen_reg_rtx (SImode); /* gp reg that saves FP status bits */
575: emit_insn (gen_fix_truncdfsi2_internal (reg1, operands[1], reg2));
576: operands[1] = reg1;
577: /* Fall through and generate default code */
578: }")
579:
580: (define_insn "fix_truncsfsi2_internal"
581: [(set (match_operand:SF 0 "register_operand" "=f")
582: (fix:SF (match_operand:SF 1 "register_operand" "f")))
583: (clobber (match_operand:SI 2 "register_operand" "r"))]
1.1 root 584: ""
1.1.1.3 root 585: "trunc.w.s %0,%1,%2")
1.1 root 586:
1.1.1.3 root 587: (define_insn ""
588: [(set (match_operand:SI 0 "register_operand" "=r")
589: (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
590: ""
591: "mfc1\\t%0,%1")
1.1 root 592:
1.1.1.3 root 593: (define_expand "fix_truncsfsi2"
594: [(set (match_operand:SI 0 "register_operand" "=r")
595: (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1.1 root 596: ""
1.1.1.3 root 597: "
598: {
599: rtx reg1 = gen_reg_rtx (SFmode); /* fp reg that gets trunc result */
600: rtx reg2 = gen_reg_rtx (SImode); /* gp reg that saves FP status bits */
601: emit_insn (gen_fix_truncsfsi2_internal (reg1, operands[1], reg2));
602: operands[1] = reg1;
603: /* Fall through and generate default code */
604: }")
1.1 root 605:
606: (define_insn "floatsidf2"
1.1.1.3 root 607: [(set (match_operand:DF 0 "register_operand" "=f")
608: (float:DF (match_operand:SI 1 "register_operand" "r")))]
1.1 root 609: ""
1.1.1.3 root 610: "mtc1\\t%1,%0\\t\\t#floatsidf2\\t%1 -> %0\;cvt.d.w\\t%0,%0")
1.1 root 611:
612:
613: (define_insn "floatsisf2"
1.1.1.3 root 614: [(set (match_operand:SF 0 "register_operand" "=f")
615: (float:SF (match_operand:SI 1 "register_operand" "r")))]
616: ""
617: "mtc1\\t%1,%0\\t\\t#floatsisf2\\t%1 -> %0\;cvt.s.w\\t%0,%0")
618:
619: (define_expand "fixuns_truncdfsi2"
620: [(set (match_operand:SI 0 "register_operand" "")
621: (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
622: ""
623: "
624: {
625: rtx reg1 = gen_reg_rtx (DFmode);
626: rtx reg2 = gen_reg_rtx (DFmode);
627: rtx reg3 = gen_reg_rtx (SImode);
628: rtx label1 = gen_label_rtx ();
629: rtx label2 = gen_label_rtx ();
630: REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
631:
632: if (reg1) /* turn off complaints about unreached code */
633: {
634: emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
635: do_pending_stack_adjust ();
636: emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx,
637: gen_rtx (COMPARE, DFmode, operands[1], reg1)));
638:
639: emit_jump_insn (gen_bge (label1));
640:
641: emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
642: emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
643: gen_rtx (LABEL_REF, VOIDmode, label2)));
644: emit_barrier ();
645:
646: emit_label (label1);
647: emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
648: emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
649:
650: emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
651: emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
652:
653: emit_label (label2);
654:
655: /* allow REG_NOTES to be set on last insn (labels don't have enough
656: fields, and can't be used for REG_NOTES anyway). */
657: emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
658: DONE;
659: }
660: }")
661:
662: (define_expand "fixuns_truncsfsi2"
663: [(set (match_operand:SI 0 "register_operand" "")
664: (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
1.1 root 665: ""
1.1.1.3 root 666: "
667: {
668: rtx reg1 = gen_reg_rtx (SFmode);
669: rtx reg2 = gen_reg_rtx (SFmode);
670: rtx reg3 = gen_reg_rtx (SImode);
671: rtx label1 = gen_label_rtx ();
672: rtx label2 = gen_label_rtx ();
673: REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
674:
675: if (reg1) /* turn off complaints about unreached code */
676: {
677: emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
678: do_pending_stack_adjust ();
679: emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx,
680: gen_rtx (COMPARE, SFmode, operands[1], reg1)));
681:
682: emit_jump_insn (gen_bge (label1));
683:
684: emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
685: emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
686: gen_rtx (LABEL_REF, VOIDmode, label2)));
687: emit_barrier ();
688:
689: emit_label (label1);
690: emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
691: emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
692:
693: emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
694: emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
695:
696: emit_label (label2);
697:
698: /* allow REG_NOTES to be set on last insn (labels don't have enough
699: fields, and can't be used for REG_NOTES anyway). */
700: emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
701: DONE;
702: }
703: }")
1.1 root 704:
705: ;;- Wild things used when
706: ;;- unions make double and int
707: ;;- overlap.
708: ;;-
709: ;;- This must be supported
710: ;;- since corresponding code
711: ;;- gets generated
712:
713: (define_insn ""
714: [(set (subreg:DF (match_operand:DI 0 "register_operand" "=ry") 0)
715: (match_operand:DF 1 "register_operand" "rf"))
716: (clobber (match_operand 2 "register_operand" "rf"))]
717: ""
1.1.1.3 root 718: "mfc1\\t%0,%L1\;mfc1\\t%D0,%M1")
1.1 root 719:
720: (define_insn ""
721: [(set (subreg:DF (match_operand:DI 0 "register_operand" "=ry") 0)
722: (match_operand:DF 1 "register_operand" "rf"))]
723: ""
1.1.1.3 root 724: "mfc1\\t%0,%L1\;mfc1\\t%D0,%M1")
1.1 root 725:
726: (define_insn ""
1.1.1.3 root 727: [(set (match_operand:DF 0 "register_operand" "=rf")
1.1 root 728: (subreg:DF (match_operand:DI 1 "register_operand" "ry") 0))
729: (clobber (match_operand 2 "register_operand" "rf"))]
730: ""
1.1.1.3 root 731: "mfc1\\t%0,%L1\;mfc1\\t%D0,%M1")
1.1 root 732:
733: (define_insn ""
1.1.1.3 root 734: [(set (match_operand:DF 0 "register_operand" "=rf")
1.1 root 735: (subreg:DF (match_operand:DI 1 "register_operand" "ry") 0))]
736: ""
1.1.1.3 root 737: "mfc1\\t%0,%L1\;mfc1\\t%D0,%M1")
1.1 root 738:
739: ;;
740: ;; ....................
741: ;;
742: ;; MOVES
743: ;;
744: ;; and
745: ;;
746: ;; LOADS AND STORES
747: ;;
748: ;; ....................
749:
1.1.1.4 ! root 750: ;; unaligned word moves generated to move unaligned structs
! 751: ;; to/from registers.
! 752: ;; We use (use (reg:SI 0)) to select this pattern rather than the
! 753: ;; normal movsi. Make these before the normal move patterns so they
! 754: ;; match first.
! 755:
! 756: (define_expand "movsi_unaligned"
! 757: [(parallel [(set (match_operand:SI 0 "general_operand" "")
! 758: (match_operand:SI 1 "general_operand" ""))
! 759: (use (reg:SI 0))])]
! 760: ""
! 761: "
! 762: {
! 763: extern rtx force_reg ();
! 764: extern rtx gen_movsi_ulw ();
! 765: extern rtx gen_movsi ();
! 766:
! 767: if (GET_CODE (operands[0]) == MEM && !register_operand (operands[1], SImode))
! 768: {
! 769: rtx reg = gen_reg_rtx (SImode);
! 770:
! 771: emit_insn (gen_movsi_ulw (reg, operands[1]));
! 772: operands[1] = reg;
! 773: }
! 774:
! 775: /* Generate appropriate load, store. If not a load or store,
! 776: do a normal movsi. */
! 777: if (GET_CODE (operands[0]) != MEM && GET_CODE (operands[1]) != MEM)
! 778: {
! 779: emit_insn (gen_movsi (operands[0], operands[1]));
! 780: DONE;
! 781: }
! 782:
! 783: /* Fall through and generate normal code. */
! 784: }")
! 785:
! 786: (define_insn "movsi_ulw"
! 787: [(set (match_operand:SI 0 "register_operand" "=&r,r,r")
! 788: (match_operand:SI 1 "general_operand" "o,r,n"))
! 789: (use (reg:SI 0))]
! 790: ""
! 791: "*
! 792: {
! 793: extern rtx eliminate_constant_term ();
! 794:
! 795: switch (which_alternative)
! 796: {
! 797: case 0: /* reg <- memory */
! 798: {
! 799: int offset = 0;
! 800: rtx addr = XEXP (operands[1], 0);
! 801: rtx mem_addr = eliminate_constant_term (addr, &offset);
! 802:
! 803: /* The stack/frame pointers are always aligned, so we can convert
! 804: to the faster lw if we are referencing an aligned stack location. */
! 805:
! 806: if ((offset & ~3) == 0
! 807: && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
! 808: return \"lw\\t%0,%1\";
! 809:
! 810: if (TARGET_GAS)
! 811: {
! 812: enum rtx_code code = GET_CODE (addr);
! 813: if (code == CONST || code == SYMBOL_REF || code == LABEL_REF)
! 814: {
! 815: operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 1);
! 816: return \".set\\tnoat\\n\\tla\\t%2,%1\;ulw\\t%0,0(%2)\\n\\t.set\\tat\";
! 817: }
! 818: }
! 819: }
! 820:
! 821: return \"ulw\\t%0,%1\";
! 822:
! 823: case 1: /* reg <- reg */
! 824: return \"move\\t%0,%1\";
! 825:
! 826: case 2: /* reg <- integer constant */
! 827: return \"li\\t%0,%1\";
! 828: }
! 829: }")
! 830:
! 831: (define_insn "movsi_usw"
! 832: [(set (match_operand:SI 0 "memory_operand" "=&o")
! 833: (match_operand:SI 1 "register_operand" "r"))
! 834: (use (reg:SI 0))]
! 835: ""
! 836: "*
! 837: {
! 838: extern rtx eliminate_constant_term ();
! 839: int offset = 0;
! 840: rtx addr = XEXP (operands[0], 0);
! 841: rtx mem_addr = eliminate_constant_term (addr, &offset);
! 842:
! 843: /* The stack/frame pointers are always aligned, so we can convert
! 844: to the faster sw if we are referencing an aligned stack location.
! 845: At present, it is not recognized if the frame pointer is omitted. */
! 846:
! 847: if ((offset & ~3) == 0
! 848: && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
! 849: return \"sw\\t%1,%0\";
! 850:
! 851: if (TARGET_GAS)
! 852: {
! 853: enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
! 854: if (code == CONST || code == SYMBOL_REF || code == LABEL_REF)
! 855: {
! 856: operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 1);
! 857: return \".set\\tnoat\\n\\tla\\t%2,%0\;usw\\t%1,0(%2)\\n\\t.set\\tat\";
! 858: }
! 859: }
! 860:
! 861: return \"usw\\t%1,%0\";
! 862: }")
! 863:
1.1 root 864: (define_insn "movdi"
865: [(set (match_operand:DI 0 "general_operand" "=r,*r,*m")
866: (match_operand:DI 1 "general_operand" "r,*miF,*r"))]
867: ""
868: "*
869: {
1.1.1.3 root 870: extern rtx adj_offsettable_operand ();
871: extern int offsettable_address_p ();
1.1 root 872:
873: if (which_alternative == 0)
874: {
1.1.1.3 root 875: /* Move REGISTER <- REGISTER */
876: if (REGNO (operands[0]) != (REGNO (operands[1])+1))
877: return \"move\\t%0,%1\\n\\tmove\\t%D0,%D1\";
1.1 root 878: else
1.1.1.3 root 879: return \"move\\t%D0,%D1\\n\\tmove\\t%0,%1\";
1.1 root 880: }
1.1.1.3 root 881:
1.1 root 882: else if (which_alternative == 1)
883: {
884: if (GET_CODE (operands[1]) == MEM)
885: {
1.1.1.3 root 886: /* REGISTER <- MEMORY */
887: if (offsettable_address_p (1, DImode, XEXP (operands[1], 0)))
888: {
889: operands[2] = adj_offsettable_operand (operands[1], 4);
890: return \"lw\\t%0,%1\;lw\\t%D0,%2\";
891: }
892:
893: else
894: {
895: operands[2] = gen_rtx (REG, Pmode, 1);
896: return \".set\\tnoat\;la\\t%2,%1\;lw\\t%0,0(%2)\;lw\\t%D0,4(%2)\;set\\tat\";
897: }
1.1 root 898: }
1.1.1.3 root 899:
900: /* REGISTER <- small integer constant */
1.1 root 901: else if (CONSTANT_P (operands[1]))
902: {
1.1.1.3 root 903: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) >= 0 ? 0 : -1);
904: return \"li\\t%M0,%2\;li\\t%L0,%1\";
1.1 root 905: }
1.1.1.3 root 906:
907: /* Register <- large integer constant */
1.1 root 908: else if (GET_CODE (operands[1]) == CONST_DOUBLE)
909: {
1.1.1.3 root 910: operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[1]));
911: operands[3] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (operands[1]));
912: return \"li\\t%M0,%3\;li\\t%L0,%2\";
1.1 root 913: }
914: }
1.1.1.3 root 915:
916: else if (which_alternative == 2 && GET_CODE (operands[0]) == MEM)
1.1 root 917: {
1.1.1.3 root 918: /* Memory <- Register */
919: if (offsettable_address_p (1, DImode, XEXP (operands[0], 0)))
1.1 root 920: {
1.1.1.3 root 921: operands[2] = adj_offsettable_operand (operands[0], 4);
922: return \"sw\\t%1,%0\;sw\\t%D1,%2\";
1.1 root 923: }
1.1.1.3 root 924:
925: else
1.1 root 926: {
1.1.1.3 root 927: operands[2] = gen_rtx (REG, Pmode, 1);
928: return \".set\\tnoat\;la\\t%2,%0\;sw\\t%1,0(%2)\;sw\\t%D1,4(%2)\;set\\tat\";
1.1 root 929: }
930: }
1.1.1.3 root 931:
932: abort_with_insn (insn, \"impossible case in movdi\");
933: return \"\";
1.1 root 934: }")
935:
936: (define_insn "movsi"
937: [(set (match_operand:SI 0 "general_operand" "=r,r,m,r,r,m,*r")
938: (match_operand:SI 1 "general_operand" "r,m,r,i,J,J,*p"))]
939: ""
940: "*
941: {
1.1.1.3 root 942: enum rtx_code code0 = GET_CODE (operands[0]);
943: enum rtx_code code1 = GET_CODE (operands[1]);
1.1 root 944:
1.1.1.3 root 945: if (code0 == REG && code1 == REG)
946: return \"move\\t%0,%1\";
947:
948: else if (code0 == REG && code1 == MEM)
949: return \"lw\\t%0,%1\";
950:
951: else if (code0 == MEM && code1 == REG)
952: return \"sw\\t%1,%0\";
953:
954: else if (code0 == REG && code1 == CONST_INT)
955: return \"li\\t%0,%1\";
956:
957: else if (code0 == MEM && code1 == CONST_INT && INTVAL (operands[1]) == 0)
958: return \"sw\\t$0,%0\";
959:
960: else if (code0 == REG && CONSTANT_P (operands[1]))
961: return \"la\\t%0,%a1\";
962:
963: else if (code0 == REG && code1 == PLUS
964: && GET_CODE (XEXP (operands[1], 0)) == REG
965: && GET_CODE (XEXP (operands[1], 1)) == CONST_INT)
1.1 root 966: {
1.1.1.3 root 967: operands[2] = XEXP (operands[1], 0);
968: operands[3] = XEXP (operands[1], 1);
969: return \"add%:\\t%0,%2,%3\";
1.1 root 970: }
1.1.1.3 root 971:
972: abort_with_insn (insn, \"Bad movsi\");
973: return 0;
1.1 root 974: }")
975:
976: (define_insn "movhi"
977: [(set (match_operand:HI 0 "general_operand" "=r,r,m,r,r,m")
978: (match_operand:HI 1 "general_operand" "r,m,r,i,J,J"))]
979: ""
980: "*
981: {
1.1.1.3 root 982: enum rtx_code code0 = GET_CODE (operands[0]);
983: enum rtx_code code1 = GET_CODE (operands[1]);
1.1 root 984:
1.1.1.3 root 985: if (code0 == REG && code1 == REG)
986: return \"move\\t%0,%1\";
1.1 root 987:
1.1.1.3 root 988: else if (code0 == REG && code1 == MEM)
989: return \"lh\\t%0,%1\";
1.1 root 990:
1.1.1.3 root 991: else if (code0 == MEM && code1 == REG)
992: return \"sh\\t%1,%0\";
1.1 root 993:
1.1.1.3 root 994: else if (code0 == REG && code1 == CONST_INT)
995: return \"li\\t%0,%1\";
1.1 root 996:
1.1.1.3 root 997: else if (code0 == MEM && code1 == CONST_INT && INTVAL (operands[1]) == 0)
998: return \"sh\\t$0,%0\";
1.1 root 999:
1.1.1.3 root 1000: else if (code0 == REG && CONSTANT_P (operands[1]))
1001: return \"la\\t%0,%a1\";
1.1 root 1002:
1.1.1.3 root 1003: else if (code0 == REG && code1 == PLUS
1004: && GET_CODE (XEXP (operands[1], 0)) == REG
1005: && GET_CODE (XEXP (operands[1], 1)) == CONST_INT)
1.1 root 1006: {
1.1.1.3 root 1007: operands[2] = XEXP (operands[1], 0);
1008: operands[3] = XEXP (operands[1], 1);
1009: return \"add%:\\t%0,%2,%3\";
1.1 root 1010: }
1011:
1.1.1.3 root 1012: abort_with_insn (insn, \"Bad movhi\");
1013: return 0;
1.1 root 1014: }")
1015:
1.1.1.3 root 1016: (define_insn "movqi"
1017: [(set (match_operand:QI 0 "general_operand" "=r,r,m,r,r,m")
1018: (match_operand:QI 1 "general_operand" "r,m,r,i,J,J"))]
1.1 root 1019: ""
1020: "*
1021: {
1.1.1.3 root 1022: enum rtx_code code0 = GET_CODE (operands[0]);
1023: enum rtx_code code1 = GET_CODE (operands[1]);
1.1 root 1024:
1.1.1.3 root 1025: if (code0 == REG && code1 == REG)
1026: return \"move\\t%0,%1\";
1.1 root 1027:
1.1.1.3 root 1028: else if (code0 == REG && code1 == MEM)
1029: return \"lb\\t%0,%1\";
1.1 root 1030:
1.1.1.3 root 1031: else if (code0 == MEM && code1 == REG)
1032: return \"sb\\t%1,%0\";
1.1 root 1033:
1.1.1.3 root 1034: else if (code0 == REG && code1 == CONST_INT)
1035: return \"li\\t%0,%1\";
1.1 root 1036:
1.1.1.3 root 1037: else if (code0 == MEM && code1 == CONST_INT && INTVAL (operands[1]) == 0)
1038: return \"sb\\t$0,%0\";
1.1 root 1039:
1.1.1.3 root 1040: else if (code0 == REG && CONSTANT_P (operands[1]))
1041: return \"la\\t%0,%a1\";
1.1 root 1042:
1.1.1.3 root 1043: else if (code0 == REG && code1 == PLUS
1044: && GET_CODE (XEXP (operands[1], 0)) == REG
1045: && GET_CODE (XEXP (operands[1], 1)) == CONST_INT)
1.1 root 1046: {
1.1.1.3 root 1047: operands[2] = XEXP (operands[1], 0);
1048: operands[3] = XEXP (operands[1], 1);
1049: return \"add%:\\t%0,%2,%3\";
1.1 root 1050: }
1051:
1.1.1.3 root 1052: abort_with_insn (insn, \"Bad movqi\");
1053: return 0;
1.1 root 1054: }")
1.1.1.3 root 1055:
1056: (define_insn "movsf"
1057: [(set (match_operand:SF 0 "general_operand" "=f,f,m,fy,*f,*y,*y,*m")
1058: (match_operand:SF 1 "general_operand" "f,m,f,F,*y,*f,*m,*y"))]
1.1 root 1059: ""
1060: "*
1061: {
1.1.1.3 root 1062: enum rtx_code code0 = GET_CODE (operands[0]);
1063: enum rtx_code code1 = GET_CODE (operands[1]);
1.1 root 1064:
1.1.1.3 root 1065: if (code0 == REG)
1.1 root 1066: {
1.1.1.3 root 1067: if (code1 == REG)
1068: {
1069: if (FP_REG_P (REGNO (operands[0])))
1070: {
1071: if (FP_REG_P (REGNO (operands[1])))
1072: return \"mov.s\\t%0,%1\";
1073: else
1074: return \"mtc1\\t%1,%0\\t\\t# Calling sequence trick\";
1075: }
1.1 root 1076:
1.1.1.3 root 1077: else if (FP_REG_P (REGNO (operands[1])))
1078: return \"mfc1\\t%0,%1\\t\\t# Calling sequence trick\";
1.1 root 1079:
1.1.1.3 root 1080: else
1081: return \"move\\t%0,%1\";
1082: }
1.1 root 1083:
1.1.1.3 root 1084: else if (code1 == CONST_DOUBLE)
1085: return \"li.s\\t%0,%1\";
1.1 root 1086:
1.1.1.3 root 1087: else if (code1 == MEM)
1088: return (GP_REG_P (REGNO (operands[0]))) ? \"lw\\t%0,%1\" : \"l.s\\t%0,%1\";
1089: }
1.1 root 1090:
1.1.1.3 root 1091: else if (code0 == MEM && code1 == REG)
1092: return (GP_REG_P (REGNO (operands[1]))) ? \"sw\\t%1,%0\" : \"s.s\\t%1,%0\";
1.1 root 1093:
1.1.1.3 root 1094: abort_with_insn (insn, \"Bad movsf\");
1095: return \"\";
1096: }")
1.1 root 1097:
1.1.1.3 root 1098:
1099: (define_insn "movdf"
1100: [(set (match_operand:DF 0 "general_operand" "=f,f,m,fy,*f,*y,&*y,*m")
1101: (match_operand:DF 1 "general_operand" "f,m,f,F,*y,*f,*m,*y"))]
1.1 root 1102: ""
1.1.1.3 root 1103: "*
1104: {
1105: extern rtx adj_offsettable_operand ();
1106: extern int offsettable_address_p ();
1.1 root 1107:
1.1.1.3 root 1108: enum rtx_code code0 = GET_CODE (operands[0]);
1109: enum rtx_code code1 = GET_CODE (operands[1]);
1.1 root 1110:
1.1.1.3 root 1111: if (code0 == REG)
1112: {
1113: if (code1 == REG)
1114: {
1115: if (FP_REG_P (REGNO (operands[0])))
1116: {
1117: if (FP_REG_P (REGNO (operands[1])))
1118: return \"mov.d\\t%0,%1\";
1119: else
1120: return \"mtc1\\t%L1,%0\\t\\t# Calling sequence trick\;mtc1\\t%M1,%D0\";
1121: }
1.1 root 1122:
1.1.1.3 root 1123: else if (FP_REG_P (REGNO (operands[1])))
1124: return \"mfc1\\t%L0,%1\\t\\t# Calling sequence trick\;mfc1\\t%M0,%D1\";
1.1 root 1125:
1.1.1.3 root 1126: else if (REGNO (operands[0]) != (REGNO (operands[1])+1))
1127: return \"move\\t%0,%1\\n\\tmove\\t%D0,%D1\";
1.1 root 1128:
1.1.1.3 root 1129: else
1130: return \"move\\t%D0,%D1\\n\\tmove\\t%0,%1\";
1131: }
1.1 root 1132:
1.1.1.3 root 1133: else if (code1 == CONST_DOUBLE)
1134: return \"li.d\\t%0,%1\";
1.1 root 1135:
1.1.1.3 root 1136: else if (code1 == MEM)
1137: {
1138: if (FP_REG_P (REGNO (operands[0])))
1139: return \"l.d\\t%0,%1\";
1.1 root 1140:
1.1.1.3 root 1141: else if (offsettable_address_p (1, DFmode, XEXP (operands[1], 0)))
1142: {
1143: operands[2] = adj_offsettable_operand (operands[1], 4);
1144: if (reg_mentioned_p (operands[0], operands[1]))
1145: return \"lw\\t%D0,%2\;lw\\t%0,%1\";
1146: else
1147: return \"lw\\t%0,%1\;lw\\t%D0,%2\";
1148: }
1.1 root 1149:
1.1.1.3 root 1150: else
1151: {
1152: operands[2] = gen_rtx (REG, Pmode, 1);
1153: return \".set\\tnoat\;la\\t%2,%1\;lw\\t%0,0(%2)\;lw\\t%D0,4(%2)\;set\\tat\";
1154: }
1155: }
1156: }
1.1 root 1157:
1.1.1.3 root 1158: else if (code0 == MEM && code1 == REG)
1159: {
1160: if (FP_REG_P (REGNO (operands[1])))
1161: return \"s.d\\t%1,%0\";
1.1 root 1162:
1.1.1.3 root 1163: else if (offsettable_address_p (1, DFmode, XEXP (operands[0], 0)))
1164: {
1165: operands[2] = adj_offsettable_operand (operands[0], 4);
1166: return \"sw\\t%1,%0\;sw\\t%D1,%2\";
1167: }
1.1 root 1168:
1.1.1.3 root 1169: else
1170: {
1171: operands[2] = gen_rtx (REG, Pmode, 1);
1172: return \".set\\tnoat\;la\\t%2,%0\;sw\\t%1,0(%2)\;sw\\t%D1,4(%2)\;set\\tat\";
1173: }
1174: }
1.1 root 1175:
1.1.1.3 root 1176: abort_with_insn (insn, \"Bad movdf\");
1177: return \"\";
1178: }")
1.1 root 1179:
1.1.1.3 root 1180:
1181: ;;
1182: ;; ....................
1183: ;;
1184: ;; OTHER ARITHMETIC AND SHIFT
1185: ;;
1186: ;; ....................
1.1 root 1187:
1.1.1.3 root 1188: (define_insn "ashlsi3"
1189: [(set (match_operand:SI 0 "register_operand" "=r")
1190: (ashift:SI (match_operand:SI 1 "register_operand" "r")
1191: (match_operand:SI 2 "arith_operand" "rI")))]
1.1 root 1192: ""
1.1.1.3 root 1193: "*
1194: {
1195: if (GET_CODE (operands[2]) == CONST_INT)
1196: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
1.1 root 1197:
1.1.1.3 root 1198: return \"sll\\t%0,%1,%2\";
1199: }")
1.1 root 1200:
1.1.1.3 root 1201: (define_insn "ashrsi3"
1202: [(set (match_operand:SI 0 "register_operand" "=r")
1203: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
1204: (match_operand:SI 2 "arith_operand" "rI")))]
1.1 root 1205: ""
1.1.1.3 root 1206: "*
1207: {
1208: if (GET_CODE (operands[2]) == CONST_INT)
1209: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
1.1 root 1210:
1.1.1.3 root 1211: return \"sra\\t%0,%1,%2\";
1212: }")
1.1 root 1213:
1.1.1.3 root 1214: (define_insn "lshrsi3"
1215: [(set (match_operand:SI 0 "register_operand" "=r")
1216: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1217: (match_operand:SI 2 "arith_operand" "rI")))]
1.1 root 1218: ""
1.1.1.3 root 1219: "*
1220: {
1221: if (GET_CODE (operands[2]) == CONST_INT)
1222: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
1.1 root 1223:
1.1.1.3 root 1224: return \"srl\\t%0,%1,%2\";
1225: }")
1226:
1227: (define_insn "negsi2"
1228: [(set (match_operand:SI 0 "register_operand" "=r")
1229: (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1.1 root 1230: ""
1.1.1.3 root 1231: "sub%:\\t%0,$0,%1")
1.1 root 1232:
1.1.1.3 root 1233: (define_insn "negdf2"
1234: [(set (match_operand:DF 0 "register_operand" "=f")
1235: (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1.1 root 1236: ""
1.1.1.3 root 1237: "neg.d\\t%0,%1")
1.1 root 1238:
1.1.1.3 root 1239: (define_insn "negsf2"
1.1 root 1240:
1.1.1.3 root 1241: [(set (match_operand:SF 0 "register_operand" "=f")
1242: (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1243: ""
1244: "neg.s\\t%0,%1")
1.1 root 1245:
1246:
1.1.1.3 root 1247: (define_insn "one_cmplsi2"
1248: [(set (match_operand:SI 0 "register_operand" "=r")
1249: (not:SI (match_operand:SI 1 "register_operand" "r")))]
1250: ""
1251: "nor\\t%0,$0,%1")
1.1 root 1252:
1253: ;;
1254: ;; ....................
1255: ;;
1256: ;; COMPARISONS
1257: ;;
1258: ;; ....................
1259:
1260: ;;- Order is significant here
1261: ;;- because there are untyped
1262: ;;- comparisons generated by
1263: ;;- the optimizer
1264: ;;- (set (cc0)
1265: ;;- (compare (const_int 2)
1266: ;;- (const_int 1)))
1267:
1268: (define_insn "cmpsi"
1269: [(set (cc0)
1270: (compare (match_operand:SI 0 "register_operand" "r")
1.1.1.3 root 1271: (match_operand:SI 1 "arith_operand" "rI")))]
1.1 root 1272: ""
1273: "*
1274: compare_collect (SImode, operands[0], operands[1]);
1.1.1.3 root 1275: return \"\\t\\t\\t\\t# cmpsi\\t%0,%1\";
1276: ")
1277:
1278:
1279: (define_insn ""
1280: [(set (cc0)
1281: (match_operand:SI 0 "register_operand" "r"))]
1282: ""
1283: "*
1284: compare_collect (SImode, operands[0], gen_rtx (REG, SImode, 0));
1285: return \"\\t\\t\\t\\t# (set (cc0)\\t%0)\";
1.1 root 1286: ")
1287:
1288: ;; These patterns are hopelessly invalid, because
1289: ;; comparing subword values properly requires extending them.
1290:
1291: ;; (define_insn "cmphi"
1292: ;; [(set (cc0)
1.1.1.3 root 1293: ;; (compare (match_operand:HI 0 "register_operand" "r")
1294: ;; (match_operand:HI 1 "register_operand" "r")))]
1.1 root 1295: ;; ""
1296: ;; "*
1297: ;; compare_collect (HImode, operands[0], operands[1]);
1298: ;; return \" #\\tcmphi\\t%0,%1\";
1299: ;; ")
1300: ;;
1301: ;; (define_insn "cmpqi"
1302: ;; [(set (cc0)
1.1.1.3 root 1303: ;; (compare (match_operand:QI 0 "register_operand" "r")
1304: ;; (match_operand:QI 1 "register_operand" "r")))]
1.1 root 1305: ;; ""
1306: ;; "*
1307: ;; compare_collect (QImode, operands[0], operands[1]);
1308: ;; return \" #\\tcmpqi\\t%0,%1\";
1309: ;; ")
1.1.1.3 root 1310: ;;
1311: ;; (define_insn ""
1312: ;; [(set (cc0)
1313: ;; (match_operand:QI 0 "register_operand" "r"))]
1314: ;; ""
1315: ;; "*
1316: ;; compare_collect (QImode, operands[0], gen_rtx (REG, QImode, 0));
1317: ;; return \" #\\t (set (cc0)\\t%0)\";
1318: ;; ")
1319: ;;
1320: ;; (define_insn ""
1321: ;; [(set (cc0)
1322: ;; (match_operand:HI 0 "register_operand" "r"))]
1323: ;; ""
1324: ;; "*
1325: ;; compare_collect (HImode, operands[0], gen_rtx (REG, HImode, 0));
1326: ;; return \" #\\t (set (cc0)\\t%0)\";
1327: ;; ")
1.1 root 1328:
1329: (define_insn "cmpdf"
1330: [(set (cc0)
1331: (compare (match_operand:DF 0 "register_operand" "f")
1332: (match_operand:DF 1 "register_operand" "f")))]
1333: ""
1334: "*
1335: compare_collect (DFmode, operands[0], operands[1]);
1.1.1.3 root 1336: return \" #\\t\\t\\t\\tcmpdf\\t%0,%1\" ;
1.1 root 1337: ")
1338:
1339: (define_insn "cmpsf"
1340: [(set (cc0)
1341: (compare (match_operand:SF 0 "register_operand" "f")
1342: (match_operand:SF 1 "register_operand" "f")))]
1343: ""
1344: "*
1345: compare_collect (SFmode, operands[0], operands[1]);
1.1.1.3 root 1346: return \"\\t\\t\\t\\t# cmpsf\\t%0,%1\" ;
1.1 root 1347: ")
1348:
1349: ;;
1350: ;; ....................
1351: ;;
1352: ;; BRANCHES
1353: ;;
1354: ;; ....................
1355:
1356: (define_insn "jump"
1357: [(set (pc)
1358: (label_ref (match_operand 0 "" "")))]
1359: ""
1360: "*
1361: {
1362: if (GET_CODE (operands[0]) == REG)
1.1.1.3 root 1363: return \"j\\t%0\";
1.1 root 1364: else
1.1.1.3 root 1365: return \"j\\t%l0\";
1.1 root 1366: }")
1367:
1368:
1.1.1.3 root 1369: (define_insn "tablejump"
1370: [(set (pc)
1371: (match_operand:SI 0 "register_operand" "r"))
1372: (use (label_ref (match_operand 1 "" "")))]
1373: ""
1374: "j\\t%0")
1375:
1376:
1.1 root 1377: (define_insn "beq"
1378: [(set (pc)
1379: (if_then_else (eq (cc0)
1380: (const_int 0))
1381: (label_ref (match_operand 0 "" ""))
1382: (pc)))]
1383: ""
1384: "*
1385: {
1386: rtx br_ops[3];
1387: enum machine_mode mode;
1388: compare_restore (br_ops, &mode, insn);
1389: br_ops[2] = operands[0];
1390: if (mode == DFmode)
1391: {
1.1.1.3 root 1392: output_asm_insn (\"c.eq.d\\t%0,%1\\t\\t# beq\", br_ops);
1393: output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
1.1 root 1394: }
1395: else if (mode == SFmode)
1396: {
1.1.1.3 root 1397: output_asm_insn (\"c.eq.s\\t%0,%1\\t\\t# beq\", br_ops);
1398: output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
1.1 root 1399: }
1400: else
1401: {
1.1.1.3 root 1402: output_asm_insn (\"beq\\t%0,%1,%2\\t\\t# beq\", br_ops);
1.1 root 1403: }
1404: return \"\";
1405: }
1406: ")
1407:
1408: (define_insn "bne"
1409: [(set (pc)
1410: (if_then_else (ne (cc0)
1411: (const_int 0))
1412: (label_ref (match_operand 0 "" ""))
1413: (pc)))]
1414: ""
1415: "*
1416: {
1417: rtx br_ops[3];
1418: enum machine_mode mode;
1419: compare_restore (br_ops, &mode, insn);
1420: br_ops[2] = operands[0];
1421: if (mode == DFmode)
1422: {
1.1.1.3 root 1423: output_asm_insn (\"c.eq.d\\t%0,%1\\t\\t# bne\", br_ops);
1424: output_asm_insn (\"bc1f\\t%2\\t\\t# bne\", br_ops);
1.1 root 1425: }
1426: else if (mode == SFmode)
1427: {
1.1.1.3 root 1428: output_asm_insn (\"c.eq.s\\t%0,%1\\t\\t# bne\", br_ops);
1429: output_asm_insn (\"bc1f\\t%2\\t\\t# bne\", br_ops);
1.1 root 1430: }
1431: else
1432: {
1.1.1.3 root 1433: output_asm_insn (\"bne\\t%0,%1,%2\\t\\t# bne\", br_ops);
1.1 root 1434: }
1435: return \"\";
1436: }
1437:
1438: ")
1439:
1440: (define_insn "bgt"
1441: [(set (pc)
1442: (if_then_else (gt (cc0)
1443: (const_int 0))
1444: (label_ref (match_operand 0 "" ""))
1445: (pc)))]
1446: ""
1447: "*
1448: {
1449: rtx br_ops[3];
1450: enum machine_mode mode;
1451: compare_restore (br_ops, &mode, insn);
1452: br_ops[2] = operands[0];
1453: if (mode == DFmode)
1454: {
1.1.1.3 root 1455: output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bgt branch %0 > %1\", br_ops);
1456: output_asm_insn (\"bc1f\\t%2\\t\\t# bgt\", br_ops);
1.1 root 1457: }
1458: else if (mode == SFmode)
1459: {
1.1.1.3 root 1460: output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bgt branch %0 > %1\", br_ops);
1461: output_asm_insn (\"bc1f\\t%2\\t\\t# bgt\", br_ops);
1.1 root 1462: }
1463: else
1464: {
1.1.1.3 root 1465: output_asm_insn (\"bgt\\t%0,%1,%2\\t\\t# bgt\", br_ops);
1.1 root 1466: }
1467: return \"\";
1468: }
1469:
1470: ")
1471:
1472: (define_insn "blt"
1473: [(set (pc)
1474: (if_then_else (lt (cc0)
1475: (const_int 0))
1476: (label_ref (match_operand 0 "" ""))
1477: (pc)))]
1478: ""
1479: "*
1480: {
1481: rtx br_ops[3];
1482: enum machine_mode mode;
1483: compare_restore (br_ops, &mode, insn);
1484: br_ops[2] = operands[0];
1485: if (mode == DFmode)
1486: {
1.1.1.3 root 1487: output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# blt\", br_ops);
1488: output_asm_insn (\"bc1t\\t%2\\t\\t# blt\", br_ops);
1.1 root 1489: }
1490: else if (mode == SFmode)
1491: {
1.1.1.3 root 1492: output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# blt\", br_ops);
1493: output_asm_insn (\"bc1t\\t%2\\t\\t# blt\", br_ops);
1.1 root 1494: }
1495: else
1496: {
1.1.1.3 root 1497: output_asm_insn (\"blt\\t%0,%1,%2\\t\\t# blt\", br_ops);
1.1 root 1498: }
1.1.1.3 root 1499: return \" #\\tblt\\t%l0\\t\\t# blt\";
1.1 root 1500: }
1501: ")
1502:
1503: (define_insn "bgtu"
1504: [(set (pc)
1505: (if_then_else (gtu (cc0)
1506: (const_int 0))
1507: (label_ref (match_operand 0 "" ""))
1508: (pc)))]
1509: ""
1510: "*
1511: {
1512: rtx br_ops[3];
1513: enum machine_mode mode;
1514: compare_restore (br_ops, &mode, insn);
1515: br_ops[2] = operands[0];
1516: if (mode == DFmode)
1517: {
1.1.1.3 root 1518: output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bgtu\", br_ops);
1519: output_asm_insn (\"bc1f\\t%2\\t\\t# bgtu\", br_ops);
1.1 root 1520: }
1521: else if (mode == SFmode)
1522: {
1.1.1.3 root 1523: output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bgtu\", br_ops);
1524: output_asm_insn (\"bc1f\\t%2\\t\\t# bgtu\", br_ops);
1.1 root 1525: }
1526: else
1527: {
1.1.1.3 root 1528: output_asm_insn (\"bgtu\\t%0,%1,%2\\t\\t# bgtu\", br_ops);
1.1 root 1529: }
1.1.1.3 root 1530: return \" #\\tbgtu\\t%l0\\t\\t# bgtu\";
1.1 root 1531: }
1532: ")
1533:
1534: (define_insn "bltu"
1535: [(set (pc)
1536: (if_then_else (ltu (cc0)
1537: (const_int 0))
1538: (label_ref (match_operand 0 "" ""))
1539: (pc)))]
1540: ""
1541: "*
1542: {
1543: rtx br_ops[3];
1544: enum machine_mode mode;
1545: compare_restore (br_ops, &mode, insn);
1546: br_ops[2] = operands[0];
1547: if (mode == DFmode)
1548: {
1.1.1.3 root 1549: output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bltu\", br_ops);
1550: output_asm_insn (\"bc1t\\t%2\\t\\t# bltu\", br_ops);
1.1 root 1551: }
1552: else if (mode == SFmode)
1553: {
1.1.1.3 root 1554: output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bltu\", br_ops);
1555: output_asm_insn (\"bc1t\\t%2\\t\\t# bltu\", br_ops);
1.1 root 1556: }
1557: else
1558: {
1.1.1.3 root 1559: output_asm_insn (\"bltu\\t%0,%1,%2\\t\\t# bltu\", br_ops);
1.1 root 1560: }
1561: return \"\";
1562: }
1563: ")
1564:
1565: (define_insn "bge"
1566: [(set (pc)
1567: (if_then_else (ge (cc0)
1568: (const_int 0))
1569: (label_ref (match_operand 0 "" ""))
1570: (pc)))]
1571: ""
1572: "*
1573: {
1574: rtx br_ops[3];
1575: enum machine_mode mode;
1576: compare_restore (br_ops, &mode, insn);
1577: br_ops[2] = operands[0];
1578: if (mode == DFmode)
1579: {
1.1.1.3 root 1580: output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bge\", br_ops);
1581: output_asm_insn (\"bc1f\\t%2\\t\\t# bge\", br_ops);
1.1 root 1582: }
1583: else if (mode == SFmode)
1584: {
1.1.1.3 root 1585: output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bge\", br_ops);
1586: output_asm_insn (\"bc1f\\t%2\\t\\t# bge\", br_ops);
1.1 root 1587: }
1588: else
1589: {
1.1.1.3 root 1590: output_asm_insn (\"bge\\t%0,%1,%2\\t\\t# bge\", br_ops);
1.1 root 1591: }
1592: return \"\";
1593: }
1594: ")
1595:
1596: (define_insn "bgeu"
1597: [(set (pc)
1598: (if_then_else (geu (cc0)
1599: (const_int 0))
1600: (label_ref (match_operand 0 "" ""))
1601: (pc)))]
1602: ""
1603: "*
1604: {
1605: rtx br_ops[3];
1606: enum machine_mode mode;
1607: compare_restore (br_ops, &mode, insn);
1608: br_ops[2] = operands[0];
1609: if (mode == DFmode)
1610: {
1.1.1.3 root 1611: output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bgeu\", br_ops);
1612: output_asm_insn (\"bc1f\\t%2\\t\\t# bgeu\", br_ops);
1.1 root 1613: }
1614: else if (mode == SFmode)
1615: {
1.1.1.3 root 1616: output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bgeu\", br_ops);
1617: output_asm_insn (\"bc1f\\t%2\\t\\t# bgeu\", br_ops);
1.1 root 1618: }
1619: else
1620: {
1.1.1.3 root 1621: output_asm_insn (\"bgeu\\t%0,%1,%2\\t\\t# bgeu\", br_ops);
1.1 root 1622: }
1623: return \"\";
1624: }
1625: ")
1626:
1627: (define_insn "ble"
1628: [(set (pc)
1629: (if_then_else (le (cc0)
1630: (const_int 0))
1631: (label_ref (match_operand 0 "" ""))
1632: (pc)))]
1633: ""
1634: "*
1635: {
1636: rtx br_ops[3];
1637: enum machine_mode mode;
1638: compare_restore (br_ops, &mode, insn);
1639: br_ops[2] = operands[0];
1640: if (mode == DFmode)
1641: {
1.1.1.3 root 1642: output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# ble\", br_ops);
1643: output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
1.1 root 1644: }
1645: else if (mode == SFmode)
1646: {
1.1.1.3 root 1647: output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# ble\", br_ops);
1648: output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
1.1 root 1649: }
1650: else
1651: {
1.1.1.3 root 1652: output_asm_insn (\"ble\\t%0,%1,%2\\t\\t# ble\", br_ops);
1.1 root 1653: }
1654: return \"\";
1655: }
1656: ")
1657:
1658: (define_insn "bleu"
1659: [(set (pc)
1660: (if_then_else (leu (cc0)
1661: (const_int 0))
1662: (label_ref (match_operand 0 "" ""))
1663: (pc)))]
1664: ""
1665: "*
1666: {
1667: rtx br_ops[3];
1668: enum machine_mode mode;
1669: compare_restore (br_ops, &mode, insn);
1670: br_ops[2] = operands[0];
1671: if (mode == DFmode)
1672: {
1.1.1.3 root 1673: output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# ble\", br_ops);
1674: output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
1.1 root 1675: }
1676: else if (mode == SFmode)
1677: {
1.1.1.3 root 1678: output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# ble\", br_ops);
1679: output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
1.1 root 1680: }
1681: else
1682: {
1.1.1.3 root 1683: output_asm_insn (\"bleu\\t%0,%1,%2\\t\\t# bleu\", br_ops);
1.1 root 1684: }
1.1.1.3 root 1685: return \" #\\tbleu\\t%l0\\t\\t# bleu\";
1.1 root 1686: }
1687: ")
1688:
1689: (define_insn ""
1690: [(set (pc)
1691: (if_then_else (ne (cc0)
1692: (const_int 0))
1693: (pc)
1694: (label_ref (match_operand 0 "" ""))))]
1695: ""
1696: "*
1697: {
1698: rtx br_ops[3];
1699: enum machine_mode mode;
1700: compare_restore (br_ops, &mode, insn);
1701: br_ops[2] = operands[0];
1702: if (mode == DFmode)
1703: {
1.1.1.3 root 1704: output_asm_insn (\"c.eq.d\\t%0,%1\\t\\t# beq\", br_ops);
1705: output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
1.1 root 1706: }
1707: else if (mode == SFmode)
1708: {
1.1.1.3 root 1709: output_asm_insn (\"c.eq.s\\t%0,%1\\t\\t# beq\", br_ops);
1710: output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
1.1 root 1711: }
1712: else
1713: {
1.1.1.3 root 1714: output_asm_insn (\"beq\\t%0,%1,%2\\t\\t# beq Inv.\", br_ops);
1.1 root 1715: }
1716: return \"\";
1717: }
1718: ")
1719:
1720: (define_insn ""
1721: [(set (pc)
1722: (if_then_else (eq (cc0)
1723: (const_int 0))
1724: (pc)
1725: (label_ref (match_operand 0 "" ""))))]
1726: ""
1727: "*
1728: {
1729: rtx br_ops[3];
1730: enum machine_mode mode;
1731: compare_restore (br_ops, &mode, insn);
1732: br_ops[2] = operands[0];
1733: if (mode == DFmode)
1734: {
1.1.1.3 root 1735: output_asm_insn (\"c.eq.d\\t%0,%1\\t\\t# bne\", br_ops);
1736: output_asm_insn (\"bc1f\\t%2\\t\\t# bne\", br_ops);
1.1 root 1737: }
1738: else if (mode == SFmode)
1739: {
1.1.1.3 root 1740: output_asm_insn (\"c.eq.s\\t%0,%1\\t\\t# bne\", br_ops);
1741: output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
1.1 root 1742: }
1743: else
1744: {
1.1.1.3 root 1745: output_asm_insn (\"bne\\t%0,%1,%2\\t\\t# bne Inv.\", br_ops);
1.1 root 1746: }
1747: return \"\";
1748: }
1749:
1750: ")
1751:
1752: (define_insn ""
1753: [(set (pc)
1754: (if_then_else (le (cc0)
1755: (const_int 0))
1756: (pc)
1757: (label_ref (match_operand 0 "" ""))))]
1758: ""
1759: "*
1760: {
1761: rtx br_ops[3];
1762: enum machine_mode mode;
1763: compare_restore (br_ops, &mode, insn);
1764: br_ops[2] = operands[0];
1765: if (mode == DFmode)
1766: {
1.1.1.3 root 1767: output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bgt\", br_ops);
1768: output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
1.1 root 1769: }
1770: else if (mode == SFmode)
1771: {
1.1.1.3 root 1772: output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bgt\", br_ops);
1773: output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
1.1 root 1774: }
1775: else
1776: {
1.1.1.3 root 1777: output_asm_insn (\"bgt\\t%0,%1,%2\\t\\t# bgt Inv.\", br_ops);
1.1 root 1778: }
1779: return \"\";
1780: }
1781: ")
1782:
1783: (define_insn ""
1784: [(set (pc)
1785: (if_then_else (leu (cc0)
1786: (const_int 0))
1787: (pc)
1788: (label_ref (match_operand 0 "" ""))))]
1789: ""
1790: "*
1791: {
1792: rtx br_ops[3];
1793: enum machine_mode mode;
1794: compare_restore (br_ops, &mode, insn);
1795: br_ops[2] = operands[0];
1796: if (mode == DFmode)
1797: {
1.1.1.3 root 1798: output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bgt\", br_ops);
1799: output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
1.1 root 1800: }
1801: else if (mode == SFmode)
1802: {
1.1.1.3 root 1803: output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bgt\", br_ops);
1804: output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
1.1 root 1805: }
1806: else
1807: {
1.1.1.3 root 1808: output_asm_insn (\"bgtu\\t%0,%1,%2\\t\\t# bgtu Inv.\", br_ops);
1.1 root 1809: }
1.1.1.3 root 1810: return \" #\\tbgtu\\t%l0\\t\\t# bgtu\";
1.1 root 1811: }
1812: ")
1813:
1814: (define_insn ""
1815: [(set (pc)
1816: (if_then_else (ge (cc0)
1817: (const_int 0))
1818: (pc)
1819: (label_ref (match_operand 0 "" ""))))]
1820: ""
1821: "*
1822: {
1823: rtx br_ops[3];
1824: enum machine_mode mode;
1825: compare_restore (br_ops, &mode, insn);
1826: br_ops[2] = operands[0];
1827: if (mode == DFmode)
1828: {
1.1.1.3 root 1829: output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# blt\", br_ops);
1830: output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
1.1 root 1831: }
1832: else if (mode == SFmode)
1833: {
1.1.1.3 root 1834: output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# blt\", br_ops);
1835: output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
1.1 root 1836: }
1837: else
1838: {
1.1.1.3 root 1839: output_asm_insn (\"blt\\t%0,%1,%2\\t\\t# blt Inv.\", br_ops);
1.1 root 1840: }
1841: return \"\";
1842: }
1843: ")
1844:
1845: (define_insn ""
1846: [(set (pc)
1847: (if_then_else (geu (cc0)
1848: (const_int 0))
1849: (pc)
1850: (label_ref (match_operand 0 "" ""))))]
1851: ""
1852: "*
1853: {
1854: rtx br_ops[3];
1855: enum machine_mode mode;
1856: compare_restore (br_ops, &mode, insn);
1857: br_ops[2] = operands[0];
1858: if (mode == DFmode)
1859: {
1.1.1.3 root 1860: output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bltu\", br_ops);
1861: output_asm_insn (\"bc1t\\t%2\\t\\t# bltu\", br_ops);
1.1 root 1862: }
1863: else if (mode == SFmode)
1864: {
1.1.1.3 root 1865: output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bltu\", br_ops);
1866: output_asm_insn (\"bc1t\\t%2\\t\\t# bltu\", br_ops);
1.1 root 1867: }
1868: else
1869: {
1.1.1.3 root 1870: output_asm_insn (\"bltu\\t%0,%1,%2\\t\\t# bltu Inv.\", br_ops);
1.1 root 1871: }
1.1.1.3 root 1872: return \" #\\tbltu\\t%l0\\t\\t# bltu\";
1.1 root 1873: }
1874: ")
1875:
1876: (define_insn ""
1877: [(set (pc)
1878: (if_then_else (lt (cc0)
1879: (const_int 0))
1880: (pc)
1881: (label_ref (match_operand 0 "" ""))))]
1882: ""
1883: "*
1884: {
1885: rtx br_ops[3];
1886: enum machine_mode mode;
1887: compare_restore (br_ops, &mode, insn);
1888: br_ops[2] = operands[0];
1889: if (mode == DFmode)
1890: {
1.1.1.3 root 1891: output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bge\", br_ops);
1892: output_asm_insn (\"bc1f\\t%2\\t\\t# bge (DF) Inv.\", br_ops);
1.1 root 1893: }
1894: else if (mode == SFmode)
1895: {
1.1.1.3 root 1896: output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bge\", br_ops);
1897: output_asm_insn (\"bc1f\\t%2\\t\\t# bge (SF) Inv.\", br_ops);
1.1 root 1898: }
1899: else
1900: {
1.1.1.3 root 1901: output_asm_insn (\"bge\\t%0,%1,%2\\t\\t# bge Inv.\", br_ops);
1.1 root 1902: }
1903: return \"\";
1904: }
1905: ")
1906:
1907: (define_insn ""
1908: [(set (pc)
1909: (if_then_else (ltu (cc0)
1910: (const_int 0))
1911: (pc)
1912: (label_ref (match_operand 0 "" ""))))]
1913: ""
1914: "*
1915: {
1916: rtx br_ops[3];
1917: enum machine_mode mode;
1918: compare_restore (br_ops, &mode, insn);
1919: br_ops[2] = operands[0];
1920: if (mode == DFmode)
1921: {
1.1.1.3 root 1922: output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bge\", br_ops);
1923: output_asm_insn (\"bc1f\\t%2\\t\\t# bgeu (DF) Inv.\", br_ops);
1.1 root 1924: }
1925: else if (mode == SFmode)
1926: {
1.1.1.3 root 1927: output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bge\", br_ops);
1928: output_asm_insn (\"bc1f\\t%2\\t\\t# bgeu (SF )Inv.\", br_ops);
1.1 root 1929: }
1930: else
1931: {
1.1.1.3 root 1932: output_asm_insn (\"bgeu\\t%0,%1,%2\\t\\t# bgeu Inv.\", br_ops);
1.1 root 1933: }
1.1.1.3 root 1934: return \" #\\tbgeu\\t%l0\\t\\t# bgeu\";
1.1 root 1935: }
1936: ")
1937:
1938: (define_insn ""
1939: [(set (pc)
1940: (if_then_else (gt (cc0)
1941: (const_int 0))
1942: (pc)
1943: (label_ref (match_operand 0 "" ""))))]
1944: ""
1945: "*
1946: {
1947: rtx br_ops[3];
1948: enum machine_mode mode;
1949: compare_restore (br_ops, &mode, insn);
1950: br_ops[2] = operands[0];
1951: if (mode == DFmode)
1952: {
1.1.1.3 root 1953: output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# ble\", br_ops);
1954: output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
1.1 root 1955: }
1956: else if (mode == SFmode)
1957: {
1.1.1.3 root 1958: output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# ble\", br_ops);
1959: output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
1.1 root 1960: }
1961: else
1962: {
1.1.1.3 root 1963: output_asm_insn (\"ble\\t%0,%1,%2\\t\\t# ble Inv.\", br_ops);
1.1 root 1964: }
1965: return \"\";
1966: }
1967: ")
1968:
1969: (define_insn ""
1970: [(set (pc)
1971: (if_then_else (gtu (cc0)
1972: (const_int 0))
1973: (pc)
1974: (label_ref (match_operand 0 "" ""))))]
1975: ""
1976: "*
1977: {
1978: rtx br_ops[3];
1979: enum machine_mode mode;
1980: compare_restore (br_ops, &mode, insn);
1981: br_ops[2] = operands[0];
1982: if (mode == DFmode)
1983: {
1.1.1.3 root 1984: output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bleu\", br_ops);
1985: output_asm_insn (\"bc1t\\t%2\\t\\t# bleu\", br_ops);
1.1 root 1986: }
1987: else if (mode == SFmode)
1988: {
1.1.1.3 root 1989: output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bleu\", br_ops);
1990: output_asm_insn (\"bc1t\\t%2\\t\\t# bleu\", br_ops);
1.1 root 1991: }
1992: else
1993: {
1.1.1.3 root 1994: output_asm_insn (\"bleu\\t%0,%1,%2\\t\\t# bleu Inv.\", br_ops);
1.1 root 1995: }
1996: return \"\";
1997: }
1998: ")
1999:
2000: ;;
2001: ;; ....................
2002: ;;
2003: ;; LINKAGE
2004: ;;
2005: ;; ....................
2006:
2007: (define_insn "call"
1.1.1.3 root 2008: [(call (match_operand 0 "memory_operand" "m")
2009: (match_operand 1 "" "i"))
1.1 root 2010: (clobber (reg:SI 31))]
2011: ""
2012: "*
2013: {
1.1.1.3 root 2014: register rtx target = XEXP (operands[0], 0);
2015:
2016: if (GET_CODE (target) == SYMBOL_REF)
2017: return \"jal\\t%0\";
2018:
1.1 root 2019: else
2020: {
1.1.1.3 root 2021: operands[0] = target;
2022: return \"jal\\t$31,%0\";
1.1 root 2023: }
1.1.1.3 root 2024: }")
1.1 root 2025:
2026:
1.1.1.3 root 2027: (define_insn "call_value"
1.1 root 2028: [(set (match_operand 0 "" "=rf")
1.1.1.3 root 2029: (call (match_operand 1 "memory_operand" "m")
2030: (match_operand 2 "" "i")))
1.1 root 2031: (clobber (reg:SI 31))]
2032: ""
1.1.1.3 root 2033: "*
1.1 root 2034: {
1.1.1.3 root 2035: register rtx target = XEXP (operands[1], 0);
1.1 root 2036:
1.1.1.3 root 2037: if (GET_CODE (target) == SYMBOL_REF)
2038: return \"jal\\t%1\";
1.1 root 2039:
2040: else
2041: {
1.1.1.3 root 2042: operands[1] = target;
2043: return \"jal\\t$31,%1\";
1.1 root 2044: }
2045: }")
2046:
2047: (define_insn "nop"
2048: [(const_int 0)]
2049: ""
1.1.1.3 root 2050: ".set\\tnoreorder\;nop\;.set\\treorder")
1.1 root 2051:
1.1.1.3 root 2052: (define_insn "probe"
2053: [(mem:SI (reg:SI 29))]
1.1 root 2054: ""
1.1.1.3 root 2055: "*
2056: {
2057: operands[0] = gen_rtx (REG, SImode, 1);
2058: operands[1] = stack_pointer_rtx;
2059: return \".set\\tnoat\;lw\\t%0,0(%1)\\t\\t# stack probe\;.set\\tat\";
2060: }")
1.1 root 2061:
2062: ;;
2063: ;;- Local variables:
2064: ;;- mode:emacs-lisp
2065: ;;- comment-start: ";;- "
2066: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
2067: ;;- eval: (modify-syntax-entry ?[ "(]")
2068: ;;- eval: (modify-syntax-entry ?] ")[")
2069: ;;- eval: (modify-syntax-entry ?{ "(}")
2070: ;;- eval: (modify-syntax-entry ?} "){")
2071: ;;- End:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.