]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/fx80/fx80.md
Merge in gcc2-ss-010999
[thirdparty/gcc.git] / gcc / config / fx80 / fx80.md
CommitLineData
85c4c3aa 1;;- Machine description for GNU C compiler for Alliant FX systems
c5c76735 2;; Copyright (C) 1989, 1994, 1996, 1998, 1999 Free Software Foundation, Inc.
996a5f59
RK
3;; Adapted from m68k.md by Paul Petersen (petersen@uicsrd.csrd.uiuc.edu)
4;; and Joe Weening (weening@gang-of-four.stanford.edu).
85c4c3aa
CH
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
a8f1399a
RK
20;; the Free Software Foundation, 59 Temple Place - Suite 330,
21;; Boston, MA 02111-1307, USA.
85c4c3aa
CH
22
23
24;;- instruction definitions
25
26;;- @@The original PO technology requires these to be ordered by speed,
27;;- @@ so that assigner will pick the fastest.
28
29;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
30
31;;- When naming insn's (operand 0 of define_insn) be careful about using
32;;- names from other targets machine descriptions.
33
34;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
35;;- updates for most instructions.
36
37;;- Operand classes for the register allocator:
38;;- 'a' one of the address registers can be used.
39;;- 'd' one of the data registers can be used.
40;;- 'f' one of the CE floating point registers can be used
41;;- 'r' either a data or an address register can be used.
42
43;;- Immediate integer operand constraints:
44;;- 'I' 1 .. 8
45;;- 'J' -32768 .. 32767
46;;- 'K' -128 .. 127
47;;- 'L' -8 .. -1
48
49;;- Some remnants of constraint codes for the m68k ('x','y','G','H')
50;;- may remain in the insn definitions.
51
52;;- Some of these insn's are composites of several Alliant op codes.
53;;- The assembler (or final @@??) insures that the appropriate one is
54;;- selected.
55\f
56;; We don't want to allow a constant operand for test insns because
57;; (set (cc0) (const_int foo)) has no mode information. Such insns will
58;; be folded while optimizing anyway.
59
60(define_insn "tstsi"
61 [(set (cc0)
62 (match_operand:SI 0 "nonimmediate_operand" "rm"))]
63 ""
64 "*
65{
66 if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
67 return \"tst%.l %0\";
68 /* If you think that the 68020 does not support tstl a0,
69 reread page B-167 of the 68020 manual more carefully. */
70 /* On an address reg, cmpw may replace cmpl. */
71 return \"cmp%.w %#0,%0\";
72}")
73
74(define_insn "tsthi"
75 [(set (cc0)
76 (match_operand:HI 0 "nonimmediate_operand" "rm"))]
77 ""
78 "*
79{
80 if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
81 return \"tst%.w %0\";
82 return \"cmp%.w %#0,%0\";
83}")
84
85(define_insn "tstqi"
86 [(set (cc0)
87 (match_operand:QI 0 "nonimmediate_operand" "dm"))]
88 ""
89 "tst%.b %0")
90
91(define_insn "tstsf"
92 [(set (cc0)
93 (match_operand:SF 0 "nonimmediate_operand" "fm"))]
94 "TARGET_CE"
95 "*
96{
97 cc_status.flags = CC_IN_FP;
98 return \"ftest%.s %0\";
99}")
100
101(define_insn "tstdf"
102 [(set (cc0)
103 (match_operand:DF 0 "nonimmediate_operand" "fm"))]
104 "TARGET_CE"
105 "*
106{
107 cc_status.flags = CC_IN_FP;
108 return \"ftest%.d %0\";
109}")
110\f
111;; compare instructions.
112
113;; A composite of the cmp, cmpa, & cmpi m68000 op codes.
114(define_insn "cmpsi"
115 [(set (cc0)
116 (compare (match_operand:SI 0 "nonimmediate_operand" "rKs,mr,>")
117 (match_operand:SI 1 "general_operand" "mr,Ksr,>")))]
118 ""
119 "*
120{
121 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
122 return \"cmpm%.l %1,%0\";
123 if (REG_P (operands[1])
124 || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
125 {
126 cc_status.flags |= CC_REVERSED;
127 return \"cmp%.l %d0,%d1\";
128 }
129 return \"cmp%.l %d1,%d0\";
130}")
131
132(define_insn "cmphi"
133 [(set (cc0)
134 (compare (match_operand:HI 0 "nonimmediate_operand" "rnm,d,n,m")
135 (match_operand:HI 1 "general_operand" "d,rnm,m,n")))]
136 ""
137 "*
138{
139 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
140 return \"cmpm%.w %1,%0\";
141 if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1]))
142 || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
143 { cc_status.flags |= CC_REVERSED;
144 return \"cmp%.w %d0,%d1\";
145 }
146 return \"cmp%.w %d1,%d0\";
147}")
148
149(define_insn "cmpqi"
150 [(set (cc0)
151 (compare (match_operand:QI 0 "nonimmediate_operand" "dn,md,>")
152 (match_operand:QI 1 "general_operand" "dm,nd,>")))]
153 ""
154 "*
155{
156 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
157 return \"cmpm%.b %1,%0\";
158 if (REG_P (operands[1])
159 || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
160 {
161 cc_status.flags |= CC_REVERSED;
162 return \"cmp%.b %d0,%d1\";
163 }
164 return \"cmp%.b %d1,%d0\";
165}")
166
167(define_insn "cmpdf"
168 [(set (cc0)
169 (compare (match_operand:DF 0 "nonimmediate_operand" "f,m")
170 (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
171 "TARGET_CE"
172 "*
173{
174 cc_status.flags = CC_IN_FP;
175 if (FP_REG_P (operands[0]))
176 return \"fcmp%.d %1,%0\";
177 cc_status.flags |= CC_REVERSED;
178 return \"fcmp%.d %0,%1\";
179}")
180
181(define_insn "cmpsf"
182 [(set (cc0)
183 (compare (match_operand:SF 0 "nonimmediate_operand" "f,m")
184 (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
185 "TARGET_CE"
186 "*
187{
188 cc_status.flags = CC_IN_FP;
189 if (FP_REG_P (operands[0]))
190 return \"fcmp%.s %1,%0\";
191 cc_status.flags |= CC_REVERSED;
192 return \"fcmp%.s %0,%1\";
193}")
194\f
195;; Recognizers for btst instructions.
196
197(define_insn ""
83199882 198 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "o")
85c4c3aa
CH
199 (const_int 1)
200 (minus:SI (const_int 7)
201 (match_operand:SI 1 "general_operand" "di"))))]
202 ""
203 "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
204
205(define_insn ""
83199882 206 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "d")
85c4c3aa
CH
207 (const_int 1)
208 (minus:SI (const_int 31)
209 (match_operand:SI 1 "general_operand" "di"))))]
210 ""
211 "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
212
213;; The following two patterns are like the previous two
214;; except that they use the fact that bit-number operands
215;; are automatically masked to 3 or 5 bits.
216
217(define_insn ""
83199882 218 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "o")
85c4c3aa
CH
219 (const_int 1)
220 (minus:SI (const_int 7)
221 (and:SI
222 (match_operand:SI 1 "general_operand" "d")
223 (const_int 7)))))]
224 ""
225 "* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
226
227(define_insn ""
83199882 228 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "d")
85c4c3aa
CH
229 (const_int 1)
230 (minus:SI (const_int 31)
231 (and:SI
232 (match_operand:SI 1 "general_operand" "d")
233 (const_int 31)))))]
234 ""
235 "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
236
237;; Nonoffsettable mem refs are ok in this one pattern
238;; since we don't try to adjust them.
239(define_insn ""
83199882 240 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
85c4c3aa
CH
241 (const_int 1)
242 (match_operand:SI 1 "general_operand" "i")))]
243 "GET_CODE (operands[1]) == CONST_INT
244 && (unsigned) INTVAL (operands[1]) < 8"
245 "*
246{
3a598fbe 247 operands[1] = GEN_INT (7 - INTVAL (operands[1]));
85c4c3aa
CH
248 return output_btst (operands, operands[1], operands[0], insn, 7);
249}")
250
251
252(define_insn ""
83199882 253 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "do")
85c4c3aa
CH
254 (const_int 1)
255 (match_operand:SI 1 "general_operand" "i")))]
256 "GET_CODE (operands[1]) == CONST_INT"
257 "*
258{
259 if (GET_CODE (operands[0]) == MEM)
260 {
261 operands[0] = adj_offsettable_operand (operands[0],
262 INTVAL (operands[1]) / 8);
3a598fbe 263 operands[1] = GEN_INT (7 - INTVAL (operands[1]) % 8);
85c4c3aa
CH
264 return output_btst (operands, operands[1], operands[0], insn, 7);
265 }
3a598fbe 266 operands[1] = GEN_INT (31 - INTVAL (operands[1]));
85c4c3aa
CH
267 return output_btst (operands, operands[1], operands[0], insn, 31);
268}")
269
270\f
271;; move instructions
272
273;; A special case in which it is not desirable
274;; to reload the constant into a data register.
275(define_insn ""
276 [(set (match_operand:SI 0 "push_operand" "=m")
277 (match_operand:SI 1 "general_operand" "J"))]
278 "GET_CODE (operands[1]) == CONST_INT
279 && INTVAL (operands[1]) >= -0x8000
280 && INTVAL (operands[1]) < 0x8000"
281 "*
282{
283 if (operands[1] == const0_rtx)
284 return \"clr%.l %0\";
285 return \"pea %a1\";
286}")
287
288;This is never used.
289;(define_insn "swapsi"
290; [(set (match_operand:SI 0 "general_operand" "r")
291; (match_operand:SI 1 "general_operand" "r"))
292; (set (match_dup 1) (match_dup 0))]
293; ""
294; "exg %1,%0")
295
296;; Special case of fullword move when source is zero.
297;; The reason this is special is to avoid loading a zero
298;; into a data reg with moveq in order to store it elsewhere.
299
300(define_insn ""
301 [(set (match_operand:SI 0 "general_operand" "=a,g")
302 (const_int 0))]
303 ""
304 "@
305 sub%.l %0,%0
306 clr%.l %0")
307
308;; General case of fullword move. The register constraints
309;; force integer constants in range for a moveq to be reloaded
310;; if they are headed for memory.
311(define_insn "movsi"
312 ;; Notes: make sure no alternative allows g vs g.
313 ;; We don't allow f-regs since fixed point cannot go in them.
314 ;; We do allow y and x regs since fixed point is allowed in them.
315 [(set (match_operand:SI 0 "general_operand" "=g,da,y,!*x*r*m")
316 (match_operand:SI 1 "general_operand" "daymKs,i,g,*x*r*m"))]
317 ""
318 "*
319{
320 if (GET_CODE (operands[1]) == CONST_INT)
321 {
322 if (operands[1] == const0_rtx
323 && (DATA_REG_P (operands[0])
324 || GET_CODE (operands[0]) == MEM))
325 return \"clr%.l %0\";
326 else if (DATA_REG_P (operands[0])
327 && INTVAL (operands[1]) < 128
328 && INTVAL (operands[1]) >= -128)
329 return \"moveq %1,%0\";
330 else if (ADDRESS_REG_P (operands[0])
331 && INTVAL (operands[1]) < 0x8000
332 && INTVAL (operands[1]) >= -0x8000)
333 return \"mov%.w %1,%0\";
334 else if (push_operand (operands[0], SImode)
335 && INTVAL (operands[1]) < 0x8000
336 && INTVAL (operands[1]) >= -0x8000)
337 return \"pea %a1\";
338 }
339 else if ((GET_CODE (operands[1]) == SYMBOL_REF
340 || GET_CODE (operands[1]) == CONST)
341 && push_operand (operands[0], SImode))
342 return \"pea %a1\";
343 else if ((GET_CODE (operands[1]) == SYMBOL_REF
344 || GET_CODE (operands[1]) == CONST)
345 && ADDRESS_REG_P (operands[0]))
346 return \"lea %a1,%0\";
347 return \"mov%.l %1,%0\";
348}")
349
350(define_insn "movhi"
351 [(set (match_operand:HI 0 "general_operand" "=g")
352 (match_operand:HI 1 "general_operand" "g"))]
353 ""
354 "*
355{
356 if (GET_CODE (operands[1]) == CONST_INT)
357 {
358 if (operands[1] == const0_rtx
359 && (DATA_REG_P (operands[0])
360 || GET_CODE (operands[0]) == MEM))
361 return \"clr%.w %0\";
362 else if (DATA_REG_P (operands[0])
363 && INTVAL (operands[1]) < 128
364 && INTVAL (operands[1]) >= -128)
365 {
366 return \"moveq %1,%0\";
367 }
368 else if (INTVAL (operands[1]) < 0x8000
369 && INTVAL (operands[1]) >= -0x8000)
370 return \"mov%.w %1,%0\";
371 }
372 else if (CONSTANT_P (operands[1]))
373 return \"mov%.l %1,%0\";
374 /* Recognize the insn before a tablejump, one that refers
375 to a table of offsets. Such an insn will need to refer
376 to a label on the insn. So output one. Use the label-number
377 of the table of offsets to generate this label. */
378 if (GET_CODE (operands[1]) == MEM
379 && GET_CODE (XEXP (operands[1], 0)) == PLUS
380 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
381 || GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF)
382 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS
383 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) != PLUS)
384 {
385 rtx labelref;
386 if (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF)
387 labelref = XEXP (XEXP (operands[1], 0), 0);
388 else
389 labelref = XEXP (XEXP (operands[1], 0), 1);
390 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\",
391 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
392 }
393 return \"mov%.w %1,%0\";
394}")
395
396(define_insn "movstricthi"
397 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
398 (match_operand:HI 1 "general_operand" "rmn"))]
399 ""
400 "*
401{
402 if (operands[1] == const0_rtx)
403 return \"clr%.w %0\";
404 return \"mov%.w %1,%0\";
405}")
406
407(define_insn "movqi"
408 [(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a")
409 (match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))]
410 ""
411 "*
412{
413 rtx xoperands[4];
414 if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM)
415 {
416 xoperands[1] = operands[1];
417 xoperands[2]
c5c76735 418 = gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, 1));
85c4c3aa
CH
419 xoperands[3] = stack_pointer_rtx;
420 /* Just pushing a byte puts it in the high byte of the halfword. */
421 /* We must put it in the low half, the second byte. */
422 output_asm_insn (\"subq%.w %#2,%3\;mov%.b %1,%2\", xoperands);
423 return \"mov%.w %+,%0\";
424 }
425 if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM)
426 {
427 xoperands[0] = operands[0];
428 xoperands[1] = operands[1];
429 xoperands[2]
c5c76735 430 = gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, 1));
85c4c3aa
CH
431 xoperands[3] = stack_pointer_rtx;
432 output_asm_insn (\"mov%.w %1,%-\;mov%.b %2,%0\;addq%.w %#2,%3\", xoperands);
433 return \"\";
434 }
435 if (operands[1] == const0_rtx)
436 return \"clr%.b %0\";
437 if (GET_CODE (operands[1]) == CONST_INT
438 && INTVAL (operands[1]) == -1)
439 return \"st %0\";
440 if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
441 return \"mov%.l %1,%0\";
442 if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
443 return \"mov%.w %1,%0\";
444 return \"mov%.b %1,%0\";
445}")
446
447(define_insn "movstrictqi"
448 [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
449 (match_operand:QI 1 "general_operand" "dmn"))]
450 ""
451 "*
452{
453 if (operands[1] == const0_rtx)
454 return \"clr%.b %0\";
455 return \"mov%.b %1,%0\";
456}")
457
458;; Floating-point moves on a CE are faster using an FP register than
459;; with movl instructions. (Especially for double floats, but also
460;; for single floats, even though it takes an extra instruction.) But
461;; on an IP, the FP registers are simulated and so should be avoided.
462;; We do this by using define_expand for movsf and movdf, and using
463;; different constraints for each target type. The constraints for
464;; TARGET_CE allow general registers because they sometimes need to
465;; hold floats, but they are not preferable.
466
467(define_expand "movsf"
468 [(set (match_operand:SF 0 "general_operand" "")
469 (match_operand:SF 1 "nonimmediate_operand" ""))]
470 ""
471 "")
472
473(define_insn ""
474 [(set (match_operand:SF 0 "general_operand" "=f,m,!*r,!f*m")
475 (match_operand:SF 1 "nonimmediate_operand" "fm,f,f*r*m,*r"))]
476 "TARGET_CE"
477 "*
478{
479 if (FP_REG_P (operands[0]))
480 {
481 if (FP_REG_P (operands[1]))
482 return \"fmove%.s %1,%0\";
483 if (REG_P (operands[1]))
484 return \"mov%.l %1,%-\;fmove%.s %+,%0\";
485 return \"fmove%.s %1,%0\";
486 }
487 if (FP_REG_P (operands[1]))
488 {
489 if (REG_P (operands[0]))
490 return \"fmove%.s %1,%-\;mov%.l %+,%0\";
491 return \"fmove%.s %1,%0\";
492 }
493 return \"mov%.l %1,%0\";
494}")
495
496(define_insn ""
497 [(set (match_operand:SF 0 "general_operand" "=frm")
498 (match_operand:SF 1 "nonimmediate_operand" "frm"))]
499 "!TARGET_CE"
500 "*
501{
502 if (FP_REG_P (operands[0]))
503 {
504 if (FP_REG_P (operands[1]))
505 return \"fmove%.s %1,%0\";
506 if (REG_P (operands[1]))
507 return \"mov%.l %1,%-\;fmove%.s %+,%0\";
508 return \"fmove%.s %1,%0\";
509 }
510 if (FP_REG_P (operands[1]))
511 {
512 if (REG_P (operands[0]))
513 return \"fmove%.s %1,%-\;mov%.l %+,%0\";
514 return \"fmove%.s %1,%0\";
515 }
516 return \"mov%.l %1,%0\";
517}")
518
519(define_expand "movdf"
520 [(set (match_operand:DF 0 "general_operand" "")
521 (match_operand:DF 1 "nonimmediate_operand" ""))]
522 ""
523 "")
524
525(define_insn ""
526 [(set (match_operand:DF 0 "general_operand" "=f,m,!*r,!f*m")
527 (match_operand:DF 1 "nonimmediate_operand" "fm,f,f*r*m,*r"))]
528 "TARGET_CE"
529 "*
530{
531 if (FP_REG_P (operands[0]))
532 {
533 if (FP_REG_P (operands[1]))
534 return \"fmove%.d %1,%0\";
535 if (REG_P (operands[1]))
536 {
537 rtx xoperands[2];
c5c76735 538 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
85c4c3aa
CH
539 output_asm_insn (\"mov%.l %1,%-\", xoperands);
540 output_asm_insn (\"mov%.l %1,%-\", operands);
541 return \"fmove%.d %+,%0\";
542 }
543 return \"fmove%.d %1,%0\";
544 }
545 else if (FP_REG_P (operands[1]))
546 {
547 if (REG_P (operands[0]))
548 {
549 output_asm_insn (\"fmove%.d %1,%-\;mov%.l %+,%0\", operands);
c5c76735 550 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
85c4c3aa
CH
551 return \"mov%.l %+,%0\";
552 }
553 return \"fmove%.d %1,%0\";
554 }
555 return output_move_double (operands);
556}")
557
558(define_insn ""
559 [(set (match_operand:DF 0 "general_operand" "=frm")
560 (match_operand:DF 1 "nonimmediate_operand" "frm"))]
561 "!TARGET_CE"
562 "*
563{
564 if (FP_REG_P (operands[0]))
565 {
566 if (FP_REG_P (operands[1]))
567 return \"fmove%.d %1,%0\";
568 if (REG_P (operands[1]))
569 {
570 rtx xoperands[2];
c5c76735 571 xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
85c4c3aa
CH
572 output_asm_insn (\"mov%.l %1,%-\", xoperands);
573 output_asm_insn (\"mov%.l %1,%-\", operands);
574 return \"fmove%.d %+,%0\";
575 }
576 return \"fmove%.d %1,%0\";
577 }
578 else if (FP_REG_P (operands[1]))
579 {
580 if (REG_P (operands[0]))
581 {
582 output_asm_insn (\"fmove%.d %1,%-\;mov%.l %+,%0\", operands);
c5c76735 583 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
85c4c3aa
CH
584 return \"mov%.l %+,%0\";
585 }
586 return \"fmove%.d %1,%0\";
587 }
588 return output_move_double (operands);
589}")
590
591(define_insn "movdi"
592 [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>")
593 (match_operand:DI 1 "general_operand" "r,m,roi<>"))]
594 ""
595 "*
596{
597 return output_move_double (operands);
598}
599")
600
601;; This goes after the move instructions
602;; because the move instructions are better (require no spilling)
603;; when they can apply. It goes before the add/sub insns
604;; so we will prefer it to them.
605
606(define_insn "pushasi"
607 [(set (match_operand:SI 0 "push_operand" "=m")
608 (match_operand:SI 1 "address_operand" "p"))]
609 ""
610 "pea %a1")
611\f
612;; truncation instructions
613(define_insn "truncsiqi2"
614 [(set (match_operand:QI 0 "general_operand" "=dm,d")
615 (truncate:QI
616 (match_operand:SI 1 "general_operand" "doJ,i")))]
617 ""
618 "*
619{
620 if (GET_CODE (operands[0]) == REG)
621 return \"mov%.l %1,%0\";
622 if (GET_CODE (operands[1]) == MEM)
623 operands[1] = adj_offsettable_operand (operands[1], 3);
624 return \"mov%.b %1,%0\";
625}")
626
627(define_insn "trunchiqi2"
628 [(set (match_operand:QI 0 "general_operand" "=dm,d")
629 (truncate:QI
630 (match_operand:HI 1 "general_operand" "doJ,i")))]
631 ""
632 "*
633{
634 if (GET_CODE (operands[0]) == REG
635 && (GET_CODE (operands[1]) == MEM
636 || GET_CODE (operands[1]) == CONST_INT))
637 return \"mov%.w %1,%0\";
638 if (GET_CODE (operands[0]) == REG)
639 return \"mov%.l %1,%0\";
640 if (GET_CODE (operands[1]) == MEM)
641 operands[1] = adj_offsettable_operand (operands[1], 1);
642 return \"mov%.b %1,%0\";
643}")
644
645(define_insn "truncsihi2"
646 [(set (match_operand:HI 0 "general_operand" "=dm,d")
647 (truncate:HI
648 (match_operand:SI 1 "general_operand" "roJ,i")))]
649 ""
650 "*
651{
652 if (GET_CODE (operands[0]) == REG)
653 return \"mov%.l %1,%0\";
654 if (GET_CODE (operands[1]) == MEM)
655 operands[1] = adj_offsettable_operand (operands[1], 2);
656 return \"mov%.w %1,%0\";
657}")
658\f
659;; zero extension instructions
660
661(define_expand "zero_extendhisi2"
662 [(set (match_operand:SI 0 "register_operand" "")
663 (const_int 0))
664 (set (strict_low_part (subreg:HI (match_dup 0) 0))
665 (match_operand:HI 1 "general_operand" ""))]
666 ""
667 "operands[1] = make_safe_from (operands[1], operands[0]);")
668
669(define_expand "zero_extendqihi2"
670 [(set (match_operand:HI 0 "register_operand" "")
671 (const_int 0))
672 (set (strict_low_part (subreg:QI (match_dup 0) 0))
673 (match_operand:QI 1 "general_operand" ""))]
674 ""
675 "operands[1] = make_safe_from (operands[1], operands[0]);")
676
677(define_expand "zero_extendqisi2"
678 [(set (match_operand:SI 0 "register_operand" "")
679 (const_int 0))
680 (set (strict_low_part (subreg:QI (match_dup 0) 0))
681 (match_operand:QI 1 "general_operand" ""))]
682 ""
683 " operands[1] = make_safe_from (operands[1], operands[0]); ")
684\f
685;; Patterns to recognize zero-extend insns produced by the combiner.
686(define_insn ""
687 [(set (match_operand:SI 0 "general_operand" "=do<>")
688 (zero_extend:SI
689 (match_operand:HI 1 "nonimmediate_operand" "rm")))]
690 ""
691 "*
692{
693 if (DATA_REG_P (operands[0]))
694 {
695 if (GET_CODE (operands[1]) == REG
696 && REGNO (operands[0]) == REGNO (operands[1]))
697 return \"and%.l %#0xFFFF,%0\";
698 if (reg_mentioned_p (operands[0], operands[1]))
699 return \"mov%.w %1,%0\;and%.l %#0xFFFF,%0\";
700 return \"clr%.l %0\;mov%.w %1,%0\";
701 }
702 else if (GET_CODE (operands[0]) == MEM
703 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
704 return \"mov%.w %1,%0\;clr%.w %0\";
705 else if (GET_CODE (operands[0]) == MEM
706 && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
707 return \"clr%.w %0\;mov%.w %1,%0\";
708 else
709 {
710 output_asm_insn (\"clr%.w %0\", operands);
711 operands[0] = adj_offsettable_operand (operands[0], 2);
712 return \"mov%.w %1,%0\";
713 }
714}")
715
716(define_insn ""
717 [(set (match_operand:HI 0 "general_operand" "=do<>")
718 (zero_extend:HI
719 (match_operand:QI 1 "nonimmediate_operand" "dm")))]
720 ""
721 "*
722{
723 if (DATA_REG_P (operands[0]))
724 {
725 if (GET_CODE (operands[1]) == REG
726 && REGNO (operands[0]) == REGNO (operands[1]))
727 return \"and%.w %#0xFF,%0\";
728 if (reg_mentioned_p (operands[0], operands[1]))
729 return \"mov%.b %1,%0\;and%.w %#0xFF,%0\";
730 return \"clr%.w %0\;mov%.b %1,%0\";
731 }
732 else if (GET_CODE (operands[0]) == MEM
733 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
734 {
735 if (REGNO (XEXP (XEXP (operands[0], 0), 0))
736 == STACK_POINTER_REGNUM)
737 return \"clr%.w %-\;mov%.b %1,%0\";
738 else
739 return \"mov%.b %1,%0\;clr%.b %0\";
740 }
741 else if (GET_CODE (operands[0]) == MEM
742 && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
743 return \"clr%.b %0\;mov%.b %1,%0\";
744 else
745 {
746 output_asm_insn (\"clr%.b %0\", operands);
747 operands[0] = adj_offsettable_operand (operands[0], 1);
748 return \"mov%.b %1,%0\";
749 }
750}")
751
752(define_insn ""
753 [(set (match_operand:SI 0 "general_operand" "=do<>")
754 (zero_extend:SI
755 (match_operand:QI 1 "nonimmediate_operand" "dm")))]
756 ""
757 "*
758{
759 if (DATA_REG_P (operands[0]))
760 {
761 if (GET_CODE (operands[1]) == REG
762 && REGNO (operands[0]) == REGNO (operands[1]))
763 return \"and%.l %#0xFF,%0\";
764 if (reg_mentioned_p (operands[0], operands[1]))
765 return \"mov%.b %1,%0\;and%.l %#0xFF,%0\";
766 return \"clr%.l %0\;mov%.b %1,%0\";
767 }
768 else if (GET_CODE (operands[0]) == MEM
769 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
770 {
771 operands[0] = XEXP (XEXP (operands[0], 0), 0);
772 return \"clr%.l %0@-\;mov%.b %1,%0@(3)\";
773 }
774 else if (GET_CODE (operands[0]) == MEM
775 && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
776 {
777 operands[0] = XEXP (XEXP (operands[0], 0), 0);
778 return \"clr%.l %0@+\;mov%.b %1,%0@(-1)\";
779 }
780 else
781 {
782 output_asm_insn (\"clr%.l %0\", operands);
783 operands[0] = adj_offsettable_operand (operands[0], 3);
784 return \"mov%.b %1,%0\";
785 }
786}")
787\f
788;; sign extension instructions
789
790(define_insn "extendhisi2"
791 [(set (match_operand:SI 0 "general_operand" "=*d,a")
792 (sign_extend:SI
793 (match_operand:HI 1 "nonimmediate_operand" "0,rmn")))]
794 ""
795 "@
796 ext%.l %0
797 mov%.w %1,%0")
798
799(define_insn "extendqihi2"
800 [(set (match_operand:HI 0 "general_operand" "=d")
801 (sign_extend:HI
802 (match_operand:QI 1 "nonimmediate_operand" "0")))]
803 ""
804 "ext%.w %0")
805
806(define_insn "extendqisi2"
807 [(set (match_operand:SI 0 "general_operand" "=d")
808 (sign_extend:SI
809 (match_operand:QI 1 "nonimmediate_operand" "0")))]
810 "TARGET_68020"
811 "extb%.l %0")
812\f
813;; Conversions between float and double.
814
815(define_insn "extendsfdf2"
816 [(set (match_operand:DF 0 "general_operand" "=f,m")
817 (float_extend:DF
818 (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
819 "TARGET_CE"
820 "fmovesd %1,%0")
821
822(define_insn "truncdfsf2"
823 [(set (match_operand:SF 0 "general_operand" "=f,m")
824 (float_truncate:SF
825 (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
826 "TARGET_CE"
827 "fmoveds %1,%0")
828\f
829;; Conversion between fixed point and floating point.
830;; Note that among the fix-to-float insns
831;; the ones that start with SImode come first.
832;; That is so that an operand that is a CONST_INT
833;; (and therefore lacks a specific machine mode).
834;; will be recognized as SImode (which is always valid)
835;; rather than as QImode or HImode.
836
837(define_insn "floatsisf2"
838 [(set (match_operand:SF 0 "register_operand" "=f")
839 (float:SF (match_operand:SI 1 "nonimmediate_operand" "dm")))]
840 "TARGET_CE"
841 "fmovels %1,%0")
842
843(define_insn "floatsidf2"
844 [(set (match_operand:DF 0 "register_operand" "=f")
845 (float:DF (match_operand:SI 1 "nonimmediate_operand" "dm")))]
846 "TARGET_CE"
847 "fmoveld %1,%0")
848
849(define_insn "floathisf2"
850 [(set (match_operand:SF 0 "register_operand" "=f")
851 (float:SF (match_operand:HI 1 "nonimmediate_operand" "dm")))]
852 "TARGET_CE"
853 "fmovews %1,%0")
854
855(define_insn "floathidf2"
856 [(set (match_operand:DF 0 "register_operand" "=f")
857 (float:DF (match_operand:HI 1 "nonimmediate_operand" "dm")))]
858 "TARGET_CE"
859 "fmovewd %1,%0")
860
861(define_insn "floatqisf2"
862 [(set (match_operand:SF 0 "register_operand" "=f")
863 (float:SF (match_operand:QI 1 "nonimmediate_operand" "dm")))]
864 "TARGET_CE"
865 "fmovebs %1,%0")
866
867(define_insn "floatqidf2"
868 [(set (match_operand:DF 0 "register_operand" "=f")
869 (float:DF (match_operand:QI 1 "nonimmediate_operand" "dm")))]
870 "TARGET_CE"
871 "fmovebd %1,%0")
872\f
873;; Float-to-fix conversion insns.
874
875(define_insn "fix_truncsfqi2"
876 [(set (match_operand:QI 0 "general_operand" "=dm")
877 (fix:QI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
878 "TARGET_CE"
879 "fmovesb %1,%0")
880
881(define_insn "fix_truncsfhi2"
882 [(set (match_operand:HI 0 "general_operand" "=dm")
883 (fix:HI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
884 "TARGET_CE"
885 "fmovesw %1,%0")
886
887(define_insn "fix_truncsfsi2"
888 [(set (match_operand:SI 0 "general_operand" "=dm")
889 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
890 "TARGET_CE"
891 "fmovesl %1,%0")
892
893(define_insn "fix_truncdfqi2"
894 [(set (match_operand:QI 0 "general_operand" "=dm")
895 (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
896 "TARGET_CE"
897 "fmovedb %1,%0")
898
899(define_insn "fix_truncdfhi2"
900 [(set (match_operand:HI 0 "general_operand" "=dm")
901 (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
902 "TARGET_CE"
903 "fmovedw %1,%0")
904
905(define_insn "fix_truncdfsi2"
906 [(set (match_operand:SI 0 "general_operand" "=dm")
907 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
908 "TARGET_CE"
909 "fmovedl %1,%0")
910\f
911;; add instructions
912
913(define_insn "addsi3"
914 [(set (match_operand:SI 0 "general_operand" "=m,r,!a,!a")
915 (plus:SI (match_operand:SI 1 "general_operand" "%0,0,a,rJK")
916 (match_operand:SI 2 "general_operand" "dIKLs,mrIKLs,rJK,a")))]
917 ""
918 "*
919{
920 if (! operands_match_p (operands[0], operands[1]))
921 {
922 if (!ADDRESS_REG_P (operands[1]))
923 {
924 rtx tmp = operands[1];
925
926 operands[1] = operands[2];
927 operands[2] = tmp;
928 }
929
930 /* These insns can result from reloads to access
931 stack slots over 64k from the frame pointer. */
932 if (GET_CODE (operands[2]) == CONST_INT
933 && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
934 return \"mov%.l %2,%0\;add%.l %1,%0\";
935 if (GET_CODE (operands[2]) == REG)
936 return \"lea %1@[%2:L:B],%0\";
937 else
938 return \"lea %1@(%c2),%0\";
939 }
940 if (GET_CODE (operands[2]) == CONST_INT)
941 {
942 if (INTVAL (operands[2]) > 0
943 && INTVAL (operands[2]) <= 8)
944 return (ADDRESS_REG_P (operands[0])
945 ? \"addq%.w %2,%0\"
946 : \"addq%.l %2,%0\");
947 if (INTVAL (operands[2]) < 0
948 && INTVAL (operands[2]) >= -8)
949 {
3a598fbe 950 operands[2] = GEN_INT (- INTVAL (operands[2]));
85c4c3aa
CH
951 return (ADDRESS_REG_P (operands[0])
952 ? \"subq%.w %2,%0\"
953 : \"subq%.l %2,%0\");
954 }
955 if (ADDRESS_REG_P (operands[0])
956 && INTVAL (operands[2]) >= -0x8000
957 && INTVAL (operands[2]) < 0x8000)
958 return \"add%.w %2,%0\";
959 }
960 return \"add%.l %2,%0\";
961}")
962
963(define_insn ""
964 [(set (match_operand:SI 0 "general_operand" "=a")
965 (plus:SI (match_operand:SI 1 "general_operand" "0")
966 (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rmn"))))]
967 ""
968 "add%.w %2,%0")
969
970(define_insn "addhi3"
971 [(set (match_operand:HI 0 "general_operand" "=mr,mr,m,r")
972 (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
973 (match_operand:HI 2 "general_operand" "I,L,dn,rmn")))]
974 ""
975 "@
976 addq%.w %2,%0
977 subq%.w #%n2,%0
978 add%.w %2,%0
979 add%.w %2,%0")
980
981(define_insn ""
982 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
983 (plus:HI (match_dup 0)
984 (match_operand:HI 1 "general_operand" "dn,rmn")))]
985 ""
986 "add%.w %1,%0")
987
988(define_insn "addqi3"
989 [(set (match_operand:QI 0 "general_operand" "=md,mr,m,d")
990 (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
991 (match_operand:QI 2 "general_operand" "I,L,dn,dmn")))]
992 ""
993 "@
994 addq%.b %2,%0
995 subq%.b #%n2,%0
996 add%.b %2,%0
997 add%.b %2,%0")
998
999(define_insn ""
1000 [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
1001 (plus:QI (match_dup 0)
1002 (match_operand:QI 1 "general_operand" "dn,dmn")))]
1003 ""
1004 "add%.b %1,%0")
1005
1006(define_insn "adddf3"
1007 [(set (match_operand:DF 0 "register_operand" "=f")
1008 (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%f")
1009 (match_operand:DF 2 "nonimmediate_operand" "fm")))]
1010 "TARGET_CE"
1011 "fadd%.d %2,%1,%0")
1012
1013(define_insn "addsf3"
1014 [(set (match_operand:SF 0 "register_operand" "=f")
1015 (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%f")
1016 (match_operand:SF 2 "nonimmediate_operand" "fm")))]
1017 "TARGET_CE"
1018 "fadd%.s %2,%1,%0")
1019\f
1020;; subtract instructions
1021
1022(define_insn "subsi3"
1023 [(set (match_operand:SI 0 "general_operand" "=m,r,!a,?d")
1024 (minus:SI (match_operand:SI 1 "general_operand" "0,0,a,mrIKs")
1025 (match_operand:SI 2 "general_operand" "dIKs,mrIKs,J,0")))]
1026 ""
1027 "*
1028{
1029 if (! operands_match_p (operands[0], operands[1]))
1030 {
1031 if (operands_match_p (operands[0], operands[2]))
1032 {
1033 if (GET_CODE (operands[1]) == CONST_INT)
1034 {
1035 if (INTVAL (operands[1]) > 0
1036 && INTVAL (operands[1]) <= 8)
1037 return \"subq%.l %1,%0\;neg%.l %0\";
1038 }
1039 return \"sub%.l %1,%0\;neg%.l %0\";
1040 }
1041 /* This case is matched by J, but negating -0x8000
1042 in an lea would give an invalid displacement.
1043 So do this specially. */
1044 if (INTVAL (operands[2]) == -0x8000)
1045 return \"mov%.l %1,%0\;sub%.l %2,%0\";
1046 return \"lea %1@(%n2),%0\";
1047 }
1048 if (GET_CODE (operands[2]) == CONST_INT)
1049 {
1050 if (INTVAL (operands[2]) > 0
1051 && INTVAL (operands[2]) <= 8)
1052 return \"subq%.l %2,%0\";
1053 if (ADDRESS_REG_P (operands[0])
1054 && INTVAL (operands[2]) >= -0x8000
1055 && INTVAL (operands[2]) < 0x8000)
1056 return \"sub%.w %2,%0\";
1057 }
1058 return \"sub%.l %2,%0\";
1059}")
1060
1061(define_insn ""
1062 [(set (match_operand:SI 0 "general_operand" "=a")
1063 (minus:SI (match_operand:SI 1 "general_operand" "0")
1064 (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rmn"))))]
1065 ""
1066 "sub%.w %2,%0")
1067
1068(define_insn "subhi3"
1069 [(set (match_operand:HI 0 "general_operand" "=m,r")
1070 (minus:HI (match_operand:HI 1 "general_operand" "0,0")
1071 (match_operand:HI 2 "general_operand" "dn,rmn")))]
1072 ""
1073 "sub%.w %2,%0")
1074
1075(define_insn ""
1076 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
1077 (minus:HI (match_dup 0)
1078 (match_operand:HI 1 "general_operand" "dn,rmn")))]
1079 ""
1080 "sub%.w %1,%0")
1081
1082(define_insn "subqi3"
1083 [(set (match_operand:QI 0 "general_operand" "=m,d")
1084 (minus:QI (match_operand:QI 1 "general_operand" "0,0")
1085 (match_operand:QI 2 "general_operand" "dn,dmn")))]
1086 ""
1087 "sub%.b %2,%0")
1088
1089(define_insn ""
1090 [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
1091 (minus:QI (match_dup 0)
1092 (match_operand:QI 1 "general_operand" "dn,dmn")))]
1093 ""
1094 "sub%.b %1,%0")
1095
1096(define_insn "subdf3"
1097 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
1098 (minus:DF (match_operand:DF 1 "nonimmediate_operand" "f,f,m")
1099 (match_operand:DF 2 "nonimmediate_operand" "f,m,f")))]
1100 "TARGET_CE"
1101 "@
1102 fsub%.d %2,%1,%0
1103 fsub%.d %2,%1,%0
1104 frsub%.d %1,%2,%0")
1105
1106(define_insn "subsf3"
1107 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
1108 (minus:SF (match_operand:SF 1 "nonimmediate_operand" "f,f,m")
1109 (match_operand:SF 2 "nonimmediate_operand" "f,m,f")))]
1110 "TARGET_CE"
1111 "@
1112 fsub%.s %2,%1,%0
1113 fsub%.s %2,%1,%0
1114 frsub%.s %1,%2,%0")
1115\f
1116;; multiply instructions
1117
1118(define_insn "mulhi3"
1119 [(set (match_operand:HI 0 "general_operand" "=d")
1120 (mult:HI (match_operand:HI 1 "general_operand" "%0")
1121 (match_operand:HI 2 "general_operand" "dmn")))]
1122 ""
1123 "muls %2,%0")
1124
1125(define_insn "mulhisi3"
1126 [(set (match_operand:SI 0 "general_operand" "=d")
1127 (mult:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%0"))
1128 (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm"))))]
1129 ""
1130 "muls %2,%0")
1131
1132(define_insn ""
1133 [(set (match_operand:SI 0 "general_operand" "=d")
1134 (mult:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%0"))
1135 (match_operand:SI 2 "const_int_operand" "n")))]
1136 ""
1137 "muls %2,%0")
1138
1139(define_insn "mulsi3"
1140 [(set (match_operand:SI 0 "general_operand" "=d")
1141 (mult:SI (match_operand:SI 1 "general_operand" "%0")
1142 (match_operand:SI 2 "general_operand" "dmsK")))]
1143 "TARGET_68020"
1144 "muls%.l %2,%0")
1145
1146(define_insn "umulhisi3"
1147 [(set (match_operand:SI 0 "general_operand" "=d")
1148 (mult:SI (zero_extend:SI
1149 (match_operand:HI 1 "nonimmediate_operand" "%0"))
1150 (zero_extend:SI
1151 (match_operand:HI 2 "nonimmediate_operand" "dm"))))]
1152 ""
1153 "mulu %2,%0")
1154
1155(define_insn ""
1156 [(set (match_operand:SI 0 "general_operand" "=d")
1157 (mult:SI (zero_extend:SI
1158 (match_operand:HI 1 "nonimmediate_operand" "%0"))
1159 (match_operand:SI 2 "const_int_operand" "n")))]
1160 ""
1161 "mulu %2,%0")
1162
1163(define_insn "muldf3"
1164 [(set (match_operand:DF 0 "register_operand" "=f")
1165 (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%f")
1166 (match_operand:DF 2 "nonimmediate_operand" "fm")))]
1167 "TARGET_CE"
1168 "fmul%.d %2,%1,%0")
1169
1170(define_insn "mulsf3"
1171 [(set (match_operand:SF 0 "register_operand" "=f")
1172 (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%f")
1173 (match_operand:SF 2 "nonimmediate_operand" "fm")))]
1174 "TARGET_CE"
1175 "fmul%.s %2,%1,%0")
1176\f
1177;; divide instructions
1178
1179(define_insn "divhi3"
1180 [(set (match_operand:HI 0 "general_operand" "=d")
1181 (div:HI (match_operand:HI 1 "general_operand" "0")
1182 (match_operand:HI 2 "general_operand" "dmn")))]
1183 ""
1184 "extl %0\;divs %2,%0")
1185
1186(define_insn "divhisi3"
1187 [(set (match_operand:HI 0 "general_operand" "=d")
1188 (truncate:HI
1189 (div:SI
1190 (match_operand:SI 1 "general_operand" "0")
1191 (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
1192 ""
1193 "divs %2,%0")
1194
1195(define_insn ""
1196 [(set (match_operand:HI 0 "general_operand" "=d")
1197 (truncate:HI (div:SI (match_operand:SI 1 "general_operand" "0")
1198 (match_operand:SI 2 "const_int_operand" "n"))))]
1199 ""
1200 "divs %2,%0")
1201
1202(define_insn "divsi3"
1203 [(set (match_operand:SI 0 "general_operand" "=d")
1204 (div:SI (match_operand:SI 1 "general_operand" "0")
1205 (match_operand:SI 2 "general_operand" "dmsK")))]
1206 "TARGET_68020"
1207 "divs%.l %2,%0,%0")
1208
1209(define_insn "udivhi3"
1210 [(set (match_operand:HI 0 "general_operand" "=d")
1211 (udiv:HI (match_operand:HI 1 "general_operand" "0")
1212 (match_operand:HI 2 "general_operand" "dmn")))]
1213 ""
1214 "and%.l %#0xFFFF,%0\;divu %2,%0")
1215
1216(define_insn "udivhisi3"
1217 [(set (match_operand:HI 0 "general_operand" "=d")
1218 (truncate:HI
1219 (udiv:SI
1220 (match_operand:SI 1 "general_operand" "0")
1221 (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
1222 ""
1223 "divu %2,%0")
1224
1225(define_insn ""
1226 [(set (match_operand:HI 0 "general_operand" "=d")
1227 (truncate:HI (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1228 (match_operand:HI 2 "const_int_operand" "n"))))]
1229 ""
1230 "divu %2,%0")
1231
1232(define_insn "udivsi3"
1233 [(set (match_operand:SI 0 "general_operand" "=d")
1234 (udiv:SI (match_operand:SI 1 "general_operand" "0")
1235 (match_operand:SI 2 "general_operand" "dmsK")))]
1236 "TARGET_68020"
1237 "divu%.l %2,%0,%0")
1238
1239(define_insn "divdf3"
1240 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
1241 (div:DF (match_operand:DF 1 "nonimmediate_operand" "f,f,m")
1242 (match_operand:DF 2 "nonimmediate_operand" "f,m,f")))]
1243 "TARGET_CE"
1244 "@
1245 fdiv%.d %2,%1,%0
1246 fdiv%.d %2,%1,%0
1247 frdiv%.d %1,%2,%0")
1248
1249(define_insn "divsf3"
1250 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
1251 (div:SF (match_operand:SF 1 "nonimmediate_operand" "f,f,m")
1252 (match_operand:SF 2 "nonimmediate_operand" "f,m,f")))]
1253 "TARGET_CE"
1254 "@
1255 fdiv%.s %2,%1,%0
1256 fdiv%.s %2,%1,%0
1257 frdiv%.s %1,%2,%0")
1258\f
1259;; Remainder instructions.
1260
1261(define_insn "modhi3"
1262 [(set (match_operand:HI 0 "general_operand" "=d")
1263 (mod:HI (match_operand:HI 1 "general_operand" "0")
1264 (match_operand:HI 2 "general_operand" "dmn")))]
1265 ""
1266 "extl %0\;divs %2,%0\;swap %0")
1267
1268(define_insn "modhisi3"
1269 [(set (match_operand:HI 0 "general_operand" "=d")
1270 (truncate:HI
1271 (mod:SI
1272 (match_operand:SI 1 "general_operand" "0")
1273 (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
1274 ""
1275 "divs %2,%0\;swap %0")
1276
1277(define_insn ""
1278 [(set (match_operand:HI 0 "general_operand" "=d")
1279 (truncate:HI (mod:SI (match_operand:SI 1 "general_operand" "0")
1280 (match_operand:SI 2 "const_int_operand" "n"))))]
1281 ""
1282 "divs %2,%0\;swap %0")
1283
1284(define_insn "umodhi3"
1285 [(set (match_operand:HI 0 "general_operand" "=d")
1286 (umod:HI (match_operand:HI 1 "general_operand" "0")
1287 (match_operand:HI 2 "general_operand" "dmn")))]
1288 ""
1289 "and%.l %#0xFFFF,%0\;divu %2,%0\;swap %0")
1290
1291(define_insn "umodhisi3"
1292 [(set (match_operand:HI 0 "general_operand" "=d")
1293 (truncate:HI
1294 (umod:SI
1295 (match_operand:SI 1 "general_operand" "0")
1296 (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))]
1297 ""
1298 "divu %2,%0\;swap %0")
1299
1300(define_insn ""
1301 [(set (match_operand:HI 0 "general_operand" "=d")
1302 (truncate:HI (umod:SI (match_operand:SI 1 "general_operand" "0")
1303 (match_operand:SI 2 "const_int_operand" "n"))))]
1304 ""
1305 "divu %2,%0\;swap %0")
1306
1307(define_insn "divmodsi4"
1308 [(set (match_operand:SI 0 "general_operand" "=d")
1309 (div:SI (match_operand:SI 1 "general_operand" "0")
1310 (match_operand:SI 2 "general_operand" "dmsK")))
1311 (set (match_operand:SI 3 "general_operand" "=d")
1312 (mod:SI (match_dup 1) (match_dup 2)))]
1313 "TARGET_68020"
1314 "divs%.l %2,%0,%3")
1315
1316(define_insn "udivmodsi4"
1317 [(set (match_operand:SI 0 "general_operand" "=d")
1318 (udiv:SI (match_operand:SI 1 "general_operand" "0")
1319 (match_operand:SI 2 "general_operand" "dmsK")))
1320 (set (match_operand:SI 3 "general_operand" "=d")
1321 (umod:SI (match_dup 1) (match_dup 2)))]
1322 "TARGET_68020"
1323 "divu%.l %2,%0,%3")
1324\f
1325;; logical-and instructions
1326
1327(define_insn "andsi3"
1328 [(set (match_operand:SI 0 "general_operand" "=m,d")
1329 (and:SI (match_operand:SI 1 "general_operand" "%0,0")
1330 (match_operand:SI 2 "general_operand" "dKs,dmKs")))]
1331 ""
1332 "*
1333{
1334 if (GET_CODE (operands[2]) == CONST_INT
1335 && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
1336 && (DATA_REG_P (operands[0])
1337 || offsettable_memref_p (operands[0])))
1338 {
1339 if (GET_CODE (operands[0]) != REG)
1340 operands[0] = adj_offsettable_operand (operands[0], 2);
3a598fbe 1341 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
85c4c3aa
CH
1342 /* Do not delete a following tstl %0 insn; that would be incorrect. */
1343 CC_STATUS_INIT;
1344 if (operands[2] == const0_rtx)
1345 return \"clr%.w %0\";
1346 return \"and%.w %2,%0\";
1347 }
1348 return \"and%.l %2,%0\";
1349}")
1350
1351(define_insn "andhi3"
1352 [(set (match_operand:HI 0 "general_operand" "=m,d")
1353 (and:HI (match_operand:HI 1 "general_operand" "%0,0")
1354 (match_operand:HI 2 "general_operand" "dn,dmn")))]
1355 ""
1356 "and%.w %2,%0")
1357
1358(define_insn "andqi3"
1359 [(set (match_operand:QI 0 "general_operand" "=m,d")
1360 (and:QI (match_operand:QI 1 "general_operand" "%0,0")
1361 (match_operand:QI 2 "general_operand" "dn,dmn")))]
1362 ""
1363 "and%.b %2,%0")
1364
1365\f
1366;; inclusive-or instructions
1367
1368(define_insn "iorsi3"
1369 [(set (match_operand:SI 0 "general_operand" "=m,d")
1370 (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
1371 (match_operand:SI 2 "general_operand" "dKs,dmKs")))]
1372 ""
1373 "*
1374{
1375 register int logval;
1376 if (GET_CODE (operands[2]) == CONST_INT
1377 && INTVAL (operands[2]) >> 16 == 0
1378 && (DATA_REG_P (operands[0])
1379 || offsettable_memref_p (operands[0])))
1380 {
1381 if (GET_CODE (operands[0]) != REG)
1382 operands[0] = adj_offsettable_operand (operands[0], 2);
1383 /* Do not delete a following tstl %0 insn; that would be incorrect. */
1384 CC_STATUS_INIT;
1385 return \"or%.w %2,%0\";
1386 }
1387 if (GET_CODE (operands[2]) == CONST_INT
1388 && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
1389 && (DATA_REG_P (operands[0])
1390 || offsettable_memref_p (operands[0])))
1391 {
1392 if (DATA_REG_P (operands[0]))
3a598fbe 1393 operands[1] = GEN_INT (logval);
85c4c3aa
CH
1394 else
1395 {
c5c76735
JL
1396 operands[0]
1397 = adj_offsettable_operand (operands[0], 3 - (logval / 8));
3a598fbe 1398 operands[1] = GEN_INT (logval % 8);
85c4c3aa
CH
1399 }
1400 return \"bset %1,%0\";
1401 }
1402 return \"or%.l %2,%0\";
1403}")
1404
1405(define_insn "iorhi3"
1406 [(set (match_operand:HI 0 "general_operand" "=m,d")
1407 (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
1408 (match_operand:HI 2 "general_operand" "dn,dmn")))]
1409 ""
1410 "or%.w %2,%0")
1411
1412(define_insn "iorqi3"
1413 [(set (match_operand:QI 0 "general_operand" "=m,d")
1414 (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
1415 (match_operand:QI 2 "general_operand" "dn,dmn")))]
1416 ""
1417 "or%.b %2,%0")
1418\f
1419;; xor instructions
1420
1421(define_insn "xorsi3"
1422 [(set (match_operand:SI 0 "general_operand" "=do,m")
1423 (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
1424 (match_operand:SI 2 "general_operand" "di,dKs")))]
1425 ""
1426 "*
1427{
1428 if (GET_CODE (operands[2]) == CONST_INT
1429 && INTVAL (operands[2]) >> 16 == 0
1430 && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0])))
1431 {
1432 if (! DATA_REG_P (operands[0]))
1433 operands[0] = adj_offsettable_operand (operands[0], 2);
1434 /* Do not delete a following tstl %0 insn; that would be incorrect. */
1435 CC_STATUS_INIT;
1436 return \"eor%.w %2,%0\";
1437 }
1438 return \"eor%.l %2,%0\";
1439}")
1440
1441(define_insn "xorhi3"
1442 [(set (match_operand:HI 0 "general_operand" "=dm")
1443 (xor:HI (match_operand:HI 1 "general_operand" "%0")
1444 (match_operand:HI 2 "general_operand" "dn")))]
1445 ""
1446 "eor%.w %2,%0")
1447
1448(define_insn "xorqi3"
1449 [(set (match_operand:QI 0 "general_operand" "=dm")
1450 (xor:QI (match_operand:QI 1 "general_operand" "%0")
1451 (match_operand:QI 2 "general_operand" "dn")))]
1452 ""
1453 "eor%.b %2,%0")
1454\f
1455;; negation instructions
1456
1457(define_insn "negsi2"
1458 [(set (match_operand:SI 0 "general_operand" "=dm")
1459 (neg:SI (match_operand:SI 1 "general_operand" "0")))]
1460 ""
1461 "neg%.l %0")
1462
1463(define_insn "neghi2"
1464 [(set (match_operand:HI 0 "general_operand" "=dm")
1465 (neg:HI (match_operand:HI 1 "general_operand" "0")))]
1466 ""
1467 "neg%.w %0")
1468
1469(define_insn "negqi2"
1470 [(set (match_operand:QI 0 "general_operand" "=dm")
1471 (neg:QI (match_operand:QI 1 "general_operand" "0")))]
1472 ""
1473 "neg%.b %0")
1474
1475(define_insn "negsf2"
1476 [(set (match_operand:SF 0 "register_operand" "=f")
1477 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1478 "TARGET_CE"
1479 "fneg%.s %1,%0")
1480
1481(define_insn "negdf2"
1482 [(set (match_operand:DF 0 "register_operand" "=f")
1483 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1484 "TARGET_CE"
1485 "fneg%.d %1,%0")
1486\f
1487;; Absolute value instructions
1488
1489(define_insn "abssf2"
1490 [(set (match_operand:SF 0 "register_operand" "=f")
1491 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1492 "TARGET_CE"
1493 "fabs%.s %1,%0")
1494
1495(define_insn "absdf2"
1496 [(set (match_operand:DF 0 "register_operand" "=f")
1497 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1498 "TARGET_CE"
1499 "fabs%.d %1,%0")
1500\f
1501;; Square root instructions
1502
1503(define_insn "sqrtsf2"
1504 [(set (match_operand:SF 0 "register_operand" "=f")
1505 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1506 "TARGET_CE"
1507 "fsqrt%.s %1,%0")
1508
1509(define_insn "sqrtdf2"
1510 [(set (match_operand:DF 0 "register_operand" "=f")
1511 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1512 "TARGET_CE"
1513 "fsqrt%.d %1,%0")
1514\f
1515;; one complement instructions
1516
1517(define_insn "one_cmplsi2"
1518 [(set (match_operand:SI 0 "general_operand" "=dm")
1519 (not:SI (match_operand:SI 1 "general_operand" "0")))]
1520 ""
1521 "not%.l %0")
1522
1523(define_insn "one_cmplhi2"
1524 [(set (match_operand:HI 0 "general_operand" "=dm")
1525 (not:HI (match_operand:HI 1 "general_operand" "0")))]
1526 ""
1527 "not%.w %0")
1528
1529(define_insn "one_cmplqi2"
1530 [(set (match_operand:QI 0 "general_operand" "=dm")
1531 (not:QI (match_operand:QI 1 "general_operand" "0")))]
1532 ""
1533 "not%.b %0")
1534\f
1535\f
1536;; arithmetic shift instructions
1537;; We don't need the shift memory by 1 bit instruction
1538
1539(define_insn "ashlsi3"
1540 [(set (match_operand:SI 0 "general_operand" "=d")
1541 (ashift:SI (match_operand:SI 1 "general_operand" "0")
1542 (match_operand:SI 2 "general_operand" "dI")))]
1543 ""
1544 "asl%.l %2,%0")
1545
1546(define_insn "ashlhi3"
1547 [(set (match_operand:HI 0 "general_operand" "=d")
1548 (ashift:HI (match_operand:HI 1 "general_operand" "0")
1549 (match_operand:HI 2 "general_operand" "dI")))]
1550 ""
1551 "asl%.w %2,%0")
1552
1553(define_insn "ashlqi3"
1554 [(set (match_operand:QI 0 "general_operand" "=d")
1555 (ashift:QI (match_operand:QI 1 "general_operand" "0")
1556 (match_operand:QI 2 "general_operand" "dI")))]
1557 ""
1558 "asl%.b %2,%0")
1559
1560(define_insn "ashrsi3"
1561 [(set (match_operand:SI 0 "general_operand" "=d")
1562 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
1563 (match_operand:SI 2 "general_operand" "dI")))]
1564 ""
1565 "asr%.l %2,%0")
1566
1567(define_insn "ashrhi3"
1568 [(set (match_operand:HI 0 "general_operand" "=d")
1569 (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
1570 (match_operand:HI 2 "general_operand" "dI")))]
1571 ""
1572 "asr%.w %2,%0")
1573
1574(define_insn "ashrqi3"
1575 [(set (match_operand:QI 0 "general_operand" "=d")
1576 (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
1577 (match_operand:QI 2 "general_operand" "dI")))]
1578 ""
1579 "asr%.b %2,%0")
1580\f
1581;; logical shift instructions
1582
85c4c3aa
CH
1583(define_insn "lshrsi3"
1584 [(set (match_operand:SI 0 "general_operand" "=d")
1585 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1586 (match_operand:SI 2 "general_operand" "dI")))]
1587 ""
1588 "lsr%.l %2,%0")
1589
1590(define_insn "lshrhi3"
1591 [(set (match_operand:HI 0 "general_operand" "=d")
1592 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
1593 (match_operand:HI 2 "general_operand" "dI")))]
1594 ""
1595 "lsr%.w %2,%0")
1596
1597(define_insn "lshrqi3"
1598 [(set (match_operand:QI 0 "general_operand" "=d")
1599 (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
1600 (match_operand:QI 2 "general_operand" "dI")))]
1601 ""
1602 "lsr%.b %2,%0")
1603\f
1604;; rotate instructions
1605
1606(define_insn "rotlsi3"
1607 [(set (match_operand:SI 0 "general_operand" "=d")
1608 (rotate:SI (match_operand:SI 1 "general_operand" "0")
1609 (match_operand:SI 2 "general_operand" "dI")))]
1610 ""
1611 "rol%.l %2,%0")
1612
1613(define_insn "rotlhi3"
1614 [(set (match_operand:HI 0 "general_operand" "=d")
1615 (rotate:HI (match_operand:HI 1 "general_operand" "0")
1616 (match_operand:HI 2 "general_operand" "dI")))]
1617 ""
1618 "rol%.w %2,%0")
1619
1620(define_insn "rotlqi3"
1621 [(set (match_operand:QI 0 "general_operand" "=d")
1622 (rotate:QI (match_operand:QI 1 "general_operand" "0")
1623 (match_operand:QI 2 "general_operand" "dI")))]
1624 ""
1625 "rol%.b %2,%0")
1626
1627(define_insn "rotrsi3"
1628 [(set (match_operand:SI 0 "general_operand" "=d")
1629 (rotatert:SI (match_operand:SI 1 "general_operand" "0")
1630 (match_operand:SI 2 "general_operand" "dI")))]
1631 ""
1632 "ror%.l %2,%0")
1633
1634(define_insn "rotrhi3"
1635 [(set (match_operand:HI 0 "general_operand" "=d")
1636 (rotatert:HI (match_operand:HI 1 "general_operand" "0")
1637 (match_operand:HI 2 "general_operand" "dI")))]
1638 ""
1639 "ror%.w %2,%0")
1640
1641(define_insn "rotrqi3"
1642 [(set (match_operand:QI 0 "general_operand" "=d")
1643 (rotatert:QI (match_operand:QI 1 "general_operand" "0")
1644 (match_operand:QI 2 "general_operand" "dI")))]
1645 ""
1646 "ror%.b %2,%0")
1647\f
1648;; Special cases of bit-field insns which we should
1649;; recognize in preference to the general case.
1650;; These handle aligned 8-bit and 16-bit fields,
1651;; which can usually be done with move instructions.
1652
1653(define_insn ""
83199882 1654 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+do")
85c4c3aa
CH
1655 (match_operand:SI 1 "const_int_operand" "i")
1656 (match_operand:SI 2 "const_int_operand" "i"))
1657 (match_operand:SI 3 "general_operand" "d"))]
1658 "TARGET_68020 && TARGET_BITFIELD
1659 && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
1660 && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
1661 && (GET_CODE (operands[0]) == REG
1662 || ! mode_dependent_address_p (XEXP (operands[0], 0)))"
1663 "*
1664{
1665 if (REG_P (operands[0]))
1666 {
1667 if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32)
1668 return \"bfins %3,[%c2,%c1]%0\";
1669 }
1670 else
1671 operands[0]
1672 = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
1673
1674 if (GET_CODE (operands[3]) == MEM)
1675 operands[3] = adj_offsettable_operand (operands[3],
1676 (32 - INTVAL (operands[1])) / 8);
1677 if (INTVAL (operands[1]) == 8)
1678 return \"mov%.b %3,%0\";
1679 return \"mov%.w %3,%0\";
1680}")
1681
1682(define_insn ""
1683 [(set (match_operand:SI 0 "general_operand" "=&d")
83199882 1684 (zero_extract:SI (match_operand:SI 1 "register_operand" "do")
85c4c3aa
CH
1685 (match_operand:SI 2 "const_int_operand" "i")
1686 (match_operand:SI 3 "const_int_operand" "i")))]
1687 "TARGET_68020 && TARGET_BITFIELD
1688 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
1689 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
1690 && (GET_CODE (operands[1]) == REG
1691 || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
1692 "*
1693{
1694 if (REG_P (operands[1]))
1695 {
1696 if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
1697 return \"bfextu [%c3,%c2]%1,%0\";
1698 }
1699 else
1700 operands[1]
1701 = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
1702
1703 output_asm_insn (\"clrl %0\", operands);
1704 if (GET_CODE (operands[0]) == MEM)
1705 operands[0] = adj_offsettable_operand (operands[0],
1706 (32 - INTVAL (operands[1])) / 8);
1707 if (INTVAL (operands[2]) == 8)
1708 return \"mov%.b %1,%0\";
1709 return \"mov%.w %1,%0\";
1710}")
1711
1712(define_insn ""
1713 [(set (match_operand:SI 0 "general_operand" "=d")
83199882 1714 (sign_extract:SI (match_operand:SI 1 "register_operand" "do")
85c4c3aa
CH
1715 (match_operand:SI 2 "const_int_operand" "i")
1716 (match_operand:SI 3 "const_int_operand" "i")))]
1717 "TARGET_68020 && TARGET_BITFIELD
1718 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
1719 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
1720 && (GET_CODE (operands[1]) == REG
1721 || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
1722 "*
1723{
1724 if (REG_P (operands[1]))
1725 {
1726 if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
1727 return \"bfexts [%c3,%c2]%1,%0\";
1728 }
1729 else
1730 operands[1]
1731 = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
1732
1733 if (INTVAL (operands[2]) == 8)
1734 return \"mov%.b %1,%0\;extb%.l %0\";
1735 return \"mov%.w %1,%0\;ext%.l %0\";
1736}")
1737\f
1738;; Bit field instructions, general cases.
1739;; "o,d" constraint causes a nonoffsettable memref to match the "o"
1740;; so that its address is reloaded.
1741
83199882
RK
1742(define_expand "extv"
1743 [(set (match_operand:SI 0 "general_operand" "")
1744 (sign_extract:SI (match_operand:SI 1 "general_operand" "")
1745 (match_operand:SI 2 "general_operand" "")
1746 (match_operand:SI 3 "general_operand" "")))]
1747 "TARGET_68020 && TARGET_BITFIELD"
1748 "")
1749
1750(define_insn ""
1751 [(set (match_operand:SI 0 "general_operand" "=d")
1752 (sign_extract:SI (match_operand:QI 1 "memory_operand" "o")
1753 (match_operand:SI 2 "general_operand" "di")
1754 (match_operand:SI 3 "general_operand" "di")))]
85c4c3aa
CH
1755 "TARGET_68020 && TARGET_BITFIELD"
1756 "bfexts [%c3,%c2]%1,%0")
1757
83199882
RK
1758(define_expand "extzv"
1759 [(set (match_operand:SI 0 "general_operand" "")
1760 (zero_extract:SI (match_operand:SI 1 "general_operand" "")
1761 (match_operand:SI 2 "general_operand" "")
1762 (match_operand:SI 3 "general_operand" "")))]
1763 "TARGET_68020 && TARGET_BITFIELD"
1764 "")
1765
1766(define_insn ""
1767 [(set (match_operand:SI 0 "general_operand" "=d")
1768 (zero_extract:SI (match_operand:QI 1 "memory_operand" "o")
1769 (match_operand:SI 2 "general_operand" "di")
1770 (match_operand:SI 3 "general_operand" "di")))]
85c4c3aa
CH
1771 "TARGET_68020 && TARGET_BITFIELD"
1772 "bfextu [%c3,%c2]%1,%0")
1773
1774(define_insn ""
83199882
RK
1775 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
1776 (match_operand:SI 1 "general_operand" "di")
1777 (match_operand:SI 2 "general_operand" "di"))
85c4c3aa
CH
1778 (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
1779 (match_operand:SI 3 "const_int_operand" "i,i")))]
1780 "TARGET_68020 && TARGET_BITFIELD
1781 && (INTVAL (operands[3]) == -1
1782 || (GET_CODE (operands[1]) == CONST_INT
1783 && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))"
1784 "*
1785{
1786 CC_STATUS_INIT;
1787 return \"bfchg [%c2,%c1]%0\";
1788}")
1789
1790(define_insn ""
83199882
RK
1791 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
1792 (match_operand:SI 1 "general_operand" "di")
1793 (match_operand:SI 2 "general_operand" "di"))
85c4c3aa
CH
1794 (const_int 0))]
1795 "TARGET_68020 && TARGET_BITFIELD"
1796 "*
1797{
1798 CC_STATUS_INIT;
1799 return \"bfclr [%c2,%c1]%0\";
1800}")
1801
1802(define_insn ""
83199882
RK
1803 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
1804 (match_operand:SI 1 "general_operand" "di")
1805 (match_operand:SI 2 "general_operand" "di"))
85c4c3aa
CH
1806 (const_int -1))]
1807 "TARGET_68020 && TARGET_BITFIELD"
1808 "*
1809{
1810 CC_STATUS_INIT;
1811 return \"bfset [%c2,%c1]%0\";
1812}")
1813
83199882
RK
1814(define_expand "insv"
1815 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
1816 (match_operand:SI 1 "general_operand" "")
1817 (match_operand:SI 2 "general_operand" ""))
1818 (match_operand:SI 3 "general_operand" ""))]
1819 "TARGET_68020 && TARGET_BITFIELD"
1820 "")
1821
1822(define_insn ""
1823 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
1824 (match_operand:SI 1 "general_operand" "di")
1825 (match_operand:SI 2 "general_operand" "di"))
1826 (match_operand:SI 3 "general_operand" "d"))]
85c4c3aa
CH
1827 "TARGET_68020 && TARGET_BITFIELD"
1828 "bfins %3,[%c2,%c1]%0")
1829
1830;; Now recognize bit field insns that operate on registers
1831;; (or at least were intended to do so).
1832
1833(define_insn ""
1834 [(set (match_operand:SI 0 "general_operand" "=d")
83199882 1835 (sign_extract:SI (match_operand:SI 1 "register_operand" "d")
85c4c3aa
CH
1836 (match_operand:SI 2 "general_operand" "di")
1837 (match_operand:SI 3 "general_operand" "di")))]
1838 "TARGET_68020 && TARGET_BITFIELD"
1839 "bfexts [%c3,%c2]%1,%0")
1840
1841(define_insn ""
1842 [(set (match_operand:SI 0 "general_operand" "=d")
83199882 1843 (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
85c4c3aa
CH
1844 (match_operand:SI 2 "general_operand" "di")
1845 (match_operand:SI 3 "general_operand" "di")))]
1846 "TARGET_68020 && TARGET_BITFIELD"
1847 "bfextu [%c3,%c2]%1,%0")
1848
1849(define_insn ""
83199882 1850 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
85c4c3aa
CH
1851 (match_operand:SI 1 "general_operand" "di")
1852 (match_operand:SI 2 "general_operand" "di"))
1853 (const_int 0))]
1854 "TARGET_68020 && TARGET_BITFIELD"
1855 "*
1856{
1857 CC_STATUS_INIT;
1858 return \"bfclr [%c2,%c1]%0\";
1859}")
1860
1861(define_insn ""
83199882 1862 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
85c4c3aa
CH
1863 (match_operand:SI 1 "general_operand" "di")
1864 (match_operand:SI 2 "general_operand" "di"))
1865 (const_int -1))]
1866 "TARGET_68020 && TARGET_BITFIELD"
1867 "*
1868{
1869 CC_STATUS_INIT;
1870 return \"bfset [%c2,%c1]%0\";
1871}")
1872
1873(define_insn ""
83199882 1874 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
85c4c3aa
CH
1875 (match_operand:SI 1 "general_operand" "di")
1876 (match_operand:SI 2 "general_operand" "di"))
1877 (match_operand:SI 3 "general_operand" "d"))]
1878 "TARGET_68020 && TARGET_BITFIELD"
1879 "*
1880{
1881 return \"bfins %3,[%c2,%c1]%0\";
1882}")
1883\f
1884;; Special patterns for optimizing bit-field instructions.
1885
1886(define_insn ""
1887 [(set (cc0)
1888 (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
1889 (match_operand:SI 1 "const_int_operand" "i")
1890 (match_operand:SI 2 "general_operand" "di")))]
1891 "TARGET_68020 && TARGET_BITFIELD"
1892 "*
1893{
1894 if (operands[1] == const1_rtx
1895 && GET_CODE (operands[2]) == CONST_INT)
1896 {
1897 int width = GET_CODE (operands[0]) == REG ? 31 : 7;
c5c76735
JL
1898 return output_btst (operands, GEN_INT (width - INTVAL (operands[2])),
1899 operands[0], insn, 1000);
85c4c3aa
CH
1900 /* Pass 1000 as SIGNPOS argument so that btst will
1901 not think we are testing the sign bit for an `and'
1902 and assume that nonzero implies a negative result. */
1903 }
1904 if (INTVAL (operands[1]) != 32)
1905 cc_status.flags = CC_NOT_NEGATIVE;
1906 return \"bftst [%c2,%c1]%0\";
1907}")
1908
1909;;; now handle the register cases
1910(define_insn ""
1911 [(set (cc0)
83199882 1912 (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
85c4c3aa
CH
1913 (match_operand:SI 1 "const_int_operand" "i")
1914 (match_operand:SI 2 "general_operand" "di")))]
1915 "TARGET_68020 && TARGET_BITFIELD"
1916 "*
1917{
1918 if (operands[1] == const1_rtx
1919 && GET_CODE (operands[2]) == CONST_INT)
1920 {
1921 int width = GET_CODE (operands[0]) == REG ? 31 : 7;
c5c76735
JL
1922 return output_btst (operands, GEN_INT (width - INTVAL (operands[2])),
1923 operands[0], insn, 1000);
85c4c3aa
CH
1924 /* Pass 1000 as SIGNPOS argument so that btst will
1925 not think we are testing the sign bit for an `and'
1926 and assume that nonzero implies a negative result. */
1927 }
1928 if (INTVAL (operands[1]) != 32)
1929 cc_status.flags = CC_NOT_NEGATIVE;
1930 return \"bftst [%c2,%c1]%0\";
1931}")
1932
1933\f
1934(define_insn "seq"
1935 [(set (match_operand:QI 0 "general_operand" "=d")
1936 (eq:QI (cc0) (const_int 0)))]
1937 ""
1938 "*
1939 cc_status = cc_prev_status;
1940 OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\");
1941")
1942
1943(define_insn "sne"
1944 [(set (match_operand:QI 0 "general_operand" "=d")
1945 (ne:QI (cc0) (const_int 0)))]
1946 ""
1947 "*
1948 cc_status = cc_prev_status;
1949 OUTPUT_JUMP (\"sne %0\", \"fsneq %0\", \"sne %0\");
1950")
1951
1952(define_insn "sgt"
1953 [(set (match_operand:QI 0 "general_operand" "=d")
1954 (gt:QI (cc0) (const_int 0)))]
1955 ""
1956 "*
1957 cc_status = cc_prev_status;
1958 OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", \"and%.b %#0xc,%!\;sgt %0\");
1959")
1960
1961(define_insn "sgtu"
1962 [(set (match_operand:QI 0 "general_operand" "=d")
1963 (gtu:QI (cc0) (const_int 0)))]
1964 ""
1965 "* cc_status = cc_prev_status;
1966 return \"shi %0\"; ")
1967
1968(define_insn "slt"
1969 [(set (match_operand:QI 0 "general_operand" "=d")
1970 (lt:QI (cc0) (const_int 0)))]
1971 ""
1972 "* cc_status = cc_prev_status;
1973 OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ")
1974
1975(define_insn "sltu"
1976 [(set (match_operand:QI 0 "general_operand" "=d")
1977 (ltu:QI (cc0) (const_int 0)))]
1978 ""
1979 "* cc_status = cc_prev_status;
1980 return \"scs %0\"; ")
1981
1982(define_insn "sge"
1983 [(set (match_operand:QI 0 "general_operand" "=d")
1984 (ge:QI (cc0) (const_int 0)))]
1985 ""
1986 "* cc_status = cc_prev_status;
1987 OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ")
1988
1989(define_insn "sgeu"
1990 [(set (match_operand:QI 0 "general_operand" "=d")
1991 (geu:QI (cc0) (const_int 0)))]
1992 ""
1993 "* cc_status = cc_prev_status;
1994 return \"scc %0\"; ")
1995
1996(define_insn "sle"
1997 [(set (match_operand:QI 0 "general_operand" "=d")
1998 (le:QI (cc0) (const_int 0)))]
1999 ""
2000 "*
2001 cc_status = cc_prev_status;
2002 OUTPUT_JUMP (\"sle %0\", \"fsle %0\", \"and%.b %#0xc,%!\;sle %0\");
2003")
2004
2005(define_insn "sleu"
2006 [(set (match_operand:QI 0 "general_operand" "=d")
2007 (leu:QI (cc0) (const_int 0)))]
2008 ""
2009 "* cc_status = cc_prev_status;
2010 return \"sls %0\"; ")
2011\f
2012;; Basic conditional jump instructions.
2013
2014(define_insn "beq"
2015 [(set (pc)
2016 (if_then_else (eq (cc0)
2017 (const_int 0))
2018 (label_ref (match_operand 0 "" ""))
2019 (pc)))]
2020 ""
2021 "*
2022{
2023 OUTPUT_JUMP (\"jeq %l0\", \"fbeq %l0\", \"jeq %l0\");
2024}")
2025
2026(define_insn "bne"
2027 [(set (pc)
2028 (if_then_else (ne (cc0)
2029 (const_int 0))
2030 (label_ref (match_operand 0 "" ""))
2031 (pc)))]
2032 ""
2033 "*
2034{
2035 OUTPUT_JUMP (\"jne %l0\", \"fbneq %l0\", \"jne %l0\");
2036}")
2037
2038(define_insn "bgt"
2039 [(set (pc)
2040 (if_then_else (gt (cc0)
2041 (const_int 0))
2042 (label_ref (match_operand 0 "" ""))
2043 (pc)))]
2044 ""
2045 "*
2046 OUTPUT_JUMP (\"jgt %l0\", \"fbgt %l0\", \"and%.b %#0xc,%!\;jgt %l0\");
2047")
2048
2049(define_insn "bgtu"
2050 [(set (pc)
2051 (if_then_else (gtu (cc0)
2052 (const_int 0))
2053 (label_ref (match_operand 0 "" ""))
2054 (pc)))]
2055 ""
2056 "*
2057 return \"jhi %l0\";
2058")
2059
2060(define_insn "blt"
2061 [(set (pc)
2062 (if_then_else (lt (cc0)
2063 (const_int 0))
2064 (label_ref (match_operand 0 "" ""))
2065 (pc)))]
2066 ""
2067 "*
2068 OUTPUT_JUMP (\"jlt %l0\", \"fblt %l0\", \"jmi %l0\");
2069")
2070
2071(define_insn "bltu"
2072 [(set (pc)
2073 (if_then_else (ltu (cc0)
2074 (const_int 0))
2075 (label_ref (match_operand 0 "" ""))
2076 (pc)))]
2077 ""
2078 "*
2079 return \"jcs %l0\";
2080")
2081
2082(define_insn "bge"
2083 [(set (pc)
2084 (if_then_else (ge (cc0)
2085 (const_int 0))
2086 (label_ref (match_operand 0 "" ""))
2087 (pc)))]
2088 ""
2089 "*
2090 OUTPUT_JUMP (\"jge %l0\", \"fbge %l0\", \"jpl %l0\");
2091")
2092
2093(define_insn "bgeu"
2094 [(set (pc)
2095 (if_then_else (geu (cc0)
2096 (const_int 0))
2097 (label_ref (match_operand 0 "" ""))
2098 (pc)))]
2099 ""
2100 "*
2101 return \"jcc %l0\";
2102")
2103
2104(define_insn "ble"
2105 [(set (pc)
2106 (if_then_else (le (cc0)
2107 (const_int 0))
2108 (label_ref (match_operand 0 "" ""))
2109 (pc)))]
2110 ""
2111 "*
2112 OUTPUT_JUMP (\"jle %l0\", \"fble %l0\", \"and%.b %#0xc,%!\;jle %l0\");
2113")
2114
2115(define_insn "bleu"
2116 [(set (pc)
2117 (if_then_else (leu (cc0)
2118 (const_int 0))
2119 (label_ref (match_operand 0 "" ""))
2120 (pc)))]
2121 ""
2122 "*
2123 return \"jls %l0\";
2124")
2125\f
2126;; Negated conditional jump instructions.
2127
2128(define_insn ""
2129 [(set (pc)
2130 (if_then_else (eq (cc0)
2131 (const_int 0))
2132 (pc)
2133 (label_ref (match_operand 0 "" ""))))]
2134 ""
2135 "*
2136{
2137 OUTPUT_JUMP (\"jne %l0\", \"fbneq %l0\", \"jne %l0\");
2138}")
2139
2140(define_insn ""
2141 [(set (pc)
2142 (if_then_else (ne (cc0)
2143 (const_int 0))
2144 (pc)
2145 (label_ref (match_operand 0 "" ""))))]
2146 ""
2147 "*
2148{
2149 OUTPUT_JUMP (\"jeq %l0\", \"fbeq %l0\", \"jeq %l0\");
2150}")
2151
2152(define_insn ""
2153 [(set (pc)
2154 (if_then_else (gt (cc0)
2155 (const_int 0))
2156 (pc)
2157 (label_ref (match_operand 0 "" ""))))]
2158 ""
2159 "*
2160 OUTPUT_JUMP (\"jle %l0\", \"fbngt %l0\", \"and%.b %#0xc,%!\;jle %l0\");
2161")
2162
2163(define_insn ""
2164 [(set (pc)
2165 (if_then_else (gtu (cc0)
2166 (const_int 0))
2167 (pc)
2168 (label_ref (match_operand 0 "" ""))))]
2169 ""
2170 "*
2171 return \"jls %l0\";
2172")
2173
2174(define_insn ""
2175 [(set (pc)
2176 (if_then_else (lt (cc0)
2177 (const_int 0))
2178 (pc)
2179 (label_ref (match_operand 0 "" ""))))]
2180 ""
2181 "*
2182 OUTPUT_JUMP (\"jge %l0\", \"fbnlt %l0\", \"jpl %l0\");
2183")
2184
2185(define_insn ""
2186 [(set (pc)
2187 (if_then_else (ltu (cc0)
2188 (const_int 0))
2189 (pc)
2190 (label_ref (match_operand 0 "" ""))))]
2191 ""
2192 "*
2193 return \"jcc %l0\";
2194")
2195
2196(define_insn ""
2197 [(set (pc)
2198 (if_then_else (ge (cc0)
2199 (const_int 0))
2200 (pc)
2201 (label_ref (match_operand 0 "" ""))))]
2202 ""
2203 "*
2204 OUTPUT_JUMP (\"jlt %l0\", \"fbnge %l0\", \"jmi %l0\");
2205")
2206
2207(define_insn ""
2208 [(set (pc)
2209 (if_then_else (geu (cc0)
2210 (const_int 0))
2211 (pc)
2212 (label_ref (match_operand 0 "" ""))))]
2213 ""
2214 "*
2215 return \"jcs %l0\";
2216")
2217
2218(define_insn ""
2219 [(set (pc)
2220 (if_then_else (le (cc0)
2221 (const_int 0))
2222 (pc)
2223 (label_ref (match_operand 0 "" ""))))]
2224 ""
2225 "*
2226 OUTPUT_JUMP (\"jgt %l0\", \"fbnle %l0\", \"and%.b %#0xc,%!\;jgt %l0\");
2227")
2228
2229(define_insn ""
2230 [(set (pc)
2231 (if_then_else (leu (cc0)
2232 (const_int 0))
2233 (pc)
2234 (label_ref (match_operand 0 "" ""))))]
2235 ""
2236 "*
2237 return \"jhi %l0\";
2238")
2239\f
2240;; Subroutines of "casesi".
2241
2242(define_expand "casesi_1"
2243 [(set (match_operand:SI 3 "general_operand" "")
2244 (plus:SI (match_operand:SI 0 "general_operand" "")
2245 ;; Note operand 1 has been negated!
2246 (match_operand:SI 1 "immediate_operand" "")))
2247 (set (cc0) (compare (match_operand:SI 2 "nonimmediate_operand" "")
2248 (match_dup 3)))
2249 (set (pc) (if_then_else (ltu (cc0) (const_int 0))
2250 (label_ref (match_operand 4 "" "")) (pc)))]
2251 ""
2252 "")
2253
2254(define_expand "casesi_2"
f7936742 2255 [(set (match_operand:HI 0 "" "") (mem:HI (match_operand:SI 1 "" "")))
85c4c3aa
CH
2256 ;; The USE here is so that at least one jump-insn will refer to the label,
2257 ;; to keep it alive in jump_optimize.
2258 (parallel [(set (pc)
f7936742 2259 (plus:SI (pc) (sign_extend:SI (match_dup 0))))
85c4c3aa
CH
2260 (use (label_ref (match_operand 2 "" "")))])]
2261 ""
2262 "")
2263
2264;; Operand 0 is index (in bytes); operand 1 is minimum, operand 2 the maximum;
2265;; operand 3 is CODE_LABEL for the table;
2266;; operand 4 is the CODE_LABEL to go to if index out of range.
2267(define_expand "casesi"
2268 ;; We don't use these for generating the RTL, but we must describe
2269 ;; the operands here.
f7936742 2270 [(match_operand:HI 0 "general_operand" "")
85c4c3aa
CH
2271 (match_operand:SI 1 "immediate_operand" "")
2272 (match_operand:SI 2 "general_operand" "")
2273 (match_operand 3 "" "")
2274 (match_operand 4 "" "")]
2275 ""
2276 "
2277{
2278 rtx table_elt_addr;
2279 rtx index_diff;
2280
2281 operands[1] = negate_rtx (SImode, operands[1]);
2282 index_diff = gen_reg_rtx (SImode);
2283 /* Emit the first few insns. */
2284 emit_insn (gen_casesi_1 (operands[0], operands[1], operands[2],
2285 index_diff, operands[4]));
2286 /* Construct a memory address. This may emit some insns. */
2287 table_elt_addr
2288 = memory_address_noforce
2289 (HImode,
c5c76735
JL
2290 gen_rtx_PLUS (Pmode,
2291 gen_rtx_MULT (Pmode, index_diff, GEN_INT (2)),
2292 gen_rtx_LABEL_REF (Pmode, operands[3])));
85c4c3aa
CH
2293 /* Emit the last few insns. */
2294 emit_insn (gen_casesi_2 (gen_reg_rtx (HImode), table_elt_addr, operands[3]));
2295 DONE;
2296}")
2297
2298;; Recognize one of the insns resulting from casesi_2.
2299(define_insn ""
2300 [(set (pc)
f7936742
RK
2301 (plus:SI (pc)
2302 (sign_extend:SI (match_operand:HI 0 "general_operand" "r"))))
85c4c3aa
CH
2303 (use (label_ref (match_operand 1 "" "")))]
2304 ""
2305 "*
2306 return \"jmp pc@(2:B)[%0:W:B]\";
2307")
2308\f
2309;; Unconditional and other jump instructions
2310(define_insn "jump"
2311 [(set (pc)
2312 (label_ref (match_operand 0 "" "")))]
2313 ""
2314 "*
2315 return \"jra %l0\";
2316")
2317
2318(define_insn ""
2319 [(set (pc)
2320 (if_then_else
2321 (ne (match_operand:HI 0 "general_operand" "d,m,g")
2322 (const_int 0))
2323 (label_ref (match_operand 1 "" ""))
2324 (pc)))
2325 (set (match_dup 0)
2326 (plus:HI (match_dup 0)
2327 (const_int -1)))]
2328 ""
2329 "@
2330 dbra %0,%l1
2331 subq%.w %#1,%0\;jcc %l1
2332 subq%.w %#1,%0\;cmp%.w %#-1,%0\;jne %l1")
2333
2334(define_insn ""
2335 [(set (pc)
2336 (if_then_else
2337 (ne (match_operand:SI 0 "general_operand" "d,m,g")
2338 (const_int 0))
2339 (label_ref (match_operand 1 "" ""))
2340 (pc)))
2341 (set (match_dup 0)
2342 (plus:SI (match_dup 0)
2343 (const_int -1)))]
2344 ""
2345 "@
2346 dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jcc %l1
2347 subq%.l %#1,%0\;jcc %l1
2348 subq%.l %#1,%0\;cmp%.l %#-1,%0\;jne %l1")
2349
2350;; dbra patterns that use REG_NOTES info generated by strength_reduce.
2351
8f61c2cc
MM
2352(define_expand "decrement_and_branch_until_zero"
2353 [(parallel [(set (pc)
2354 (if_then_else
2355 (ge (match_operand:SI 0 "general_operand" "")
2356 (const_int 1))
2357 (label_ref (match_operand 1 "" ""))
2358 (pc)))
2359 (set (match_dup 0)
2360 (plus:SI (match_dup 0)
2361 (const_int -1)))])]
2362 ""
2363 "")
2364
2365(define_insn ""
85c4c3aa
CH
2366 [(set (pc)
2367 (if_then_else
2368 (ge (match_operand:SI 0 "general_operand" "d,m,g")
2369 (const_int 1))
2370 (label_ref (match_operand 1 "" ""))
2371 (pc)))
2372 (set (match_dup 0)
2373 (plus:SI (match_dup 0)
2374 (const_int -1)))]
2375 "find_reg_note (insn, REG_NONNEG, 0)"
2376 "@
2377 dbra %0,%l1\;clrw %0\;subql %#1,%0\;jcc %l1
2378 subq%.l %#1,%0\;jcc %l1
2379 subq%.l %#1,%0\;cmp%.l %#-1,%0\;jne %l1")
2380
2381;; Call subroutine with no return value.
2382(define_insn "call"
2383 [(call (match_operand:QI 0 "memory_operand" "o")
2384 (match_operand:SI 1 "general_operand" "g"))]
2385 ""
2386 "*
2387{
2388 rtx xoperands[2];
2389 int size = XINT(operands[1],0);
2390
2391 if (size == 0)
2392 output_asm_insn (\"sub%.l a0,a0\;jbsr %0\", operands);
2393 else
2394 {
3a598fbe 2395 xoperands[1] = GEN_INT (size/4);
85c4c3aa
CH
2396 output_asm_insn (\"mov%.l sp,a0\;pea %a1\", xoperands);
2397 output_asm_insn (\"jbsr %0\", operands);
2398 size = size + 4;
3a598fbe 2399 xoperands[1] = GEN_INT (size);
85c4c3aa
CH
2400 if (size <= 8)
2401 output_asm_insn (\"addq%.l %1,sp\", xoperands);
2402 else if (size < 0x8000)
2403 output_asm_insn (\"add%.w %1,sp\", xoperands);
2404 else
2405 output_asm_insn (\"add%.l %1,sp\", xoperands);
2406 }
2407 return \"mov%.l a6@(-4),a0\";
2408}")
2409
2410;; Call subroutine, returning value in operand 0
2411;; (which must be a hard register).
2412(define_insn "call_value"
2413 [(set (match_operand 0 "" "=rf")
2414 (call (match_operand:QI 1 "memory_operand" "o")
2415 (match_operand:SI 2 "general_operand" "g")))]
2416 ""
2417 "*
2418{
2419 rtx xoperands[3];
2420 int size = XINT(operands[2],0);
2421
2422 if (size == 0)
2423 output_asm_insn(\"sub%.l a0,a0\;jbsr %1\", operands);
2424 else
2425 {
3a598fbe 2426 xoperands[2] = GEN_INT (size/4);
85c4c3aa
CH
2427 output_asm_insn (\"mov%.l sp,a0\;pea %a2\", xoperands);
2428 output_asm_insn (\"jbsr %1\", operands);
2429 size = size + 4;
3a598fbe 2430 xoperands[2] = GEN_INT (size);
85c4c3aa
CH
2431 if (size <= 8)
2432 output_asm_insn (\"addq%.l %2,sp\", xoperands);
2433 else if (size < 0x8000)
2434 output_asm_insn (\"add%.w %2,sp\", xoperands);
2435 else
2436 output_asm_insn (\"add%.l %2,sp\", xoperands);
2437 }
2438 return \"mov%.l a6@(-4),a0\";
2439}")
2440
e165d9e5
TW
2441;; Call subroutine returning any type.
2442
2443(define_expand "untyped_call"
2444 [(parallel [(call (match_operand 0 "" "")
2445 (const_int 0))
2446 (match_operand 1 "" "")
2447 (match_operand 2 "" "")])]
2448 ""
2449 "
2450{
2451 int i;
2452
2453 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2454
2455 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2456 {
2457 rtx set = XVECEXP (operands[2], 0, i);
2458 emit_move_insn (SET_DEST (set), SET_SRC (set));
2459 }
2460
2461 /* The optimizer does not know that the call sets the function value
2462 registers we stored in the result block. We avoid problems by
2463 claiming that all hard registers are used and clobbered at this
2464 point. */
2465 emit_insn (gen_blockage ());
2466
2467 DONE;
2468}")
2469
2470;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2471;; all of memory. This blocks insns from being moved across this point.
2472
2473(define_insn "blockage"
2474 [(unspec_volatile [(const_int 0)] 0)]
2475 ""
2476 "")
2477
85c4c3aa
CH
2478(define_insn "nop"
2479 [(const_int 0)]
2480 ""
2481 "nop")
2482\f
2483;; This should not be used unless the add/sub insns can't be.
2484
2485(define_insn ""
2486 [(set (match_operand:SI 0 "general_operand" "=a")
2487 (match_operand:QI 1 "address_operand" "p"))]
2488 ""
2489 "lea %a1,%0")
2490\f
2491;; This is the first machine-dependent peephole optimization.
2492;; It is useful when a floating value is returned from a function call
2493;; and then is moved into an FP register.
2494;; But it is mainly intended to test the support for these optimizations.
2495
2496;Not applicable to Alliant -- floating results are returned in fp0
2497;(define_peephole
2498; [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4)))
2499; (set (match_operand:DF 0 "register_operand" "f")
2500; (match_operand:DF 1 "register_operand" "ad"))]
2501; "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
2502; "*
2503;{
2504; rtx xoperands[2];
c5c76735 2505; xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
85c4c3aa
CH
2506; output_asm_insn (\"mov%.l %1,%@\", xoperands);
2507; output_asm_insn (\"mov%.l %1,%-\", operands);
2508; return \"fmove%.d %+,%0\";
2509;}
2510;")