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