|
|
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 distributed in the hope that it will be useful,
7: ;; but WITHOUT ANY WARRANTY. No author or distributor
8: ;; accepts responsibility to anyone for the consequences of using it
9: ;; or for whether it serves any particular purpose or works at all,
10: ;; unless he says so in writing. Refer to the GNU CC General Public
11: ;; License for full details.
12:
13: ;; Everyone is granted permission to copy, modify and redistribute
14: ;; GNU CC, but only under the conditions described in the
15: ;; GNU CC General Public License. A copy of this license is
16: ;; supposed to have been given to you along with GNU CC so you
17: ;; can know your rights and responsibilities. It should be in a
18: ;; file named COPYING. Among other things, the copyright notice
19: ;; and this notice must be preserved on all copies.
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: (minus (match_operand:SI 0 "nonmemory_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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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\"); ")
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: emit_move_insn (tem, gen_rtx (MEM, SImode, addr));
290: emit_insn (gen_rtx (SET, VOIDmode,
291: gen_rtx (SUBREG, SImode, operands[0], 0),
292: gen_rtx (ZERO_EXTRACT, SImode, tem,
293: gen_rtx (CONST_INT, VOIDmode, 8),
294: addr)));
295: }
296: else if (GET_CODE (operands[0]) == MEM)
297: {
298: rtx tem = gen_reg_rtx (SImode);
299: rtx addr = force_reg (SImode, XEXP (operands[0], 0));
300: emit_move_insn (tem, gen_rtx (MEM, SImode, addr));
301: if (! CONSTANT_ADDRESS_P (operands[1]))
302: operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
303: emit_insn (gen_rtx (SET, VOIDmode,
304: gen_rtx (ZERO_EXTRACT, SImode, tem,
305: gen_rtx (CONST_INT, VOIDmode, 8),
306: addr),
307: operands[1]));
308: emit_move_insn (gen_rtx (MEM, SImode, addr), tem);
309: }
310: else
311: {
312: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
313: }
314: DONE;
315: }")
316:
317: ;; Recognize insns generated for moving single bytes.
318:
319: (define_insn ""
320: [(set (match_operand:QI 0 "general_operand" "=r,m")
321: (match_operand:QI 1 "general_operand" "rmi,r"))]
322: ""
323: "*
324: {
325: if (GET_CODE (operands[0]) == MEM)
326: return \"st_32 %1,%0\";
327: if (GET_CODE (operands[1]) == MEM)
328: return \"ld_32 %0,%1\;nop\";
329: if (GET_CODE (operands[1]) == REG)
330: return \"add_nt %0,%1,$0\";
331: return \"add_nt %0,r0,%1\";
332: }")
333:
334: (define_insn ""
335: [(set (match_operand:SI 0 "register_operand" "=r")
336: (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
337: (const_int 8)
338: (match_operand:SI 2 "nonmemory_operand" "rI")))]
339: ""
340: "extract %0,%1,%2")
341:
342: (define_insn ""
343: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
344: (const_int 8)
345: (match_operand:SI 1 "nonmemory_operand" "rI"))
346: (match_operand:SI 2 "nonmemory_operand" "ri"))]
347: ""
348: "wr_insert %1\;insert %0,%0,%2")
349:
350: ;; Constant propagation can optimize the previous pattern into this pattern.
351: ;[Not any more. It could when the position-operand contains a MULT.]
352:
353: ;(define_insn ""
354: ; [(set (zero_extract:QI (match_operand:SI 0 "register_operand" "+r")
355: ; (const_int 8)
356: ; (match_operand:SI 1 "immediate_operand" "I"))
357: ; (match_operand:QI 2 "register_operand" "r"))]
358: ; "GET_CODE (operands[1]) == CONST_INT
359: ; && INTVAL (operands[1]) % 8 == 0
360: ; && (unsigned) INTVAL (operands[1]) < 32"
361: ; "*
362: ;{
363: ; operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 8);
364: ; return \"wr_insert 0,0,%1\;insert %0,%0,%2\";
365: ;}")
366:
367: ;; The three define_expand patterns on this page
368: ;; serve as subroutines of "movhi".
369:
370: ;; Generate code to fetch an aligned halfword from memory.
371: ;; Operand 0 is the destination register (HImode).
372: ;; Operand 1 is the memory address (SImode).
373: ;; Operand 2 is a temporary (SImode).
374: ;; Operand 3 is a temporary (SImode).
375: ;; Operand 4 is a temporary (QImode).
376:
377: (define_expand "loadhi"
378: [(set (match_operand:SI 2 "register_operand" "")
379: (mem:SI (match_operand:SI 1 "register_operand" "")))
380: ;; Extract the low byte.
381: (set (subreg:SI (match_dup 5) 0)
382: (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 1)))
383: ;; Form address of high byte.
384: (set (match_operand:SI 3 "register_operand" "")
385: (plus:SI (match_dup 1) (const_int 1)))
386: ;; Extract the high byte.
387: (set (subreg:SI (match_operand:QI 4 "register_operand" "") 0)
388: (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3)))
389: ;; Put the high byte in with the low one.
390: (set (zero_extract:SI (match_dup 5) (const_int 8) (const_int 1))
391: (subreg:SI (match_dup 4) 0))
392: (set (match_operand:HI 0 "register_operand" "") (match_dup 5))]
393: ""
394: "operands[5] = gen_reg_rtx (HImode);")
395:
396: ;; Generate code to store an aligned halfword into memory.
397: ;; Operand 0 is the destination address (SImode).
398: ;; Operand 1 is the source register (HImode, not constant).
399: ;; Operand 2 is a temporary (SImode).
400: ;; Operand 3 is a temporary (SImode).
401: ;; Operand 4 is a temporary (QImode).
402:
403: (define_expand "storehi"
404: [(set (match_operand:SI 2 "register_operand" "")
405: (mem:SI (match_operand:SI 0 "register_operand" "")))
406: ;; Insert the low byte.
407: (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 0))
408: (subreg:SI (match_operand:HI 1 "register_operand" "") 0))
409: ;; Form address of high byte.
410: (set (match_operand:SI 3 "register_operand" "")
411: (plus:SI (match_dup 0) (const_int 1)))
412: ;; Extract the high byte from the source.
413: (set (subreg:SI (match_operand:QI 4 "register_operand" "") 0)
414: (zero_extract:SI (match_dup 1) (const_int 8) (const_int 1)))
415: ;; Store high byte into the memory word
416: (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3))
417: (subreg:SI (match_dup 4) 0))
418: ;; Put memory word back into memory.
419: (set (mem:SI (match_dup 0))
420: (match_dup 2))]
421: ""
422: "")
423:
424: ;; Like storehi but operands[1] is a CONST_INT.
425:
426: (define_expand "storeinthi"
427: [(set (match_operand:SI 2 "register_operand" "")
428: (mem:SI (match_operand:SI 0 "register_operand" "")))
429: ;; Insert the low byte.
430: (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 0))
431: (match_dup 5))
432: ;; Form address of high byte.
433: (set (match_operand:SI 3 "register_operand" "")
434: (plus:SI (match_dup 0) (const_int 1)))
435: ;; Store high byte into the memory word
436: (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3))
437: (match_dup 6))
438: ;; Put memory word back into memory.
439: (set (mem:SI (match_dup 0))
440: (match_dup 2))]
441: ""
442: " operands[5] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 255);
443: operands[6] = gen_rtx (CONST_INT, VOIDmode,
444: (INTVAL (operands[1]) >> 8) & 255);
445: ")
446:
447: ;; Main entry for generating insns to move halfwords.
448:
449: (define_expand "movhi"
450: [(set (match_operand:HI 0 "general_operand" "")
451: (match_operand:HI 1 "general_operand" ""))]
452: ""
453: "
454: {
455: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
456: operands[1] = copy_to_reg (operands[1]);
457:
458: if (GET_CODE (operands[1]) == MEM)
459: {
460: rtx insn =
461: emit_insn (gen_loadhi (operands[0],
462: force_reg (SImode, XEXP (operands[1], 0)),
463: gen_reg_rtx (SImode), gen_reg_rtx (SImode),
464: gen_reg_rtx (QImode)));
465: /* Tell cse what value the loadhi produces, so it detect duplicates. */
466: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, operands[1], 0);
467: }
468: else if (GET_CODE (operands[0]) == MEM)
469: {
470: if (GET_CODE (operands[1]) == CONST_INT)
471: emit_insn (gen_storeinthi (force_reg (SImode, XEXP (operands[0], 0)),
472: operands[1],
473: gen_reg_rtx (SImode), gen_reg_rtx (SImode),
474: gen_reg_rtx (QImode)));
475: else
476: {
477: if (CONSTANT_P (operands[1]))
478: operands[1] = force_reg (HImode, operands[1]);
479: emit_insn (gen_storehi (force_reg (SImode, XEXP (operands[0], 0)),
480: operands[1],
481: gen_reg_rtx (SImode), gen_reg_rtx (SImode),
482: gen_reg_rtx (QImode)));
483: }
484: }
485: else
486: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
487: DONE;
488: }")
489:
490: ;; Recognize insns generated for moving halfwords.
491: ;; (Note that the extract and insert patterns for single-byte moves
492: ;; are also involved in recognizing some of the insns used for this purpose.)
493:
494: (define_insn ""
495: [(set (match_operand:HI 0 "general_operand" "=r,m")
496: (match_operand:HI 1 "general_operand" "rmi,r"))]
497: ""
498: "*
499: {
500: if (GET_CODE (operands[0]) == MEM)
501: return \"st_32 %1,%0\";
502: if (GET_CODE (operands[1]) == MEM)
503: return \"ld_32 %0,%1\;nop\";
504: if (GET_CODE (operands[1]) == REG)
505: return \"add_nt %0,%1,$0\";
506: return \"add_nt %0,r0,%1\";
507: }")
508:
509: (define_insn ""
510: [(set (match_operand:SI 0 "register_operand" "=r")
511: (zero_extract:SI (match_operand:HI 1 "register_operand" "r")
512: (const_int 8)
513: (match_operand:SI 2 "nonmemory_operand" "rI")))]
514: ""
515: "extract %0,%1,%2")
516:
517: (define_insn ""
518: [(set (zero_extract:SI (match_operand:HI 0 "register_operand" "+r")
519: (const_int 8)
520: (match_operand:SI 1 "nonmemory_operand" "rI"))
521: (match_operand:SI 2 "nonmemory_operand" "ri"))]
522: ""
523: "wr_insert %1\;insert %0,%0,%2")
524:
525: ;; Constant propagation can optimize the previous pattern into this pattern.
526:
527: ;(define_insn ""
528: ; [(set (zero_extract:QI (match_operand:HI 0 "register_operand" "+r")
529: ; (const_int 8)
530: ; (match_operand:SI 1 "immediate_operand" "I"))
531: ; (match_operand:QI 2 "register_operand" "r"))]
532: ; "GET_CODE (operands[1]) == CONST_INT
533: ; && INTVAL (operands[1]) % 8 == 0
534: ; && (unsigned) INTVAL (operands[1]) < 32"
535: ; "*
536: ;{
537: ; operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 8);
538: ; return \"wr_insert 0,0,%1\;insert %0,%0,%2\";
539: ;}")
540:
541: ;; This pattern forces (set (reg:DF ...) (const_double ...))
542: ;; to be reloaded by putting the constant into memory.
543: ;; It must come before the more general movdf pattern.
544: (define_insn ""
545: [(set (match_operand:DF 0 "general_operand" "=r,f,o")
546: (match_operand:DF 1 "" "mG,m,G"))]
547: "GET_CODE (operands[1]) == CONST_DOUBLE"
548: "*
549: {
550: if (FP_REG_P (operands[0]))
551: return output_fp_move_double (operands);
552: if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == REG)
553: {
554: operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
555: return \"add_nt %0,r0,$0\;add_nt %1,r0,$0\";
556: }
557: if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == MEM)
558: {
559: operands[1] = adj_offsetable_operand (operands[0], 4);
560: return \"st_32 r0,%0\;st_32 r0,%1\";
561: }
562: return output_move_double (operands);
563: }
564: ")
565:
566: (define_insn "movdf"
567: [(set (match_operand:DF 0 "general_operand" "=r,m,?f,?rm")
568: (match_operand:DF 1 "general_operand" "rm,r,rfm,f"))]
569: ""
570: "*
571: {
572: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
573: return output_fp_move_double (operands);
574: return output_move_double (operands);
575: }
576: ")
577:
578: (define_insn "movdi"
579: [(set (match_operand:DI 0 "general_operand" "=r,m,?f,?rm")
580: (match_operand:DI 1 "general_operand" "rm,r,rfm,f"))]
581: ""
582: "*
583: {
584: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
585: return output_fp_move_double (operands);
586: return output_move_double (operands);
587: }
588: ")
589:
590: (define_insn "movsf"
591: [(set (match_operand:SF 0 "general_operand" "=rf,m")
592: (match_operand:SF 1 "general_operand" "rfm,rf"))]
593: ""
594: "*
595: {
596: if (FP_REG_P (operands[0]))
597: {
598: if (FP_REG_P (operands[1]))
599: return \"fmov %0,%1\";
600: if (GET_CODE (operands[1]) == REG)
601: {
602: rtx xoperands[2];
603: int offset = - get_frame_size () - 8;
604: xoperands[1] = operands[1];
605: xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset);
606: output_asm_insn (\"st_32 %1,r25,%0\", xoperands);
607: xoperands[1] = operands[0];
608: output_asm_insn (\"ld_sgl %1,r25,%0\;nop\", xoperands);
609: return \"\";
610: }
611: return \"ld_sgl %0,%1\;nop\";
612: }
613: if (FP_REG_P (operands[1]))
614: {
615: if (GET_CODE (operands[0]) == REG)
616: {
617: rtx xoperands[2];
618: int offset = - get_frame_size () - 8;
619: xoperands[0] = gen_rtx (CONST_INT, VOIDmode, offset);
620: xoperands[1] = operands[1];
621: output_asm_insn (\"st_sgl %1,r25,%0\", xoperands);
622: xoperands[1] = operands[0];
623: output_asm_insn (\"ld_32 %1,r25,%0\;nop\", xoperands);
624: return \"\";
625: }
626: return \"st_sgl %1,%0\";
627: }
628: if (GET_CODE (operands[0]) == MEM)
629: return \"st_32 %r1,%0\";
630: if (GET_CODE (operands[1]) == MEM)
631: return \"ld_32 %0,%1\;nop\";
632: if (GET_CODE (operands[1]) == REG)
633: return \"add_nt %0,%1,$0\";
634: return \"add_nt %0,r0,%1\";
635: }")
636:
637: ;;- truncation instructions
638: ;; I think these are unnecessary, since subreg will be used instead.
639: ;(define_insn "truncsiqi2"
640: ; [(set (match_operand:QI 0 "register_operand" "=r")
641: ; (truncate:QI
642: ; (match_operand:SI 1 "register_operand" "r")))]
643: ; ""
644: ; "add_nt, %0,%1,$0")
645: ;
646: ;(define_insn "trunchiqi2"
647: ; [(set (match_operand:QI 0 "register_operand" "=r")
648: ; (truncate:QI
649: ; (match_operand:HI 1 "register_operand" "r")))]
650: ; ""
651: ; "add_nt, %0,%1,$0")
652: ;
653: ;(define_insn "truncsihi2"
654: ; [(set (match_operand:HI 0 "register_operand" "=r")
655: ; (truncate:HI
656: ; (match_operand:SI 1 "register_operand" "r")))]
657: ; ""
658: ; "add_nt, %0,%1,$0")
659:
660: ;;- zero extension instructions
661:
662: ;; Note that the one starting from HImode comes before those for QImode
663: ;; so that a constant operand will match HImode, not QImode.
664: (define_expand "zero_extendhisi2"
665: [(set (match_operand:SI 0 "register_operand" "")
666: (and:SI (subreg:SI (match_operand:HI 1 "register_operand" "") 0)
667: ;; This constant is invalid, but reloading will handle it.
668: ;; It's useless to generate here the insns to construct it
669: ;; because constant propagation would simplify them anyway.
670: (match_dup 2)))]
671: ""
672: " operands[2] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, 65535)); ")
673:
674: (define_insn "zero_extendqihi2"
675: [(set (match_operand:HI 0 "register_operand" "=r")
676: (zero_extend:HI
677: (match_operand:QI 1 "register_operand" "r")))]
678: ""
679: "extract %0,%1,$0")
680:
681: (define_insn "zero_extendqisi2"
682: [(set (match_operand:SI 0 "register_operand" "=r")
683: (zero_extend:SI
684: (match_operand:QI 1 "register_operand" "r")))]
685: ""
686: "extract %0,%1,$0")
687:
688: ;;- sign extension instructions
689: ;; Note that the one starting from HImode comes before those for QImode
690: ;; so that a constant operand will match HImode, not QImode.
691:
692: (define_expand "extendhisi2"
693: [(set (match_dup 2)
694: (and:SI (subreg:SI (match_operand:HI 1 "register_operand" "") 0)
695: (match_dup 4)))
696: (set (match_dup 3) (plus:SI (match_dup 2) (match_dup 5)))
697: (set (match_operand:SI 0 "register_operand" "")
698: (xor:SI (match_dup 3) (match_dup 5)))]
699: ""
700: "
701: {
702: operands[2] = gen_reg_rtx (SImode);
703: operands[3] = gen_reg_rtx (SImode);
704: operands[4] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, 65535));
705: operands[5] = force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, -32768));
706: }")
707:
708: (define_expand "extendqihi2"
709: [(set (match_dup 2)
710: (and:HI (subreg:HI (match_operand:QI 1 "register_operand" "") 0)
711: (const_int 255)))
712: (set (match_dup 3)
713: (plus:SI (match_dup 2) (const_int -128)))
714: (set (match_operand:HI 0 "register_operand" "")
715: (xor:SI (match_dup 3) (const_int -128)))]
716: ""
717: "
718: {
719: operands[2] = gen_reg_rtx (HImode);
720: operands[3] = gen_reg_rtx (HImode);
721: }")
722:
723: (define_expand "extendqisi2"
724: [(set (match_dup 2)
725: (and:SI (subreg:SI (match_operand:QI 1 "register_operand" "") 0)
726: (const_int 255)))
727: (set (match_dup 3) (plus:SI (match_dup 2) (const_int -128)))
728: (set (match_operand:SI 0 "register_operand" "")
729: (xor:SI (match_dup 3) (const_int -128)))]
730: ""
731: "
732: {
733: operands[2] = gen_reg_rtx (SImode);
734: operands[3] = gen_reg_rtx (SImode);
735: }")
736:
737: ;;- arithmetic instructions
738:
739: (define_insn "addsi3"
740: [(set (match_operand:SI 0 "register_operand" "=r")
741: (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r")
742: (match_operand:SI 2 "nonmemory_operand" "rI")))]
743: ""
744: "add %0,%1,%2")
745:
746: (define_insn "subsi3"
747: [(set (match_operand:SI 0 "register_operand" "=r")
748: (minus:SI (match_operand:SI 1 "register_operand" "r")
749: (match_operand:SI 2 "nonmemory_operand" "rI")))]
750: ""
751: "sub %0,%1,%2")
752:
753: (define_insn "andsi3"
754: [(set (match_operand:SI 0 "register_operand" "=r")
755: (and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
756: (match_operand:SI 2 "nonmemory_operand" "rI")))]
757: ""
758: "and %0,%1,%2")
759:
760: (define_insn "iorsi3"
761: [(set (match_operand:SI 0 "register_operand" "=r")
762: (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
763: (match_operand:SI 2 "nonmemory_operand" "rI")))]
764: ""
765: "or %0,%1,%2")
766:
767: (define_insn "xorsi3"
768: [(set (match_operand:SI 0 "register_operand" "=r")
769: (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
770: (match_operand:SI 2 "nonmemory_operand" "rI")))]
771: ""
772: "xor %0,%1,%2")
773:
774: (define_insn "negsi2"
775: [(set (match_operand:SI 0 "register_operand" "=r")
776: (neg:SI (match_operand:SI 1 "nonmemory_operand" "rI")))]
777: ""
778: "sub %0,r0,%1")
779:
780: (define_insn "one_cmplsi2"
781: [(set (match_operand:SI 0 "register_operand" "=r")
782: (not:SI (match_operand:SI 1 "register_operand" "r")))]
783: ""
784: "xor %0,%1,$-1")
785:
786: ;; Floating point arithmetic instructions.
787:
788: (define_insn "adddf3"
789: [(set (match_operand:DF 0 "register_operand" "=f")
790: (plus:DF (match_operand:DF 1 "register_operand" "f")
791: (match_operand:DF 2 "register_operand" "f")))]
792: "TARGET_FPU"
793: "fadd %0,%1,%2")
794:
795: (define_insn "addsf3"
796: [(set (match_operand:SF 0 "register_operand" "=f")
797: (plus:SF (match_operand:SF 1 "register_operand" "f")
798: (match_operand:SF 2 "register_operand" "f")))]
799: "TARGET_FPU"
800: "fadd %0,%1,%2")
801:
802: (define_insn "subdf3"
803: [(set (match_operand:DF 0 "register_operand" "=f")
804: (minus:DF (match_operand:DF 1 "register_operand" "f")
805: (match_operand:DF 2 "register_operand" "f")))]
806: "TARGET_FPU"
807: "fsub %0,%1,%2")
808:
809: (define_insn "subsf3"
810: [(set (match_operand:SF 0 "register_operand" "=f")
811: (minus:SF (match_operand:SF 1 "register_operand" "f")
812: (match_operand:SF 2 "register_operand" "f")))]
813: "TARGET_FPU"
814: "fsub %0,%1,%2")
815:
816: (define_insn "muldf3"
817: [(set (match_operand:DF 0 "register_operand" "=f")
818: (mult:DF (match_operand:DF 1 "register_operand" "f")
819: (match_operand:DF 2 "register_operand" "f")))]
820: "TARGET_FPU"
821: "fmul %0,%1,%2")
822:
823: (define_insn "mulsf3"
824: [(set (match_operand:SF 0 "register_operand" "=f")
825: (mult:SF (match_operand:SF 1 "register_operand" "f")
826: (match_operand:SF 2 "register_operand" "f")))]
827: "TARGET_FPU"
828: "fmul %0,%1,%2")
829:
830: (define_insn "divdf3"
831: [(set (match_operand:DF 0 "register_operand" "=f")
832: (div:DF (match_operand:DF 1 "register_operand" "f")
833: (match_operand:DF 2 "register_operand" "f")))]
834: "TARGET_FPU"
835: "fdiv %0,%1,%2")
836:
837: (define_insn "divsf3"
838: [(set (match_operand:SF 0 "register_operand" "=f")
839: (div:SF (match_operand:SF 1 "register_operand" "f")
840: (match_operand:SF 2 "register_operand" "f")))]
841: "TARGET_FPU"
842: "fdiv %0,%1,%2")
843:
844: (define_insn "negdf2"
845: [(set (match_operand:DF 0 "register_operand" "=f")
846: (neg:DF (match_operand:DF 1 "nonmemory_operand" "f")))]
847: "TARGET_FPU"
848: "fneg %0,%1")
849:
850: (define_insn "negsf2"
851: [(set (match_operand:SF 0 "register_operand" "=f")
852: (neg:SF (match_operand:SF 1 "nonmemory_operand" "f")))]
853: "TARGET_FPU"
854: "fneg %0,%1")
855:
856: (define_insn "absdf2"
857: [(set (match_operand:DF 0 "register_operand" "=f")
858: (abs:DF (match_operand:DF 1 "nonmemory_operand" "f")))]
859: "TARGET_FPU"
860: "fabs %0,%1")
861:
862: (define_insn "abssf2"
863: [(set (match_operand:SF 0 "register_operand" "=f")
864: (abs:SF (match_operand:SF 1 "nonmemory_operand" "f")))]
865: "TARGET_FPU"
866: "fabs %0,%1")
867:
868: ;; Shift instructions
869:
870: (define_insn ""
871: [(set (match_operand:SI 0 "register_operand" "=r")
872: (ashift:SI (match_operand:SI 1 "register_operand" "r")
873: (match_operand:SI 2 "immediate_operand" "I")))]
874: "GET_CODE (operands[2]) == CONST_INT
875: && (unsigned) INTVAL (operands[2]) <= 3"
876: "sll %0,%1,%2")
877:
878: (define_insn ""
879: [(set (match_operand:SI 0 "register_operand" "=r")
880: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
881: (const_int 1)))]
882: ""
883: "sra %0,%1,$1")
884:
885: (define_insn ""
886: [(set (match_operand:SI 0 "register_operand" "=r")
887: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
888: (const_int 1)))]
889: ""
890: "srl %0,%1,$1")
891:
892: (define_expand "ashlsi3"
893: [(set (match_operand:SI 0 "register_operand" "")
894: (ashift:SI (match_operand:SI 1 "register_operand" "")
895: (match_operand:SI 2 "nonmemory_operand" "")))]
896: ""
897: "
898: {
899: if (GET_CODE (operands[2]) != CONST_INT
900: || (unsigned) INTVAL (operands[2]) > 3)
901: FAIL;
902: }")
903:
904: (define_expand "lshlsi3"
905: [(set (match_operand:SI 0 "register_operand" "")
906: (ashift:SI (match_operand:SI 1 "register_operand" "")
907: (match_operand:SI 2 "nonmemory_operand" "")))]
908: ""
909: "
910: {
911: if (GET_CODE (operands[2]) != CONST_INT
912: || (unsigned) INTVAL (operands[2]) > 3)
913: FAIL;
914: }")
915:
916: (define_expand "ashrsi3"
917: [(set (match_operand:SI 0 "register_operand" "")
918: (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
919: (match_operand:SI 2 "nonmemory_operand" "")))]
920: ""
921: "
922: {
923: if (GET_CODE (operands[2]) != CONST_INT
924: || (unsigned) INTVAL (operands[2]) > 1)
925: FAIL;
926: }")
927:
928: (define_expand "lshrsi3"
929: [(set (match_operand:SI 0 "register_operand" "")
930: (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
931: (match_operand:SI 2 "nonmemory_operand" "")))]
932: ""
933: "
934: {
935: if (GET_CODE (operands[2]) != CONST_INT
936: || (unsigned) INTVAL (operands[2]) > 1)
937: FAIL;
938: }")
939:
940: ;; Unconditional and other jump instructions
941: (define_insn "jump"
942: [(set (pc)
943: (label_ref (match_operand 0 "" "")))]
944: ""
945: "jump %l0\;nop")
946:
947: (define_insn "tablejump"
948: [(set (pc) (match_operand:SI 0 "register_operand" "r"))
949: (use (label_ref (match_operand 1 "" "")))]
950: ""
951: "jump_reg r0,%0\;nop")
952:
953: ;;- jump to subroutine
954: (define_insn "call"
955: [(call (match_operand:SI 0 "memory_operand" "m")
956: (match_operand:SI 1 "general_operand" "g"))]
957: ;;- Don't use operand 1 for most machines.
958: ""
959: "add_nt r9,%0\;call .+8\;jump_reg r0,r9\;nop")
960:
961: (define_insn "call_value"
962: [(set (match_operand 0 "" "g")
963: (call (match_operand:SI 1 "memory_operand" "m")
964: (match_operand:SI 2 "general_operand" "g")))]
965: ;;- Don't use operand 1 for most machines.
966: ""
967: "add_nt r9,%1\;call .+8\;jump_reg r0,r9\;nop")
968:
969: ;; A memory ref with constant address is not normally valid.
970: ;; But it is valid in a call insns. This pattern allows the
971: ;; loading of the address to combine with the call.
972: (define_insn ""
973: [(call (mem:SI (match_operand:SI 0 "" "i"))
974: (match_operand:SI 1 "general_operand" "g"))]
975: ;;- Don't use operand 1 for most machines.
976: "GET_CODE (operands[0]) == SYMBOL_REF"
977: "call %0\;nop")
978:
979: (define_insn ""
980: [(set (match_operand 0 "" "g")
981: (call (mem:SI (match_operand:SI 1 "" "i"))
982: (match_operand:SI 2 "general_operand" "g")))]
983: ;;- Don't use operand 1 for most machines.
984: "GET_CODE (operands[1]) == SYMBOL_REF"
985: "call %1\;nop")
986:
987: ;;- Local variables:
988: ;;- mode:emacs-lisp
989: ;;- comment-start: ";;- "
990: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
991: ;;- eval: (modify-syntax-entry ?[ "(]")
992: ;;- eval: (modify-syntax-entry ?] ")[")
993: ;;- eval: (modify-syntax-entry ?{ "(}")
994: ;;- eval: (modify-syntax-entry ?} "){")
995: ;;- End:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.