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