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