1750a.md, [...]: Use GEN_INT consistently.
[gcc.git] / gcc / config / spur / spur.md
1 ;;- Machine description for SPUR chip for GNU C compiler
2 ;; Copyright (C) 1988 Free Software Foundation, Inc.
3
4 ;; This file is part of GNU CC.
5
6 ;; GNU CC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 2, or (at your option)
9 ;; any later version.
10
11 ;; GNU CC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;; GNU General Public License for more details.
15
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GNU CC; see the file COPYING. If not, write to
18 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
19 ;; Boston, MA 02111-1307, USA.
20
21
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23
24 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
25 ;;- updates for most instructions.
26
27 ;;- Operand classes for the register allocator:
28 \f
29 ;; Compare instructions.
30 ;; This pattern is used for generating an "insn"
31 ;; which does just a compare and sets a (fictitious) condition code.
32
33 ;; The actual SPUR insns are compare-and-conditional-jump.
34 ;; The define_peephole's below recognize the combinations of
35 ;; compares and jumps, and output each pair as a single assembler insn.
36
37 ;; This controls RTL generation and register allocation.
38 (define_insn "cmpsi"
39 [(set (cc0)
40 (compare (match_operand:SI 0 "register_operand" "rK")
41 (match_operand:SI 1 "nonmemory_operand" "rK")))]
42 ""
43 "*
44 {
45 cc_status.value1 = operands[0], cc_status.value2 = operands[1];
46 return \"\";
47 }")
48
49 ;; We have to have this because cse can optimize the previous pattern
50 ;; into this one.
51
52 (define_insn "tstsi"
53 [(set (cc0)
54 (match_operand:SI 0 "register_operand" "r"))]
55 ""
56 "*
57 {
58 cc_status.value1 = operands[0], cc_status.value2 = const0_rtx;
59 return \"\";
60 }")
61
62
63 ;; These control RTL generation for conditional jump insns
64 ;; and match them for register allocation.
65
66 (define_insn "beq"
67 [(set (pc)
68 (if_then_else (eq (cc0)
69 (const_int 0))
70 (label_ref (match_operand 0 "" ""))
71 (pc)))]
72 ""
73 "* return output_compare (operands, \"eq\", \"eq\", \"ne\", \"ne\"); ")
74
75 (define_insn "bne"
76 [(set (pc)
77 (if_then_else (ne (cc0)
78 (const_int 0))
79 (label_ref (match_operand 0 "" ""))
80 (pc)))]
81 ""
82 "* return output_compare (operands, \"ne\", \"ne\", \"eq\", \"eq\"); ")
83
84 (define_insn "bgt"
85 [(set (pc)
86 (if_then_else (gt (cc0)
87 (const_int 0))
88 (label_ref (match_operand 0 "" ""))
89 (pc)))]
90 ""
91 "* return output_compare (operands, \"gt\", \"lt\", \"le\", \"ge\"); ")
92
93 (define_insn "bgtu"
94 [(set (pc)
95 (if_then_else (gtu (cc0)
96 (const_int 0))
97 (label_ref (match_operand 0 "" ""))
98 (pc)))]
99 ""
100 "* return output_compare (operands, \"ugt\", \"ult\", \"ule\", \"uge\"); ")
101
102 (define_insn "blt"
103 [(set (pc)
104 (if_then_else (lt (cc0)
105 (const_int 0))
106 (label_ref (match_operand 0 "" ""))
107 (pc)))]
108 ""
109 "* return output_compare (operands, \"lt\", \"gt\", \"ge\", \"le\"); ")
110
111 (define_insn "bltu"
112 [(set (pc)
113 (if_then_else (ltu (cc0)
114 (const_int 0))
115 (label_ref (match_operand 0 "" ""))
116 (pc)))]
117 ""
118 "* return output_compare (operands, \"ult\", \"ugt\", \"uge\", \"ule\"); ")
119
120 (define_insn "bge"
121 [(set (pc)
122 (if_then_else (ge (cc0)
123 (const_int 0))
124 (label_ref (match_operand 0 "" ""))
125 (pc)))]
126 ""
127 "* return output_compare (operands, \"ge\", \"le\", \"lt\", \"gt\"); ")
128
129 (define_insn "bgeu"
130 [(set (pc)
131 (if_then_else (geu (cc0)
132 (const_int 0))
133 (label_ref (match_operand 0 "" ""))
134 (pc)))]
135 ""
136 "* return output_compare (operands, \"uge\", \"ule\", \"ult\", \"ugt\"); ")
137
138 (define_insn "ble"
139 [(set (pc)
140 (if_then_else (le (cc0)
141 (const_int 0))
142 (label_ref (match_operand 0 "" ""))
143 (pc)))]
144 ""
145 "* return output_compare (operands, \"le\", \"ge\", \"gt\", \"lt\"); ")
146
147 (define_insn "bleu"
148 [(set (pc)
149 (if_then_else (leu (cc0)
150 (const_int 0))
151 (label_ref (match_operand 0 "" ""))
152 (pc)))]
153 ""
154 "* return output_compare (operands, \"ule\", \"uge\", \"ugt\", \"ult\"); ")
155 \f
156 ;; These match inverted jump insns for register allocation.
157
158 (define_insn ""
159 [(set (pc)
160 (if_then_else (eq (cc0)
161 (const_int 0))
162 (pc)
163 (label_ref (match_operand 0 "" ""))))]
164 ""
165 "* return output_compare (operands, \"ne\", \"ne\", \"eq\", \"eq\"); ")
166
167 (define_insn ""
168 [(set (pc)
169 (if_then_else (ne (cc0)
170 (const_int 0))
171 (pc)
172 (label_ref (match_operand 0 "" ""))))]
173 ""
174 "* return output_compare (operands, \"eq\", \"eq\", \"ne\", \"ne\"); ")
175
176 (define_insn ""
177 [(set (pc)
178 (if_then_else (gt (cc0)
179 (const_int 0))
180 (pc)
181 (label_ref (match_operand 0 "" ""))))]
182 ""
183 "* return output_compare (operands, \"le\", \"ge\", \"gt\", \"lt\"); ")
184
185 (define_insn ""
186 [(set (pc)
187 (if_then_else (gtu (cc0)
188 (const_int 0))
189 (pc)
190 (label_ref (match_operand 0 "" ""))))]
191 ""
192 "* return output_compare (operands, \"ule\", \"uge\", \"ugt\", \"ult\"); ")
193
194 (define_insn ""
195 [(set (pc)
196 (if_then_else (lt (cc0)
197 (const_int 0))
198 (pc)
199 (label_ref (match_operand 0 "" ""))))]
200 ""
201 "* return output_compare (operands, \"ge\", \"le\", \"lt\", \"gt\"); ")
202
203 (define_insn ""
204 [(set (pc)
205 (if_then_else (ltu (cc0)
206 (const_int 0))
207 (pc)
208 (label_ref (match_operand 0 "" ""))))]
209 ""
210 "* return output_compare (operands, \"uge\", \"ule\", \"ult\", \"ugt\"); ")
211
212 (define_insn ""
213 [(set (pc)
214 (if_then_else (ge (cc0)
215 (const_int 0))
216 (pc)
217 (label_ref (match_operand 0 "" ""))))]
218 ""
219 "* return output_compare (operands, \"lt\", \"gt\", \"ge\", \"le\"); ")
220
221 (define_insn ""
222 [(set (pc)
223 (if_then_else (geu (cc0)
224 (const_int 0))
225 (pc)
226 (label_ref (match_operand 0 "" ""))))]
227 ""
228 "* return output_compare (operands, \"ult\", \"ugt\", \"uge\", \"ule\"); ")
229
230 (define_insn ""
231 [(set (pc)
232 (if_then_else (le (cc0)
233 (const_int 0))
234 (pc)
235 (label_ref (match_operand 0 "" ""))))]
236 ""
237 "* return output_compare (operands, \"gt\", \"lt\", \"le\", \"ge\"); ")
238
239 (define_insn ""
240 [(set (pc)
241 (if_then_else (leu (cc0)
242 (const_int 0))
243 (pc)
244 (label_ref (match_operand 0 "" ""))))]
245 ""
246 "* return output_compare (operands, \"ugt\", \"ult\", \"ule\", \"uge\"); ")
247 \f
248 ;; Move instructions
249
250 (define_insn "movsi"
251 [(set (match_operand:SI 0 "general_operand" "=r,m")
252 (match_operand:SI 1 "general_operand" "rmi,rJ"))]
253 ""
254 "*
255 {
256 if (GET_CODE (operands[0]) == MEM)
257 return \"st_32 %r1,%0\";
258 if (GET_CODE (operands[1]) == MEM)
259 return \"ld_32 %0,%1\;nop\";
260 if (GET_CODE (operands[1]) == REG)
261 return \"add_nt %0,%1,$0\";
262 if (GET_CODE (operands[1]) == SYMBOL_REF && operands[1]->unchanging)
263 return \"add_nt %0,r24,$(%1-0b)\";
264 return \"add_nt %0,r0,%1\";
265 }")
266
267 (define_insn ""
268 [(set (match_operand:SI 0 "register_operand" "=r")
269 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
270 (match_operand:SI 2 "register_operand" "r"))))]
271 ""
272 "ld_32 %0,%1,%2\;nop")
273 \f
274 ;; Generate insns for moving single bytes.
275
276 (define_expand "movqi"
277 [(set (match_operand:QI 0 "general_operand" "")
278 (match_operand:QI 1 "general_operand" ""))]
279 ""
280 "
281 {
282 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
283 operands[1] = copy_to_reg (operands[1]);
284
285 if (GET_CODE (operands[1]) == MEM)
286 {
287 rtx tem = gen_reg_rtx (SImode);
288 rtx addr = force_reg (SImode, XEXP (operands[1], 0));
289 rtx subreg;
290
291 emit_move_insn (tem, gen_rtx (MEM, SImode, addr));
292 if (GET_CODE (operands[0]) == SUBREG)
293 subreg = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[0]),
294 SUBREG_WORD (operands[0]));
295 else
296 subreg = gen_rtx (SUBREG, SImode, operands[0], 0);
297
298 emit_insn (gen_rtx (SET, VOIDmode, subreg,
299 gen_rtx (ZERO_EXTRACT, SImode, tem,
300 GEN_INT (8),
301 addr)));
302 }
303 else if (GET_CODE (operands[0]) == MEM)
304 {
305 rtx tem = gen_reg_rtx (SImode);
306 rtx addr = force_reg (SImode, XEXP (operands[0], 0));
307 rtx subreg;
308
309 emit_move_insn (tem, gen_rtx (MEM, SImode, addr));
310 if (! CONSTANT_ADDRESS_P (operands[1]))
311 {
312 if (GET_CODE (operands[1]) == SUBREG)
313 subreg = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
314 SUBREG_WORD (operands[1]));
315 else
316 subreg = gen_rtx (SUBREG, SImode, operands[1], 0);
317 }
318
319 emit_insn (gen_rtx (SET, VOIDmode,
320 gen_rtx (ZERO_EXTRACT, SImode, tem,
321 GEN_INT (8),
322 addr),
323 subreg));
324 emit_move_insn (gen_rtx (MEM, SImode, addr), tem);
325 }
326 else
327 {
328 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
329 }
330 DONE;
331 }")
332 \f
333 ;; Recognize insns generated for moving single bytes.
334
335 (define_insn ""
336 [(set (match_operand:QI 0 "general_operand" "=r,m")
337 (match_operand:QI 1 "general_operand" "rmi,r"))]
338 ""
339 "*
340 {
341 if (GET_CODE (operands[0]) == MEM)
342 return \"st_32 %1,%0\";
343 if (GET_CODE (operands[1]) == MEM)
344 return \"ld_32 %0,%1\;nop\";
345 if (GET_CODE (operands[1]) == REG)
346 return \"add_nt %0,%1,$0\";
347 return \"add_nt %0,r0,%1\";
348 }")
349
350 (define_insn ""
351 [(set (match_operand:SI 0 "register_operand" "=r")
352 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
353 (const_int 8)
354 (match_operand:SI 2 "nonmemory_operand" "rI")))]
355 ""
356 "extract %0,%1,%2")
357
358 (define_insn ""
359 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
360 (const_int 8)
361 (match_operand:SI 1 "nonmemory_operand" "rI"))
362 (match_operand:SI 2 "nonmemory_operand" "ri"))]
363 ""
364 "wr_insert %1\;insert %0,%0,%2")
365
366 ;; Constant propagation can optimize the previous pattern into this pattern.
367 ;[Not any more. It could when the position-operand contains a MULT.]
368
369 ;(define_insn ""
370 ; [(set (zero_extract:QI (match_operand:SI 0 "register_operand" "+r")
371 ; (const_int 8)
372 ; (match_operand:SI 1 "immediate_operand" "I"))
373 ; (match_operand:QI 2 "register_operand" "r"))]
374 ; "GET_CODE (operands[1]) == CONST_INT
375 ; && INTVAL (operands[1]) % 8 == 0
376 ; && (unsigned) INTVAL (operands[1]) < 32"
377 ; "*
378 ;{
379 ; operands[1] = GEN_INT (INTVAL (operands[1]) / 8);
380 ; return \"wr_insert 0,0,%1\;insert %0,%0,%2\";
381 ;}")
382 \f
383 ;; The three define_expand patterns on this page
384 ;; serve as subroutines of "movhi".
385
386 ;; Generate code to fetch an aligned halfword from memory.
387 ;; Operand 0 is the destination register (HImode).
388 ;; Operand 1 is the memory address (SImode).
389 ;; Operand 2 is a temporary (SImode).
390 ;; Operand 3 is a temporary (SImode).
391 ;; Operand 4 is a temporary (QImode).
392
393 ;; Operand 5 is an internal temporary (HImode).
394
395 (define_expand "loadhi"
396 [(set (match_operand:SI 2 "register_operand" "")
397 (mem:SI (match_operand:SI 1 "register_operand" "")))
398 ;; Extract the low byte.
399 (set (subreg:SI (match_dup 5) 0)
400 (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 1)))
401 ;; Form address of high byte.
402 (set (match_operand:SI 3 "register_operand" "")
403 (plus:SI (match_dup 1) (const_int 1)))
404 ;; Extract the high byte.
405 (set (subreg:SI (match_operand:QI 4 "register_operand" "") 0)
406 (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3)))
407 ;; Put the high byte in with the low one.
408 (set (zero_extract:SI (match_dup 5) (const_int 8) (const_int 1))
409 (subreg:SI (match_dup 4) 0))
410 (set (match_operand:HI 0 "register_operand" "") (match_dup 5))]
411 ""
412 "operands[5] = gen_reg_rtx (HImode);")
413
414 ;; Generate code to store an aligned halfword into memory.
415 ;; Operand 0 is the destination address (SImode).
416 ;; Operand 1 is the source register (HImode, not constant).
417 ;; Operand 2 is a temporary (SImode).
418 ;; Operand 3 is a temporary (SImode).
419 ;; Operand 4 is a temporary (QImode).
420
421 ;; Operand 5 is an internal variable made from operand 1.
422
423 (define_expand "storehi"
424 [(set (match_operand:SI 2 "register_operand" "")
425 (mem:SI (match_operand:SI 0 "register_operand" "")))
426 ;; Insert the low byte.
427 (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 0))
428 (match_dup 5))
429 ;; Form address of high byte.
430 (set (match_operand:SI 3 "register_operand" "")
431 (plus:SI (match_dup 0) (const_int 1)))
432 ;; Extract the high byte from the source.
433 (set (subreg:SI (match_operand:QI 4 "register_operand" "") 0)
434 (zero_extract:SI (match_operand:HI 1 "register_operand" "")
435 (const_int 8) (const_int 1)))
436 ;; Store high byte into the memory word
437 (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3))
438 (subreg:SI (match_dup 4) 0))
439 ;; Put memory word back into memory.
440 (set (mem:SI (match_dup 0))
441 (match_dup 2))]
442 ""
443 "
444 {
445 if (GET_CODE (operands[1]) == SUBREG)
446 operands[5] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
447 SUBREG_WORD (operands[1]));
448 else
449 operands[5] = gen_rtx (SUBREG, SImode, operands[1], 0);
450 }")
451
452 ;; Like storehi but operands[1] is a CONST_INT.
453
454 (define_expand "storeinthi"
455 [(set (match_operand:SI 2 "register_operand" "")
456 (mem:SI (match_operand:SI 0 "register_operand" "")))
457 ;; Insert the low byte.
458 (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 0))
459 (match_dup 5))
460 ;; Form address of high byte.
461 (set (match_operand:SI 3 "register_operand" "")
462 (plus:SI (match_dup 0) (const_int 1)))
463 ;; Store high byte into the memory word
464 (set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3))
465 (match_dup 6))
466 ;; Put memory word back into memory.
467 (set (mem:SI (match_dup 0))
468 (match_dup 2))]
469 ""
470 " operands[5] = GEN_INT (INTVAL (operands[1]) & 255);
471 operands[6] = GEN_INT ((INTVAL (operands[1]) >> 8) & 255);
472 ")
473 \f
474 ;; Main entry for generating insns to move halfwords.
475
476 (define_expand "movhi"
477 [(set (match_operand:HI 0 "general_operand" "")
478 (match_operand:HI 1 "general_operand" ""))]
479 ""
480 "
481 {
482 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
483 operands[1] = copy_to_reg (operands[1]);
484
485 if (GET_CODE (operands[1]) == MEM)
486 {
487 rtx insn =
488 emit_insn (gen_loadhi (operands[0],
489 force_reg (SImode, XEXP (operands[1], 0)),
490 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
491 gen_reg_rtx (QImode)));
492 /* Tell cse what value the loadhi produces, so it detect duplicates. */
493 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, operands[1],
494 REG_NOTES (insn));
495 }
496 else if (GET_CODE (operands[0]) == MEM)
497 {
498 if (GET_CODE (operands[1]) == CONST_INT)
499 emit_insn (gen_storeinthi (force_reg (SImode, XEXP (operands[0], 0)),
500 operands[1],
501 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
502 gen_reg_rtx (QImode)));
503 else
504 {
505 if (CONSTANT_P (operands[1]))
506 operands[1] = force_reg (HImode, operands[1]);
507 emit_insn (gen_storehi (force_reg (SImode, XEXP (operands[0], 0)),
508 operands[1],
509 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
510 gen_reg_rtx (QImode)));
511 }
512 }
513 else
514 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
515 DONE;
516 }")
517 \f
518 ;; Recognize insns generated for moving halfwords.
519 ;; (Note that the extract and insert patterns for single-byte moves
520 ;; are also involved in recognizing some of the insns used for this purpose.)
521
522 (define_insn ""
523 [(set (match_operand:HI 0 "general_operand" "=r,m")
524 (match_operand:HI 1 "general_operand" "rmi,r"))]
525 ""
526 "*
527 {
528 if (GET_CODE (operands[0]) == MEM)
529 return \"st_32 %1,%0\";
530 if (GET_CODE (operands[1]) == MEM)
531 return \"ld_32 %0,%1\;nop\";
532 if (GET_CODE (operands[1]) == REG)
533 return \"add_nt %0,%1,$0\";
534 return \"add_nt %0,r0,%1\";
535 }")
536
537 (define_insn ""
538 [(set (match_operand:SI 0 "register_operand" "=r")
539 (zero_extract:SI (match_operand:HI 1 "register_operand" "r")
540 (const_int 8)
541 (match_operand:SI 2 "nonmemory_operand" "rI")))]
542 ""
543 "extract %0,%1,%2")
544
545 (define_insn ""
546 [(set (zero_extract:SI (match_operand:HI 0 "register_operand" "+r")
547 (const_int 8)
548 (match_operand:SI 1 "nonmemory_operand" "rI"))
549 (match_operand:SI 2 "nonmemory_operand" "ri"))]
550 ""
551 "wr_insert %1\;insert %0,%0,%2")
552
553 ;; Constant propagation can optimize the previous pattern into this pattern.
554
555 ;(define_insn ""
556 ; [(set (zero_extract:QI (match_operand:HI 0 "register_operand" "+r")
557 ; (const_int 8)
558 ; (match_operand:SI 1 "immediate_operand" "I"))
559 ; (match_operand:QI 2 "register_operand" "r"))]
560 ; "GET_CODE (operands[1]) == CONST_INT
561 ; && INTVAL (operands[1]) % 8 == 0
562 ; && (unsigned) INTVAL (operands[1]) < 32"
563 ; "*
564 ;{
565 ; operands[1] = GEN_INT (INTVAL (operands[1]) / 8);
566 ; return \"wr_insert 0,0,%1\;insert %0,%0,%2\";
567 ;}")
568 \f
569 ;; This pattern forces (set (reg:DF ...) (const_double ...))
570 ;; to be reloaded by putting the constant into memory.
571 ;; It must come before the more general movdf pattern.
572 (define_insn ""
573 [(set (match_operand:DF 0 "general_operand" "=&r,f,&o")
574 (match_operand:DF 1 "" "mG,m,G"))]
575 "GET_CODE (operands[1]) == CONST_DOUBLE"
576 "*
577 {
578 if (FP_REG_P (operands[0]))
579 return output_fp_move_double (operands);
580 if (operands[1] == CONST0_RTX (DFmode) && GET_CODE (operands[0]) == REG)
581 {
582 operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
583 return \"add_nt %0,r0,$0\;add_nt %1,r0,$0\";
584 }
585 if (operands[1] == CONST0_RTX (DFmode) && GET_CODE (operands[0]) == MEM)
586 {
587 operands[1] = adj_offsettable_operand (operands[0], 4);
588 return \"st_32 r0,%0\;st_32 r0,%1\";
589 }
590 return output_move_double (operands);
591 }
592 ")
593
594 (define_insn "movdf"
595 [(set (match_operand:DF 0 "general_operand" "=r,&r,m,?f,?rm")
596 (match_operand:DF 1 "general_operand" "r,m,r,rfm,f"))]
597 ""
598 "*
599 {
600 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
601 return output_fp_move_double (operands);
602 return output_move_double (operands);
603 }
604 ")
605
606 (define_insn "movdi"
607 [(set (match_operand:DI 0 "general_operand" "=r,&r,m,?f,?rm")
608 (match_operand:DI 1 "general_operand" "r,m,r,rfm,f"))]
609 ""
610 "*
611 {
612 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
613 return output_fp_move_double (operands);
614 return output_move_double (operands);
615 }
616 ")
617
618 (define_insn "movsf"
619 [(set (match_operand:SF 0 "general_operand" "=rf,m")
620 (match_operand:SF 1 "general_operand" "rfm,rf"))]
621 ""
622 "*
623 {
624 if (FP_REG_P (operands[0]))
625 {
626 if (FP_REG_P (operands[1]))
627 return \"fmov %0,%1\";
628 if (GET_CODE (operands[1]) == REG)
629 {
630 rtx xoperands[2];
631 int offset = - get_frame_size () - 8;
632 xoperands[1] = operands[1];
633 xoperands[0] = GEN_INT (offset);
634 output_asm_insn (\"st_32 %1,r25,%0\", xoperands);
635 xoperands[1] = operands[0];
636 output_asm_insn (\"ld_sgl %1,r25,%0\;nop\", xoperands);
637 return \"\";
638 }
639 return \"ld_sgl %0,%1\;nop\";
640 }
641 if (FP_REG_P (operands[1]))
642 {
643 if (GET_CODE (operands[0]) == REG)
644 {
645 rtx xoperands[2];
646 int offset = - get_frame_size () - 8;
647 xoperands[0] = GEN_INT (offset);
648 xoperands[1] = operands[1];
649 output_asm_insn (\"st_sgl %1,r25,%0\", xoperands);
650 xoperands[1] = operands[0];
651 output_asm_insn (\"ld_32 %1,r25,%0\;nop\", xoperands);
652 return \"\";
653 }
654 return \"st_sgl %1,%0\";
655 }
656 if (GET_CODE (operands[0]) == MEM)
657 return \"st_32 %r1,%0\";
658 if (GET_CODE (operands[1]) == MEM)
659 return \"ld_32 %0,%1\;nop\";
660 if (GET_CODE (operands[1]) == REG)
661 return \"add_nt %0,%1,$0\";
662 return \"add_nt %0,r0,%1\";
663 }")
664 \f
665 ;;- truncation instructions
666 (define_insn "truncsiqi2"
667 [(set (match_operand:QI 0 "register_operand" "=r")
668 (truncate:QI
669 (match_operand:SI 1 "register_operand" "r")))]
670 ""
671 "add_nt %0,%1,$0")
672
673 (define_insn "trunchiqi2"
674 [(set (match_operand:QI 0 "register_operand" "=r")
675 (truncate:QI
676 (match_operand:HI 1 "register_operand" "r")))]
677 ""
678 "add_nt %0,%1,$0")
679
680 (define_insn "truncsihi2"
681 [(set (match_operand:HI 0 "register_operand" "=r")
682 (truncate:HI
683 (match_operand:SI 1 "register_operand" "r")))]
684 ""
685 "add_nt %0,%1,$0")
686 \f
687 ;;- zero extension instructions
688
689 ;; Note that the one starting from HImode comes before those for QImode
690 ;; so that a constant operand will match HImode, not QImode.
691 (define_expand "zero_extendhisi2"
692 [(set (match_operand:SI 0 "register_operand" "")
693 (and:SI (match_operand:HI 1 "register_operand" "") ;Changed to SI below
694 ;; This constant is invalid, but reloading will handle it.
695 ;; It's useless to generate here the insns to construct it
696 ;; because constant propagation would simplify them anyway.
697 (match_dup 2)))]
698 ""
699 "
700 {
701 if (GET_CODE (operands[1]) == SUBREG)
702 operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
703 SUBREG_WORD (operands[1]));
704 else
705 operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
706
707 operands[2] = force_reg (SImode, GEN_INT (65535));
708 }")
709
710 (define_insn "zero_extendqihi2"
711 [(set (match_operand:HI 0 "register_operand" "=r")
712 (zero_extend:HI
713 (match_operand:QI 1 "register_operand" "r")))]
714 ""
715 "extract %0,%1,$0")
716
717 (define_insn "zero_extendqisi2"
718 [(set (match_operand:SI 0 "register_operand" "=r")
719 (zero_extend:SI
720 (match_operand:QI 1 "register_operand" "r")))]
721 ""
722 "extract %0,%1,$0")
723 \f
724 ;;- sign extension instructions
725 ;; Note that the one starting from HImode comes before those for QImode
726 ;; so that a constant operand will match HImode, not QImode.
727
728 (define_expand "extendhisi2"
729 [(set (match_dup 2)
730 (and:SI (match_operand:HI 1 "register_operand" "") ;Changed to SI below
731 (match_dup 4)))
732 (set (match_dup 3) (plus:SI (match_dup 2) (match_dup 5)))
733 (set (match_operand:SI 0 "register_operand" "")
734 (xor:SI (match_dup 3) (match_dup 5)))]
735 ""
736 "
737 {
738 if (GET_CODE (operands[1]) == SUBREG)
739 operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
740 SUBREG_WORD (operands[1]));
741 else
742 operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
743
744 operands[2] = gen_reg_rtx (SImode);
745 operands[3] = gen_reg_rtx (SImode);
746 operands[4] = force_reg (SImode, GEN_INT (65535));
747 operands[5] = force_reg (SImode, GEN_INT (-32768));
748 }")
749
750 (define_expand "extendqihi2"
751 [(set (match_dup 2)
752 (and:HI (match_operand:QI 1 "register_operand" "") ;Changed to SI below
753 (const_int 255)))
754 (set (match_dup 3)
755 (plus:SI (match_dup 2) (const_int -128)))
756 (set (match_operand:HI 0 "register_operand" "")
757 (xor:SI (match_dup 3) (const_int -128)))]
758 ""
759 "
760 {
761 if (GET_CODE (operands[1]) == SUBREG)
762 operands[1] = gen_rtx (SUBREG, HImode, SUBREG_REG (operands[1]),
763 SUBREG_WORD (operands[1]));
764 else
765 operands[1] = gen_rtx (SUBREG, HImode, operands[1], 0);
766
767 operands[2] = gen_reg_rtx (HImode);
768 operands[3] = gen_reg_rtx (HImode);
769 }")
770
771 (define_expand "extendqisi2"
772 [(set (match_dup 2)
773 (and:SI (match_operand:QI 1 "register_operand" "") ;Changed to SI below
774 (const_int 255)))
775 (set (match_dup 3) (plus:SI (match_dup 2) (const_int -128)))
776 (set (match_operand:SI 0 "register_operand" "")
777 (xor:SI (match_dup 3) (const_int -128)))]
778 ""
779 "
780 {
781 if (GET_CODE (operands[1]) == SUBREG)
782 operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
783 SUBREG_WORD (operands[1]));
784 else
785 operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
786
787 operands[2] = gen_reg_rtx (SImode);
788 operands[3] = gen_reg_rtx (SImode);
789 }")
790 \f
791 ;;- arithmetic instructions
792
793 (define_insn "addsi3"
794 [(set (match_operand:SI 0 "register_operand" "=r")
795 (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r")
796 (match_operand:SI 2 "nonmemory_operand" "rI")))]
797 ""
798 "add %0,%1,%2")
799
800 (define_insn ""
801 [(set (match_operand:SI 0 "register_operand" "=r")
802 (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r")
803 (match_operand:SI 2 "big_immediate_operand" "g")))]
804 "GET_CODE (operands[2]) == CONST_INT
805 && (unsigned) (INTVAL (operands[2]) + 0x8000000) < 0x10000000"
806 "*
807 {
808 return
809 output_add_large_offset (operands[0], operands[1], INTVAL (operands[2]));
810 }")
811
812 (define_insn "subsi3"
813 [(set (match_operand:SI 0 "register_operand" "=r")
814 (minus:SI (match_operand:SI 1 "register_operand" "r")
815 (match_operand:SI 2 "nonmemory_operand" "rI")))]
816 ""
817 "sub %0,%1,%2")
818
819 (define_insn "andsi3"
820 [(set (match_operand:SI 0 "register_operand" "=r")
821 (and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
822 (match_operand:SI 2 "nonmemory_operand" "rI")))]
823 ""
824 "and %0,%1,%2")
825
826 (define_insn "iorsi3"
827 [(set (match_operand:SI 0 "register_operand" "=r")
828 (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
829 (match_operand:SI 2 "nonmemory_operand" "rI")))]
830 ""
831 "or %0,%1,%2")
832
833 (define_insn "xorsi3"
834 [(set (match_operand:SI 0 "register_operand" "=r")
835 (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
836 (match_operand:SI 2 "nonmemory_operand" "rI")))]
837 ""
838 "xor %0,%1,%2")
839
840 (define_insn "negsi2"
841 [(set (match_operand:SI 0 "register_operand" "=r")
842 (neg:SI (match_operand:SI 1 "nonmemory_operand" "rI")))]
843 ""
844 "sub %0,r0,%1")
845
846 (define_insn "one_cmplsi2"
847 [(set (match_operand:SI 0 "register_operand" "=r")
848 (not:SI (match_operand:SI 1 "register_operand" "r")))]
849 ""
850 "xor %0,%1,$-1")
851 \f
852 ;; Floating point arithmetic instructions.
853
854 (define_insn "adddf3"
855 [(set (match_operand:DF 0 "register_operand" "=f")
856 (plus:DF (match_operand:DF 1 "register_operand" "f")
857 (match_operand:DF 2 "register_operand" "f")))]
858 "TARGET_FPU"
859 "fadd %0,%1,%2")
860
861 (define_insn "addsf3"
862 [(set (match_operand:SF 0 "register_operand" "=f")
863 (plus:SF (match_operand:SF 1 "register_operand" "f")
864 (match_operand:SF 2 "register_operand" "f")))]
865 "TARGET_FPU"
866 "fadd %0,%1,%2")
867
868 (define_insn "subdf3"
869 [(set (match_operand:DF 0 "register_operand" "=f")
870 (minus:DF (match_operand:DF 1 "register_operand" "f")
871 (match_operand:DF 2 "register_operand" "f")))]
872 "TARGET_FPU"
873 "fsub %0,%1,%2")
874
875 (define_insn "subsf3"
876 [(set (match_operand:SF 0 "register_operand" "=f")
877 (minus:SF (match_operand:SF 1 "register_operand" "f")
878 (match_operand:SF 2 "register_operand" "f")))]
879 "TARGET_FPU"
880 "fsub %0,%1,%2")
881
882 (define_insn "muldf3"
883 [(set (match_operand:DF 0 "register_operand" "=f")
884 (mult:DF (match_operand:DF 1 "register_operand" "f")
885 (match_operand:DF 2 "register_operand" "f")))]
886 "TARGET_FPU"
887 "fmul %0,%1,%2")
888
889 (define_insn "mulsf3"
890 [(set (match_operand:SF 0 "register_operand" "=f")
891 (mult:SF (match_operand:SF 1 "register_operand" "f")
892 (match_operand:SF 2 "register_operand" "f")))]
893 "TARGET_FPU"
894 "fmul %0,%1,%2")
895
896 (define_insn "divdf3"
897 [(set (match_operand:DF 0 "register_operand" "=f")
898 (div:DF (match_operand:DF 1 "register_operand" "f")
899 (match_operand:DF 2 "register_operand" "f")))]
900 "TARGET_FPU"
901 "fdiv %0,%1,%2")
902
903 (define_insn "divsf3"
904 [(set (match_operand:SF 0 "register_operand" "=f")
905 (div:SF (match_operand:SF 1 "register_operand" "f")
906 (match_operand:SF 2 "register_operand" "f")))]
907 "TARGET_FPU"
908 "fdiv %0,%1,%2")
909
910 (define_insn "negdf2"
911 [(set (match_operand:DF 0 "register_operand" "=f")
912 (neg:DF (match_operand:DF 1 "nonmemory_operand" "f")))]
913 "TARGET_FPU"
914 "fneg %0,%1")
915
916 (define_insn "negsf2"
917 [(set (match_operand:SF 0 "register_operand" "=f")
918 (neg:SF (match_operand:SF 1 "nonmemory_operand" "f")))]
919 "TARGET_FPU"
920 "fneg %0,%1")
921
922 (define_insn "absdf2"
923 [(set (match_operand:DF 0 "register_operand" "=f")
924 (abs:DF (match_operand:DF 1 "nonmemory_operand" "f")))]
925 "TARGET_FPU"
926 "fabs %0,%1")
927
928 (define_insn "abssf2"
929 [(set (match_operand:SF 0 "register_operand" "=f")
930 (abs:SF (match_operand:SF 1 "nonmemory_operand" "f")))]
931 "TARGET_FPU"
932 "fabs %0,%1")
933 \f
934 ;; Shift instructions
935
936 (define_insn ""
937 [(set (match_operand:SI 0 "register_operand" "=r")
938 (ashift:SI (match_operand:SI 1 "register_operand" "r")
939 (match_operand:SI 2 "immediate_operand" "I")))]
940 "GET_CODE (operands[2]) == CONST_INT"
941 "*
942 {
943 unsigned int amount = INTVAL (operands[2]);
944
945 switch (amount)
946 {
947 case 0:
948 return \"add_nt %0,%1,$0\";
949 case 1:
950 return \"sll %0,%1,$1\";
951 case 2:
952 return \"sll %0,%1,$2\";
953 default:
954 output_asm_insn (\"sll %0,%1,$3\", operands);
955
956 for (amount -= 3; amount >= 3; amount -= 3)
957 output_asm_insn (\"sll %0,%0,$3\", operands);
958
959 if (amount > 0)
960 output_asm_insn (amount == 1 ? \"sll %0,%0,$1\" : \"sll %0,%0,$2\",
961 operands);
962 return \"\";
963 }
964 }")
965
966 (define_insn ""
967 [(set (match_operand:SI 0 "register_operand" "=r")
968 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
969 (match_operand:SI 2 "immediate_operand" "I")))]
970 "GET_CODE (operands[2]) == CONST_INT"
971 "*
972 {
973 unsigned int amount = INTVAL (operands[2]);
974
975 if (amount == 0)
976 return \"add_nt %0,%1,$0\";
977 else
978 output_asm_insn (\"sra %0,%1,$1\", operands);
979
980 for (amount -= 1; amount > 0; amount -= 1)
981 output_asm_insn (\"sra %0,%0,$1\", operands);
982
983 return \"\";
984 }")
985
986 (define_insn ""
987 [(set (match_operand:SI 0 "register_operand" "=r")
988 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
989 (match_operand:SI 2 "immediate_operand" "I")))]
990 "GET_CODE (operands[2]) == CONST_INT"
991 "*
992 {
993 unsigned int amount = INTVAL (operands[2]);
994
995 if (amount == 0)
996 return \"add_nt %0,%1,$0\";
997 else
998 output_asm_insn (\"srl %0,%1,$1\", operands);
999
1000 for (amount -= 1; amount > 0; amount -= 1)
1001 output_asm_insn (\"srl %0,%0,$1\", operands);
1002
1003 return \"\";
1004 }")
1005
1006 (define_expand "ashlsi3"
1007 [(set (match_operand:SI 0 "register_operand" "")
1008 (ashift:SI (match_operand:SI 1 "register_operand" "")
1009 (match_operand:SI 2 "nonmemory_operand" "")))]
1010 ""
1011 "
1012 {
1013 if (GET_CODE (operands[2]) != CONST_INT
1014 || (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands[2]) > 3))
1015 FAIL;
1016 }")
1017
1018 (define_expand "ashrsi3"
1019 [(set (match_operand:SI 0 "register_operand" "")
1020 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1021 (match_operand:SI 2 "nonmemory_operand" "")))]
1022 ""
1023 "
1024 {
1025 if (GET_CODE (operands[2]) != CONST_INT
1026 || (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands[2]) > 1))
1027 FAIL;
1028 }")
1029
1030 (define_expand "lshrsi3"
1031 [(set (match_operand:SI 0 "register_operand" "")
1032 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1033 (match_operand:SI 2 "nonmemory_operand" "")))]
1034 ""
1035 "
1036 {
1037 if (GET_CODE (operands[2]) != CONST_INT
1038 || (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands[2]) > 1))
1039 FAIL;
1040 }")
1041 \f
1042 ;; Unconditional and other jump instructions
1043 (define_insn "jump"
1044 [(set (pc)
1045 (label_ref (match_operand 0 "" "")))]
1046 ""
1047 "jump %l0\;nop")
1048
1049 (define_insn "tablejump"
1050 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1051 (use (label_ref (match_operand 1 "" "")))]
1052 ""
1053 "jump_reg r0,%0\;nop")
1054
1055 ;;- jump to subroutine
1056 (define_insn "call"
1057 [(call (match_operand:SI 0 "memory_operand" "m")
1058 (match_operand:SI 1 "general_operand" "g"))]
1059 ;;- Don't use operand 1 for most machines.
1060 ""
1061 "add_nt r2,%0\;call .+8\;jump_reg r0,r2\;nop")
1062
1063 (define_insn "call_value"
1064 [(set (match_operand 0 "" "=g")
1065 (call (match_operand:SI 1 "memory_operand" "m")
1066 (match_operand:SI 2 "general_operand" "g")))]
1067 ;;- Don't use operand 1 for most machines.
1068 ""
1069 "add_nt r2,%1\;call .+8\;jump_reg r0,r2\;nop")
1070
1071 ;; A memory ref with constant address is not normally valid.
1072 ;; But it is valid in a call insns. This pattern allows the
1073 ;; loading of the address to combine with the call.
1074 (define_insn ""
1075 [(call (mem:SI (match_operand:SI 0 "" "i"))
1076 (match_operand:SI 1 "general_operand" "g"))]
1077 ;;- Don't use operand 1 for most machines.
1078 "GET_CODE (operands[0]) == SYMBOL_REF"
1079 "call %0\;nop")
1080
1081 (define_insn ""
1082 [(set (match_operand 0 "" "=g")
1083 (call (mem:SI (match_operand:SI 1 "" "i"))
1084 (match_operand:SI 2 "general_operand" "g")))]
1085 ;;- Don't use operand 1 for most machines.
1086 "GET_CODE (operands[1]) == SYMBOL_REF"
1087 "call %1\;nop")
1088
1089 (define_insn "nop"
1090 [(const_int 0)]
1091 ""
1092 "nop")