|
|
1.1 root 1: ;; GNU C machine description for Pyramid 90x, 9000, MIServer Series
2: ;; Copyright (C) 1989, 1990 Free Software Foundation, Inc.
3:
4: ;; This file is part of GNU CC.
5:
6: ;; GNU CC is free software; you can redistribute it and/or modify
7: ;; it under the terms of the GNU General Public License as published by
8: ;; the Free Software Foundation; either version 2, or (at your option)
9: ;; any later version.
10:
11: ;; GNU CC is distributed in the hope that it will be useful,
12: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: ;; GNU General Public License for more details.
15:
16: ;; You should have received a copy of the GNU General Public License
17: ;; along with GNU CC; see the file COPYING. If not, write to
18: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19:
20: ;; Instruction patterns. When multiple patterns apply,
21: ;; the first one in the file is chosen.
22: ;;
23: ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
24: ;;
25: ;; cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
26: ;; updates for most instructions.
27:
28: ;; These comments are mostly obsolete. Written for gcc version 1.XX.
29: ;; * Try using define_insn instead of some peepholes in more places.
30: ;; * Set REG_NOTES:REG_EQUIV for cvt[bh]w loads. This would make the
31: ;; backward scan in sign_extend needless.
32: ;; * Match (pc) (label_ref) case in peephole patterns.
33: ;; * Should optimize
34: ;; "cmpX op1,op2; b{eq,ne} LY; ucmpX op1.op2; b{lt,le,gt,ge} LZ"
35: ;; to
36: ;; "ucmpX op1,op2; b{eq,ne} LY; b{lt,le,gt,ge} LZ"
37: ;; by pre-scanning insn and running notice_update_cc for them.
38: ;; * Is it necessary to do copy_rtx in the test and compare patterns?
39: ;; * Fix true frame pointer omission.
40: ;; * Make the jump tables contain branches, not addresses! This would
41: ;; save us one instruction.
42: ;; * Could the complicated scheme for compares be simplified, if we had
43: ;; no named cmpqi or cmphi patterns, and instead anonymous patterns for
44: ;; the less-than-word compare cases pyr can handle???
45: ;; * The jump insn seems to accept more than just IR addressing. Would
46: ;; we win by telling GCC? Or can we use movw into the global reg which
47: ;; is a synonym for pc?
48: ;; * More DImode patterns.
49: ;; * Scan backwards in "zero_extendhisi2", "zero_extendqisi2" to find out
50: ;; if the extension can be omitted.
51: ;; * "divmodsi" with Pyramid "ediv" insn. Is it possible in rtl??
52: ;; * Would "rcsp tmpreg; u?cmp[bh] op1_regdispl(tmpreg),op2" win in
53: ;; comparison with the two extensions and single test generated now?
54: ;; The rcsp insn could be expanded, and moved out of loops by the
55: ;; optimizer, making 1 (64 bit) insn of 3 (32 bit) insns in loops.
56: ;; The rcsp insn could be followed by an add insn, making non-displacement
57: ;; IR addressing sufficient.
58:
59: ;______________________________________________________________________
60: ;
61: ; Test and Compare Patterns.
62: ;______________________________________________________________________
63:
64: ; The argument for the rather complicated test and compare expansion
65: ; scheme, is the irregular pyramid instructions for these operations.
66: ; 1) Pyramid has different signed and unsigned compares. 2) HImode
67: ; and QImode integers are memory-memory and immediate-memory only. 3)
68: ; Unsigned HImode compares doesn't exist. 4) Only certain
69: ; combinations of addresses are allowed for memory-memory compares.
70: ; Whenever necessary, in order to fulfill these addressing
71: ; constraints, the compare operands are swapped.
72:
73: (define_expand "tstsi"
74: [(set (cc0)
75: (match_operand:SI 0 "general_operand" ""))]
76: "" "operands[0] = force_reg (SImode, operands[0]);")
77:
78: (define_insn ""
79: [(set (cc0)
80: (compare (match_operand:SI 0 "memory_operand" "m")
81: (match_operand:SI 1 "memory_operand" "m")))]
82: "weird_memory_memory (operands[0], operands[1])"
83: "*
84: {
85: rtx br_insn = NEXT_INSN (insn);
86: RTX_CODE br_code;
87:
88: if (GET_CODE (br_insn) != JUMP_INSN)
89: abort();
90: br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
91:
92: weird_memory_memory (operands[0], operands[1]);
93:
94: if (swap_operands)
95: {
96: cc_status.flags = CC_REVERSED;
97: if (TRULY_UNSIGNED_COMPARE_P (br_code))
98: {
99: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
100: return \"ucmpw %0,%1\";
101: }
102: return \"cmpw %0,%1\";
103: }
104:
105: if (TRULY_UNSIGNED_COMPARE_P (br_code))
106: {
107: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
108: return \"ucmpw %1,%0\";
109: }
110: return \"cmpw %1,%0\";
111: }")
112:
113: (define_insn "cmpsi"
114: [(set (cc0)
115: (compare (match_operand:SI 0 "nonimmediate_operand" "r,g")
116: (match_operand:SI 1 "general_operand" "g,r")))]
117: ""
118: "*
119: {
120: rtx br_insn = NEXT_INSN (insn);
121: RTX_CODE br_code;
122:
123: if (GET_CODE (br_insn) != JUMP_INSN)
124: abort();
125: br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
126:
127: if (which_alternative != 0)
128: {
129: cc_status.flags = CC_REVERSED;
130: if (TRULY_UNSIGNED_COMPARE_P (br_code))
131: {
132: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
133: return \"ucmpw %0,%1\";
134: }
135: return \"cmpw %0,%1\";
136: }
137:
138: if (TRULY_UNSIGNED_COMPARE_P (br_code))
139: {
140: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
141: return \"ucmpw %1,%0\";
142: }
143: return \"cmpw %1,%0\";
144: }")
145:
146: (define_insn ""
147: [(set (cc0)
148: (match_operand:SI 0 "nonimmediate_operand" "r"))]
149: ""
150: "*
151: {
152: #if 0
153: cc_status.flags |= CC_NO_OVERFLOW;
154: return \"cmpw $0,%0\";
155: #endif
156: rtx br_insn = NEXT_INSN (insn);
157: RTX_CODE br_code;
158:
159: if (GET_CODE (br_insn) != JUMP_INSN)
160: abort();
161: br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
162:
163: if (TRULY_UNSIGNED_COMPARE_P (br_code))
164: {
165: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
166: return \"ucmpw $0,%0\";
167: }
168: return \"mtstw %0,%0\";
169: }")
170:
171: (define_expand "cmphi"
172: [(set (cc0)
173: (compare (match_operand:HI 0 "nonimmediate_operand" "")
174: (match_operand:HI 1 "general_operand" "")))]
175: ""
176: "
177: {
178: extern rtx test_op0, test_op1; extern enum machine_mode test_mode;
179: test_op0 = copy_rtx (operands[0]);
180: test_op1 = copy_rtx (operands[1]);
181: test_mode = HImode;
182: DONE;
183: }")
184:
185: (define_expand "tsthi"
186: [(set (cc0)
187: (match_operand:HI 0 "nonimmediate_operand" ""))]
188: ""
189: "
190: {
191: extern rtx test_op0; extern enum machine_mode test_mode;
192: test_op0 = copy_rtx (operands[0]);
193: test_mode = HImode;
194: DONE;
195: }")
196:
197: (define_insn ""
198: [(set (cc0)
199: (compare (match_operand:HI 0 "memory_operand" "m")
200: (match_operand:HI 1 "memory_operand" "m")))]
201: "(!TRULY_UNSIGNED_COMPARE_P (GET_CODE (XEXP (SET_SRC (PATTERN (NEXT_INSN (insn))), 0))))
202: && weird_memory_memory (operands[0], operands[1])"
203: "*
204: {
205: rtx br_insn = NEXT_INSN (insn);
206:
207: if (GET_CODE (br_insn) != JUMP_INSN)
208: abort();
209:
210: weird_memory_memory (operands[0], operands[1]);
211:
212: if (swap_operands)
213: {
214: cc_status.flags = CC_REVERSED;
215: return \"cmph %0,%1\";
216: }
217:
218: return \"cmph %1,%0\";
219: }")
220:
221: (define_insn ""
222: [(set (cc0)
223: (compare (match_operand:HI 0 "nonimmediate_operand" "r,m")
224: (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
225: "(!TRULY_UNSIGNED_COMPARE_P (GET_CODE (XEXP (SET_SRC (PATTERN (NEXT_INSN (insn))), 0))))
226: && (GET_CODE (operands[0]) != GET_CODE (operands[1]))"
227: "*
228: {
229: rtx br_insn = NEXT_INSN (insn);
230:
231: if (GET_CODE (br_insn) != JUMP_INSN)
232: abort();
233:
234: if (which_alternative != 0)
235: {
236: cc_status.flags = CC_REVERSED;
237: return \"cmph %0,%1\";
238: }
239:
240: return \"cmph %1,%0\";
241: }")
242:
243: (define_expand "cmpqi"
244: [(set (cc0)
245: (compare (match_operand:QI 0 "nonimmediate_operand" "")
246: (match_operand:QI 1 "general_operand" "")))]
247: ""
248: "
249: {
250: extern rtx test_op0, test_op1; extern enum machine_mode test_mode;
251: test_op0 = copy_rtx (operands[0]);
252: test_op1 = copy_rtx (operands[1]);
253: test_mode = QImode;
254: DONE;
255: }")
256:
257: (define_expand "tstqi"
258: [(set (cc0)
259: (match_operand:QI 0 "nonimmediate_operand" ""))]
260: ""
261: "
262: {
263: extern rtx test_op0; extern enum machine_mode test_mode;
264: test_op0 = copy_rtx (operands[0]);
265: test_mode = QImode;
266: DONE;
267: }")
268:
269: (define_insn ""
270: [(set (cc0)
271: (compare (match_operand:QI 0 "memory_operand" "m")
272: (match_operand:QI 1 "memory_operand" "m")))]
273: "weird_memory_memory (operands[0], operands[1])"
274: "*
275: {
276: rtx br_insn = NEXT_INSN (insn);
277: RTX_CODE br_code;
278:
279: if (GET_CODE (br_insn) != JUMP_INSN)
280: abort();
281: br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
282:
283: weird_memory_memory (operands[0], operands[1]);
284:
285: if (swap_operands)
286: {
287: cc_status.flags = CC_REVERSED;
288: if (TRULY_UNSIGNED_COMPARE_P (br_code))
289: {
290: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
291: return \"ucmpb %0,%1\";
292: }
293: return \"cmpb %0,%1\";
294: }
295:
296: if (TRULY_UNSIGNED_COMPARE_P (br_code))
297: {
298: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
299: return \"ucmpb %1,%0\";
300: }
301: return \"cmpb %1,%0\";
302: }")
303:
304: (define_insn ""
305: [(set (cc0)
306: (compare (match_operand:QI 0 "nonimmediate_operand" "r,m")
307: (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
308: "(GET_CODE (operands[0]) != GET_CODE (operands[1]))"
309: "*
310: {
311: rtx br_insn = NEXT_INSN (insn);
312: RTX_CODE br_code;
313:
314: if (GET_CODE (br_insn) != JUMP_INSN)
315: abort();
316: br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
317:
318: if (which_alternative != 0)
319: {
320: cc_status.flags = CC_REVERSED;
321: if (TRULY_UNSIGNED_COMPARE_P (br_code))
322: {
323: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
324: return \"ucmpb %0,%1\";
325: }
326: return \"cmpb %0,%1\";
327: }
328:
329: if (TRULY_UNSIGNED_COMPARE_P (br_code))
330: {
331: cc_status.mdep = CC_VALID_FOR_UNSIGNED;
332: return \"ucmpb %1,%0\";
333: }
334: return \"cmpb %1,%0\";
335: }")
336:
337: (define_expand "bgt"
338: [(set (pc) (if_then_else (gt (cc0) (const_int 0))
339: (label_ref (match_operand 0 "" "")) (pc)))]
340: "" "extend_and_branch (SIGN_EXTEND);")
341:
342: (define_expand "blt"
343: [(set (pc) (if_then_else (lt (cc0) (const_int 0))
344: (label_ref (match_operand 0 "" "")) (pc)))]
345: "" "extend_and_branch (SIGN_EXTEND);")
346:
347: (define_expand "bge"
348: [(set (pc) (if_then_else (ge (cc0) (const_int 0))
349: (label_ref (match_operand 0 "" "")) (pc)))]
350: "" "extend_and_branch (SIGN_EXTEND);")
351:
352: (define_expand "ble"
353: [(set (pc) (if_then_else (le (cc0) (const_int 0))
354: (label_ref (match_operand 0 "" "")) (pc)))]
355: "" "extend_and_branch (SIGN_EXTEND);")
356:
357: (define_expand "beq"
358: [(set (pc) (if_then_else (eq (cc0) (const_int 0))
359: (label_ref (match_operand 0 "" "")) (pc)))]
360: "" "extend_and_branch (SIGN_EXTEND);")
361:
362: (define_expand "bne"
363: [(set (pc) (if_then_else (ne (cc0) (const_int 0))
364: (label_ref (match_operand 0 "" "")) (pc)))]
365: "" "extend_and_branch (SIGN_EXTEND);")
366:
367: (define_expand "bgtu"
368: [(set (pc) (if_then_else (gtu (cc0) (const_int 0))
369: (label_ref (match_operand 0 "" "")) (pc)))]
370: "" "extend_and_branch (ZERO_EXTEND);")
371:
372: (define_expand "bltu"
373: [(set (pc) (if_then_else (ltu (cc0) (const_int 0))
374: (label_ref (match_operand 0 "" "")) (pc)))]
375: "" "extend_and_branch (ZERO_EXTEND);")
376:
377: (define_expand "bgeu"
378: [(set (pc) (if_then_else (geu (cc0) (const_int 0))
379: (label_ref (match_operand 0 "" "")) (pc)))]
380: "" "extend_and_branch (ZERO_EXTEND);")
381:
382: (define_expand "bleu"
383: [(set (pc) (if_then_else (leu (cc0) (const_int 0))
384: (label_ref (match_operand 0 "" "")) (pc)))]
385: "" "extend_and_branch (ZERO_EXTEND);")
386:
387: (define_insn "cmpdf"
388: [(set (cc0)
389: (compare (match_operand:DF 0 "register_operand" "r")
390: (match_operand:DF 1 "register_operand" "r")))]
391: ""
392: "cmpd %1,%0")
393:
394: (define_insn "cmpsf"
395: [(set (cc0)
396: (compare (match_operand:SF 0 "register_operand" "r")
397: (match_operand:SF 1 "register_operand" "r")))]
398: ""
399: "cmpf %1,%0")
400:
401: (define_insn "tstdf"
402: [(set (cc0)
403: (match_operand:DF 0 "register_operand" "r"))]
404: ""
405: "mtstd %0,%0")
406:
407: (define_insn "tstsf"
408: [(set (cc0)
409: (match_operand:SF 0 "register_operand" "r"))]
410: ""
411: "mtstf %0,%0")
412:
413: ;______________________________________________________________________
414: ;
415: ; Fixed-point Arithmetic.
416: ;______________________________________________________________________
417:
418: (define_insn "addsi3"
419: [(set (match_operand:SI 0 "register_operand" "=r,!r")
420: (plus:SI (match_operand:SI 1 "general_operand" "%0,r")
421: (match_operand:SI 2 "general_operand" "g,rJ")))]
422: ""
423: "*
424: {
425: if (which_alternative == 0)
426: return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 32
427: ? \"subw %n2,%0\" : \"addw %2,%0\");
428: else
429: {
430: forget_cc_if_dependent (operands[0]);
431: return \"mova %a2[%1*1],%0\";
432: }
433: }")
434:
435: (define_insn "subsi3"
436: [(set (match_operand:SI 0 "register_operand" "=r,r")
437: (minus:SI (match_operand:SI 1 "general_operand" "0,g")
438: (match_operand:SI 2 "general_operand" "g,0")))]
439: ""
440: "* return (which_alternative == 0) ? \"subw %2,%0\" : \"rsubw %1,%0\";")
441:
442: (define_insn "mulsi3"
443: [(set (match_operand:SI 0 "register_operand" "=r")
444: (mult:SI (match_operand:SI 1 "general_operand" "%0")
445: (match_operand:SI 2 "general_operand" "g")))]
446: ""
447: "mulw %2,%0")
448:
449: (define_insn "divsi3"
450: [(set (match_operand:SI 0 "register_operand" "=r,r")
451: (div:SI (match_operand:SI 1 "general_operand" "0,g")
452: (match_operand:SI 2 "general_operand" "g,0")))]
453: ""
454: "* return (which_alternative == 0) ? \"divw %2,%0\" : \"rdivw %1,%0\";")
455:
456: (define_insn "udivsi3"
457: [(set (match_operand:SI 0 "register_operand" "=r")
458: (udiv:SI (match_operand:SI 1 "register_operand" "0")
459: (match_operand:SI 2 "general_operand" "g")))]
460: ""
461: "udivw %2,%0")
462:
463: (define_insn "modsi3"
464: [(set (match_operand:SI 0 "register_operand" "=r")
465: (mod:SI (match_operand:SI 1 "register_operand" "0")
466: (match_operand:SI 2 "general_operand" "g")))]
467: ""
468: "modw %2,%0")
469:
470: (define_insn "umodsi3"
471: [(set (match_operand:SI 0 "register_operand" "=r")
472: (umod:SI (match_operand:SI 1 "register_operand" "0")
473: (match_operand:SI 2 "general_operand" "g")))]
474: ""
475: "umodw %2,%0")
476:
477: (define_insn "negsi2"
478: [(set (match_operand:SI 0 "register_operand" "=r")
479: (neg:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
480: ""
481: "mnegw %1,%0")
482:
483: (define_insn "one_cmplsi2"
484: [(set (match_operand:SI 0 "register_operand" "=r")
485: (not:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
486: ""
487: "mcomw %1,%0")
488:
489: (define_insn "abssi2"
490: [(set (match_operand:SI 0 "register_operand" "=r")
491: (abs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
492: ""
493: "mabsw %1,%0")
494:
495: ;______________________________________________________________________
496: ;
497: ; Floating-point Arithmetic.
498: ;______________________________________________________________________
499:
500: (define_insn "adddf3"
501: [(set (match_operand:DF 0 "register_operand" "=r")
502: (plus:DF (match_operand:DF 1 "register_operand" "%0")
503: (match_operand:DF 2 "register_operand" "r")))]
504: ""
505: "addd %2,%0")
506:
507: (define_insn "addsf3"
508: [(set (match_operand:SF 0 "register_operand" "=r")
509: (plus:SF (match_operand:SF 1 "register_operand" "%0")
510: (match_operand:SF 2 "register_operand" "r")))]
511: ""
512: "addf %2,%0")
513:
514: (define_insn "subdf3"
515: [(set (match_operand:DF 0 "register_operand" "=r")
516: (minus:DF (match_operand:DF 1 "register_operand" "0")
517: (match_operand:DF 2 "register_operand" "r")))]
518: ""
519: "subd %2,%0")
520:
521: (define_insn "subsf3"
522: [(set (match_operand:SF 0 "register_operand" "=r")
523: (minus:SF (match_operand:SF 1 "register_operand" "0")
524: (match_operand:SF 2 "register_operand" "r")))]
525: ""
526: "subf %2,%0")
527:
528: (define_insn "muldf3"
529: [(set (match_operand:DF 0 "register_operand" "=r")
530: (mult:DF (match_operand:DF 1 "register_operand" "%0")
531: (match_operand:DF 2 "register_operand" "r")))]
532: ""
533: "muld %2,%0")
534:
535: (define_insn "mulsf3"
536: [(set (match_operand:SF 0 "register_operand" "=r")
537: (mult:SF (match_operand:SF 1 "register_operand" "%0")
538: (match_operand:SF 2 "register_operand" "r")))]
539: ""
540: "mulf %2,%0")
541:
542: (define_insn "divdf3"
543: [(set (match_operand:DF 0 "register_operand" "=r")
544: (div:DF (match_operand:DF 1 "register_operand" "0")
545: (match_operand:DF 2 "register_operand" "r")))]
546: ""
547: "divd %2,%0")
548:
549: (define_insn "divsf3"
550: [(set (match_operand:SF 0 "register_operand" "=r")
551: (div:SF (match_operand:SF 1 "register_operand" "0")
552: (match_operand:SF 2 "register_operand" "r")))]
553: ""
554: "divf %2,%0")
555:
556: (define_insn "negdf2"
557: [(set (match_operand:DF 0 "register_operand" "=r")
558: (neg:DF (match_operand:DF 1 "register_operand" "r")))]
559: ""
560: "mnegd %1,%0")
561:
562: (define_insn "negsf2"
563: [(set (match_operand:SF 0 "register_operand" "=r")
564: (neg:SF (match_operand:SF 1 "register_operand" "r")))]
565: ""
566: "mnegf %1,%0")
567:
568: (define_insn "absdf2"
569: [(set (match_operand:DF 0 "register_operand" "=r")
570: (abs:DF (match_operand:DF 1 "register_operand" "r")))]
571: ""
572: "mabsd %1,%0")
573:
574: (define_insn "abssf2"
575: [(set (match_operand:SF 0 "register_operand" "=r")
576: (abs:SF (match_operand:SF 1 "register_operand" "r")))]
577: ""
578: "mabsf %1,%0")
579:
580: ;______________________________________________________________________
581: ;
582: ; Logical and Shift Instructions.
583: ;______________________________________________________________________
584:
585: (define_insn ""
586: [(set (cc0)
587: (and:SI (match_operand:SI 0 "general_operand" "%r")
588: (match_operand:SI 1 "general_operand" "g")))]
589: ""
590: "*
591: {
592: cc_status.flags |= CC_NO_OVERFLOW;
593: return \"bitw %1,%0\";
594: }")
595:
596: (define_insn "andsi3"
597: [(set (match_operand:SI 0 "register_operand" "=r,r")
598: (and:SI (match_operand:SI 1 "general_operand" "%0,r")
599: (match_operand:SI 2 "general_operand" "g,K")))]
600: ""
601: "*
602: {
603: if (which_alternative == 0)
604: return \"andw %2,%0\";
605:
606: cc_status.flags = CC_NOT_NEGATIVE;
607: return (INTVAL (operands[2]) == 255
608: ? \"movzbw %1,%0\" : \"movzhw %1,%0\");
609: }")
610:
611: (define_insn ""
612: [(set (match_operand:SI 0 "register_operand" "=r")
613: (and:SI (not:SI (match_operand:SI 1 "general_operand" "g"))
614: (match_operand:SI 2 "register_operand" "0")))]
615: ""
616: "bicw %1,%0")
617:
618: (define_insn "iorsi3"
619: [(set (match_operand:SI 0 "register_operand" "=r")
620: (ior:SI (match_operand:SI 1 "general_operand" "%0")
621: (match_operand:SI 2 "general_operand" "g")))]
622: ""
623: "orw %2,%0")
624:
625: (define_insn "xorsi3"
626: [(set (match_operand:SI 0 "register_operand" "=r")
627: (xor:SI (match_operand:SI 1 "general_operand" "%0")
628: (match_operand:SI 2 "general_operand" "g")))]
629: ""
630: "xorw %2,%0")
631:
632: ; The arithmetic left shift instructions work strangely on pyramids.
633: ; They fail to modify the sign bit. Therefore, use logic shifts.
634:
635: (define_insn "ashlsi3"
636: [(set (match_operand:SI 0 "register_operand" "=r")
637: (ashift:SI (match_operand:SI 1 "register_operand" "0")
638: (match_operand:SI 2 "general_operand" "rnm")))]
639: ""
640: "*
641: {
642: extern char *output_shift ();
643: return output_shift (\"lshlw %2,%0\", operands[2], 32);
644: }")
645:
646: (define_insn "ashrsi3"
647: [(set (match_operand:SI 0 "register_operand" "=r")
648: (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
649: (match_operand:SI 2 "general_operand" "rnm")))]
650: ""
651: "*
652: {
653: extern char *output_shift ();
654: return output_shift (\"ashrw %2,%0\", operands[2], 32);
655: }")
656:
657: (define_insn "ashrdi3"
658: [(set (match_operand:DI 0 "register_operand" "=r")
659: (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
660: (match_operand:SI 2 "general_operand" "rnm")))]
661: ""
662: "*
663: {
664: extern char *output_shift ();
665: return output_shift (\"ashrl %2,%0\", operands[2], 64);
666: }")
667:
668: (define_insn "lshrsi3"
669: [(set (match_operand:SI 0 "register_operand" "=r")
670: (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
671: (match_operand:SI 2 "general_operand" "rnm")))]
672: ""
673: "*
674: {
675: extern char *output_shift ();
676: return output_shift (\"lshrw %2,%0\", operands[2], 32);
677: }")
678:
679: (define_insn "rotlsi3"
680: [(set (match_operand:SI 0 "register_operand" "=r")
681: (rotate:SI (match_operand:SI 1 "register_operand" "0")
682: (match_operand:SI 2 "general_operand" "rnm")))]
683: ""
684: "*
685: {
686: extern char *output_shift ();
687: return output_shift (\"rotlw %2,%0\", operands[2], 32);
688: }")
689:
690: (define_insn "rotrsi3"
691: [(set (match_operand:SI 0 "register_operand" "=r")
692: (rotatert:SI (match_operand:SI 1 "register_operand" "0")
693: (match_operand:SI 2 "general_operand" "rnm")))]
694: ""
695: "*
696: {
697: extern char *output_shift ();
698: return output_shift (\"rotrw %2,%0\", operands[2], 32);
699: }")
700:
701: ;______________________________________________________________________
702: ;
703: ; Fixed and Floating Moves.
704: ;______________________________________________________________________
705:
706: ;; If the destination is a memory operand, indexed source operands are
707: ;; disallowed. Big DImode constants are always loaded into a reg pair,
708: ;; although offsettable memory addresses really could be dealt with.
709:
710: (define_insn ""
711: [(set (match_operand:DI 0 "memory_operand" "=m")
712: (match_operand:DI 1 "nonindexed_operand" "gF"))]
713: "(GET_CODE (operands[1]) == CONST_DOUBLE
714: ? ((CONST_DOUBLE_HIGH (operands[1]) == 0
715: && CONST_DOUBLE_LOW (operands[1]) >= 0)
716: || (CONST_DOUBLE_HIGH (operands[1]) == -1
717: && CONST_DOUBLE_LOW (operands[1]) < 0))
718: : 1)"
719: "*
720: {
721: if (GET_CODE (operands[1]) == CONST_DOUBLE)
722: operands[1] = gen_rtx (CONST_INT, VOIDmode,
723: CONST_DOUBLE_LOW (operands[1]));
724: return \"movl %1,%0\";
725: }")
726:
727: ;; Force the destination to a register, so all source operands are allowed.
728:
729: (define_insn "movdi"
730: [(set (match_operand:DI 0 "general_operand" "=r")
731: (match_operand:DI 1 "general_operand" "gF"))]
732: ""
733: "*
734: {
735: extern char *output_move_double ();
736: return output_move_double (operands);
737: }")
738:
739: ;; If the destination is a memory address, indexed source operands are
740: ;; disallowed.
741:
742: (define_insn ""
743: [(set (match_operand:SI 0 "memory_operand" "=m")
744: (match_operand:SI 1 "nonindexed_operand" "g"))]
745: ""
746: "movw %1,%0")
747:
748: ;; Force the destination to a register, so all source operands are allowed.
749:
750: (define_insn "movsi"
751: [(set (match_operand:SI 0 "general_operand" "=r")
752: (match_operand:SI 1 "general_operand" "g"))]
753: ""
754: "movw %1,%0")
755:
756: ;; If the destination is a memory address, indexed source operands are
757: ;; disallowed.
758:
759: (define_insn ""
760: [(set (match_operand:HI 0 "memory_operand" "=m")
761: (match_operand:HI 1 "nonindexed_operand" "g"))]
762: ""
763: "*
764: {
765: if (REG_P (operands[1]))
766: return \"cvtwh %1,%0\"; /* reg -> mem */
767: else
768: return \"movh %1,%0\"; /* mem imm -> mem */
769: }")
770:
771: ;; Force the destination to a register, so all source operands are allowed.
772:
773: (define_insn "movhi"
774: [(set (match_operand:HI 0 "general_operand" "=r")
775: (match_operand:HI 1 "general_operand" "g"))]
776: ""
777: "*
778: {
779: if (GET_CODE (operands[1]) != MEM)
780: return \"movw %1,%0\"; /* reg imm -> reg */
781: return \"cvthw %1,%0\"; /* mem -> reg */
782: }")
783:
784: ;; If the destination is a memory address, indexed source operands are
785: ;; disallowed.
786:
787: (define_insn ""
788: [(set (match_operand:QI 0 "memory_operand" "=m")
789: (match_operand:QI 1 "nonindexed_operand" "g"))]
790: ""
791: "*
792: {
793: if (REG_P (operands[1]))
794: return \"cvtwb %1,%0\"; /* reg -> mem */
795: else
796: return \"movb %1,%0\"; /* mem imm -> mem */
797: }")
798:
799: ;; Force the destination to a register, so all source operands are allowed.
800:
801: (define_insn "movqi"
802: [(set (match_operand:QI 0 "general_operand" "=r")
803: (match_operand:QI 1 "general_operand" "g"))]
804: ""
805: "*
806: {
807: if (GET_CODE (operands[1]) != MEM)
808: return \"movw %1,%0\"; /* reg imm -> reg */
809: return \"cvtbw %1,%0\"; /* mem -> reg */
810: }")
811:
812: ;; If the destination is a memory address, indexed source operands are
813: ;; disallowed.
814:
815: (define_insn ""
816: [(set (match_operand:DF 0 "memory_operand" "=m")
817: (match_operand:DF 1 "nonindexed_operand" "g"))]
818: "GET_CODE (operands[1]) != CONST_DOUBLE"
819: "movl %1,%0")
820:
821: ;; Force the destination to a register, so all source operands are allowed.
822:
823: (define_insn "movdf"
824: [(set (match_operand:DF 0 "general_operand" "=r")
825: (match_operand:DF 1 "general_operand" "gF"))]
826: ""
827: "*
828: {
829: extern char *output_move_double ();
830: return output_move_double (operands);
831: }")
832:
833: ;; If the destination is a memory address, indexed source operands are
834: ;; disallowed.
835:
836: (define_insn ""
837: [(set (match_operand:SF 0 "memory_operand" "=m")
838: (match_operand:SF 1 "nonindexed_operand" "g"))]
839: ""
840: "movw %1,%0")
841:
842: ;; Force the destination to a register, so all source operands are allowed.
843:
844: (define_insn "movsf"
845: [(set (match_operand:SF 0 "general_operand" "=r")
846: (match_operand:SF 1 "general_operand" "g"))]
847: ""
848: "movw %1,%0")
849:
850: (define_insn ""
851: [(set (match_operand:SI 0 "register_operand" "=r")
852: (match_operand:QI 1 "address_operand" "p"))]
853: ""
854: "*
855: {
856: forget_cc_if_dependent (operands[0]);
857: return \"mova %a1,%0\";
858: }")
859:
860: ;______________________________________________________________________
861: ;
862: ; Conversion patterns.
863: ;______________________________________________________________________
864:
865: ;; The trunc patterns are used only when non compile-time constants are used.
866:
867: (define_insn "truncsiqi2"
868: [(set (match_operand:QI 0 "register_operand" "=r")
869: (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
870: ""
871: "*
872: {
873: if (REG_P (operands[0]) && REG_P (operands[1])
874: && REGNO (operands[0]) == REGNO (operands[1]))
875: {
876: cc_status = cc_prev_status;
877: return \"\";
878: }
879: forget_cc_if_dependent (operands[0]);
880: return \"movw %1,%0\";
881: }")
882:
883: (define_insn "truncsihi2"
884: [(set (match_operand:HI 0 "register_operand" "=r")
885: (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
886: ""
887: "*
888: {
889: if (REG_P (operands[0]) && REG_P (operands[1])
890: && REGNO (operands[0]) == REGNO (operands[1]))
891: {
892: cc_status = cc_prev_status;
893: return \"\";
894: }
895: forget_cc_if_dependent (operands[0]);
896: return \"movw %1,%0\";
897: }")
898:
899: (define_insn "extendhisi2"
900: [(set (match_operand:SI 0 "general_operand" "=r,m")
901: (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm,r")))]
902: ""
903: "*
904: {
905: extern int optimize;
906: if (optimize && REG_P (operands[0]) && REG_P (operands[1])
907: && REGNO (operands[0]) == REGNO (operands[1])
908: && already_sign_extended (insn, HImode, operands[0]))
909: {
910: cc_status = cc_prev_status;
911: return \"\";
912: }
913: return \"cvthw %1,%0\";
914: }")
915:
916: (define_insn "extendqisi2"
917: [(set (match_operand:SI 0 "general_operand" "=r,m")
918: (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm,r")))]
919: ""
920: "*
921: {
922: extern int optimize;
923: if (optimize && REG_P (operands[0]) && REG_P (operands[1])
924: && REGNO (operands[0]) == REGNO (operands[1])
925: && already_sign_extended (insn, QImode, operands[0]))
926: {
927: cc_status = cc_prev_status;
928: return \"\";
929: }
930: return \"cvtbw %1,%0\";
931: }")
932:
933: ; Pyramid doesn't have insns *called* "cvtbh" or "movzbh".
934: ; But we can cvtbw/movzbw into a register, where there is no distinction
935: ; between words and halfwords.
936:
937: (define_insn "extendqihi2"
938: [(set (match_operand:HI 0 "register_operand" "=r")
939: (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
940: ""
941: "cvtbw %1,%0")
942:
943: (define_insn "zero_extendhisi2"
944: [(set (match_operand:SI 0 "register_operand" "=r")
945: (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
946: ""
947: "*
948: {
949: cc_status.flags = CC_NOT_NEGATIVE;
950: return \"movzhw %1,%0\";
951: }")
952:
953: (define_insn "zero_extendqisi2"
954: [(set (match_operand:SI 0 "register_operand" "=r")
955: (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
956: ""
957: "*
958: {
959: cc_status.flags = CC_NOT_NEGATIVE;
960: return \"movzbw %1,%0\";
961: }")
962:
963: (define_insn "zero_extendqihi2"
964: [(set (match_operand:HI 0 "register_operand" "=r")
965: (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
966: ""
967: "*
968: {
969: cc_status.flags = CC_NOT_NEGATIVE;
970: return \"movzbw %1,%0\";
971: }")
972:
973: (define_insn "extendsfdf2"
974: [(set (match_operand:DF 0 "general_operand" "=&r,m")
975: (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "rm,r")))]
976: ""
977: "cvtfd %1,%0")
978:
979: (define_insn "truncdfsf2"
980: [(set (match_operand:SF 0 "general_operand" "=&r,m")
981: (float_truncate:SF (match_operand:DF 1 "nonimmediate_operand" "rm,r")))]
982: ""
983: "cvtdf %1,%0")
984:
985: (define_insn "floatsisf2"
986: [(set (match_operand:SF 0 "general_operand" "=&r,m")
987: (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,r")))]
988: ""
989: "cvtwf %1,%0")
990:
991: (define_insn "floatsidf2"
992: [(set (match_operand:DF 0 "general_operand" "=&r,m")
993: (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm,r")))]
994: ""
995: "cvtwd %1,%0")
996:
997: (define_insn "fix_truncsfsi2"
998: [(set (match_operand:SI 0 "general_operand" "=&r,m")
999: (fix:SI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "rm,r"))))]
1000: ""
1001: "cvtfw %1,%0")
1002:
1003: (define_insn "fix_truncdfsi2"
1004: [(set (match_operand:SI 0 "general_operand" "=&r,m")
1005: (fix:SI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "rm,r"))))]
1006: ""
1007: "cvtdw %1,%0")
1008:
1009: ;______________________________________________________________________
1010: ;
1011: ; Flow Control Patterns.
1012: ;______________________________________________________________________
1013:
1014: ;; Prefer "br" to "jump" for unconditional jumps, since it's faster.
1015: ;; (The assembler can manage with out-of-range branches.)
1016:
1017: (define_insn "jump"
1018: [(set (pc)
1019: (label_ref (match_operand 0 "" "")))]
1020: ""
1021: "br %l0")
1022:
1023: (define_insn ""
1024: [(set (pc)
1025: (if_then_else (match_operator 0 "relop" [(cc0) (const_int 0)])
1026: (label_ref (match_operand 1 "" ""))
1027: (pc)))]
1028: ""
1029: "*
1030: {
1031: extern int optimize;
1032: if (optimize)
1033: switch (GET_CODE (operands[0]))
1034: {
1035: case EQ: case NE:
1036: break;
1037: case LT: case LE: case GE: case GT:
1038: if (cc_prev_status.mdep == CC_VALID_FOR_UNSIGNED)
1039: return 0;
1040: break;
1041: case LTU: case LEU: case GEU: case GTU:
1042: if (cc_prev_status.mdep != CC_VALID_FOR_UNSIGNED)
1043: return 0;
1044: break;
1045: }
1046:
1047: return \"b%N0 %l1\";
1048: }")
1049:
1050: (define_insn ""
1051: [(set (pc)
1052: (if_then_else (match_operator 0 "relop" [(cc0) (const_int 0)])
1053: (pc)
1054: (label_ref (match_operand 1 "" ""))))]
1055: ""
1056: "*
1057: {
1058: extern int optimize;
1059: if (optimize)
1060: switch (GET_CODE (operands[0]))
1061: {
1062: case EQ: case NE:
1063: break;
1064: case LT: case LE: case GE: case GT:
1065: if (cc_prev_status.mdep == CC_VALID_FOR_UNSIGNED)
1066: return 0;
1067: break;
1068: case LTU: case LEU: case GEU: case GTU:
1069: if (cc_prev_status.mdep != CC_VALID_FOR_UNSIGNED)
1070: return 0;
1071: break;
1072: }
1073:
1074: return \"b%C0 %l1\";
1075: }")
1076:
1077: (define_insn "call"
1078: [(call (match_operand:QI 0 "memory_operand" "m")
1079: (match_operand:SI 1 "immediate_operand" "n"))]
1080: ""
1081: "call %0")
1082:
1083: (define_insn "call_value"
1084: [(set (match_operand 0 "" "=r")
1085: (call (match_operand:QI 1 "memory_operand" "m")
1086: (match_operand:SI 2 "immediate_operand" "n")))]
1087: ;; Operand 2 not really used on Pyramid architecture.
1088: ""
1089: "call %1")
1090:
1091: (define_insn "return"
1092: [(return)]
1093: ""
1094: "*
1095: {
1096: if (get_frame_size () + current_function_pretend_args_size
1097: + current_function_args_size != 0
1098: || current_function_calls_alloca)
1099: {
1100: int dealloc_size = current_function_pretend_args_size;
1101: if (current_function_pops_args)
1102: dealloc_size += current_function_args_size;
1103: operands[0] = gen_rtx (CONST_INT, VOIDmode, dealloc_size);
1104: return \"retd %0\";
1105: }
1106: else
1107: return \"ret\";
1108: }")
1109:
1110: (define_insn "tablejump"
1111: [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1112: (use (label_ref (match_operand 1 "" "")))]
1113: ""
1114: "jump (%0)")
1115:
1116: (define_insn "nop"
1117: [(const_int 0)]
1118: ""
1119: "movw gr0,gr0 # nop")
1120:
1121: ;______________________________________________________________________
1122: ;
1123: ; Peep-hole Optimization Patterns.
1124: ;______________________________________________________________________
1125:
1126: ;; Optimize fullword move followed by a test of the moved value.
1127:
1128: (define_peephole
1129: [(set (match_operand:SI 0 "register_operand" "=r")
1130: (match_operand:SI 1 "nonimmediate_operand" "rm"))
1131: (set (cc0) (match_operand:SI 2 "nonimmediate_operand" "rm"))]
1132: "rtx_equal_p (operands[2], operands[0])
1133: || rtx_equal_p (operands[2], operands[1])"
1134: "*
1135: cc_status.flags |= CC_NO_OVERFLOW;
1136: return \"mtstw %1,%0\";
1137: ")
1138:
1139: ;; Same for HI and QI mode move-test as well.
1140:
1141: (define_peephole
1142: [(set (match_operand:HI 0 "register_operand" "=r")
1143: (match_operand:HI 1 "nonimmediate_operand" "rm"))
1144: (set (match_operand:SI 2 "register_operand" "=r")
1145: (sign_extend:SI (match_operand:HI 3 "nonimmediate_operand" "rm")))
1146: (set (cc0) (match_dup 2))]
1147: "dead_or_set_p (insn, operands[2])
1148: && (rtx_equal_p (operands[3], operands[0])
1149: || rtx_equal_p (operands[3], operands[1]))"
1150: "*
1151: cc_status.flags |= CC_NO_OVERFLOW;
1152: return \"cvthw %1,%0\";
1153: ")
1154:
1155: (define_peephole
1156: [(set (match_operand:QI 0 "register_operand" "=r")
1157: (match_operand:QI 1 "nonimmediate_operand" "rm"))
1158: (set (match_operand:SI 2 "register_operand" "=r")
1159: (sign_extend:SI (match_operand:QI 3 "nonimmediate_operand" "rm")))
1160: (set (cc0) (match_dup 2))]
1161: "dead_or_set_p (insn, operands[2])
1162: && (rtx_equal_p (operands[3], operands[0])
1163: || rtx_equal_p (operands[3], operands[1]))"
1164: "*
1165: cc_status.flags |= CC_NO_OVERFLOW;
1166: return \"cvtbw %1,%0\";
1167: ")
1168:
1169: ;; Optimize loops with an incremented/decremented variable.
1170:
1171: (define_peephole
1172: [(set (match_operand:SI 0 "register_operand" "=r")
1173: (plus:SI (match_dup 0)
1174: (const_int -1)))
1175: (set (cc0)
1176: (compare (match_operand:SI 1 "register_operand" "r")
1177: (match_operand:SI 2 "nonmemory_operand" "ri")))
1178: (set (pc)
1179: (if_then_else (match_operator:SI 3 "signed_comparison"
1180: [(cc0) (const_int 0)])
1181: (label_ref (match_operand 4 "" ""))
1182: (pc)))]
1183: "(GET_CODE (operands[2]) == CONST_INT
1184: ? (unsigned)INTVAL (operands[2]) + 32 >= 64
1185: : 1) && (rtx_equal_p (operands[0], operands[1])
1186: || rtx_equal_p (operands[0], operands[2]))"
1187: "*
1188: if (rtx_equal_p (operands[0], operands[1]))
1189: {
1190: output_asm_insn (\"dcmpw %2,%0\", operands);
1191: return \"b%N3 %l4\";
1192: }
1193: else
1194: {
1195: output_asm_insn (\"dcmpw %1,%0\", operands);
1196: return \"b%R3 %l4\";
1197: }
1198: ")
1199:
1200: (define_peephole
1201: [(set (match_operand:SI 0 "register_operand" "=r")
1202: (plus:SI (match_dup 0)
1203: (const_int 1)))
1204: (set (cc0)
1205: (compare (match_operand:SI 1 "register_operand" "r")
1206: (match_operand:SI 2 "nonmemory_operand" "ri")))
1207: (set (pc)
1208: (if_then_else (match_operator:SI 3 "signed_comparison"
1209: [(cc0) (const_int 0)])
1210: (label_ref (match_operand 4 "" ""))
1211: (pc)))]
1212: "(GET_CODE (operands[2]) == CONST_INT
1213: ? (unsigned)INTVAL (operands[2]) + 32 >= 64
1214: : 1) && (rtx_equal_p (operands[0], operands[1])
1215: || rtx_equal_p (operands[0], operands[2]))"
1216: "*
1217: if (rtx_equal_p (operands[0], operands[1]))
1218: {
1219: output_asm_insn (\"icmpw %2,%0\", operands);
1220: return \"b%N3 %l4\";
1221: }
1222: else
1223: {
1224: output_asm_insn (\"icmpw %1,%0\", operands);
1225: return \"b%R3 %l4\";
1226: }
1227: ")
1228:
1229: ;; Combine two word moves with consecutive operands into one long move.
1230: ;; Also combines immediate moves, if the high-order destination operand
1231: ;; is loaded with 0 or -1 and the low-order destination operand is loaded
1232: ;; with a constant with the same sign.
1233:
1234: (define_peephole
1235: [(set (match_operand:SI 0 "general_operand" "=g")
1236: (match_operand:SI 1 "general_operand" "g"))
1237: (set (match_operand:SI 2 "general_operand" "=g")
1238: (match_operand:SI 3 "general_operand" "g"))]
1239: "movdi_possible (operands)"
1240: "*
1241: {
1242: output_asm_insn (\"# COMBINE movw %1,%0\", operands);
1243: output_asm_insn (\"# COMBINE movw %3,%2\", operands);
1244: movdi_possible (operands);
1245: if (CONSTANT_P (operands[1]))
1246: return (swap_operands ? \"movl %3,%0\" : \"movl %1,%2\");
1247:
1248: return (swap_operands ? \"movl %1,%0\" : \"movl %3,%2\");
1249: }")
1250:
1251: ;; Optimize certain tests after memory stores.
1252:
1253: (define_peephole
1254: [(set (match_operand 0 "memory_operand" "=m")
1255: (match_operand 1 "register_operand" "r"))
1256: (set (match_operand:SI 2 "register_operand" "=r")
1257: (sign_extend:SI (match_dup 1)))
1258: (set (cc0)
1259: (match_dup 2))]
1260: "dead_or_set_p (insn, operands[2])"
1261: "*
1262: cc_status.flags |= CC_NO_OVERFLOW;
1263: if (GET_MODE (operands[0]) == QImode)
1264: return \"cvtwb %1,%0\";
1265: else
1266: return \"cvtwh %1,%0\";
1267: ")
1268:
1269: ;______________________________________________________________________
1270: ;
1271: ; DImode Patterns.
1272: ;______________________________________________________________________
1273:
1274: (define_expand "extendsidi2"
1275: [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 1)
1276: (match_operand:SI 1 "general_operand" "g"))
1277: (set (subreg:SI (match_dup 0) 0)
1278: (subreg:SI (match_dup 0) 1))
1279: (set (subreg:SI (match_dup 0) 0)
1280: (ashiftrt:SI (subreg:SI (match_dup 0) 0)
1281: (const_int 31)))]
1282: ""
1283: "")
1284:
1285: (define_insn "adddi3"
1286: [(set (match_operand:DI 0 "register_operand" "=r")
1287: (plus:DI (match_operand:DI 1 "nonmemory_operand" "%0")
1288: (match_operand:DI 2 "nonmemory_operand" "rF")))]
1289: ""
1290: "*
1291: {
1292: rtx xoperands[2];
1293: CC_STATUS_INIT;
1294: xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1295: if (REG_P (operands[2]))
1296: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
1297: else
1298: {
1299: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
1300: CONST_DOUBLE_LOW (operands[2]));
1301: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1302: CONST_DOUBLE_HIGH (operands[2]));
1303: }
1304: output_asm_insn (\"addw %1,%0\", xoperands);
1305: return \"addwc %2,%0\";
1306: }")
1307:
1308: (define_insn "subdi3"
1309: [(set (match_operand:DI 0 "register_operand" "=r")
1310: (minus:DI (match_operand:DI 1 "register_operand" "0")
1311: (match_operand:DI 2 "nonmemory_operand" "rF")))]
1312: ""
1313: "*
1314: {
1315: rtx xoperands[2];
1316: CC_STATUS_INIT;
1317: xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1318: if (REG_P (operands[2]))
1319: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
1320: else
1321: {
1322: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
1323: CONST_DOUBLE_LOW (operands[2]));
1324: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1325: CONST_DOUBLE_HIGH (operands[2]));
1326: }
1327: output_asm_insn (\"subw %1,%0\", xoperands);
1328: return \"subwb %2,%0\";
1329: }")
1330:
1331: (define_insn "iordi3"
1332: [(set (match_operand:DI 0 "register_operand" "=r")
1333: (ior:DI (match_operand:DI 1 "nonmemory_operand" "%0")
1334: (match_operand:DI 2 "nonmemory_operand" "rF")))]
1335: ""
1336: "*
1337: {
1338: rtx xoperands[2];
1339: CC_STATUS_INIT;
1340: xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1341: if (REG_P (operands[2]))
1342: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
1343: else
1344: {
1345: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
1346: CONST_DOUBLE_LOW (operands[2]));
1347: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1348: CONST_DOUBLE_HIGH (operands[2]));
1349: }
1350: output_asm_insn (\"orw %1,%0\", xoperands);
1351: return \"orw %2,%0\";
1352: }")
1353:
1354: (define_insn "anddi3"
1355: [(set (match_operand:DI 0 "register_operand" "=r")
1356: (and:DI (match_operand:DI 1 "nonmemory_operand" "%0")
1357: (match_operand:DI 2 "nonmemory_operand" "rF")))]
1358: ""
1359: "*
1360: {
1361: rtx xoperands[2];
1362: CC_STATUS_INIT;
1363: xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1364: if (REG_P (operands[2]))
1365: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
1366: else
1367: {
1368: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
1369: CONST_DOUBLE_LOW (operands[2]));
1370: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1371: CONST_DOUBLE_HIGH (operands[2]));
1372: }
1373: output_asm_insn (\"andw %1,%0\", xoperands);
1374: return \"andw %2,%0\";
1375: }")
1376:
1377: (define_insn "xordi3"
1378: [(set (match_operand:DI 0 "register_operand" "=r")
1379: (xor:DI (match_operand:DI 1 "nonmemory_operand" "%0")
1380: (match_operand:DI 2 "nonmemory_operand" "rF")))]
1381: ""
1382: "*
1383: {
1384: rtx xoperands[2];
1385: CC_STATUS_INIT;
1386: xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1387: if (REG_P (operands[2]))
1388: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
1389: else
1390: {
1391: xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
1392: CONST_DOUBLE_LOW (operands[2]));
1393: operands[2] = gen_rtx (CONST_INT, VOIDmode,
1394: CONST_DOUBLE_HIGH (operands[2]));
1395: }
1396: output_asm_insn (\"xorw %1,%0\", xoperands);
1397: return \"xorw %2,%0\";
1398: }")
1399:
1400: ;; My version, modelled after Jonathan Stone's and "tablejump" - S.P.
1401: (define_insn "indirect_jump"
1402: [(set (pc) (match_operand:SI 0 "general_operand" "r"))]
1403: ""
1404: "jump (%0)")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.