|
|
1.1 root 1: ;;- Machine description for HP PA-RISC architecture for GNU C compiler
2: ;; Copyright (C) 1992 Free Software Foundation, Inc.
3: ;; Contributed by the Center for Software Science at the University
4: ;; of Utah.
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 2, 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: ;; This gcc Version 2 machine description is inspired by sparc.md and
23: ;; mips.md.
24:
25: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26:
27: ;; Insn type. Used to default other attribute values.
28:
29: ;; type "unary" insns have one input operand (1) and one output operand (0)
30: ;; type "binary" insns have two input operands (1,2) and one output (0)
31:
32: (define_attr "type"
33: "move,unary,binary,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmul,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,misc,milli"
34: (const_string "binary"))
35:
36: ;; Length (in # of insns).
37: (define_attr "length" ""
38: (cond [(eq_attr "type" "load,fpload")
39: (if_then_else (match_operand 1 "symbolic_memory_operand" "")
40: (const_int 8) (const_int 4))
41:
42: (eq_attr "type" "store,fpstore")
43: (if_then_else (match_operand 0 "symbolic_memory_operand" "")
44: (const_int 8) (const_int 4))
45:
46: (eq_attr "type" "binary")
47: (if_then_else (match_operand 2 "arith_operand" "")
48: (const_int 4) (const_int 12))
49:
50: (eq_attr "type" "move,unary")
51: (if_then_else (match_operand 1 "arith_operand" "")
52: (const_int 4) (const_int 8))]
53:
54: (const_int 4)))
55:
56: (define_asm_attributes
57: [(set_attr "length" "4")
58: (set_attr "type" "multi")])
59:
60: ;; Attributes for instruction and branch scheduling
61:
62: ;; For conditional branches.
63: (define_attr "in_branch_delay" "false,true"
64: (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli")
65: (eq_attr "length" "4"))
66: (const_string "true")
67: (const_string "false")))
68:
69: ;; Disallow instructions which use the FPU since they will tie up the FPU
70: ;; even if the instruction is nullified.
71: (define_attr "in_nullified_branch_delay" "false,true"
72: (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmul,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl")
73: (eq_attr "length" "4"))
74: (const_string "true")
75: (const_string "false")))
76:
77: ;; For calls and millicode calls. Allow unconditional branches in the
78: ;; delay slot.
79: (define_attr "in_call_delay" "false,true"
80: (cond [(and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli")
81: (eq_attr "length" "4"))
82: (const_string "true")
83: (eq_attr "type" "uncond_branch")
84: (if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY")
85: (const_int 0))
86: (const_string "true")
87: (const_string "false"))]
88: (const_string "false")))
89:
90:
91:
92: ;; Unconditional branch, call, and millicode call delay slot description.
93: (define_delay (eq_attr "type" "uncond_branch,branch,call,milli")
94: [(eq_attr "in_call_delay" "true") (nil) (nil)])
95:
96: ;; Unconditional branch, return and other similar instructions.
97: (define_delay (eq_attr "type" "uncond_branch,branch")
98: [(eq_attr "in_branch_delay" "true") (nil) (nil)])
99:
100: ;; Floating point conditional branch delay slot description and
101: (define_delay (eq_attr "type" "fbranch")
102: [(eq_attr "in_branch_delay" "true")
103: (eq_attr "in_nullified_branch_delay" "true")
104: (nil)])
105:
106: ;; Integer conditional branch delay slot description.
107: ;; Nullification of conditional branches on the PA is dependent on the
108: ;; direction of the branch. Forward branches nullify true and
109: ;; backward branches nullify false. If the direction is unknown
110: ;; then nullification is not allowed.
111: (define_delay (eq_attr "type" "cbranch")
112: [(eq_attr "in_branch_delay" "true")
113: (and (eq_attr "in_nullified_branch_delay" "true")
114: (attr_flag "forward"))
115: (and (eq_attr "in_nullified_branch_delay" "true")
116: (attr_flag "backward"))])
117:
118: ;; Function units of the HPPA. The following data is for the "Snake"
119: ;; (Mustang CPU + Timex FPU) because that's what I have the docs for.
120: ;; Scheduling instructions for PA-83 machines according to the Snake
121: ;; constraints shouldn't hurt.
122:
123: ;; (define_function_unit {name} {num-units} {n-users} {test}
124: ;; {ready-delay} {issue-delay} [{conflict-list}])
125:
126: ;; The integer ALU.
127: ;; (Noted only for documentation; units that take one cycle do not need to
128: ;; be specified.)
129:
130: ;; (define_function_unit "alu" 1 0
131: ;; (eq_attr "type" "unary,binary,move,address") 1 0)
132:
133:
134: ;; Memory. Disregarding Cache misses, the Mustang memory times are:
135: ;; load: 2
136: ;; store, fpstore: 3, no D-cache operations should be scheduled.
137: ;; fpload: 3 (really 2 for flops, but I don't think we can specify that).
138:
139: (define_function_unit "memory" 1 0 (eq_attr "type" "load") 2 0)
140: (define_function_unit "memory" 1 0 (eq_attr "type" "store,fpstore") 3 3)
141: (define_function_unit "memory" 1 0 (eq_attr "type" "fpload") 2 0)
142:
143: ;; The Timex has two floating-point units: ALU, and MUL/DIV/SQRT unit.
144: ;; Timings:
145: ;; Instruction Time Unit Minimum Distance (unit contention)
146: ;; fcpy 3 ALU 2
147: ;; fabs 3 ALU 2
148: ;; fadd 3 ALU 2
149: ;; fsub 3 ALU 2
150: ;; fcmp 3 ALU 2
151: ;; fcnv 3 ALU 2
152: ;; fmpyadd 3 ALU,MPY 2
153: ;; fmpysub 3 ALU,MPY 2
154: ;; fmpycfxt 3 ALU,MPY 2
155: ;; fmpy 3 MPY 2
156: ;; fmpyi 3 MPY 2
157: ;; fdiv,sgl 10 MPY 10
158: ;; fdiv,dbl 12 MPY 12
159: ;; fsqrt,sgl 14 MPY 14
160: ;; fsqrt,dbl 18 MPY 18
161:
162: (define_function_unit "fp_alu" 1 0 (eq_attr "type" "fpcc") 4 2)
163: (define_function_unit "fp_alu" 1 0 (eq_attr "type" "fpalu") 3 2)
164: (define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpmul") 3 2)
165: (define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpdivsgl") 10 10)
166: (define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpdivdbl") 12 12)
167: (define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpsqrtsgl") 14 14)
168: (define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpsqrtdbl") 18 18)
169:
170: ;; Compare instructions.
171: ;; This controls RTL generation and register allocation.
172:
173: ;; We generate RTL for comparisons and branches by having the cmpxx
174: ;; patterns store away the operands. Then, the scc and bcc patterns
175: ;; emit RTL for both the compare and the branch.
176: ;;
177:
178: (define_expand "cmpsi"
179: [(set (reg:CC 0)
180: (compare:CC (match_operand:SI 0 "reg_or_0_operand" "")
181: (match_operand:SI 1 "arith5_operand" "")))]
182: ""
183: "
184: {
185: hppa_compare_op0 = operands[0];
186: hppa_compare_op1 = operands[1];
187: hppa_branch_type = CMP_SI;
188: DONE;
189: }")
190:
191: (define_expand "cmpsf"
192: [(set (reg:CCFP 0)
193: (compare:CCFP (match_operand:SF 0 "reg_or_0_operand" "")
194: (match_operand:SF 1 "reg_or_0_operand" "")))]
195: ""
196: "
197: {
198: hppa_compare_op0 = operands[0];
199: hppa_compare_op1 = operands[1];
200: hppa_branch_type = CMP_SF;
201: DONE;
202: }")
203:
204: (define_expand "cmpdf"
205: [(set (reg:CCFP 0)
206: (compare:CCFP (match_operand:DF 0 "reg_or_0_operand" "")
207: (match_operand:DF 1 "reg_or_0_operand" "")))]
208: ""
209: "
210: {
211: hppa_compare_op0 = operands[0];
212: hppa_compare_op1 = operands[1];
213: hppa_branch_type = CMP_DF;
214: DONE;
215: }")
216:
217: (define_insn ""
218: [(set (reg:CCFP 0)
219: (match_operator:CCFP 2 "comparison_operator"
220: [(match_operand:SF 0 "reg_or_0_operand" "fxG")
221: (match_operand:SF 1 "reg_or_0_operand" "fxG")]))]
222: ""
223: "fcmp,sgl,%Y2 %r0,%r1"
224: [(set_attr "type" "fpcc")])
225:
226: (define_insn ""
227: [(set (reg:CCFP 0)
228: (match_operator:CCFP 2 "comparison_operator"
229: [(match_operand:DF 0 "reg_or_0_operand" "fxG")
230: (match_operand:DF 1 "reg_or_0_operand" "fxG")]))]
231: ""
232: "fcmp,dbl,%Y2 %r0,%r1"
233: [(set_attr "type" "fpcc")])
234:
235: ;; scc insns.
236:
237: (define_expand "seq"
238: [(set (match_operand:SI 0 "register_operand" "")
239: (eq:SI (match_dup 1)
240: (match_dup 2)))]
241: ""
242: "
243: {
244: /* fp scc patterns rarely match, and are not a win on the PA. */
245: if (hppa_branch_type != CMP_SI)
246: FAIL;
247: /* set up operands from compare. */
248: operands[1] = hppa_compare_op0;
249: operands[2] = hppa_compare_op1;
250: /* fall through and generate default code */
251: }")
252:
253: (define_expand "sne"
254: [(set (match_operand:SI 0 "register_operand" "")
255: (ne:SI (match_dup 1)
256: (match_dup 2)))]
257: ""
258: "
259: {
260: /* fp scc patterns rarely match, and are not a win on the PA. */
261: if (hppa_branch_type != CMP_SI)
262: FAIL;
263: operands[1] = hppa_compare_op0;
264: operands[2] = hppa_compare_op1;
265: }")
266:
267: (define_expand "slt"
268: [(set (match_operand:SI 0 "register_operand" "")
269: (lt:SI (match_dup 1)
270: (match_dup 2)))]
271: ""
272: "
273: {
274: /* fp scc patterns rarely match, and are not a win on the PA. */
275: if (hppa_branch_type != CMP_SI)
276: FAIL;
277: operands[1] = hppa_compare_op0;
278: operands[2] = hppa_compare_op1;
279: }")
280:
281: (define_expand "sgt"
282: [(set (match_operand:SI 0 "register_operand" "")
283: (gt:SI (match_dup 1)
284: (match_dup 2)))]
285: ""
286: "
287: {
288: /* fp scc patterns rarely match, and are not a win on the PA. */
289: if (hppa_branch_type != CMP_SI)
290: FAIL;
291: operands[1] = hppa_compare_op0;
292: operands[2] = hppa_compare_op1;
293: }")
294:
295: (define_expand "sle"
296: [(set (match_operand:SI 0 "register_operand" "")
297: (le:SI (match_dup 1)
298: (match_dup 2)))]
299: ""
300: "
301: {
302: /* fp scc patterns rarely match, and are not a win on the PA. */
303: if (hppa_branch_type != CMP_SI)
304: FAIL;
305: operands[1] = hppa_compare_op0;
306: operands[2] = hppa_compare_op1;
307: }")
308:
309: (define_expand "sge"
310: [(set (match_operand:SI 0 "register_operand" "")
311: (ge:SI (match_dup 1)
312: (match_dup 2)))]
313: ""
314: "
315: {
316: /* fp scc patterns rarely match, and are not a win on the PA. */
317: if (hppa_branch_type != CMP_SI)
318: FAIL;
319: operands[1] = hppa_compare_op0;
320: operands[2] = hppa_compare_op1;
321: }")
322:
323: (define_expand "sltu"
324: [(set (match_operand:SI 0 "register_operand" "")
325: (ltu:SI (match_dup 1)
326: (match_dup 2)))]
327: ""
328: "
329: {
330: if (hppa_branch_type != CMP_SI)
331: FAIL;
332: operands[1] = hppa_compare_op0;
333: operands[2] = hppa_compare_op1;
334: }")
335:
336: (define_expand "sgtu"
337: [(set (match_operand:SI 0 "register_operand" "")
338: (gtu:SI (match_dup 1)
339: (match_dup 2)))]
340: ""
341: "
342: {
343: if (hppa_branch_type != CMP_SI)
344: FAIL;
345: operands[1] = hppa_compare_op0;
346: operands[2] = hppa_compare_op1;
347: }")
348:
349: (define_expand "sleu"
350: [(set (match_operand:SI 0 "register_operand" "")
351: (leu:SI (match_dup 1)
352: (match_dup 2)))]
353: ""
354: "
355: {
356: if (hppa_branch_type != CMP_SI)
357: FAIL;
358: operands[1] = hppa_compare_op0;
359: operands[2] = hppa_compare_op1;
360: }")
361:
362: (define_expand "sgeu"
363: [(set (match_operand:SI 0 "register_operand" "")
364: (geu:SI (match_dup 1)
365: (match_dup 2)))]
366: ""
367: "
368: {
369: if (hppa_branch_type != CMP_SI)
370: FAIL;
371: operands[1] = hppa_compare_op0;
372: operands[2] = hppa_compare_op1;
373: }")
374:
375: ;; Instruction canonicalization puts immediate operands second, which
376: ;; is the reverse of what we want.
377:
378: (define_insn "scc"
379: [(set (match_operand:SI 0 "register_operand" "=r")
380: (match_operator:SI 3 "comparison_operator"
381: [(match_operand:SI 1 "register_operand" "r")
382: (match_operand:SI 2 "arith11_operand" "rI")]))]
383: ""
384: "com%I2clr,%B3 %2,%1,%0\;ldi 1,%0"
385: [(set_attr "type" "binary")
386: (set_attr "length" "8")])
387:
388: ;; Combiner patterns for common operations performed with the output
389: ;; from an scc insn (negscc and incscc).
390: (define_insn "negscc"
391: [(set (match_operand:SI 0 "register_operand" "=r")
392: (neg:SI (match_operator:SI 3 "comparison_operator"
393: [(match_operand:SI 1 "register_operand" "r")
394: (match_operand:SI 2 "arith11_operand" "rI")])))]
395: ""
396: "com%I2clr,%B3 %2,%1,%0\;ldi -1,%0"
397: [(set_attr "type" "binary")
398: (set_attr "length" "8")])
399:
400: ;; Patterns for adding/subtracting the result of a boolean expression from
401: ;; a register. First we have special patterns that make use of the carry
402: ;; bit, and output only two instructions. For the cases we can't in
403: ;; general do in two instructions, the incscc pattern at the end outputs
404: ;; two or three instructions.
405:
406: (define_insn ""
407: [(set (match_operand:SI 0 "register_operand" "=r")
408: (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
409: (match_operand:SI 3 "arith11_operand" "rI"))
410: (match_operand:SI 1 "register_operand" "r")))]
411: ""
412: "sub%I3 %3,%2,0\;addc 0,%1,%0"
413: [(set_attr "type" "binary")
414: (set_attr "length" "8")])
415:
416: ; This need only accept registers for op3, since canonicalization
417: ; replaces geu with gtu when op3 is an integer.
418: (define_insn ""
419: [(set (match_operand:SI 0 "register_operand" "=r")
420: (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
421: (match_operand:SI 3 "register_operand" "r"))
422: (match_operand:SI 1 "register_operand" "r")))]
423: ""
424: "sub %2,%3,0\;addc 0,%1,%0"
425: [(set_attr "type" "binary")
426: (set_attr "length" "8")])
427:
428: ; Match only integers for op3 here. This is used as canonical form of the
429: ; geu pattern when op3 is an integer. Don't match registers since we can't
430: ; make better code than the general incscc pattern.
431: (define_insn ""
432: [(set (match_operand:SI 0 "register_operand" "=r")
433: (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
434: (match_operand:SI 3 "int11_operand" "I"))
435: (match_operand:SI 1 "register_operand" "r")))]
436: ""
437: "addi %k3,%2,0\;addc 0,%1,%0"
438: [(set_attr "type" "binary")
439: (set_attr "length" "8")])
440:
441: (define_insn "incscc"
442: [(set (match_operand:SI 0 "register_operand" "=r,r")
443: (plus:SI (match_operator:SI 4 "comparison_operator"
444: [(match_operand:SI 2 "register_operand" "r,r")
445: (match_operand:SI 3 "arith11_operand" "rI,rI")])
446: (match_operand:SI 1 "register_operand" "0,?r")))]
447: ""
448: "@
449: com%I3clr,%B4 %3,%2,%%r0\;addi 1,%0,%0
450: com%I3clr,%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
451: [(set_attr "type" "binary,binary")
452: (set_attr "length" "8,12")])
453:
454: (define_insn ""
455: [(set (match_operand:SI 0 "register_operand" "=r")
456: (minus:SI (match_operand:SI 1 "register_operand" "r")
457: (gtu:SI (match_operand:SI 2 "register_operand" "r")
458: (match_operand:SI 3 "arith11_operand" "rI"))))]
459: ""
460: "sub%I3 %3,%2,0\;subb %1,0,%0"
461: [(set_attr "type" "binary")
462: (set_attr "length" "8")])
463:
464: ; This need only accept registers for op3, since canonicalization
465: ; replaces ltu with leu when op3 is an integer.
466: (define_insn ""
467: [(set (match_operand:SI 0 "register_operand" "=r")
468: (minus:SI (match_operand:SI 1 "register_operand" "r")
469: (ltu:SI (match_operand:SI 2 "register_operand" "r")
470: (match_operand:SI 3 "register_operand" "r"))))]
471: ""
472: "sub %2,%3,0\;subb %1,0,%0"
473: [(set_attr "type" "binary")
474: (set_attr "length" "8")])
475:
476: ; Match only integers for op3 here. This is used as canonical form of the
477: ; ltu pattern when op3 is an integer. Don't match registers since we can't
478: ; make better code than the general incscc pattern.
479: (define_insn ""
480: [(set (match_operand:SI 0 "register_operand" "=r")
481: (minus:SI (match_operand:SI 1 "register_operand" "r")
482: (leu:SI (match_operand:SI 2 "register_operand" "r")
483: (match_operand:SI 3 "int11_operand" "I"))))]
484: ""
485: "addi %k3,%2,0\;subb %1,0,%0"
486: [(set_attr "type" "binary")
487: (set_attr "length" "8")])
488:
489: (define_insn "decscc"
490: [(set (match_operand:SI 0 "register_operand" "=r,r")
491: (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
492: (match_operator:SI 4 "comparison_operator"
493: [(match_operand:SI 2 "register_operand" "r,r")
494: (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
495: ""
496: "@
497: com%I3clr,%B4 %3,%2,%%r0\;addi -1,%0,%0
498: com%I3clr,%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
499: [(set_attr "type" "binary,binary")
500: (set_attr "length" "8,12")])
501:
502: ; Patterns for max and min. (There is no need for an earlyclobber in the
503: ; last alternative since the middle alternative will match if op0 == op1.)
504:
505: (define_insn "sminsi3"
506: [(set (match_operand:SI 0 "register_operand" "=r,r,r")
507: (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
508: (match_operand:SI 2 "arith11_operand" "r,I,M")))]
509: ""
510: "@
511: comclr,> %2,%0,%%r0\;copy %2,%0
512: comiclr,> %2,%0,%%r0\;ldi %2,%0
513: comclr,> %1,%2,%0\;copy %1,%0"
514: [(set_attr "type" "multi,multi,multi")
515: (set_attr "length" "8,8,8")])
516:
517: (define_insn "uminsi3"
518: [(set (match_operand:SI 0 "register_operand" "=r,r")
519: (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
520: (match_operand:SI 2 "arith11_operand" "r,I")))]
521: ""
522: "@
523: comclr,>> %2,%0,%%r0\;copy %2,%0
524: comiclr,>> %2,%0,%%r0\;ldi %2,%0"
525: [(set_attr "type" "multi,multi")
526: (set_attr "length" "8,8")])
527:
528: (define_insn "smaxsi3"
529: [(set (match_operand:SI 0 "register_operand" "=r,r,r")
530: (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
531: (match_operand:SI 2 "arith11_operand" "r,I,M")))]
532: ""
533: "@
534: comclr,< %2,%0,%%r0\;copy %2,%0
535: comiclr,< %2,%0,%%r0\;ldi %2,%0
536: comclr,< %1,%2,%0\;copy %1,%0"
537: [(set_attr "type" "multi,multi,multi")
538: (set_attr "length" "8,8,8")])
539:
540: (define_insn "umaxsi3"
541: [(set (match_operand:SI 0 "register_operand" "=r,r")
542: (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
543: (match_operand:SI 2 "arith11_operand" "r,I")))]
544: ""
545: "@
546: comclr,<< %2,%0,%%r0\;copy %2,%0
547: comiclr,<< %2,%0,%%r0\;ldi %2,%0"
548: [(set_attr "type" "multi,multi")
549: (set_attr "length" "8,8")])
550: ;;; Experimental conditional move patterns
551:
552: ; We need the first constraint alternative in order to avoid
553: ; earlyclobbers on all other alternatives.
554: (define_insn ""
555: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
556: (if_then_else:SI
557: (match_operator 5 "comparison_operator"
558: [(match_operand:SI 3 "register_operand" "r,r,r,r,r")
559: (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
560: (match_operand:SI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
561: (const_int 0)))]
562: ""
563: "@
564: com%I4clr,%S5 %4,%3,%%r0\;ldi 0,%0
565: com%I4clr,%B5 %4,%3,%0\;copy %1,%0
566: com%I4clr,%B5 %4,%3,%0\;ldi %1,%0
567: com%I4clr,%B5 %4,%3,%0\;ldil L%'%1,%0
568: com%I4clr,%B5 %4,%3,%0\;zdepi %Z1,%0"
569: [(set_attr "type" "multi,multi,multi,multi,multi")
570: (set_attr "length" "8,8,8,8,8")])
571:
572: (define_insn ""
573: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
574: (if_then_else:SI
575: (match_operator 5 "comparison_operator"
576: [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
577: (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
578: (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
579: (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
580: ""
581: "@
582: com%I4clr,%S5 %4,%3,%%r0\;copy %2,%0
583: com%I4clr,%S5 %4,%3,%%r0\;ldi %2,%0
584: com%I4clr,%S5 %4,%3,%%r0\;ldil L%'%2,%0
585: com%I4clr,%S5 %4,%3,%%r0\;zdepi %Z2,%0
586: com%I4clr,%B5 %4,%3,%%r0\;copy %1,%0
587: com%I4clr,%B5 %4,%3,%%r0\;ldi %1,%0
588: com%I4clr,%B5 %4,%3,%%r0\;ldil L%'%1,%0
589: com%I4clr,%B5 %4,%3,%%r0\;zdepi %Z1,%0"
590: [(set_attr "type" "multi,multi,multi,multi,multi,multi,multi,multi")
591: (set_attr "length" "8,8,8,8,8,8,8,8")])
592:
593: ;; Conditional Branches
594:
595: (define_expand "beq"
596: [(set (pc)
597: (if_then_else (eq (match_dup 1) (match_dup 2))
598: (label_ref (match_operand 0 "" ""))
599: (pc)))]
600: ""
601: "
602: {
603: if (hppa_branch_type != CMP_SI)
604: {
605: emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1));
606: emit_bcond_fp (NE, operands[0]);
607: DONE;
608: }
609: /* set up operands from compare. */
610: operands[1] = hppa_compare_op0;
611: operands[2] = hppa_compare_op1;
612: /* fall through and generate default code */
613: }")
614:
615: (define_expand "bne"
616: [(set (pc)
617: (if_then_else (ne (match_dup 1) (match_dup 2))
618: (label_ref (match_operand 0 "" ""))
619: (pc)))]
620: ""
621: "
622: {
623: if (hppa_branch_type != CMP_SI)
624: {
625: emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1));
626: emit_bcond_fp (NE, operands[0]);
627: DONE;
628: }
629: operands[1] = hppa_compare_op0;
630: operands[2] = hppa_compare_op1;
631: }")
632:
633: (define_expand "bgt"
634: [(set (pc)
635: (if_then_else (gt (match_dup 1) (match_dup 2))
636: (label_ref (match_operand 0 "" ""))
637: (pc)))]
638: ""
639: "
640: {
641: if (hppa_branch_type != CMP_SI)
642: {
643: emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1));
644: emit_bcond_fp (NE, operands[0]);
645: DONE;
646: }
647: operands[1] = hppa_compare_op0;
648: operands[2] = hppa_compare_op1;
649: }")
650:
651: (define_expand "blt"
652: [(set (pc)
653: (if_then_else (lt (match_dup 1) (match_dup 2))
654: (label_ref (match_operand 0 "" ""))
655: (pc)))]
656: ""
657: "
658: {
659: if (hppa_branch_type != CMP_SI)
660: {
661: emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1));
662: emit_bcond_fp (NE, operands[0]);
663: DONE;
664: }
665: operands[1] = hppa_compare_op0;
666: operands[2] = hppa_compare_op1;
667: }")
668:
669: (define_expand "bge"
670: [(set (pc)
671: (if_then_else (ge (match_dup 1) (match_dup 2))
672: (label_ref (match_operand 0 "" ""))
673: (pc)))]
674: ""
675: "
676: {
677: if (hppa_branch_type != CMP_SI)
678: {
679: emit_insn (gen_cmp_fp (GE, hppa_compare_op0, hppa_compare_op1));
680: emit_bcond_fp (NE, operands[0]);
681: DONE;
682: }
683: operands[1] = hppa_compare_op0;
684: operands[2] = hppa_compare_op1;
685: }")
686:
687: (define_expand "ble"
688: [(set (pc)
689: (if_then_else (le (match_dup 1) (match_dup 2))
690: (label_ref (match_operand 0 "" ""))
691: (pc)))]
692: ""
693: "
694: {
695: if (hppa_branch_type != CMP_SI)
696: {
697: emit_insn (gen_cmp_fp (LE, hppa_compare_op0, hppa_compare_op1));
698: emit_bcond_fp (NE, operands[0]);
699: DONE;
700: }
701: operands[1] = hppa_compare_op0;
702: operands[2] = hppa_compare_op1;
703: }")
704:
705: (define_expand "bgtu"
706: [(set (pc)
707: (if_then_else (gtu (match_dup 1) (match_dup 2))
708: (label_ref (match_operand 0 "" ""))
709: (pc)))]
710: ""
711: "
712: {
713: if (hppa_branch_type != CMP_SI)
714: FAIL;
715: operands[1] = hppa_compare_op0;
716: operands[2] = hppa_compare_op1;
717: }")
718:
719: (define_expand "bltu"
720: [(set (pc)
721: (if_then_else (ltu (match_dup 1) (match_dup 2))
722: (label_ref (match_operand 0 "" ""))
723: (pc)))]
724: ""
725: "
726: {
727: if (hppa_branch_type != CMP_SI)
728: FAIL;
729: operands[1] = hppa_compare_op0;
730: operands[2] = hppa_compare_op1;
731: }")
732:
733: (define_expand "bgeu"
734: [(set (pc)
735: (if_then_else (geu (match_dup 1) (match_dup 2))
736: (label_ref (match_operand 0 "" ""))
737: (pc)))]
738: ""
739: "
740: {
741: if (hppa_branch_type != CMP_SI)
742: FAIL;
743: operands[1] = hppa_compare_op0;
744: operands[2] = hppa_compare_op1;
745: }")
746:
747: (define_expand "bleu"
748: [(set (pc)
749: (if_then_else (leu (match_dup 1) (match_dup 2))
750: (label_ref (match_operand 0 "" ""))
751: (pc)))]
752: ""
753: "
754: {
755: if (hppa_branch_type != CMP_SI)
756: FAIL;
757: operands[1] = hppa_compare_op0;
758: operands[2] = hppa_compare_op1;
759: }")
760:
761: ;; Match the branch patterns.
762:
763:
764: ;; Note a long backward conditional branch with an annulled delay slot
765: ;; has a length of 12.
766: (define_insn ""
767: [(set (pc)
768: (if_then_else
769: (match_operator 3 "comparison_operator"
770: [(match_operand:SI 1 "register_operand" "r")
771: (match_operand:SI 2 "arith5_operand" "rL")])
772: (label_ref (match_operand 0 "" ""))
773: (pc)))]
774: ""
775: "*
776: {
777: return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
778: get_attr_length (insn), 0, insn);
779: }"
780: [(set_attr "type" "cbranch")
781: (set (attr "length")
782: (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
783: (const_int 8188))
784: (const_int 4)
785: (const_int 8)))])
786:
787: ;; Match the negated branch.
788:
789: (define_insn ""
790: [(set (pc)
791: (if_then_else
792: (match_operator 3 "comparison_operator"
793: [(match_operand:SI 1 "register_operand" "r")
794: (match_operand:SI 2 "arith5_operand" "rL")])
795: (pc)
796: (label_ref (match_operand 0 "" ""))))]
797: ""
798: "*
799: {
800: return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
801: get_attr_length (insn), 1, insn);
802: }"
803: [(set_attr "type" "cbranch")
804: (set (attr "length")
805: (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
806: (const_int 8188))
807: (const_int 4)
808: (const_int 8)))])
809:
810: ;; Branch on Bit patterns.
811: (define_insn ""
812: [(set (pc)
813: (if_then_else
814: (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
815: (const_int 1)
816: (match_operand:SI 1 "uint5_operand" ""))
817: (const_int 0))
818: (match_operand 2 "pc_or_label_operand" "")
819: (match_operand 3 "pc_or_label_operand" "")))]
820: ""
821: "*
822: {
823: return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
824: get_attr_length (insn),
825: (operands[3] != pc_rtx),
826: insn, 0);
827: }"
828: [(set_attr "type" "cbranch")
829: (set (attr "length")
830: (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
831: (const_int 8188))
832: (const_int 4)
833: (const_int 8)))])
834:
835: (define_insn ""
836: [(set (pc)
837: (if_then_else
838: (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
839: (const_int 1)
840: (match_operand:SI 1 "uint5_operand" ""))
841: (const_int 0))
842: (match_operand 2 "pc_or_label_operand" "")
843: (match_operand 3 "pc_or_label_operand" "")))]
844: ""
845: "*
846: {
847: return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
848: get_attr_length (insn),
849: (operands[3] != pc_rtx),
850: insn, 1);
851: }"
852: [(set_attr "type" "cbranch")
853: (set (attr "length")
854: (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
855: (const_int 8188))
856: (const_int 4)
857: (const_int 8)))])
858:
859: ;; Floating point branches
860: (define_insn ""
861: [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
862: (label_ref (match_operand 0 "" ""))
863: (pc)))]
864: ""
865: "*
866: {
867: if (INSN_ANNULLED_BRANCH_P (insn))
868: return \"ftest\;bl,n %0,%%r0\";
869: else
870: return \"ftest\;bl%* %0,%%r0\";
871: }"
872: [(set_attr "type" "fbranch")
873: (set_attr "length" "8")])
874:
875: (define_insn ""
876: [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
877: (pc)
878: (label_ref (match_operand 0 "" ""))))]
879: ""
880: "*
881: {
882: if (INSN_ANNULLED_BRANCH_P (insn))
883: return \"ftest\;add,tr 0,0,0\;bl,n %0,%%r0\";
884: else
885: return \"ftest\;add,tr 0,0,0\;bl%* %0,%%r0\";
886: }"
887: [(set_attr "type" "fbranch")
888: (set_attr "length" "12")])
889:
890: ;; Move instructions
891:
892: (define_expand "movsi"
893: [(set (match_operand:SI 0 "general_operand" "")
894: (match_operand:SI 1 "general_operand" ""))]
895: ""
896: "
897: {
898: if (emit_move_sequence (operands, SImode, 0))
899: DONE;
900: }")
901:
902: ;; Reloading an SImode or DImode value requires a scratch register if
903: ;; going in to or out of float point registers.
904:
905: (define_expand "reload_insi"
906: [(set (match_operand:SI 0 "register_operand" "=Z")
907: (match_operand:SI 1 "general_operand" ""))
908: (clobber (match_operand:SI 2 "register_operand" "=&r"))]
909: ""
910: "
911: {
912: if (emit_move_sequence (operands, SImode, operands[2]))
913: DONE;
914:
915: /* We don't want the clobber emitted, so handle this ourselves. */
916: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
917: DONE;
918: }")
919:
920: (define_expand "reload_outsi"
921: [(set (match_operand:SI 0 "general_operand" "")
922: (match_operand:SI 1 "register_operand" "Z"))
923: (clobber (match_operand:SI 2 "register_operand" "=&r"))]
924: ""
925: "
926: {
927: if (emit_move_sequence (operands, SImode, operands[2]))
928: DONE;
929:
930: /* We don't want the clobber emitted, so handle this ourselves. */
931: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
932: DONE;
933: }")
934:
935: ;;; pic symbol references
936:
937: (define_insn ""
938: [(set (match_operand:SI 0 "register_operand" "=r")
939: (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
940: (match_operand:SI 2 "symbolic_operand" ""))))]
941: "flag_pic && operands[1] == pic_offset_table_rtx"
942: "ldw T%'%2(%1),%0"
943: [(set_attr "type" "load")
944: (set_attr "length" "4")])
945:
946: (define_insn ""
947: [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
948: "=r,r,r,r,r,Q,*q,!fx,fx,*T")
949: (match_operand:SI 1 "move_operand"
950: "rM,J,N,K,Q,rM,rM,!fxM,*T,fx"))]
951: "register_operand (operands[0], SImode)
952: || reg_or_0_operand (operands[1], SImode)"
953: "@
954: copy %r1,%0
955: ldi %1,%0
956: ldil L%'%1,%0
957: zdepi %Z1,%0
958: ldw%M1 %1,%0
959: stw%M0 %r1,%0
960: mtsar %r1
961: fcpy,sgl %r1,%0
962: fldws%F1 %1,%0
963: fstws%F0 %1,%0"
964: [(set_attr "type" "move,move,move,move,load,store,move,fpalu,fpload,fpstore")
965: (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
966:
967: ;; Load indexed. We don't use unscaled modes since they can't be used
968: ;; unless we can tell which of the registers is the base and which is
969: ;; the index, due to PA's idea of segment selection using the top bits
970: ;; of the base register.
971:
972: (define_insn ""
973: [(set (match_operand:SI 0 "register_operand" "=r")
974: (mem:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
975: (const_int 4))
976: (match_operand:SI 2 "register_operand" "r"))))]
977: "! TARGET_DISABLE_INDEXING"
978: "ldwx,s %1(0,%2),%0"
979: [(set_attr "type" "load")
980: (set_attr "length" "4")])
981:
982: ;; This variant of the above insn can occur if the second operand
983: ;; is the frame pointer. This is a kludge, but there doesn't
984: ;; seem to be a way around it. Only recognize it while reloading.
985: (define_insn ""
986: [(set (match_operand:SI 0 "register_operand" "&=r")
987: (mem:SI (plus:SI (plus:SI
988: (mult:SI (match_operand:SI 1 "register_operand" "r")
989: (const_int 4))
990: (match_operand:SI 2 "register_operand" "r"))
991: (match_operand:SI 3 "const_int_operand" "rI"))))]
992: "! TARGET_DISABLE_INDEXING && reload_in_progress"
993: "*
994: {
995: if (GET_CODE (operands[3]) == CONST_INT)
996: return \"sh2add %1,%2,%0\;ldw %3(0,%0),%0\";
997: else
998: return \"sh2add %1,%2,%0\;ldwx %3(0,%0),%0\";
999: }"
1000: [(set_attr "type" "load")
1001: (set_attr "length" "8")])
1002:
1003: ;; Load or store with base-register modification.
1004:
1005: (define_insn "pre_ldwm"
1006: [(set (match_operand:SI 3 "register_operand" "=r")
1007: (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "0")
1008: (match_operand:SI 2 "pre_cint_operand" ""))))
1009: (set (match_operand:SI 0 "register_operand" "=r")
1010: (plus:SI (match_dup 1) (match_dup 2)))]
1011: ""
1012: "*
1013: {
1014: if (INTVAL (operands[2]) < 0)
1015: return \"ldwm %2(0,%0),%3\";
1016: return \"ldws,mb %2(0,%0),%3\";
1017: }"
1018: [(set_attr "type" "load")
1019: (set_attr "length" "4")])
1020:
1021: (define_insn "pre_stwm"
1022: [(set (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "0")
1023: (match_operand:SI 2 "pre_cint_operand" "")))
1024: (match_operand:SI 3 "reg_or_0_operand" "rM"))
1025: (set (match_operand:SI 0 "register_operand" "=r")
1026: (plus:SI (match_dup 1) (match_dup 2)))]
1027: ""
1028: "*
1029: {
1030: if (INTVAL (operands[2]) < 0)
1031: return \"stwm %r3,%2(0,%0)\";
1032: return \"stws,mb %r3,%2(0,%0)\";
1033: }"
1034: [(set_attr "type" "store")
1035: (set_attr "length" "4")])
1036:
1037: (define_insn "post_ldwm"
1038: [(set (match_operand:SI 3 "register_operand" "r")
1039: (mem:SI (match_operand:SI 1 "register_operand" "0")))
1040: (set (match_operand:SI 0 "register_operand" "=r")
1041: (plus:SI (match_dup 1)
1042: (match_operand:SI 2 "post_cint_operand" "")))]
1043: ""
1044: "*
1045: {
1046: if (INTVAL (operands[2]) > 0)
1047: return \"ldwm %2(0,%0),%3\";
1048: return \"ldws,ma %2(0,%0),%3\";
1049: }"
1050: [(set_attr "type" "load")
1051: (set_attr "length" "4")])
1052:
1053: (define_insn "post_stwm"
1054: [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
1055: (match_operand:SI 3 "reg_or_0_operand" "rM"))
1056: (set (match_operand:SI 0 "register_operand" "=r")
1057: (plus:SI (match_dup 1)
1058: (match_operand:SI 2 "post_cint_operand" "")))]
1059: ""
1060: "*
1061: {
1062: if (INTVAL (operands[2]) > 0)
1063: return \"stwm %r3,%2(0,%0)\";
1064: return \"stws,ma %r3,%2(0,%0)\";
1065: }"
1066: [(set_attr "type" "store")
1067: (set_attr "length" "4")])
1068:
1069: ;; For pic
1070: (define_insn ""
1071: [(set (match_operand:SI 0 "register_operand" "=r")
1072: (match_operand:SI 1 "pic_operand" "i"))
1073: (clobber (match_scratch:SI 2 "=a"))]
1074: ""
1075: "*
1076: {
1077: rtx label_rtx = gen_label_rtx ();
1078: rtx xoperands[3];
1079: extern FILE *asm_out_file;
1080:
1081: xoperands[0] = operands[0];
1082: xoperands[1] = operands[1];
1083: xoperands[2] = label_rtx;
1084: output_asm_insn (\"bl .+8,%0\;addil L%'%1-%2,%0\", xoperands);
1085: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label_rtx));
1086: output_asm_insn (\"ldo R%'%1-%2(1),%0\", xoperands);
1087: return \"\";
1088: }
1089: "
1090: [(set_attr "type" "multi")
1091: (set_attr "length" "12")])
1092:
1093: ;; Always use addil rather than ldil;add sequences. This allows the
1094: ;; HP linker to eliminate the dp relocation if the symbolic operand
1095: ;; lives in the TEXT space.
1096: (define_insn ""
1097: [(set (match_operand:SI 0 "register_operand" "=a")
1098: (high:SI (match_operand 1 "" "")))]
1099: "!TARGET_STUB_CALLS
1100: && symbolic_operand(operands[1], Pmode)
1101: && ! function_label_operand (operands[1])
1102: && ! read_only_operand (operands[1])"
1103: "@
1104: addil L%'%G1,%%r27"
1105: [(set_attr "type" "binary")
1106: (set_attr "length" "4")])
1107:
1108: ;; This is for use in the prologue/epilogue code. We need it
1109: ;; to add large constants to a stack pointer or frame pointer.
1110: ;; Because of the additional %r1 pressure, we probably do not
1111: ;; want to use this in general code, so make it available
1112: ;; only after reload.
1113: (define_insn "add_high_const"
1114: [(set (match_operand:SI 0 "register_operand" "=!a,*r")
1115: (plus (match_operand:SI 1 "register_operand" "r,r")
1116: (high:SI (match_operand 2 "const_int_operand" ""))))]
1117: "reload_completed"
1118: "@
1119: addil L%'%G2,%1
1120: ldil L%'%G2,%0\;add %0,%1,%0"
1121: [(set_attr "type" "binary,binary")
1122: (set_attr "length" "4,8")])
1123:
1124: ;; For function addresses.
1125: (define_insn ""
1126: [(set (match_operand:SI 0 "register_operand" "=r")
1127: (high:SI (match_operand:SI 1 "function_label_operand" "")))]
1128: ""
1129: "ldil LP%'%G1,%0"
1130: [(set_attr "type" "move")
1131: (set_attr "length" "4")])
1132:
1133: (define_insn ""
1134: [(set (match_operand:SI 0 "register_operand" "=r")
1135: (high:SI (match_operand 1 "" "")))]
1136: "check_pic (1)"
1137: "ldil L%'%G1,%0"
1138: [(set_attr "type" "move")
1139: (set_attr "length" "4")])
1140:
1141: ;; lo_sum of a function address.
1142: (define_insn ""
1143: [(set (match_operand:SI 0 "register_operand" "=r")
1144: (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1145: (match_operand:SI 2 "function_label_operand" "")))
1146: (clobber (match_operand:SI 3 "register_operand" "=r"))]
1147: ""
1148: "ldo RP%'%G2(%1),%0\;extru,= %0,31,1,%3\;ldw -4(0,%%r27),%3\;add %0,%3,%0"
1149: [(set_attr "type" "multi")
1150: (set_attr "length" "16")])
1151:
1152: (define_insn ""
1153: [(set (match_operand:SI 0 "register_operand" "=r")
1154: (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1155: (match_operand:SI 2 "immediate_operand" "i")))]
1156: ""
1157: "ldo R%'%G2(%1),%0"
1158: [(set_attr "length" "4")])
1159:
1160: (define_insn "hi_sum"
1161: [(set (match_operand:SI 0 "register_operand" "=a")
1162: (plus:SI (match_operand:SI 1 "register_operand" "r")
1163: (high:SI (match_operand:SI 2 "immediate_operand" ""))))]
1164: ""
1165: "addil L%'%G2,%1"
1166: [(set_attr "length" "4")])
1167:
1168: (define_insn "lo_sum_and_indirect"
1169: [(set (match_operand:SI 0 "register_operand" "=r")
1170: (mem:SI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1171: (match_operand:SI 2 "immediate_operand" "i"))))]
1172: ""
1173: "ldw R%'%G2(%1),%0"
1174: [(set_attr "length" "4")])
1175:
1176: ;; Now that a symbolic_address plus a constant is broken up early
1177: ;; in the compilation phase (for better CSE) we need a special
1178: ;; combiner pattern to load the symbolic address plus the constant
1179: ;; in only 2 instructions. (For cases where the symbolic address
1180: ;; was not a common subexpression.)
1181: (define_split
1182: [(set (match_operand:SI 0 "register_operand" "")
1183: (match_operand 1 "symbolic_operand" ""))
1184: (clobber (match_operand:SI 2 "register_operand" ""))]
1185: ""
1186: [(set (match_dup 2) (high:SI (match_dup 1)))
1187: (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
1188: "")
1189:
1190: (define_expand "movhi"
1191: [(set (match_operand:HI 0 "general_operand" "")
1192: (match_operand:HI 1 "general_operand" ""))]
1193: ""
1194: "
1195: {
1196: if (emit_move_sequence (operands, HImode, 0))
1197: DONE;
1198: }")
1199:
1200: (define_insn ""
1201: [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!fx")
1202: (match_operand:HI 1 "move_operand" "rM,J,N,K,Q,rM,rM,!fxM"))]
1203: "register_operand (operands[0], HImode)
1204: || reg_or_0_operand (operands[1], HImode)"
1205: "@
1206: copy %r1,%0
1207: ldi %1,%0
1208: ldil L%'%1,%0
1209: zdepi %Z1,%0
1210: ldh%M1 %1,%0
1211: sth%M0 %r1,%0
1212: mtsar %r1
1213: fcpy,sgl %r1,%0"
1214: [(set_attr "type" "move,move,move,move,load,store,move,fpalu")
1215: (set_attr "length" "4,4,4,4,4,4,4,4")])
1216:
1217: (define_insn ""
1218: [(set (match_operand:HI 0 "register_operand" "=r")
1219: (mem:HI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
1220: (const_int 2))
1221: (match_operand:SI 1 "register_operand" "r"))))]
1222: "! TARGET_DISABLE_INDEXING"
1223: "ldhx,s %2(0,%1),%0"
1224: [(set_attr "type" "load")
1225: (set_attr "length" "4")])
1226:
1227: ;; This variant of the above insn can occur if the second operand
1228: ;; is the frame pointer. This is a kludge, but there doesn't
1229: ;; seem to be a way around it. Only recognize it while reloading.
1230: (define_insn ""
1231: [(set (match_operand:HI 0 "register_operand" "=&r")
1232: (mem:HI (plus:SI (plus:SI
1233: (mult:SI (match_operand:SI 2 "register_operand" "r")
1234: (const_int 2))
1235: (match_operand:SI 1 "register_operand" "r"))
1236: (match_operand:SI 3 "const_int_operand" "rI"))))]
1237: "! TARGET_DISABLE_INDEXING && reload_in_progress"
1238: "*
1239: {
1240: if (GET_CODE (operands[3]) == CONST_INT)
1241: return \"sh1add %2,%1,%0\;ldh %3(0,%0),%0\";
1242: else
1243: return \"sh1add %2,%1,%0\;ldhx %3(0,%0),%0\";
1244: }"
1245: [(set_attr "type" "load")
1246: (set_attr "length" "8")])
1247:
1248: (define_insn ""
1249: [(set (match_operand:HI 3 "register_operand" "=r")
1250: (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "0")
1251: (match_operand:SI 2 "int5_operand" "L"))))
1252: (set (match_operand:SI 0 "register_operand" "=r")
1253: (plus:SI (match_dup 1) (match_dup 2)))]
1254: ""
1255: "ldhs,mb %2(0,%0),%3"
1256: [(set_attr "type" "load")
1257: (set_attr "length" "4")])
1258:
1259: (define_insn ""
1260: [(set (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "0")
1261: (match_operand:SI 2 "int5_operand" "L")))
1262: (match_operand:HI 3 "reg_or_0_operand" "rM"))
1263: (set (match_operand:SI 0 "register_operand" "=r")
1264: (plus:SI (match_dup 1) (match_dup 2)))]
1265: ""
1266: "sths,mb %r3,%2(0,%0)"
1267: [(set_attr "type" "store")
1268: (set_attr "length" "4")])
1269:
1270: (define_insn ""
1271: [(set (match_operand:HI 0 "register_operand" "=r")
1272: (high:HI (match_operand 1 "" "")))]
1273: "check_pic (1)"
1274: "ldil L%'%G1,%0"
1275: [(set_attr "type" "move")
1276: (set_attr "length" "4")])
1277:
1278: (define_insn ""
1279: [(set (match_operand:HI 0 "register_operand" "=r")
1280: (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
1281: (match_operand 2 "immediate_operand" "i")))]
1282: ""
1283: "ldo R%'%G2(%1),%0"
1284: [(set_attr "length" "4")])
1285:
1286: (define_expand "movqi"
1287: [(set (match_operand:QI 0 "general_operand" "")
1288: (match_operand:QI 1 "general_operand" ""))]
1289: ""
1290: "
1291: {
1292: if (emit_move_sequence (operands, QImode, 0))
1293: DONE;
1294: }")
1295:
1296: (define_insn ""
1297: [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!fx")
1298: (match_operand:QI 1 "move_operand" "rM,J,N,K,Q,rM,rM,!fxM"))]
1299: "register_operand (operands[0], QImode)
1300: || reg_or_0_operand (operands[1], QImode)"
1301: "@
1302: copy %r1,%0
1303: ldi %1,%0
1304: ldil L%'%1,%0
1305: zdepi %Z1,%0
1306: ldb%M1 %1,%0
1307: stb%M0 %r1,%0
1308: mtsar %r1
1309: fcpy,sgl %r1,%0"
1310: [(set_attr "type" "move,move,move,move,load,store,move,fpalu")
1311: (set_attr "length" "4,4,4,4,4,4,4,4")])
1312:
1313: (define_insn ""
1314: [(set (match_operand:QI 3 "register_operand" "=r")
1315: (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "0")
1316: (match_operand:SI 2 "int5_operand" "L"))))
1317: (set (match_operand:SI 0 "register_operand" "=r")
1318: (plus:SI (match_dup 1) (match_dup 2)))]
1319: ""
1320: "ldbs,mb %2(0,%0),%3"
1321: [(set_attr "type" "load")
1322: (set_attr "length" "4")])
1323:
1324: (define_insn ""
1325: [(set (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "0")
1326: (match_operand:SI 2 "int5_operand" "L")))
1327: (match_operand:QI 3 "reg_or_0_operand" "rM"))
1328: (set (match_operand:SI 0 "register_operand" "=r")
1329: (plus:SI (match_dup 1) (match_dup 2)))]
1330: ""
1331: "stbs,mb %r3,%2(0,%0)"
1332: [(set_attr "type" "store")
1333: (set_attr "length" "4")])
1334:
1335: ;; The definition of this insn does not really explain what it does,
1336: ;; but it should suffice
1337: ;; that anything generated as this insn will be recognized as one
1338: ;; and that it will not successfully combine with anything.
1339: (define_expand "movstrsi"
1340: [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1341: (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1342: (clobber (match_dup 0))
1343: (clobber (match_dup 1))
1344: (clobber (match_dup 4))
1345: (clobber (match_dup 5))
1346: (use (match_operand:SI 2 "arith_operand" ""))
1347: (use (match_operand:SI 3 "const_int_operand" ""))])]
1348: ""
1349: "
1350: {
1351: /* If the blocks are not at least word-aligned and rather big (>16 items),
1352: or the size is indeterminate, don't inline the copy code. A
1353: procedure call is better since it can check the alignment at
1354: runtime and make the optimal decisions. */
1355: if (INTVAL (operands[3]) < 4
1356: && (GET_CODE (operands[2]) != CONST_INT
1357: || (INTVAL (operands[2]) / INTVAL (operands[3]) > 16)))
1358: FAIL;
1359:
1360: operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
1361: operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1362: operands[4] = gen_reg_rtx (SImode);
1363: operands[5] = gen_reg_rtx (SImode);
1364: }")
1365:
1366: ;; The operand constraints are written like this to support both compile-time
1367: ;; and run-time determined byte count. If the count is run-time determined,
1368: ;; the register with the byte count is clobbered by the copying code, and
1369: ;; therefore it is forced to operand 2. If the count is compile-time
1370: ;; determined, we need two scratch registers for the unrolled code.
1371: (define_insn ""
1372: [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
1373: (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
1374: (clobber (match_dup 0))
1375: (clobber (match_dup 1))
1376: (clobber (match_operand:SI 2 "register_operand" "=r,r")) ;loop cnt/tmp
1377: (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp
1378: (use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count
1379: (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
1380: ""
1381: "* return output_block_move (operands, !which_alternative);"
1382: [(set_attr "type" "multi,multi")])
1383:
1384: ;; Floating point move insns
1385:
1386: ;; This pattern forces (set (reg:DF ...) (const_double ...))
1387: ;; to be reloaded by putting the constant into memory when
1388: ;; reg is a floating point register.
1389: ;;
1390: ;; For integer registers we use ldil;ldo to set the appropriate
1391: ;; value.
1392: ;;
1393: ;; This must come before the movdf pattern, and it must be present
1394: ;; to handle obscure reloading cases.
1395: (define_insn ""
1396: [(set (match_operand:DF 0 "general_operand" "=?r,fx")
1397: (match_operand:DF 1 "" "?E,m"))]
1398: "GET_CODE (operands[1]) == CONST_DOUBLE
1399: && operands[1] != CONST0_RTX (DFmode)"
1400: "* return (which_alternative == 0 ? output_move_double (operands)
1401: : \" fldds%F1 %1,%0\");"
1402: [(set_attr "type" "move,fpload")
1403: (set_attr "length" "16,4")])
1404:
1405: (define_expand "movdf"
1406: [(set (match_operand:DF 0 "general_operand" "")
1407: (match_operand:DF 1 "general_operand" ""))]
1408: ""
1409: "
1410: {
1411: if (emit_move_sequence (operands, DFmode, 0))
1412: DONE;
1413: }")
1414:
1415: (define_insn ""
1416: [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
1417: "=fx,*r,Q,?o,?Q,fx,*&r,*&r")
1418: (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
1419: "fxG,*rG,fx,*r,*r,Q,o,Q"))]
1420: "register_operand (operands[0], DFmode)
1421: || reg_or_0_operand (operands[1], DFmode)"
1422: "*
1423: {
1424: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
1425: || operands[1] == CONST0_RTX (DFmode))
1426: return output_fp_move_double (operands);
1427: return output_move_double (operands);
1428: }"
1429: [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load")
1430: (set_attr "length" "4,8,4,8,16,4,8,16")])
1431:
1432: (define_insn ""
1433: [(set (match_operand:DF 0 "register_operand" "=fx")
1434: (mem:DF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
1435: (const_int 8))
1436: (match_operand:SI 2 "register_operand" "r"))))]
1437: "! TARGET_DISABLE_INDEXING"
1438: "flddx,s %1(0,%2),%0"
1439: [(set_attr "type" "fpload")
1440: (set_attr "length" "4")])
1441:
1442: ;; This variant of the above insn can occur if the second operand
1443: ;; is the frame pointer. This is a kludge, but there doesn't
1444: ;; seem to be a way around it. Only recognize it while reloading.
1445: ;; Ugh. Output is a FP register; so we need to earlyclobber something
1446: ;; else as a temporary.
1447: (define_insn ""
1448: [(set (match_operand:DF 0 "register_operand" "=fx")
1449: (mem:DF (plus:SI
1450: (plus:SI
1451: (mult:SI (match_operand:SI 1 "register_operand" "+&r")
1452: (const_int 8))
1453: (match_operand:SI 2 "register_operand" "r"))
1454: (match_operand:SI 3 "const_int_operand" "rL"))))]
1455: "! TARGET_DISABLE_INDEXING && reload_in_progress"
1456: "*
1457: {
1458: if (GET_CODE (operands[3]) == CONST_INT)
1459: return \"sh3add %1,%2,%1\;fldds %3(0,%1),%0\";
1460: else
1461: return \"sh3add %1,%2,%1\;flddx %3(0,%1),%0\";
1462: }"
1463: [(set_attr "type" "fpload")
1464: (set_attr "length" "8")])
1465:
1466: (define_insn ""
1467: [(set (mem:DF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
1468: (const_int 8))
1469: (match_operand:SI 2 "register_operand" "r")))
1470: (match_operand:DF 0 "register_operand" "fx"))]
1471: "! TARGET_DISABLE_INDEXING"
1472: "fstdx,s %0,%1(0,%2)"
1473: [(set_attr "type" "fpstore")
1474: (set_attr "length" "4")])
1475:
1476: ;; This variant of the above insn can occur if the second operand
1477: ;; is the frame pointer. This is a kludge, but there doesn't
1478: ;; seem to be a way around it. Only recognize it while reloading.
1479: ;; Ugh. Output is a FP register; so we need to earlyclobber something
1480: ;; else as a temporary.
1481: (define_insn ""
1482: [(set (mem:DF (plus:SI
1483: (plus:SI
1484: (mult:SI (match_operand:SI 1 "register_operand" "+&r")
1485: (const_int 8))
1486: (match_operand:SI 2 "register_operand" "r"))
1487: (match_operand:SI 3 "const_int_operand" "rL")))
1488: (match_operand:DF 0 "register_operand" "=fx"))]
1489: "! TARGET_DISABLE_INDEXING && reload_in_progress"
1490: "*
1491: {
1492: if (GET_CODE (operands[3]) == CONST_INT)
1493: return \"sh3add %1,%2,%1\;fstds %3(0,%1),%0\";
1494: else
1495: return \"sh3add %1,%2,%1\;fstdx %3(0,%1),%0\";
1496: }"
1497: [(set_attr "type" "fpstore")
1498: (set_attr "length" "8")])
1499:
1500: (define_expand "movdi"
1501: [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1502: (match_operand:DI 1 "general_operand" ""))]
1503: ""
1504: "
1505: {
1506: if (emit_move_sequence (operands, DImode, 0))
1507: DONE;
1508: }")
1509:
1510: (define_expand "reload_indi"
1511: [(set (match_operand:DI 0 "register_operand" "=z")
1512: (match_operand:DI 1 "general_operand" ""))
1513: (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1514: ""
1515: "
1516: {
1517: if (emit_move_sequence (operands, DImode, operands[2]))
1518: DONE;
1519:
1520: /* We don't want the clobber emitted, so handle this ourselves. */
1521: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
1522: DONE;
1523: }")
1524:
1525: (define_expand "reload_outdi"
1526: [(set (match_operand:DI 0 "general_operand" "")
1527: (match_operand:DI 1 "register_operand" "z"))
1528: (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1529: ""
1530: "
1531: {
1532: if (emit_move_sequence (operands, DImode, operands[2]))
1533: DONE;
1534:
1535: /* We don't want the clobber emitted, so handle this ourselves. */
1536: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
1537: DONE;
1538: }")
1539:
1540: (define_insn ""
1541: [(set (match_operand:DI 0 "register_operand" "=r")
1542: (high:DI (match_operand 1 "" "")))]
1543: "check_pic (1)"
1544: "*
1545: {
1546: rtx op0 = operands[0];
1547: rtx op1 = operands[1];
1548:
1549: if (GET_CODE (op1) == CONST_INT)
1550: {
1551: operands[0] = operand_subword (op0, 1, 0, DImode);
1552: output_asm_insn (\"ldil L%'%1,%0\", operands);
1553:
1554: operands[0] = operand_subword (op0, 0, 0, DImode);
1555: if (INTVAL (op1) < 0)
1556: output_asm_insn (\"ldi -1,%0\", operands);
1557: else
1558: output_asm_insn (\"ldi 0,%0\", operands);
1559: return \"\";
1560: }
1561: else if (GET_CODE (op1) == CONST_DOUBLE)
1562: {
1563: operands[0] = operand_subword (op0, 1, 0, DImode);
1564: operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
1565: output_asm_insn (\"ldil L%'%1,%0\", operands);
1566:
1567: operands[0] = operand_subword (op0, 0, 0, DImode);
1568: operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
1569: output_asm_insn (singlemove_string (operands), operands);
1570: return \"\";
1571: }
1572: else
1573: abort ();
1574: }"
1575: [(set_attr "type" "move")
1576: (set_attr "length" "8")])
1577:
1578: ;;; Experimental
1579:
1580: (define_insn ""
1581: [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
1582: "=r,o,Q,&r,&r,&r,x,x,*T")
1583: (match_operand:DI 1 "general_operand"
1584: "rM,r,r,o,Q,i,xM,*T,x"))]
1585: "register_operand (operands[0], DImode)
1586: || reg_or_0_operand (operands[1], DImode)"
1587: "*
1588: {
1589: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
1590: || (operands[1] == CONST0_RTX (DImode)))
1591: return output_fp_move_double (operands);
1592: return output_move_double (operands);
1593: }"
1594: [(set_attr "type" "move,store,store,load,load,misc,fpalu,fpload,fpstore")
1595: (set_attr "length" "8,8,16,8,16,16,4,4,4")])
1596:
1597: (define_insn ""
1598: [(set (match_operand:DI 0 "register_operand" "=r,r")
1599: (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
1600: (match_operand:DI 2 "immediate_operand" "i,i")))]
1601: ""
1602: "*
1603: {
1604: /* Don't output a 64 bit constant, since we can't trust the assembler to
1605: handle it correctly. */
1606: if (GET_CODE (operands[2]) == CONST_DOUBLE)
1607: operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
1608: if (which_alternative == 1)
1609: output_asm_insn (\"copy %1,%0\", operands);
1610: return \"ldo R%'%G2(%R1),%R0\";
1611: }"
1612: ;; Need to set length for this arith insn because operand2
1613: ;; is not an "arith_operand".
1614: [(set_attr "length" "4,8")])
1615:
1616: ;; This pattern forces (set (reg:SF ...) (const_double ...))
1617: ;; to be reloaded by putting the constant into memory when
1618: ;; reg is a floating point register.
1619: ;;
1620: ;; For integer registers we use ldil;ldo to set the appropriate
1621: ;; value.
1622: ;;
1623: ;; This must come before the movsf pattern, and it must be present
1624: ;; to handle obscure reloading cases.
1625: (define_insn ""
1626: [(set (match_operand:SF 0 "general_operand" "=?r,fx")
1627: (match_operand:SF 1 "" "?E,m"))]
1628: "GET_CODE (operands[1]) == CONST_DOUBLE
1629: && operands[1] != CONST0_RTX (SFmode)"
1630: "* return (which_alternative == 0 ? singlemove_string (operands)
1631: : \" fldws%F1 %1,%0\");"
1632: [(set_attr "type" "move,fpload")
1633: (set_attr "length" "8,4")])
1634:
1635: (define_expand "movsf"
1636: [(set (match_operand:SF 0 "general_operand" "")
1637: (match_operand:SF 1 "general_operand" ""))]
1638: ""
1639: "
1640: {
1641: if (emit_move_sequence (operands, SFmode, 0))
1642: DONE;
1643: }")
1644:
1645: (define_insn ""
1646: [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
1647: "=fx,r,fx,r,Q,Q")
1648: (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
1649: "fxG,rG,Q,Q,fx,rG"))]
1650: "register_operand (operands[0], SFmode)
1651: || reg_or_0_operand (operands[1], SFmode)"
1652: "@
1653: fcpy,sgl %r1,%0
1654: copy %r1,%0
1655: fldws%F1 %1,%0
1656: ldw%M1 %1,%0
1657: fstws%F0 %r1,%0
1658: stw%M0 %r1,%0"
1659: [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
1660: (set_attr "length" "4,4,4,4,4,4")])
1661:
1662: (define_insn ""
1663: [(set (match_operand:SF 0 "register_operand" "=fx")
1664: (mem:SF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
1665: (const_int 4))
1666: (match_operand:SI 2 "register_operand" "r"))))]
1667: "! TARGET_DISABLE_INDEXING"
1668: "fldwx,s %1(0,%2),%0"
1669: [(set_attr "type" "fpload")
1670: (set_attr "length" "4")])
1671:
1672: ;; This variant of the above insn can occur if the second operand
1673: ;; is the frame pointer. This is a kludge, but there doesn't
1674: ;; seem to be a way around it. Only recognize it while reloading.
1675: ;; Ugh. Output is a FP register; so we need to earlyclobber something
1676: ;; else as a temporary.
1677: (define_insn ""
1678: [(set (match_operand:SF 0 "register_operand" "=fx")
1679: (mem:SF (plus:SI
1680: (plus:SI
1681: (mult:SI (match_operand:SI 1 "register_operand" "+&r")
1682: (const_int 4))
1683: (match_operand:SI 2 "register_operand" "r"))
1684: (match_operand:SI 3 "const_int_operand" "rL"))))]
1685: "! TARGET_DISABLE_INDEXING && reload_in_progress"
1686: "*
1687: {
1688: if (GET_CODE (operands[3]) == CONST_INT)
1689: return \"sh2add %1,%2,%1\;fldws %3(0,%1),%0\";
1690: else
1691: return \"sh2add %1,%2,%1\;fldwx %3(0,%1),%0\";
1692: }"
1693: [(set_attr "type" "fpload")
1694: (set_attr "length" "8")])
1695:
1696: (define_insn ""
1697: [(set (mem:SF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
1698: (const_int 4))
1699: (match_operand:SI 2 "register_operand" "r")))
1700: (match_operand:SF 0 "register_operand" "fx"))]
1701: "! TARGET_DISABLE_INDEXING"
1702: "fstwx,s %0,%1(0,%2)"
1703: [(set_attr "type" "fpstore")
1704: (set_attr "length" "4")])
1705:
1706: ;; This variant of the above insn can occur if the second operand
1707: ;; is the frame pointer. This is a kludge, but there doesn't
1708: ;; seem to be a way around it. Only recognize it while reloading.
1709: ;; Ugh. Output is a FP register; so we need to earlyclobber something
1710: ;; else as a temporary.
1711: (define_insn ""
1712: [(set (mem:SF (plus:SI
1713: (plus:SI
1714: (mult:SI (match_operand:SI 1 "register_operand" "+&r")
1715: (const_int 4))
1716: (match_operand:SI 2 "register_operand" "r"))
1717: (match_operand:SI 3 "const_int_operand" "rL")))
1718: (match_operand:SF 0 "register_operand" "=fx"))]
1719: "! TARGET_DISABLE_INDEXING && reload_in_progress"
1720: "*
1721: {
1722: if (GET_CODE (operands[3]) == CONST_INT)
1723: return \"sh2add %1,%2,%1\;fstds %3(0,%1),%0\";
1724: else
1725: return \"sh2add %1,%2,%1\;fstdx %3(0,%1),%0\";
1726: }"
1727: [(set_attr "type" "fpstore")
1728: (set_attr "length" "8")])
1729:
1730: ;;- zero extension instructions
1731:
1732: (define_insn "zero_extendhisi2"
1733: [(set (match_operand:SI 0 "register_operand" "=r,r")
1734: (zero_extend:SI
1735: (match_operand:HI 1 "reg_or_nonsymb_mem_operand" "r,Q")))]
1736: ""
1737: "@
1738: extru %1,31,16,%0
1739: ldh%M1 %1,%0"
1740: [(set_attr "type" "unary,load")])
1741:
1742: (define_insn "zero_extendqihi2"
1743: [(set (match_operand:HI 0 "register_operand" "=r,r")
1744: (zero_extend:HI
1745: (match_operand:QI 1 "reg_or_nonsymb_mem_operand" "r,Q")))]
1746: ""
1747: "@
1748: extru %1,31,8,%0
1749: ldb%M1 %1,%0"
1750: [(set_attr "type" "unary,load")])
1751:
1752: (define_insn "zero_extendqisi2"
1753: [(set (match_operand:SI 0 "register_operand" "=r,r")
1754: (zero_extend:SI
1755: (match_operand:QI 1 "reg_or_nonsymb_mem_operand" "r,Q")))]
1756: ""
1757: "@
1758: extru %1,31,8,%0
1759: ldb%M1 %1,%0"
1760: [(set_attr "type" "unary,load")])
1761:
1762: ;;- sign extension instructions
1763:
1764: (define_insn "extendhisi2"
1765: [(set (match_operand:SI 0 "register_operand" "=r")
1766: (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1767: ""
1768: "extrs %1,31,16,%0"
1769: [(set_attr "type" "unary")])
1770:
1771: (define_insn "extendqihi2"
1772: [(set (match_operand:HI 0 "register_operand" "=r")
1773: (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1774: ""
1775: "extrs %1,31,8,%0"
1776: [(set_attr "type" "unary")])
1777:
1778: (define_insn "extendqisi2"
1779: [(set (match_operand:SI 0 "register_operand" "=r")
1780: (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1781: ""
1782: "extrs %1,31,8,%0"
1783: [(set_attr "type" "unary")])
1784:
1785: ;; Conversions between float and double.
1786:
1787: (define_insn "extendsfdf2"
1788: [(set (match_operand:DF 0 "register_operand" "=fx")
1789: (float_extend:DF
1790: (match_operand:SF 1 "register_operand" "fx")))]
1791: ""
1792: "fcnvff,sgl,dbl %1,%0"
1793: [(set_attr "type" "fpalu")])
1794:
1795: (define_insn "truncdfsf2"
1796: [(set (match_operand:SF 0 "register_operand" "=fx")
1797: (float_truncate:SF
1798: (match_operand:DF 1 "register_operand" "fx")))]
1799: ""
1800: "fcnvff,dbl,sgl %1,%0"
1801: [(set_attr "type" "fpalu")])
1802:
1803: ;; Conversion between fixed point and floating point.
1804: ;; Note that among the fix-to-float insns
1805: ;; the ones that start with SImode come first.
1806: ;; That is so that an operand that is a CONST_INT
1807: ;; (and therefore lacks a specific machine mode).
1808: ;; will be recognized as SImode (which is always valid)
1809: ;; rather than as QImode or HImode.
1810:
1811: ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
1812: ;; to be reloaded by putting the constant into memory.
1813: ;; It must come before the more general floatsisf2 pattern.
1814: (define_insn ""
1815: [(set (match_operand:SF 0 "general_operand" "=fx")
1816: (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
1817: ""
1818: "fldws %1,%0\;fcnvxf,sgl,sgl %0,%0"
1819: [(set_attr "type" "fpalu")
1820: (set_attr "length" "8")])
1821:
1822: (define_insn "floatsisf2"
1823: [(set (match_operand:SF 0 "general_operand" "=fx")
1824: (float:SF (match_operand:SI 1 "register_operand" "fx")))]
1825: ""
1826: "fcnvxf,sgl,sgl %1,%0"
1827: [(set_attr "type" "fpalu")])
1828:
1829: ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
1830: ;; to be reloaded by putting the constant into memory.
1831: ;; It must come before the more general floatsidf2 pattern.
1832: (define_insn ""
1833: [(set (match_operand:DF 0 "general_operand" "=fx")
1834: (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
1835: ""
1836: "fldws %1,%0\;fcnvxf,sgl,dbl %0,%0"
1837: [(set_attr "type" "fpalu")
1838: (set_attr "length" "8")])
1839:
1840: (define_insn "floatsidf2"
1841: [(set (match_operand:DF 0 "general_operand" "=fx")
1842: (float:DF (match_operand:SI 1 "register_operand" "fx")))]
1843: ""
1844: "fcnvxf,sgl,dbl %1,%0"
1845: [(set_attr "type" "fpalu")])
1846:
1847: (define_expand "floatunssisf2"
1848: [(set (subreg:SI (match_dup 2) 1)
1849: (match_operand:SI 1 "register_operand" ""))
1850: (set (subreg:SI (match_dup 2) 0)
1851: (const_int 0))
1852: (set (match_operand:SF 0 "general_operand" "")
1853: (float:SF (match_dup 2)))]
1854: "TARGET_SNAKE"
1855: "operands[2] = gen_reg_rtx (DImode);")
1856:
1857: (define_expand "floatunssidf2"
1858: [(set (subreg:SI (match_dup 2) 1)
1859: (match_operand:SI 1 "register_operand" ""))
1860: (set (subreg:SI (match_dup 2) 0)
1861: (const_int 0))
1862: (set (match_operand:DF 0 "general_operand" "")
1863: (float:DF (match_dup 2)))]
1864: "TARGET_SNAKE"
1865: "operands[2] = gen_reg_rtx (DImode);")
1866:
1867: (define_insn "floatdisf2"
1868: [(set (match_operand:SF 0 "general_operand" "=x")
1869: (float:SF (match_operand:DI 1 "register_operand" "x")))]
1870: "TARGET_SNAKE"
1871: "fcnvxf,dbl,sgl %1,%0"
1872: [(set_attr "type" "fpalu")])
1873:
1874: (define_insn "floatdidf2"
1875: [(set (match_operand:DF 0 "general_operand" "=x")
1876: (float:DF (match_operand:DI 1 "register_operand" "x")))]
1877: "TARGET_SNAKE"
1878: "fcnvxf,dbl,dbl %1,%0"
1879: [(set_attr "type" "fpalu")])
1880:
1881: ;; Convert a float to an actual integer.
1882: ;; Truncation is performed as part of the conversion.
1883:
1884: (define_insn "fix_truncsfsi2"
1885: [(set (match_operand:SI 0 "register_operand" "=fx")
1886: (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "fx"))))]
1887: ""
1888: "fcnvfxt,sgl,sgl %1,%0"
1889: [(set_attr "type" "fpalu")])
1890:
1891: (define_insn "fix_truncdfsi2"
1892: [(set (match_operand:SI 0 "register_operand" "=fx")
1893: (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "fx"))))]
1894: ""
1895: "fcnvfxt,dbl,sgl %1,%0"
1896: [(set_attr "type" "fpalu")])
1897:
1898: (define_insn "fix_truncsfdi2"
1899: [(set (match_operand:DI 0 "register_operand" "=x")
1900: (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "x"))))]
1901: "TARGET_SNAKE"
1902: "fcnvfxt,sgl,dbl %1,%0"
1903: [(set_attr "type" "fpalu")])
1904:
1905: (define_insn "fix_truncdfdi2"
1906: [(set (match_operand:DI 0 "register_operand" "=x")
1907: (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "x"))))]
1908: "TARGET_SNAKE"
1909: "fcnvfxt,dbl,dbl %1,%0"
1910: [(set_attr "type" "fpalu")])
1911:
1912: ;;- arithmetic instructions
1913:
1914: (define_insn "adddi3"
1915: [(set (match_operand:DI 0 "register_operand" "=r")
1916: (plus:DI (match_operand:DI 1 "register_operand" "%r")
1917: (match_operand:DI 2 "arith11_operand" "rI")))]
1918: ""
1919: "*
1920: {
1921: if (GET_CODE (operands[2]) == CONST_INT)
1922: {
1923: if (INTVAL (operands[2]) >= 0)
1924: return \"addi %2,%R1,%R0\;addc %1,0,%0\";
1925: else
1926: return \"addi %2,%R1,%R0\;subb %1,0,%0\";
1927: }
1928: else
1929: return \"add %R2,%R1,%R0\;addc %2,%1,%0\";
1930: }"
1931: [(set_attr "length" "8")])
1932:
1933: (define_insn ""
1934: [(set (match_operand:SI 0 "register_operand" "=r")
1935: (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
1936: (match_operand:SI 2 "register_operand" "r")))]
1937: ""
1938: "uaddcm %2,%1,%0")
1939:
1940: ;; define_splits to optimize cases of adding a constant integer
1941: ;; to a register when the constant does not fit in 14 bits. */
1942: (define_split
1943: [(set (match_operand:SI 0 "register_operand" "")
1944: (plus:SI (match_operand:SI 1 "register_operand" "")
1945: (match_operand:SI 2 "const_int_operand" "")))
1946: (clobber (match_operand:SI 4 "register_operand" ""))]
1947: "! cint_ok_for_move (INTVAL (operands[2]))
1948: && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
1949: [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
1950: (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
1951: "
1952: {
1953: int val = INTVAL (operands[2]);
1954: int low = (val < 0) ? -0x2000 : 0x1fff;
1955: int rest = val - low;
1956:
1957: operands[2] = GEN_INT (rest);
1958: operands[3] = GEN_INT (low);
1959: }")
1960:
1961: (define_split
1962: [(set (match_operand:SI 0 "register_operand" "")
1963: (plus:SI (match_operand:SI 1 "register_operand" "")
1964: (match_operand:SI 2 "const_int_operand" "")))
1965: (clobber (match_operand:SI 4 "register_operand" ""))]
1966: "! cint_ok_for_move (INTVAL (operands[2]))"
1967: [(set (match_dup 4) (match_dup 2))
1968: (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
1969: (match_dup 1)))]
1970: "
1971: {
1972: int intval = INTVAL (operands[2]);
1973:
1974: /* Try diving the constant by 2, then 4, and finally 8 to see
1975: if we can get a constant which can be loaded into a register
1976: in a single instruction (cint_ok_for_move). */
1977: if (intval % 2 == 0 && cint_ok_for_move (intval / 2))
1978: {
1979: operands[2] = GEN_INT (INTVAL (operands[2]) / 2);
1980: operands[3] = GEN_INT (2);
1981: }
1982: else if (intval % 4 == 0 && cint_ok_for_move (intval / 4))
1983: {
1984: operands[2] = GEN_INT (INTVAL (operands[2]) / 4);
1985: operands[3] = GEN_INT (4);
1986: }
1987: else if (intval % 8 == 0 && cint_ok_for_move (intval / 8))
1988: {
1989: operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
1990: operands[3] = GEN_INT (8);
1991: }
1992: else
1993: FAIL;
1994: }")
1995:
1996: (define_insn "addsi3"
1997: [(set (match_operand:SI 0 "register_operand" "=r,r")
1998: (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
1999: (match_operand:SI 2 "arith_operand" "r,J")))]
2000: ""
2001: "@
2002: add %1,%2,%0
2003: ldo %2(%1),%0")
2004:
2005: (define_insn "add_and_indirect"
2006: [(set (match_operand:SI 0 "register_operand" "=r")
2007: (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "%r")
2008: (match_operand:SI 2 "arith_operand" "r"))))]
2009: ""
2010: "add %1,%2,%0\;ldw 0(%0),%0"
2011: [(set_attr "length" "8")])
2012:
2013: (define_insn "subdi3"
2014: [(set (match_operand:DI 0 "register_operand" "=r")
2015: (minus:DI (match_operand:DI 1 "register_operand" "r")
2016: (match_operand:DI 2 "register_operand" "r")))]
2017: ""
2018: "sub %R1,%R2,%R0\;subb %1,%2,%0"
2019: [(set_attr "length" "8")])
2020:
2021: (define_insn "subsi3"
2022: [(set (match_operand:SI 0 "register_operand" "=r,r")
2023: (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
2024: (match_operand:SI 2 "register_operand" "r,r")))]
2025: ""
2026: "@
2027: sub %1,%2,%0
2028: subi %1,%2,%0")
2029:
2030: ;; Clobbering a "register_operand" instead of a match_scratch
2031: ;; in operand3 of millicode calls avoids spilling %r1 and
2032: ;; produces better code.
2033:
2034: ;; The mulsi3 insns set up registers for the millicode call.
2035: (define_expand "mulsi3"
2036: [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
2037: (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
2038: (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
2039: (clobber (match_operand:SI 3 "register_operand" ""))
2040: (clobber (reg:SI 26))
2041: (clobber (reg:SI 25))
2042: (clobber (reg:SI 19))
2043: (clobber (reg:SI 31))])
2044: (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
2045: ""
2046: "
2047: {
2048: if (TARGET_SNAKE && ! TARGET_DISABLE_FPREGS)
2049: {
2050: rtx scratch = gen_reg_rtx (DImode);
2051: operands[1] = force_reg (SImode, operands[1]);
2052: operands[2] = force_reg (SImode, operands[2]);
2053: emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
2054: emit_insn (gen_rtx (SET, VOIDmode,
2055: operands[0],
2056: gen_rtx (SUBREG, SImode, scratch, 1)));
2057: DONE;
2058: }
2059: operands[3] = gen_reg_rtx(SImode);
2060: }")
2061:
2062: (define_insn "umulsidi3"
2063: [(set (match_operand:DI 0 "register_operand" "=x")
2064: (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "x"))
2065: (zero_extend:DI (match_operand:SI 2 "register_operand" "x"))))]
2066: "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS"
2067: "xmpyu %1,%2,%0"
2068: [(set_attr "type" "fpmul")])
2069:
2070: (define_insn ""
2071: [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
2072: (clobber (match_operand:SI 0 "register_operand" "=a"))
2073: (clobber (reg:SI 26))
2074: (clobber (reg:SI 25))
2075: (clobber (reg:SI 19))
2076: (clobber (reg:SI 31))]
2077: ""
2078: "* return output_mul_insn (0, insn);"
2079: [(set_attr "type" "milli")])
2080:
2081: ;;; Division and mod.
2082: (define_expand "divsi3"
2083: [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
2084: (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
2085: (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
2086: (clobber (match_operand:SI 3 "register_operand" ""))
2087: (clobber (reg:SI 26))
2088: (clobber (reg:SI 25))
2089: (clobber (reg:SI 19))
2090: (clobber (reg:SI 31))])
2091: (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
2092: ""
2093: "
2094: {
2095: operands[3] = gen_reg_rtx(SImode);
2096: if (!(GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const(operands, 0)))
2097: {
2098: emit_move_insn (gen_rtx (REG, SImode, 26), operands[1]);
2099: emit_move_insn (gen_rtx (REG, SImode, 25), operands[2]);
2100: emit
2101: (gen_rtx
2102: (PARALLEL, VOIDmode,
2103: gen_rtvec (6, gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 29),
2104: gen_rtx (DIV, SImode,
2105: gen_rtx (REG, SImode, 26),
2106: gen_rtx (REG, SImode, 25))),
2107: gen_rtx (CLOBBER, VOIDmode, operands[3]),
2108: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)),
2109: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)),
2110: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 19)),
2111: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31)))));
2112: emit_move_insn (operands[0], gen_rtx (REG, SImode, 29));
2113: }
2114: DONE;
2115: }")
2116:
2117: (define_insn ""
2118: [(set (reg:SI 29)
2119: (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
2120: (clobber (match_operand:SI 1 "register_operand" "=a"))
2121: (clobber (reg:SI 26))
2122: (clobber (reg:SI 25))
2123: (clobber (reg:SI 19))
2124: (clobber (reg:SI 31))]
2125: ""
2126: "*
2127: return output_div_insn (operands, 0, insn);"
2128: [(set_attr "type" "milli")])
2129:
2130: (define_expand "udivsi3"
2131: [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
2132: (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
2133: (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
2134: (clobber (match_operand:SI 3 "register_operand" ""))
2135: (clobber (reg:SI 26))
2136: (clobber (reg:SI 25))
2137: (clobber (reg:SI 19))
2138: (clobber (reg:SI 31))])
2139: (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
2140: ""
2141: "
2142: {
2143: operands[3] = gen_reg_rtx(SImode);
2144: if (!(GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const(operands, 1)))
2145: {
2146: emit_move_insn (gen_rtx (REG, SImode, 26), operands[1]);
2147: emit_move_insn (gen_rtx (REG, SImode, 25), operands[2]);
2148: emit
2149: (gen_rtx
2150: (PARALLEL, VOIDmode,
2151: gen_rtvec (6, gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 29),
2152: gen_rtx (UDIV, SImode,
2153: gen_rtx (REG, SImode, 26),
2154: gen_rtx (REG, SImode, 25))),
2155: gen_rtx (CLOBBER, VOIDmode, operands[3]),
2156: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)),
2157: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)),
2158: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 19)),
2159: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31)))));
2160: emit_move_insn (operands[0], gen_rtx (REG, SImode, 29));
2161: }
2162: DONE;
2163: }")
2164:
2165: (define_insn ""
2166: [(set (reg:SI 29)
2167: (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
2168: (clobber (match_operand:SI 1 "register_operand" "=a"))
2169: (clobber (reg:SI 26))
2170: (clobber (reg:SI 25))
2171: (clobber (reg:SI 19))
2172: (clobber (reg:SI 31))]
2173: ""
2174: "*
2175: return output_div_insn (operands, 1, insn);"
2176: [(set_attr "type" "milli")])
2177:
2178: (define_expand "modsi3"
2179: [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
2180: (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
2181: (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
2182: (clobber (match_operand:SI 3 "register_operand" ""))
2183: (clobber (reg:SI 26))
2184: (clobber (reg:SI 25))
2185: (clobber (reg:SI 19))
2186: (clobber (reg:SI 31))])
2187: (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
2188: ""
2189: "
2190: {
2191: operands[3] = gen_reg_rtx(SImode);
2192: emit_move_insn (gen_rtx (REG, SImode, 26), operands[1]);
2193: emit_move_insn (gen_rtx (REG, SImode, 25), operands[2]);
2194: emit
2195: (gen_rtx
2196: (PARALLEL, VOIDmode,
2197: gen_rtvec (6, gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 29),
2198: gen_rtx (MOD, SImode,
2199: gen_rtx (REG, SImode, 26),
2200: gen_rtx (REG, SImode, 25))),
2201: gen_rtx (CLOBBER, VOIDmode, operands[3]),
2202: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)),
2203: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)),
2204: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 19)),
2205: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31)))));
2206: emit_move_insn (operands[0], gen_rtx (REG, SImode, 29));
2207: DONE;
2208: }")
2209:
2210: (define_insn ""
2211: [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
2212: (clobber (match_operand:SI 0 "register_operand" "=a"))
2213: (clobber (reg:SI 26))
2214: (clobber (reg:SI 25))
2215: (clobber (reg:SI 19))
2216: (clobber (reg:SI 31))]
2217: ""
2218: "*
2219: return output_mod_insn (0, insn);"
2220: [(set_attr "type" "milli")])
2221:
2222: (define_expand "umodsi3"
2223: [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
2224: (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
2225: (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
2226: (clobber (match_operand:SI 3 "register_operand" ""))
2227: (clobber (reg:SI 26))
2228: (clobber (reg:SI 25))
2229: (clobber (reg:SI 19))
2230: (clobber (reg:SI 31))])
2231: (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
2232: ""
2233: "
2234: {
2235: operands[3] = gen_reg_rtx(SImode);
2236: emit_move_insn (gen_rtx (REG, SImode, 26), operands[1]);
2237: emit_move_insn (gen_rtx (REG, SImode, 25), operands[2]);
2238: emit
2239: (gen_rtx
2240: (PARALLEL, VOIDmode,
2241: gen_rtvec (6, gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 29),
2242: gen_rtx (UMOD, SImode,
2243: gen_rtx (REG, SImode, 26),
2244: gen_rtx (REG, SImode, 25))),
2245: gen_rtx (CLOBBER, VOIDmode, operands[3]),
2246: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)),
2247: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)),
2248: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 19)),
2249: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31)))));
2250: emit_move_insn (operands[0], gen_rtx (REG, SImode, 29));
2251: DONE;
2252: }")
2253:
2254: (define_insn ""
2255: [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
2256: (clobber (match_operand:SI 0 "register_operand" "=a"))
2257: (clobber (reg:SI 26))
2258: (clobber (reg:SI 25))
2259: (clobber (reg:SI 19))
2260: (clobber (reg:SI 31))]
2261: ""
2262: "*
2263: return output_mod_insn (1, insn);"
2264: [(set_attr "type" "milli")])
2265:
2266: ;;- and instructions
2267: ;; We define DImode `and` so with DImode `not` we can get
2268: ;; DImode `andn`. Other combinations are possible.
2269:
2270: (define_expand "anddi3"
2271: [(set (match_operand:DI 0 "register_operand" "")
2272: (and:DI (match_operand:DI 1 "arith_double_operand" "")
2273: (match_operand:DI 2 "arith_double_operand" "")))]
2274: ""
2275: "
2276: {
2277: if (! register_operand (operands[1], DImode)
2278: || ! register_operand (operands[2], DImode))
2279: /* Let GCC break this into word-at-a-time operations. */
2280: FAIL;
2281: }")
2282:
2283: (define_insn ""
2284: [(set (match_operand:DI 0 "register_operand" "=r")
2285: (and:DI (match_operand:DI 1 "register_operand" "%r")
2286: (match_operand:DI 2 "register_operand" "r")))]
2287: ""
2288: "and %1,%2,%0\;and %R1,%R2,%R0"
2289: [(set_attr "length" "8")])
2290:
2291: (define_insn "andsi3"
2292: [(set (match_operand:SI 0 "register_operand" "=r,r")
2293: (and:SI (match_operand:SI 1 "register_operand" "%r,0")
2294: (match_operand:SI 2 "and_operand" "rO,P")))]
2295: ""
2296: "* return output_and (operands); "
2297: [(set_attr "type" "binary")
2298: (set_attr "length" "4")])
2299:
2300: (define_insn ""
2301: [(set (match_operand:DI 0 "register_operand" "=r")
2302: (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2303: (match_operand:DI 2 "register_operand" "r")))]
2304: ""
2305: "andcm %2,%1,%0\;andcm %R2,%R1,%R0"
2306: [(set_attr "length" "8")])
2307:
2308: (define_insn ""
2309: [(set (match_operand:SI 0 "register_operand" "=r")
2310: (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2311: (match_operand:SI 2 "register_operand" "r")))]
2312: ""
2313: "andcm %2,%1,%0")
2314:
2315: (define_expand "iordi3"
2316: [(set (match_operand:DI 0 "register_operand" "")
2317: (ior:DI (match_operand:DI 1 "arith_double_operand" "")
2318: (match_operand:DI 2 "arith_double_operand" "")))]
2319: ""
2320: "
2321: {
2322: if (! register_operand (operands[1], DImode)
2323: || ! register_operand (operands[2], DImode))
2324: /* Let GCC break this into word-at-a-time operations. */
2325: FAIL;
2326: }")
2327:
2328: (define_insn ""
2329: [(set (match_operand:DI 0 "register_operand" "=r")
2330: (ior:DI (match_operand:DI 1 "register_operand" "%r")
2331: (match_operand:DI 2 "register_operand" "r")))]
2332: ""
2333: "or %1,%2,%0\;or %R1,%R2,%R0"
2334: [(set_attr "length" "8")])
2335:
2336: ;; Need a define_expand because we've run out of CONST_OK... characters.
2337: (define_expand "iorsi3"
2338: [(set (match_operand:SI 0 "register_operand" "")
2339: (ior:SI (match_operand:SI 1 "register_operand" "")
2340: (match_operand:SI 2 "arith32_operand" "")))]
2341: ""
2342: "
2343: {
2344: if (! (ior_operand (operands[2]) || register_operand (operands[2])))
2345: operands[2] = force_reg (SImode, operands[2]);
2346: }")
2347:
2348: (define_insn ""
2349: [(set (match_operand:SI 0 "register_operand" "=r")
2350: (ior:SI (match_operand:SI 1 "register_operand" "0")
2351: (match_operand:SI 2 "ior_operand" "")))]
2352: ""
2353: "* return output_ior (operands); "
2354: [(set_attr "type" "binary")
2355: (set_attr "length" "4")])
2356:
2357: (define_insn ""
2358: [(set (match_operand:SI 0 "register_operand" "=r")
2359: (ior:SI (match_operand:SI 1 "register_operand" "%r")
2360: (match_operand:SI 2 "register_operand" "r")))]
2361: ""
2362: "or %1,%2,%0")
2363:
2364: (define_expand "xordi3"
2365: [(set (match_operand:DI 0 "register_operand" "")
2366: (xor:DI (match_operand:DI 1 "arith_double_operand" "")
2367: (match_operand:DI 2 "arith_double_operand" "")))]
2368: ""
2369: "
2370: {
2371: if (! register_operand (operands[1], DImode)
2372: || ! register_operand (operands[2], DImode))
2373: /* Let GCC break this into word-at-a-time operations. */
2374: FAIL;
2375: }")
2376:
2377: (define_insn ""
2378: [(set (match_operand:DI 0 "register_operand" "=r")
2379: (xor:DI (match_operand:DI 1 "register_operand" "%r")
2380: (match_operand:DI 2 "register_operand" "r")))]
2381: ""
2382: "xor %1,%2,%0\;xor %R1,%R2,%R0"
2383: [(set_attr "length" "8")])
2384:
2385: (define_insn "xorsi3"
2386: [(set (match_operand:SI 0 "register_operand" "=r")
2387: (xor:SI (match_operand:SI 1 "register_operand" "%r")
2388: (match_operand:SI 2 "register_operand" "r")))]
2389: ""
2390: "xor %1,%2,%0")
2391:
2392: (define_insn "negdi2"
2393: [(set (match_operand:DI 0 "register_operand" "=r")
2394: (neg:DI (match_operand:DI 1 "register_operand" "r")))]
2395: ""
2396: "sub 0,%R1,%R0\;subb 0,%1,%0"
2397: [(set_attr "type" "unary")
2398: (set_attr "length" "8")])
2399:
2400: (define_insn "negsi2"
2401: [(set (match_operand:SI 0 "register_operand" "=r")
2402: (neg:SI (match_operand:SI 1 "register_operand" "r")))]
2403: ""
2404: "sub 0,%1,%0"
2405: [(set_attr "type" "unary")])
2406:
2407: (define_expand "one_cmpldi2"
2408: [(set (match_operand:DI 0 "register_operand" "")
2409: (not:DI (match_operand:DI 1 "arith_double_operand" "")))]
2410: ""
2411: "
2412: {
2413: if (! register_operand (operands[1], DImode))
2414: FAIL;
2415: }")
2416:
2417: (define_insn ""
2418: [(set (match_operand:DI 0 "register_operand" "=r")
2419: (not:DI (match_operand:DI 1 "register_operand" "r")))]
2420: ""
2421: "uaddcm 0,%1,%0\;uaddcm 0,%R1,%R0"
2422: [(set_attr "type" "unary")
2423: (set_attr "length" "8")])
2424:
2425: (define_insn "one_cmplsi2"
2426: [(set (match_operand:SI 0 "register_operand" "=r")
2427: (not:SI (match_operand:SI 1 "register_operand" "r")))]
2428: ""
2429: "uaddcm 0,%1,%0"
2430: [(set_attr "type" "unary")])
2431:
2432: ;; Floating point arithmetic instructions.
2433:
2434: (define_insn "adddf3"
2435: [(set (match_operand:DF 0 "register_operand" "=fx")
2436: (plus:DF (match_operand:DF 1 "register_operand" "fx")
2437: (match_operand:DF 2 "register_operand" "fx")))]
2438: ""
2439: "fadd,dbl %1,%2,%0"
2440: [(set_attr "type" "fpalu")])
2441:
2442: (define_insn "addsf3"
2443: [(set (match_operand:SF 0 "register_operand" "=fx")
2444: (plus:SF (match_operand:SF 1 "register_operand" "fx")
2445: (match_operand:SF 2 "register_operand" "fx")))]
2446: ""
2447: "fadd,sgl %1,%2,%0"
2448: [(set_attr "type" "fpalu")])
2449:
2450: (define_insn "subdf3"
2451: [(set (match_operand:DF 0 "register_operand" "=fx")
2452: (minus:DF (match_operand:DF 1 "register_operand" "fx")
2453: (match_operand:DF 2 "register_operand" "fx")))]
2454: ""
2455: "fsub,dbl %1,%2,%0"
2456: [(set_attr "type" "fpalu")])
2457:
2458: (define_insn "subsf3"
2459: [(set (match_operand:SF 0 "register_operand" "=fx")
2460: (minus:SF (match_operand:SF 1 "register_operand" "fx")
2461: (match_operand:SF 2 "register_operand" "fx")))]
2462: ""
2463: "fsub,sgl %1,%2,%0"
2464: [(set_attr "type" "fpalu")])
2465:
2466: (define_insn "muldf3"
2467: [(set (match_operand:DF 0 "register_operand" "=fx")
2468: (mult:DF (match_operand:DF 1 "register_operand" "fx")
2469: (match_operand:DF 2 "register_operand" "fx")))]
2470: ""
2471: "fmpy,dbl %1,%2,%0"
2472: [(set_attr "type" "fpmul")])
2473:
2474: (define_insn "mulsf3"
2475: [(set (match_operand:SF 0 "register_operand" "=fx")
2476: (mult:SF (match_operand:SF 1 "register_operand" "fx")
2477: (match_operand:SF 2 "register_operand" "fx")))]
2478: ""
2479: "fmpy,sgl %1,%2,%0"
2480: [(set_attr "type" "fpmul")])
2481:
2482: (define_insn "divdf3"
2483: [(set (match_operand:DF 0 "register_operand" "=fx")
2484: (div:DF (match_operand:DF 1 "register_operand" "fx")
2485: (match_operand:DF 2 "register_operand" "fx")))]
2486: ""
2487: "fdiv,dbl %1,%2,%0"
2488: [(set_attr "type" "fpdivdbl")])
2489:
2490: (define_insn "divsf3"
2491: [(set (match_operand:SF 0 "register_operand" "=fx")
2492: (div:SF (match_operand:SF 1 "register_operand" "fx")
2493: (match_operand:SF 2 "register_operand" "fx")))]
2494: ""
2495: "fdiv,sgl %1,%2,%0"
2496: [(set_attr "type" "fpdivsgl")])
2497:
2498: (define_insn "negdf2"
2499: [(set (match_operand:DF 0 "register_operand" "=fx")
2500: (neg:DF (match_operand:DF 1 "register_operand" "fx")))]
2501: ""
2502: "fsub,dbl 0,%1,%0"
2503: [(set_attr "type" "fpalu")])
2504:
2505: (define_insn "negsf2"
2506: [(set (match_operand:SF 0 "register_operand" "=fx")
2507: (neg:SF (match_operand:SF 1 "register_operand" "fx")))]
2508: ""
2509: "fsub,sgl 0,%1,%0"
2510: [(set_attr "type" "fpalu")])
2511:
2512: (define_insn "absdf2"
2513: [(set (match_operand:DF 0 "register_operand" "=fx")
2514: (abs:DF (match_operand:DF 1 "register_operand" "fx")))]
2515: ""
2516: "fabs,dbl %1,%0"
2517: [(set_attr "type" "fpalu")])
2518:
2519: (define_insn "abssf2"
2520: [(set (match_operand:SF 0 "register_operand" "=fx")
2521: (abs:SF (match_operand:SF 1 "register_operand" "fx")))]
2522: ""
2523: "fabs,sgl %1,%0"
2524: [(set_attr "type" "fpalu")])
2525:
2526: (define_insn "sqrtdf2"
2527: [(set (match_operand:DF 0 "register_operand" "=fx")
2528: (sqrt:DF (match_operand:DF 1 "register_operand" "fx")))]
2529: ""
2530: "fsqrt,dbl %1,%0"
2531: [(set_attr "type" "fpsqrtdbl")])
2532:
2533: (define_insn "sqrtsf2"
2534: [(set (match_operand:SF 0 "register_operand" "=fx")
2535: (sqrt:SF (match_operand:SF 1 "register_operand" "fx")))]
2536: ""
2537: "fsqrt,sgl %1,%0"
2538: [(set_attr "type" "fpsqrtsgl")])
2539:
2540: ;;- Shift instructions
2541:
2542: ;; Optimized special case of shifting.
2543:
2544: (define_insn ""
2545: [(set (match_operand:SI 0 "register_operand" "=r")
2546: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2547: (const_int 24)))]
2548: ""
2549: "ldb%M1 %1,%0"
2550: [(set_attr "type" "load")
2551: (set_attr "length" "4")])
2552:
2553: (define_insn ""
2554: [(set (match_operand:SI 0 "register_operand" "=r")
2555: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2556: (const_int 16)))]
2557: ""
2558: "ldh%M1 %1,%0"
2559: [(set_attr "type" "load")
2560: (set_attr "length" "4")])
2561:
2562: (define_insn ""
2563: [(set (match_operand:SI 0 "register_operand" "=r")
2564: (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
2565: (match_operand:SI 3 "shadd_operand" ""))
2566: (match_operand:SI 1 "register_operand" "r")))]
2567: ""
2568: "sh%O3add %2,%1,%0")
2569:
2570: ;; This variant of the above insn can occur if the first operand
2571: ;; is the frame pointer. This is a kludge, but there doesn't
2572: ;; seem to be a way around it. Only recognize it while reloading.
2573:
2574: (define_insn ""
2575: [(set (match_operand:SI 0 "register_operand" "=&r")
2576: (plus:SI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
2577: (match_operand:SI 4 "shadd_operand" ""))
2578: (match_operand:SI 1 "register_operand" "r"))
2579: (match_operand:SI 3 "const_int_operand" "rI")))]
2580: "reload_in_progress"
2581: "sh%O4add %2,%1,%0\;add%I3 %3,%0,%0"
2582: [(set_attr "type" "multi")
2583: (set_attr "length" "8")])
2584:
2585: (define_expand "ashlsi3"
2586: [(set (match_operand:SI 0 "register_operand" "")
2587: (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
2588: (match_operand:SI 2 "arith32_operand" "")))]
2589: ""
2590: "
2591: {
2592: if (GET_CODE (operands[2]) != CONST_INT)
2593: {
2594: rtx temp = gen_reg_rtx (SImode);
2595: emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
2596: if (GET_CODE (operands[1]) == CONST_INT)
2597: emit_insn (gen_zvdep_imm (operands[0], operands[1], temp));
2598: else
2599: emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
2600: DONE;
2601: }
2602: /* Make sure both inputs are not constants,
2603: the recognizer can't handle that. */
2604: operands[1] = force_reg (SImode, operands[1]);
2605: }")
2606:
2607: (define_insn ""
2608: [(set (match_operand:SI 0 "register_operand" "=r")
2609: (ashift:SI (match_operand:SI 1 "register_operand" "r")
2610: (match_operand:SI 2 "const_int_operand" "n")))]
2611: ""
2612: "zdep %1,%P2,%L2,%0"
2613: [(set_attr "type" "binary")
2614: (set_attr "length" "4")])
2615:
2616: ; Match cases of op1 a CONST_INT here that zvdep_imm doesn't handle.
2617: ; Doing it like this makes slightly better code since reload can
2618: ; replace a register with a known value in range -16..15 with a
2619: ; constant. Ideally, we would like to merge zvdep32 and zvdep_imm,
2620: ; but since we have no more CONST_OK... characters, that is not
2621: ; possible.
2622: (define_insn "zvdep32"
2623: [(set (match_operand:SI 0 "register_operand" "=r,r")
2624: (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
2625: (minus:SI (const_int 31)
2626: (match_operand:SI 2 "register_operand" "q,q"))))]
2627: ""
2628: "@
2629: zvdep %1,32,%0
2630: zvdepi %1,32,%0")
2631:
2632: (define_insn "zvdep_imm"
2633: [(set (match_operand:SI 0 "register_operand" "=r")
2634: (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
2635: (minus:SI (const_int 31)
2636: (match_operand:SI 2 "register_operand" "q"))))]
2637: ""
2638: "*
2639: {
2640: int x = INTVAL (operands[1]);
2641: operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
2642: operands[1] = GEN_INT ((x & 0xf) - 0x10);
2643: return \"zvdepi %1,%2,%0\";
2644: }")
2645:
2646: (define_expand "ashrsi3"
2647: [(set (match_operand:SI 0 "register_operand" "")
2648: (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
2649: (match_operand:SI 2 "arith32_operand" "")))]
2650: ""
2651: "
2652: {
2653: if (GET_CODE (operands[2]) != CONST_INT)
2654: {
2655: rtx temp = gen_reg_rtx (SImode);
2656: emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
2657: emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
2658: DONE;
2659: }
2660: }")
2661:
2662: (define_insn ""
2663: [(set (match_operand:SI 0 "register_operand" "=r")
2664: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2665: (match_operand:SI 2 "const_int_operand" "n")))]
2666: ""
2667: "extrs %1,%P2,%L2,%0"
2668: [(set_attr "type" "binary")
2669: (set_attr "length" "4")])
2670:
2671: (define_insn "vextrs32"
2672: [(set (match_operand:SI 0 "register_operand" "=r")
2673: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2674: (minus:SI (const_int 31)
2675: (match_operand:SI 2 "register_operand" "q"))))]
2676: ""
2677: "vextrs %1,32,%0")
2678:
2679: (define_insn "lshrsi3"
2680: [(set (match_operand:SI 0 "register_operand" "=r,r")
2681: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
2682: (match_operand:SI 2 "arith32_operand" "q,n")))]
2683: ""
2684: "@
2685: vshd 0,%1,%0
2686: extru %1,%P2,%L2,%0"
2687: [(set_attr "type" "binary")
2688: (set_attr "length" "4")])
2689:
2690: (define_insn "rotrsi3"
2691: [(set (match_operand:SI 0 "register_operand" "=r,r")
2692: (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
2693: (match_operand:SI 2 "arith32_operand" "q,n")))]
2694: ""
2695: "*
2696: {
2697: if (GET_CODE (operands[2]) == CONST_INT)
2698: {
2699: operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
2700: return \"shd %1,%1,%2,%0\";
2701: }
2702: else
2703: return \"vshd %1,%1,%0\";
2704: }"
2705: [(set_attr "type" "binary")
2706: (set_attr "length" "4")])
2707:
2708: (define_insn "rotlsi3"
2709: [(set (match_operand:SI 0 "register_operand" "=r")
2710: (rotate:SI (match_operand:SI 1 "register_operand" "r")
2711: (match_operand:SI 2 "const_int_operand" "n")))]
2712: ""
2713: "*
2714: {
2715: operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
2716: return \"shd %1,%1,%2,%0\";
2717: }"
2718: [(set_attr "type" "binary")
2719: (set_attr "length" "4")])
2720:
2721: (define_insn ""
2722: [(set (match_operand:SI 0 "register_operand" "=r")
2723: (match_operator:SI 5 "plus_xor_ior_operator"
2724: [(ashift:SI (match_operand:SI 1 "register_operand" "r")
2725: (match_operand:SI 3 "const_int_operand" "n"))
2726: (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
2727: (match_operand:SI 4 "const_int_operand" "n"))]))]
2728: "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
2729: "shd %1,%2,%4,%0"
2730: [(set_attr "type" "binary")
2731: (set_attr "length" "4")])
2732:
2733: (define_insn ""
2734: [(set (match_operand:SI 0 "register_operand" "=r")
2735: (match_operator:SI 5 "plus_xor_ior_operator"
2736: [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
2737: (match_operand:SI 4 "const_int_operand" "n"))
2738: (ashift:SI (match_operand:SI 1 "register_operand" "r")
2739: (match_operand:SI 3 "const_int_operand" "n"))]))]
2740: "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
2741: "shd %1,%2,%4,%0"
2742: [(set_attr "type" "binary")
2743: (set_attr "length" "4")])
2744:
2745: (define_insn ""
2746: [(set (match_operand:SI 0 "register_operand" "=r")
2747: (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
2748: (match_operand:SI 2 "const_int_operand" ""))
2749: (match_operand:SI 3 "const_int_operand" "")))]
2750: "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) >= 0"
2751: "*
2752: {
2753: int cnt = INTVAL (operands[2]) & 31;
2754: operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
2755: operands[2] = GEN_INT (31 - cnt);
2756: return \"zdep %1,%2,%3,%0\";
2757: }"
2758: [(set_attr "type" "binary")
2759: (set_attr "length" "4")])
2760:
2761: ;; Unconditional and other jump instructions.
2762:
2763: (define_insn "return"
2764: [(return)]
2765: "hppa_can_use_return_insn_p ()"
2766: "bv%* 0(%%r2)"
2767: [(set_attr "type" "branch")])
2768:
2769: ;; Use a different pattern for functions which have non-trivial
2770: ;; epilogues so as not to confuse jump and reorg.
2771: (define_insn "return_internal"
2772: [(use (reg:SI 2))
2773: (return)]
2774: ""
2775: "bv%* 0(%%r2)"
2776: [(set_attr "type" "branch")])
2777:
2778: (define_expand "prologue"
2779: [(const_int 0)]
2780: ""
2781: "hppa_expand_prologue ();DONE;")
2782:
2783: (define_expand "epilogue"
2784: [(return)]
2785: ""
2786: "
2787: {
2788: /* Try to use the trivial return first. Else use the full
2789: epilogue. */
2790: if (hppa_can_use_return_insn_p ())
2791: emit_jump_insn (gen_return ());
2792: else
2793: {
2794: hppa_expand_epilogue ();
2795: emit_jump_insn (gen_return_internal ());
2796: }
2797: DONE;
2798: }")
2799:
2800: ;; Special because we use the value placed in %r2 by the bl instruction
2801: ;; from within its delay slot to set the value for the 2nd parameter to
2802: ;; the call.
2803: (define_insn "call_profiler"
2804: [(unspec_volatile [(const_int 0)] 0)
2805: (use (match_operand:SI 0 "const_int_operand" ""))]
2806: ""
2807: "*
2808: {
2809: #ifdef NeXT_ASM
2810: extern char *output_profile_call (rtx, rtx*);
2811: return output_profile_call (insn, operands);
2812: #else
2813: return \"bl _mcount,%%r2\;ldo %0(%%r2),%%r25\";
2814: #endif
2815: }"
2816: [(set_attr "length" "8")])
2817:
2818: (define_insn "blockage"
2819: [(unspec_volatile [(const_int 2)] 0)]
2820: ""
2821: ""
2822: [(set_attr "length" "0")])
2823:
2824: (define_insn "jump"
2825: [(set (pc) (label_ref (match_operand 0 "" "")))]
2826: ""
2827: "bl%* %l0,%%r0"
2828: [(set_attr "type" "uncond_branch")
2829: (set (attr "length")
2830: (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 0))
2831: (const_int 4)
2832: ;; If the jump is in the delay slot of a call, then its length depends
2833: ;; on whether or not we can add the proper offset to %r2 with an ldo
2834: ;; instruction.
2835: (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2836: (const_int 8188))
2837: (const_int 4)]
2838: (const_int 8)))])
2839:
2840: (define_expand "movpc"
2841: [(set (match_operand:SI 0 "register_operand" "=r")
2842: (match_operand 1 "code_label_operand" ""))]
2843: ""
2844: "{ rtx label = operands[1]; rtx target = operands[0];
2845: emit_insn (gen_rtx (SET, VOIDmode, pc_rtx, label));
2846: emit_insn (gen_branch_and_link (label, target));
2847: emit_label (label);
2848: LABEL_PRESERVE_P (label) = 1;
2849: emit_insn (gen_rtx (SET, VOIDmode, target,
2850: gen_rtx (AND, VOIDmode, target,
2851: gen_rtx (NOT, SImode, gen_rtx (CONST_INT, SImode, 3)))));
2852: {
2853: rtx insn = get_last_insn ();
2854: rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
2855:
2856: if (note)
2857: XEXP (note, 0) = label;
2858: else
2859: REG_NOTES (insn) = gen_rtx (EXPR_LIST,
2860: REG_EQUAL, label, REG_NOTES (insn));
2861: }
2862: }")
2863:
2864: (define_insn "branch_and_link"
2865: [(set (pc) (label_ref (match_operand 0 "" "")))
2866: (clobber (match_operand 1 "register_operand" "=r"))]
2867: ""
2868: "bl %l0,%1%#"
2869: [(set_attr "type" "uncond_branch")
2870: (set (attr "length")
2871: (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 0))
2872: (const_int 4)
2873: ;; If the jump is in the delay slot of a call, then its length depends
2874: ;; on whether or not we can add the proper offset to %r2 with an ldo
2875: ;; instruction.
2876: (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2877: (const_int 8188))
2878: (const_int 4)]
2879: (const_int 8)))])
2880:
2881: ;; Subroutines of "casesi".
2882: ;; operand 0 is index
2883: ;; operand 1 is the minimum bound
2884: ;; operand 2 is the maximum bound - minimum bound + 1
2885: ;; operand 3 is CODE_LABEL for the table;
2886: ;; operand 4 is the CODE_LABEL to go to if index out of range.
2887:
2888: (define_expand "casesi"
2889: [(match_operand:SI 0 "general_operand" "")
2890: (match_operand:SI 1 "const_int_operand" "")
2891: (match_operand:SI 2 "const_int_operand" "")
2892: (match_operand 3 "" "")
2893: (match_operand 4 "" "")]
2894: ""
2895: "
2896: {
2897: if (GET_CODE (operands[0]) != REG)
2898: operands[0] = force_reg (SImode, operands[0]);
2899:
2900: if (operands[1] != const0_rtx)
2901: {
2902: rtx reg = gen_reg_rtx (SImode);
2903:
2904: operands[1] = GEN_INT (-INTVAL (operands[1]));
2905: if (!INT_14_BITS (operands[1]))
2906: operands[1] = force_reg (SImode, operands[1]);
2907: emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
2908:
2909: operands[0] = reg;
2910: }
2911:
2912: if (!INT_11_BITS (operands[2]))
2913: operands[2] = force_reg (SImode, operands[2]);
2914:
2915: emit_jump_insn (gen_casesi0 (operands[0], operands[2],
2916: operands[3], operands[4]));
2917: DONE;
2918: }")
2919:
2920: (define_insn "casesi0"
2921: [(set (pc)
2922: (if_then_else (leu (match_operand:SI 0 "register_operand" "r")
2923: (match_operand:SI 1 "arith11_operand" "rI"))
2924: (plus:SI (mem:SI (plus:SI (pc) (match_dup 0)))
2925: (label_ref (match_operand 2 "" "")))
2926: (pc)))
2927: (use (label_ref (match_operand 3 "" "")))]
2928: ""
2929: "*
2930: {
2931: if (GET_CODE (operands[1]) == CONST_INT)
2932: {
2933: operands[1] = GEN_INT (~INTVAL (operands[1]));
2934: return \"addi,uv %1,%0,0\;blr,n %0,%%r0\;b,n %l3\";
2935: }
2936: else
2937: {
2938: return \"sub,>> %0,%1,0\;blr,n %0,%%r0\;b,n %l3\";
2939: }
2940: }"
2941: [(set_attr "length" "12")])
2942:
2943: ;; Need nops for the calls because execution is supposed to continue
2944: ;; past; we don't want to nullify an instruction that we need.
2945: ;;- jump to subroutine
2946:
2947: (define_expand "call"
2948: [(parallel [(call (match_operand:SI 0 "" "")
2949: (match_operand 1 "" ""))
2950: (clobber (reg:SI 2))])]
2951: ""
2952: "
2953: {
2954: rtx op;
2955:
2956: #ifndef NeXT_ASM
2957: if (flag_pic)
2958: emit_insn (gen_rtx (USE, VOIDmode,
2959: gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
2960: #endif
2961:
2962: if (TARGET_LONG_CALLS)
2963: op = force_reg (SImode, XEXP (operands[0], 0));
2964: else
2965: op = XEXP (operands[0], 0);
2966:
2967: /* Use two different patterns for calls to explicitly named functions
2968: and calls through function pointers. This is necessary as these two
2969: types of calls use different calling conventions, and CSE might try
2970: to change the named call into an indirect call in some cases (using
2971: two patterns keeps CSE from performing this optimization). */
2972: if (GET_CODE (op) == SYMBOL_REF)
2973: emit_call_insn (gen_call_internal_symref (op, operands[1]));
2974: else
2975: emit_call_insn (gen_call_internal_reg (op, operands[1]));
2976:
2977: #ifndef NeXT_ASM
2978: if (flag_pic)
2979: {
2980: if (!hppa_save_pic_table_rtx)
2981: hppa_save_pic_table_rtx = gen_reg_rtx (Pmode);
2982: emit_insn (gen_rtx (SET, VOIDmode,
2983: gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM),
2984: hppa_save_pic_table_rtx));
2985: }
2986: #endif
2987:
2988: DONE;
2989: }")
2990:
2991: (define_insn "call_internal_symref"
2992: [(call (mem:SI (match_operand:SI 0 "call_operand_address" ""))
2993: (match_operand 1 "" "i"))
2994: (clobber (reg:SI 2))
2995: (use (const_int 0))]
2996: "! TARGET_LONG_CALLS"
2997: "*
2998: {
2999: output_arg_descriptor (insn);
3000: return output_call (insn, operands[0], gen_rtx (REG, SImode, 2));
3001: }"
3002: [(set_attr "type" "call")
3003: (set_attr "length" "4")])
3004:
3005: (define_insn "call_internal_reg"
3006: [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
3007: (match_operand 1 "" "i"))
3008: (clobber (reg:SI 2))
3009: (use (const_int 1))]
3010: ""
3011: "*
3012: {
3013: #ifdef NeXT_ASM
3014: return \"copy %0,22\;blr %%r0, %%r2\;bv,n 0\(%%r22\)\";
3015: #else
3016: return \"copy %r0,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\";
3017: #endif
3018: }"
3019: [(set_attr "type" "dyncall")
3020: (set_attr "length" "12")])
3021:
3022: (define_expand "call_value"
3023: [(parallel [(set (match_operand 0 "" "")
3024: (call (match_operand:SI 1 "" "")
3025: (match_operand 2 "" "")))
3026: (clobber (reg:SI 2))])]
3027: ;;- Don't use operand 1 for most machines.
3028: ""
3029: "
3030: {
3031: rtx op;
3032:
3033: #ifndef NeXT_ASM
3034: if (flag_pic)
3035: emit_insn (gen_rtx (USE, VOIDmode,
3036: gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
3037: #endif
3038:
3039: if (TARGET_LONG_CALLS)
3040: op = force_reg (SImode, XEXP (operands[1], 0));
3041: else
3042: op = XEXP (operands[1], 0);
3043:
3044: /* Use two different patterns for calls to explicitly named functions
3045: and calls through function pointers. This is necessary as these two
3046: types of calls use different calling conventions, and CSE might try
3047: to change the named call into an indirect call in some cases (using
3048: two patterns keeps CSE from performing this optimization). */
3049: if (GET_CODE (op) == SYMBOL_REF)
3050: emit_call_insn (gen_call_value_internal_symref (operands[0], op,
3051: operands[2]));
3052: else
3053: emit_call_insn (gen_call_value_internal_reg (operands[0], op, operands[2]));
3054:
3055: #ifndef NeXT_ASM
3056: if (flag_pic)
3057: {
3058: if (!hppa_save_pic_table_rtx)
3059: hppa_save_pic_table_rtx = gen_reg_rtx (Pmode);
3060: emit_insn (gen_rtx (SET, VOIDmode,
3061: gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM),
3062: hppa_save_pic_table_rtx));
3063: }
3064: #endif
3065: DONE;
3066: }")
3067:
3068: (define_insn "call_value_internal_symref"
3069: [(set (match_operand 0 "" "=rfx")
3070: (call (mem:SI (match_operand:SI 1 "call_operand_address" ""))
3071: (match_operand 2 "" "i")))
3072: (clobber (reg:SI 2))
3073: (use (const_int 0))]
3074: ;;- Don't use operand 1 for most machines.
3075: "! TARGET_LONG_CALLS"
3076: "*
3077: {
3078: output_arg_descriptor (insn);
3079: return output_call (insn, operands[1], gen_rtx (REG, SImode, 2));
3080: }"
3081: [(set_attr "type" "call")
3082: (set_attr "length" "4")])
3083:
3084: (define_insn "call_value_internal_reg"
3085: [(set (match_operand 0 "" "=rfx")
3086: (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
3087: (match_operand 2 "" "i")))
3088: (clobber (reg:SI 2))
3089: (use (const_int 1))]
3090: ;;- Don't use operand 1 for most machines.
3091: ""
3092: "*
3093: {
3094: #ifdef NeXT_ASM
3095: return \"copy %r1,%%r22\;blr %%r0, %%r2\;bv,n 0\(%%r22\)\";
3096: #else
3097: return \"copy %r1,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\";
3098: #endif
3099: }"
3100: [(set_attr "type" "dyncall")
3101: (set_attr "length" "12")])
3102:
3103: ;; Call subroutine returning any type.
3104:
3105: (define_expand "untyped_call"
3106: [(parallel [(call (match_operand 0 "" "")
3107: (const_int 0))
3108: (match_operand 1 "" "")
3109: (match_operand 2 "" "")])]
3110: ""
3111: "
3112: {
3113: int i;
3114:
3115: emit_call_insn (gen_call (operands[0], const0_rtx));
3116:
3117: for (i = 0; i < XVECLEN (operands[2], 0); i++)
3118: {
3119: rtx set = XVECEXP (operands[2], 0, i);
3120: emit_move_insn (SET_DEST (set), SET_SRC (set));
3121: }
3122:
3123: /* The optimizer does not know that the call sets the function value
3124: registers we stored in the result block. We avoid problems by
3125: claiming that all hard registers are used and clobbered at this
3126: point. */
3127: emit_insn (gen_blockage ());
3128:
3129: DONE;
3130: }")
3131: (define_insn "nop"
3132: [(const_int 0)]
3133: ""
3134: "nop")
3135:
3136: ;;; Hope this is only within a function...
3137: (define_insn "indirect_jump"
3138: [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
3139: ""
3140: "bv%* 0(%0)"
3141: [(set_attr "type" "branch")])
3142:
3143: (define_insn "extzv"
3144: [(set (match_operand:SI 0 "register_operand" "=r")
3145: (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3146: (match_operand:SI 2 "uint5_operand" "")
3147: (match_operand:SI 3 "uint5_operand" "")))]
3148: ""
3149: "extru %1,%3+%2-1,%2,%0")
3150:
3151: (define_insn "extv"
3152: [(set (match_operand:SI 0 "register_operand" "=r")
3153: (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3154: (match_operand:SI 2 "uint5_operand" "")
3155: (match_operand:SI 3 "uint5_operand" "")))]
3156: ""
3157: "extrs %1,%3+%2-1,%2,%0")
3158:
3159: (define_insn "insv"
3160: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
3161: (match_operand:SI 1 "uint5_operand" "")
3162: (match_operand:SI 2 "uint5_operand" ""))
3163: (match_operand:SI 3 "arith5_operand" "r,L"))]
3164: ""
3165: "@
3166: dep %3,%2+%1-1,%1,%0
3167: depi %3,%2+%1-1,%1,%0")
3168:
3169: ;; Optimize insertion of const_int values of type 1...1xxxx.
3170: (define_insn ""
3171: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3172: (match_operand:SI 1 "uint5_operand" "")
3173: (match_operand:SI 2 "uint5_operand" ""))
3174: (match_operand:SI 3 "const_int_operand" ""))]
3175: "(INTVAL (operands[3]) & 0x10) != 0 &&
3176: (~INTVAL (operands[3]) & (1L << INTVAL (operands[1])) - 1 & ~0xf) == 0"
3177: "*
3178: {
3179: operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
3180: return \"depi %3,%2+%1-1,%1,%0\";
3181: }")
3182:
3183: ;; This insn is used for some loop tests, typically loops reversed when
3184: ;; strength reduction is used. It is actually created when the instruction
3185: ;; combination phase combines the special loop test. Since this insn
3186: ;; is both a jump insn and has an output, it must deal with it's own
3187: ;; reloads, hence the `m' constraints. The `!' constraints direct reload
3188: ;; to not choose the register alternatives in the event a reload is needed.
3189: (define_insn "decrement_and_branch_until_zero"
3190: [(set (pc)
3191: (if_then_else
3192: (match_operator 2 "comparison_operator"
3193: [(plus:SI (match_operand:SI 0 "register_operand" "+!r,!*f*x,!*m")
3194: (match_operand:SI 1 "int5_operand" "L,L,L"))
3195: (const_int 0)])
3196: (label_ref (match_operand 3 "" ""))
3197: (pc)))
3198: (set (match_dup 0)
3199: (plus:SI (match_dup 0) (match_dup 1)))
3200: (clobber (match_scratch:SI 4 "=X,r,r"))]
3201: ""
3202: "* return output_dbra (operands, insn, which_alternative); "
3203: ;; Do not expect to understand this the first time through.
3204: [(set_attr "type" "cbranch,multi,multi")
3205: (set (attr "length")
3206: (if_then_else (eq_attr "alternative" "0")
3207: ;; Loop counter in register case
3208: ;; Short branch has length of 4
3209: ;; Long branch has length of 8
3210: (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
3211: (const_int 8188))
3212: (const_int 4)
3213: (const_int 8))
3214:
3215: ;; Loop counter in FP reg case.
3216: ;; Extra goo to deal with additional reload insns.
3217: (if_then_else (eq_attr "alternative" "1")
3218: (if_then_else (lt (match_dup 3) (pc))
3219: (if_then_else
3220: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
3221: (const_int 8188))
3222: (const_int 24)
3223: (const_int 28))
3224: (if_then_else
3225: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
3226: (const_int 8188))
3227: (const_int 24)
3228: (const_int 28)))
3229: ;; Loop counter in memory case.
3230: ;; Extra goo to deal with additional reload insns.
3231: (if_then_else (lt (match_dup 3) (pc))
3232: (if_then_else
3233: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
3234: (const_int 8188))
3235: (const_int 12)
3236: (const_int 16))
3237: (if_then_else
3238: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
3239: (const_int 8188))
3240: (const_int 12)
3241: (const_int 16))))))])
3242:
3243: ;; Simply another variant of the dbra pattern. More restrictive
3244: ;; in testing the comparison operator as it must worry about overflow
3245: ;; problems.
3246: (define_insn ""
3247: [(set (pc)
3248: (if_then_else
3249: (match_operator 2 "eq_neq_comparison_operator"
3250: [(match_operand:SI 0 "register_operand" "+!r,!*f*x,!*m")
3251: (match_operand:SI 5 "const_int_operand" "")])
3252: (label_ref (match_operand 3 "" ""))
3253: (pc)))
3254: (set (match_dup 0)
3255: (plus:SI (match_dup 0) (match_operand:SI 1 "int5_operand" "L,L,L")))
3256: (clobber (match_scratch:SI 4 "=X,r,r"))]
3257: "INTVAL (operands[5]) == - INTVAL (operands[1])"
3258: "* return output_dbra (operands, insn, which_alternative);"
3259: ;; Do not expect to understand this the first time through.
3260: [(set_attr "type" "cbranch,multi,multi")
3261: (set (attr "length")
3262: (if_then_else (eq_attr "alternative" "0")
3263: ;; Loop counter in register case
3264: ;; Short branch has length of 4
3265: ;; Long branch has length of 8
3266: (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
3267: (const_int 8188))
3268: (const_int 4)
3269: (const_int 8))
3270:
3271: ;; Loop counter in FP reg case.
3272: ;; Extra goo to deal with additional reload insns.
3273: (if_then_else (eq_attr "alternative" "1")
3274: (if_then_else (lt (match_dup 3) (pc))
3275: (if_then_else
3276: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
3277: (const_int 8188))
3278: (const_int 24)
3279: (const_int 28))
3280: (if_then_else
3281: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
3282: (const_int 8188))
3283: (const_int 24)
3284: (const_int 28)))
3285: ;; Loop counter in memory case.
3286: ;; Extra goo to deal with additional reload insns.
3287: (if_then_else (lt (match_dup 3) (pc))
3288: (if_then_else
3289: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
3290: (const_int 8188))
3291: (const_int 12)
3292: (const_int 16))
3293: (if_then_else
3294: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
3295: (const_int 8188))
3296: (const_int 12)
3297: (const_int 16))))))])
3298:
3299: (define_insn ""
3300: [(set (pc)
3301: (if_then_else
3302: (match_operator 2 "movb_comparison_operator"
3303: [(match_operand:SI 1 "register_operand" "r,r,r") (const_int 0)])
3304: (label_ref (match_operand 3 "" ""))
3305: (pc)))
3306: (set (match_operand:SI 0 "register_operand" "=!r,!*f*x,!*m")
3307: (match_dup 1))]
3308: ""
3309: "* return output_movb (operands, insn, which_alternative, 0); "
3310: ;; Do not expect to understand this the first time through.
3311: [(set_attr "type" "cbranch,multi,multi")
3312: (set (attr "length")
3313: (if_then_else (eq_attr "alternative" "0")
3314: ;; Loop counter in register case
3315: ;; Short branch has length of 4
3316: ;; Long branch has length of 8
3317: (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
3318: (const_int 8188))
3319: (const_int 4)
3320: (const_int 8))
3321:
3322: ;; Loop counter in FP reg case.
3323: ;; Extra goo to deal with additional reload insns.
3324: (if_then_else (eq_attr "alternative" "1")
3325: (if_then_else (lt (match_dup 3) (pc))
3326: (if_then_else
3327: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
3328: (const_int 8188))
3329: (const_int 12)
3330: (const_int 16))
3331: (if_then_else
3332: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
3333: (const_int 8188))
3334: (const_int 12)
3335: (const_int 16)))
3336: ;; Loop counter in memory case.
3337: ;; Extra goo to deal with additional reload insns.
3338: (if_then_else
3339: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
3340: (const_int 8188))
3341: (const_int 8)
3342: (const_int 12)))))])
3343:
3344: ;; Handle negated branch.
3345: (define_insn ""
3346: [(set (pc)
3347: (if_then_else
3348: (match_operator 2 "movb_comparison_operator"
3349: [(match_operand:SI 1 "register_operand" "r,r,r") (const_int 0)])
3350: (pc)
3351: (label_ref (match_operand 3 "" ""))))
3352: (set (match_operand:SI 0 "register_operand" "=!r,!*f*x,!*m")
3353: (match_dup 1))]
3354: ""
3355: "* return output_movb (operands, insn, which_alternative, 1); "
3356: ;; Do not expect to understand this the first time through.
3357: [(set_attr "type" "cbranch,multi,multi")
3358: (set (attr "length")
3359: (if_then_else (eq_attr "alternative" "0")
3360: ;; Loop counter in register case
3361: ;; Short branch has length of 4
3362: ;; Long branch has length of 8
3363: (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
3364: (const_int 8188))
3365: (const_int 4)
3366: (const_int 8))
3367:
3368: ;; Loop counter in FP reg case.
3369: ;; Extra goo to deal with additional reload insns.
3370: (if_then_else (eq_attr "alternative" "1")
3371: (if_then_else (lt (match_dup 3) (pc))
3372: (if_then_else
3373: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
3374: (const_int 8188))
3375: (const_int 12)
3376: (const_int 16))
3377: (if_then_else
3378: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
3379: (const_int 8188))
3380: (const_int 12)
3381: (const_int 16)))
3382: ;; Loop counter in memory case.
3383: ;; Extra goo to deal with additional reload insns.
3384: (if_then_else
3385: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
3386: (const_int 8188))
3387: (const_int 8)
3388: (const_int 12)))))])
3389:
3390: ;; The next four peepholes take advantage of the new 5 operand
3391: ;; fmpy{add,sub} instructions available on 1.1 CPUS. Basically
3392: ;; fmpyadd performs a multiply and add/sub of independent operands
3393: ;; at the same time. Because the operands must be independent
3394: ;; combine will not try to combine such insns... Thus we have
3395: ;; to use a peephole.
3396: (define_peephole
3397: [(set (match_operand 0 "register_operand" "=fx")
3398: (mult (match_operand 1 "register_operand" "fx")
3399: (match_operand 2 "register_operand" "fx")))
3400: (set (match_operand 3 "register_operand" "+fx")
3401: (plus (match_operand 4 "register_operand" "fx")
3402: (match_operand 5 "register_operand" "fx")))]
3403: "TARGET_SNAKE && fmpyaddoperands (operands)"
3404: "*
3405: {
3406: if (GET_MODE (operands[0]) == DFmode)
3407: {
3408: if (rtx_equal_p (operands[5], operands[3]))
3409: return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
3410: else
3411: return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
3412: }
3413: else
3414: {
3415: if (rtx_equal_p (operands[5], operands[3]))
3416: return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
3417: else
3418: return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
3419: }
3420: }")
3421:
3422: (define_peephole
3423: [(set (match_operand 3 "register_operand" "+fx")
3424: (plus (match_operand 4 "register_operand" "fx")
3425: (match_operand 5 "register_operand" "fx")))
3426: (set (match_operand 0 "register_operand" "=fx")
3427: (mult (match_operand 1 "register_operand" "fx")
3428: (match_operand 2 "register_operand" "fx")))]
3429: "TARGET_SNAKE && fmpyaddoperands (operands)"
3430: "*
3431: {
3432: if (GET_MODE (operands[0]) == DFmode)
3433: {
3434: if (rtx_equal_p (operands[3], operands[5]))
3435: return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
3436: else
3437: return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
3438: }
3439: else
3440: {
3441: if (rtx_equal_p (operands[3], operands[5]))
3442: return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
3443: else
3444: return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
3445: }
3446: }")
3447:
3448: ;; Note fsub subtracts the second operand from the first while fmpysub
3449: ;; does the opposite for the subtraction operands!
3450: (define_peephole
3451: [(set (match_operand 0 "register_operand" "=fx")
3452: (mult (match_operand 1 "register_operand" "fx")
3453: (match_operand 2 "register_operand" "fx")))
3454: (set (match_operand 3 "register_operand" "+fx")
3455: (minus (match_operand 4 "register_operand" "fx")
3456: (match_operand 5 "register_operand" "fx")))]
3457: "TARGET_SNAKE && fmpysuboperands (operands)"
3458: "*
3459: {
3460: if (GET_MODE (operands[0]) == DFmode)
3461: return \"fmpysub,dbl %1,%2,%0,%5,%3\";
3462: else
3463: return \"fmpysub,sgl %1,%2,%0,%5,%3\";
3464: }")
3465:
3466: (define_peephole
3467: [(set (match_operand 3 "register_operand" "+fx")
3468: (minus (match_operand 4 "register_operand" "fx")
3469: (match_operand 5 "register_operand" "fx")))
3470: (set (match_operand 0 "register_operand" "=fx")
3471: (mult (match_operand 1 "register_operand" "fx")
3472: (match_operand 2 "register_operand" "fx")))]
3473: "TARGET_SNAKE && fmpysuboperands (operands)"
3474: "*
3475: {
3476: if (GET_MODE (operands[0]) == DFmode)
3477: return \"fmpysub,dbl %1,%2,%0,%5,%3\";
3478: else
3479: return \"fmpysub,sgl %1,%2,%0,%5,%3\";
3480: }")
3481:
3482: ;; These are NeXT PIC code generation
3483: (define_peephole
3484: [(set (match_operand:SI 0 "register_operand" "=r")
3485: (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
3486: (match_operand:SI 2 "immediate_operand" "i")))
3487: (set (match_operand:SI 3 "register_operand" "=r")
3488: (mem:SI (plus:SI (match_dup 0) (match_operand:SI 4 "const_int_operand" ""))))]
3489: "flag_pic == 2 && (operands[0] == operands[3])"
3490: "ldw R%'%2+%4(%1),%3")
3491:
3492: ;; Flush the I and D cache line found at the address in operand 0.
3493: ;; This is used by the trampoline code for nested functions.
3494: ;; So long as the trampoline itself is less than 32 bytes this
3495: ;; is sufficient.
3496:
3497: (define_insn "dcacheflush"
3498: [(unspec_volatile [(const_int 1)] 0)
3499: (use (mem:SI (match_operand:SI 0 "register_operand" "r")))
3500: (use (mem:SI (match_operand:SI 1 "register_operand" "r")))]
3501: ""
3502: "fdc 0(0,%0)\;fdc 0(0,%1)\;sync"
3503: [(set_attr "length" "12")])
3504:
3505: (define_insn "icacheflush"
3506: [(unspec_volatile [(const_int 2)] 0)
3507: (use (mem:SI (match_operand:SI 0 "register_operand" "r")))
3508: (use (mem:SI (match_operand:SI 1 "register_operand" "r")))
3509: (use (match_operand:SI 2 "register_operand" "r"))
3510: (clobber (match_operand:SI 3 "register_operand" "=&r"))
3511: (clobber (match_operand:SI 4 "register_operand" "=&r"))]
3512: ""
3513: "mfsp %%sr0,%4\;ldsid (0,%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
3514: [(set_attr "length" "52")])
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.