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