]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/mn10300/mn10300.md
rtl.h (emit_clobber, [...]): Declare.
[thirdparty/gcc.git] / gcc / config / mn10300 / mn10300.md
CommitLineData
956d6950 1;; GCC machine description for Matsushita MN10300
2f83c7d6
NC
2;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3;; 2007 Free Software Foundation, Inc.
c5c76735 4;; Contributed by Jeff Law (law@cygnus.com).
11bb1f11 5
7ec022b2 6;; This file is part of GCC.
11bb1f11 7
7ec022b2 8;; GCC is free software; you can redistribute it and/or modify
11bb1f11 9;; it under the terms of the GNU General Public License as published by
2f83c7d6 10;; the Free Software Foundation; either version 3, or (at your option)
11bb1f11
JL
11;; any later version.
12
7ec022b2 13;; GCC is distributed in the hope that it will be useful,
11bb1f11
JL
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
2f83c7d6
NC
19;; along with GCC; see the file COPYING3. If not see
20;; <http://www.gnu.org/licenses/>.
11bb1f11
JL
21
22;; The original PO technology requires these to be ordered by speed,
23;; so that assigner will pick the fastest.
24
25;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
27;; Condition code settings.
28;; none - insn does not affect cc
29;; none_0hit - insn does not affect cc but it does modify operand 0
30;; This attribute is used to keep track of when operand 0 changes.
31;; See the description of NOTICE_UPDATE_CC for more info.
956d6950
JL
32;; set_znv - insn sets z,n,v to usable values; c is unusable.
33;; set_zn - insn sets z,n to usable values; v,c are unusable.
11bb1f11
JL
34;; compare - compare instruction
35;; clobber - value of cc is unknown
7ae4afcb 36(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
11bb1f11 37 (const_string "clobber"))
d1776069
AO
38
39(define_constants [
40 (PIC_REG 6)
41 (SP_REG 9)
42
43 (UNSPEC_INT_LABEL 0)
44 (UNSPEC_PIC 1)
45 (UNSPEC_GOT 2)
46 (UNSPEC_GOTOFF 3)
47 (UNSPEC_PLT 4)
48])
14755fb0
KH
49
50(include "predicates.md")
5abc5de9 51(include "constraints.md")
11bb1f11
JL
52\f
53;; ----------------------------------------------------------------------
54;; MOVE INSTRUCTIONS
55;; ----------------------------------------------------------------------
56
57;; movqi
58
59(define_expand "movqi"
60 [(set (match_operand:QI 0 "general_operand" "")
61 (match_operand:QI 1 "general_operand" ""))]
62 ""
63 "
64{
65 /* One of the ops has to be in a register */
66 if (!register_operand (operand0, QImode)
67 && !register_operand (operand1, QImode))
68 operands[1] = copy_to_mode_reg (QImode, operand1);
69}")
70
705ac34f 71(define_insn ""
18e9d2f9
AO
72 [(set (match_operand:QI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
73 (match_operand:QI 1 "general_operand" "0,I,d*xai,m,d*xa,d*xa*f,*f"))]
705ac34f
JL
74 "TARGET_AM33
75 && (register_operand (operands[0], QImode)
76 || register_operand (operands[1], QImode))"
77 "*
78{
79 switch (which_alternative)
80 {
81 case 0:
705ac34f 82 return \"nop\";
5e849f6e 83 case 1:
705ac34f 84 return \"clr %0\";
5e849f6e 85 case 2:
705ac34f
JL
86 if (GET_CODE (operands[1]) == CONST_DOUBLE)
87 {
88 rtx xoperands[2];
89 xoperands[0] = operands[0];
90 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
91 output_asm_insn (\"mov %1,%0\", xoperands);
92 return \"\";
93 }
94
95 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
96 && GET_CODE (operands[1]) == CONST_INT)
97 {
98 HOST_WIDE_INT val = INTVAL (operands[1]);
99
100 if (((val & 0x80) && ! (val & 0xffffff00))
101 || ((val & 0x800000) && ! (val & 0xff000000)))
102 return \"movu %1,%0\";
103 }
104 return \"mov %1,%0\";
5e849f6e
AO
105 case 3:
106 case 4:
705ac34f 107 return \"movbu %1,%0\";
18e9d2f9
AO
108 case 5:
109 case 6:
110 return \"fmov %1,%0\";
69bc71fa 111 default:
dc759020 112 gcc_unreachable ();
705ac34f
JL
113 }
114}"
18e9d2f9 115 [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
705ac34f 116
11bb1f11 117(define_insn ""
f3d6a3cb 118 [(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
5e849f6e 119 (match_operand:QI 1 "general_operand" "0,I,dai,m,d"))]
11bb1f11
JL
120 "register_operand (operands[0], QImode)
121 || register_operand (operands[1], QImode)"
74452ac3
JL
122 "*
123{
124 switch (which_alternative)
125 {
126 case 0:
74452ac3 127 return \"nop\";
5e849f6e 128 case 1:
74452ac3 129 return \"clr %0\";
5e849f6e 130 case 2:
e2bc7d00
JL
131 if (GET_CODE (operands[1]) == CONST_DOUBLE)
132 {
133 rtx xoperands[2];
134 xoperands[0] = operands[0];
135 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
136 output_asm_insn (\"mov %1,%0\", xoperands);
137 return \"\";
138 }
139
74452ac3 140 return \"mov %1,%0\";
5e849f6e
AO
141 case 3:
142 case 4:
74452ac3 143 return \"movbu %1,%0\";
69bc71fa 144 default:
dc759020 145 gcc_unreachable ();
74452ac3
JL
146 }
147}"
5e849f6e 148 [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
11bb1f11
JL
149
150;; movhi
151
152(define_expand "movhi"
153 [(set (match_operand:HI 0 "general_operand" "")
154 (match_operand:HI 1 "general_operand" ""))]
155 ""
156 "
157{
158 /* One of the ops has to be in a register */
159 if (!register_operand (operand1, HImode)
160 && !register_operand (operand0, HImode))
161 operands[1] = copy_to_mode_reg (HImode, operand1);
162}")
163
705ac34f 164(define_insn ""
18e9d2f9
AO
165 [(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
166 (match_operand:HI 1 "general_operand" "0,I,d*x*ai,m,d*x*a,d*x*a*f,*f"))]
705ac34f
JL
167 "TARGET_AM33
168 && (register_operand (operands[0], HImode)
169 || register_operand (operands[1], HImode))"
170 "*
171{
172 switch (which_alternative)
173 {
174 case 0:
705ac34f 175 return \"nop\";
b340d2b8 176 case 1:
705ac34f 177 return \"clr %0\";
b340d2b8 178 case 2:
705ac34f
JL
179 if (GET_CODE (operands[1]) == CONST_DOUBLE)
180 {
181 rtx xoperands[2];
182 xoperands[0] = operands[0];
183 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
184 output_asm_insn (\"mov %1,%0\", xoperands);
185 return \"\";
186 }
187
188 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
189 && GET_CODE (operands[1]) == CONST_INT)
190 {
191 HOST_WIDE_INT val = INTVAL (operands[1]);
192
193 if (((val & 0x80) && ! (val & 0xffffff00))
194 || ((val & 0x800000) && ! (val & 0xff000000)))
195 return \"movu %1,%0\";
196 }
197 return \"mov %1,%0\";
b340d2b8
AO
198 case 3:
199 case 4:
705ac34f 200 return \"movhu %1,%0\";
18e9d2f9
AO
201 case 5:
202 case 6:
203 return \"fmov %1,%0\";
69bc71fa 204 default:
dc759020 205 gcc_unreachable ();
705ac34f
JL
206 }
207}"
18e9d2f9 208 [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
705ac34f 209
11bb1f11 210(define_insn ""
f3d6a3cb 211 [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
b340d2b8 212 (match_operand:HI 1 "general_operand" "0,I,dai,m,d"))]
11bb1f11
JL
213 "register_operand (operands[0], HImode)
214 || register_operand (operands[1], HImode)"
74452ac3
JL
215 "*
216{
217 switch (which_alternative)
218 {
219 case 0:
74452ac3 220 return \"nop\";
b340d2b8 221 case 1:
74452ac3 222 return \"clr %0\";
b340d2b8 223 case 2:
e2bc7d00
JL
224 if (GET_CODE (operands[1]) == CONST_DOUBLE)
225 {
226 rtx xoperands[2];
227 xoperands[0] = operands[0];
228 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
229 output_asm_insn (\"mov %1,%0\", xoperands);
230 return \"\";
231 }
74452ac3 232 return \"mov %1,%0\";
b340d2b8
AO
233 case 3:
234 case 4:
74452ac3 235 return \"movhu %1,%0\";
69bc71fa 236 default:
dc759020 237 gcc_unreachable ();
74452ac3
JL
238 }
239}"
b340d2b8 240 [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
11bb1f11
JL
241
242;; movsi and helpers
243
460f4b9d
JL
244;; We use this to handle addition of two values when one operand is the
245;; stack pointer and the other is a memory reference of some kind. Reload
246;; does not handle them correctly without this expander.
247(define_expand "reload_insi"
248 [(set (match_operand:SI 0 "register_operand" "=a")
249 (match_operand:SI 1 "impossible_plus_operand" ""))
4c742813 250 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
460f4b9d
JL
251 ""
252 "
253{
4c742813
JL
254 if (XEXP (operands[1], 0) == stack_pointer_rtx)
255 {
bb75a000
JL
256 if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
257 && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
258 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
259 emit_move_insn (operands[2],
c5c76735
JL
260 gen_rtx_ZERO_EXTEND
261 (GET_MODE (XEXP (operands[1], 1)),
262 SUBREG_REG (XEXP (operands[1], 1))));
bb75a000
JL
263 else
264 emit_move_insn (operands[2], XEXP (operands[1], 1));
f15ec016 265 emit_move_insn (operands[0], XEXP (operands[1], 0));
4c742813
JL
266 }
267 else
268 {
bb75a000
JL
269 if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
270 && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
271 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
272 emit_move_insn (operands[2],
c5c76735
JL
273 gen_rtx_ZERO_EXTEND
274 (GET_MODE (XEXP (operands[1], 0)),
275 SUBREG_REG (XEXP (operands[1], 0))));
bb75a000
JL
276 else
277 emit_move_insn (operands[2], XEXP (operands[1], 0));
f15ec016 278 emit_move_insn (operands[0], XEXP (operands[1], 1));
4c742813 279 }
460f4b9d
JL
280 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
281 DONE;
282}")
283
d1776069
AO
284(define_insn "pop_pic_reg"
285 [(set (reg:SI PIC_REG)
286 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
287 "reload_completed"
288 "movm (sp),[a2]")
289
11bb1f11
JL
290(define_expand "movsi"
291 [(set (match_operand:SI 0 "general_operand" "")
292 (match_operand:SI 1 "general_operand" ""))]
293 ""
294 "
295{
296 /* One of the ops has to be in a register */
297 if (!register_operand (operand1, SImode)
298 && !register_operand (operand0, SImode))
299 operands[1] = copy_to_mode_reg (SImode, operand1);
d1776069
AO
300 if (flag_pic)
301 {
302 rtx temp;
303 if (SYMBOLIC_CONST_P (operands[1]))
304 {
305 if (GET_CODE (operands[0]) == MEM)
306 operands[1] = force_reg (Pmode, operands[1]);
307 else
308 {
b3a13419
ILT
309 temp = (!can_create_pseudo_p ()
310 ? operands[0]
311 : gen_reg_rtx (Pmode));
d1776069
AO
312 operands[1] = legitimize_pic_address (operands[1], temp);
313 }
314 }
315 else if (GET_CODE (operands[1]) == CONST
316 && GET_CODE (XEXP (operands[1], 0)) == PLUS
317 && SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0)))
318 {
b3a13419 319 temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
d1776069
AO
320 temp = legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0),
321 temp);
322 operands[1] = expand_binop (SImode, add_optab, temp,
323 XEXP (XEXP (operands[1], 0), 1),
b3a13419
ILT
324 (!can_create_pseudo_p ()
325 ? temp
326 : gen_reg_rtx (Pmode)),
d1776069
AO
327 0, OPTAB_LIB_WIDEN);
328 }
329 }
11bb1f11
JL
330}")
331
11bb1f11 332(define_insn ""
f3d6a3cb 333 [(set (match_operand:SI 0 "nonimmediate_operand"
18e9d2f9 334 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,!*y,*f,*f,dxaQ")
74452ac3 335 (match_operand:SI 1 "general_operand"
18e9d2f9 336 "0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,!*y,axR,0,dxaQi*f,*f"))]
11bb1f11
JL
337 "register_operand (operands[0], SImode)
338 || register_operand (operands[1], SImode)"
74452ac3
JL
339 "*
340{
341 switch (which_alternative)
342 {
343 case 0:
344 case 1:
345 return \"nop\";
346 case 2:
347 return \"clr %0\";
348 case 3:
74452ac3
JL
349 case 4:
350 case 5:
351 case 6:
352 case 7:
353 case 8:
354 case 9:
355 case 10:
356 case 11:
357 case 12:
358 case 13:
e2bc7d00
JL
359 if (GET_CODE (operands[1]) == CONST_DOUBLE)
360 {
361 rtx xoperands[2];
362 xoperands[0] = operands[0];
363 xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
364 output_asm_insn (\"mov %1,%0\", xoperands);
365 return \"\";
366 }
705ac34f
JL
367
368 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
369 && GET_CODE (operands[1]) == CONST_INT)
370 {
371 HOST_WIDE_INT val = INTVAL (operands[1]);
372
373 if (((val & 0x80) && ! (val & 0xffffff00))
374 || ((val & 0x800000) && ! (val & 0xff000000)))
375 return \"movu %1,%0\";
376 }
74452ac3 377 return \"mov %1,%0\";
18e9d2f9
AO
378 case 14:
379 return \"nop\";
380 case 15:
381 case 16:
382 return \"fmov %1,%0\";
69bc71fa 383 default:
dc759020 384 gcc_unreachable ();
74452ac3
JL
385 }
386}"
18e9d2f9 387 [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none,none_0hit,none_0hit")])
11bb1f11
JL
388
389(define_expand "movsf"
390 [(set (match_operand:SF 0 "general_operand" "")
391 (match_operand:SF 1 "general_operand" ""))]
392 ""
393 "
394{
395 /* One of the ops has to be in a register */
396 if (!register_operand (operand1, SFmode)
397 && !register_operand (operand0, SFmode))
398 operands[1] = copy_to_mode_reg (SFmode, operand1);
399}")
400
11bb1f11 401(define_insn ""
18e9d2f9
AO
402 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,dx,ax,dx,a,f,dxaQ,daxm,dax")
403 (match_operand:SF 1 "general_operand" "0,0,0,G,G,fdxaQF,f,dax,daxFm"))]
11bb1f11
JL
404 "register_operand (operands[0], SFmode)
405 || register_operand (operands[1], SFmode)"
74452ac3
JL
406 "*
407{
408 switch (which_alternative)
409 {
410 case 0:
411 case 1:
74452ac3 412 case 2:
18e9d2f9 413 return \"nop\";
74452ac3 414 case 3:
18e9d2f9
AO
415 return \"clr %0\";
416 /* case 4: below */
74452ac3 417 case 5:
18e9d2f9
AO
418 case 6:
419 return \"fmov %1, %0\";
420 case 4:
421 case 7:
422 case 8:
705ac34f
JL
423 if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
424 && GET_CODE (operands[1]) == CONST_INT)
425 {
426 HOST_WIDE_INT val = INTVAL (operands[1]);
427
428 if (((val & 0x80) && ! (val & 0xffffff00))
429 || ((val & 0x800000) && ! (val & 0xff000000)))
430 return \"movu %1,%0\";
431 }
74452ac3 432 return \"mov %1,%0\";
69bc71fa 433 default:
dc759020 434 gcc_unreachable ();
74452ac3
JL
435 }
436}"
18e9d2f9 437 [(set_attr "cc" "none,none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
11bb1f11 438
38c37a0e
JL
439(define_expand "movdi"
440 [(set (match_operand:DI 0 "general_operand" "")
441 (match_operand:DI 1 "general_operand" ""))]
442 ""
443 "
444{
445 /* One of the ops has to be in a register */
446 if (!register_operand (operand1, DImode)
447 && !register_operand (operand0, DImode))
448 operands[1] = copy_to_mode_reg (DImode, operand1);
449}")
450
451(define_insn ""
f3d6a3cb 452 [(set (match_operand:DI 0 "nonimmediate_operand"
18e9d2f9 453 "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,*f,*f,*f,dxa,*f,Q")
74452ac3 454 (match_operand:DI 1 "general_operand"
18e9d2f9 455 "0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim,0,*f,dxai,*f,Q,*f"))]
38c37a0e
JL
456 "register_operand (operands[0], DImode)
457 || register_operand (operands[1], DImode)"
862bff88
JL
458 "*
459{
22ef4e9b
JL
460 long val[2];
461 REAL_VALUE_TYPE rv;
462
862bff88
JL
463 switch (which_alternative)
464 {
465 case 0:
466 case 1:
467 return \"nop\";
468
469 case 2:
470 return \"clr %L0\;clr %H0\";
471
472 case 3:
6e755043
JL
473 if (rtx_equal_p (operands[0], operands[1]))
474 return \"sub %L1,%L0\;mov %L0,%H0\";
475 else
476 return \"mov %1,%L0\;mov %L0,%H0\";
862bff88
JL
477 case 4:
478 case 5:
479 case 6:
480 case 7:
481 case 8:
482 case 9:
483 case 10:
74452ac3 484 case 11:
22ef4e9b
JL
485 if (GET_CODE (operands[1]) == CONST_INT)
486 {
212bc5fa
AO
487 rtx low, high;
488 split_double (operands[1], &low, &high);
489 val[0] = INTVAL (low);
490 val[1] = INTVAL (high);
22ef4e9b
JL
491 }
492 if (GET_CODE (operands[1]) == CONST_DOUBLE)
493 {
494 if (GET_MODE (operands[1]) == DFmode)
495 {
496 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
497 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
498 }
499 else if (GET_MODE (operands[1]) == VOIDmode
500 || GET_MODE (operands[1]) == DImode)
501 {
502 val[0] = CONST_DOUBLE_LOW (operands[1]);
503 val[1] = CONST_DOUBLE_HIGH (operands[1]);
504 }
505 }
506
862bff88
JL
507 if (GET_CODE (operands[1]) == MEM
508 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
509 {
510 rtx temp = operands[0];
511
512 while (GET_CODE (temp) == SUBREG)
513 temp = SUBREG_REG (temp);
514
dc759020 515 gcc_assert (GET_CODE (temp) == REG);
862bff88 516
c5c76735 517 if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
862bff88
JL
518 XEXP (operands[1], 0)))
519 return \"mov %H1,%H0\;mov %L1,%L0\";
520 else
521 return \"mov %L1,%L0\;mov %H1,%H0\";
5abc5de9 522
862bff88 523 }
74452ac3
JL
524 else if (GET_CODE (operands[1]) == MEM
525 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
526 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
527 {
528 rtx xoperands[2];
529
530 xoperands[0] = operands[0];
531 xoperands[1] = XEXP (operands[1], 0);
532
533 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
534 xoperands);
535 return \"\";
536 }
862bff88 537 else
22ef4e9b
JL
538 {
539 if ((GET_CODE (operands[1]) == CONST_INT
540 || GET_CODE (operands[1]) == CONST_DOUBLE)
74452ac3
JL
541 && val[0] == 0)
542 {
543 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
544 output_asm_insn (\"clr %L0\", operands);
74452ac3
JL
545 else
546 output_asm_insn (\"mov %L1,%L0\", operands);
547 }
8ca17330
AO
548 else if ((GET_CODE (operands[1]) == CONST_INT
549 || GET_CODE (operands[1]) == CONST_DOUBLE)
550 && (REGNO_REG_CLASS (true_regnum (operands[0]))
551 == EXTENDED_REGS)
705ac34f
JL
552 && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
553 || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
6bb1041e 554 output_asm_insn (\"movu %L1,%L0\", operands);
22ef4e9b
JL
555 else
556 output_asm_insn (\"mov %L1,%L0\", operands);
557
558 if ((GET_CODE (operands[1]) == CONST_INT
559 || GET_CODE (operands[1]) == CONST_DOUBLE)
74452ac3
JL
560 && val[1] == 0)
561 {
562 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
563 output_asm_insn (\"clr %H0\", operands);
74452ac3
JL
564 else
565 output_asm_insn (\"mov %H1,%H0\", operands);
566 }
567 else if ((GET_CODE (operands[1]) == CONST_INT
568 || GET_CODE (operands[1]) == CONST_DOUBLE)
569 && val[0] == val[1])
570 output_asm_insn (\"mov %L0,%H0\", operands);
8ca17330
AO
571 else if ((GET_CODE (operands[1]) == CONST_INT
572 || GET_CODE (operands[1]) == CONST_DOUBLE)
573 && (REGNO_REG_CLASS (true_regnum (operands[0]))
574 == EXTENDED_REGS)
705ac34f
JL
575 && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
576 || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
6bb1041e 577 output_asm_insn (\"movu %H1,%H0\", operands);
22ef4e9b
JL
578 else
579 output_asm_insn (\"mov %H1,%H0\", operands);
580 return \"\";
581 }
18e9d2f9
AO
582 case 12:
583 return \"nop\";
584 case 13:
585 case 14:
586 case 15:
587 return \"fmov %L1, %L0\;fmov %H1, %H0\";
588 case 16:
589 if (GET_CODE (operands[1]) == MEM
590 && GET_CODE (XEXP (operands[1], 0)) == CONST_INT
591 && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
592 return \"fmov %D1, %D0\";
593 else
594 return \"fmov %L1, %L0\;fmov %H1, %H0\";
595 case 17:
596 if (GET_CODE (operands[0]) == MEM
597 && GET_CODE (XEXP (operands[0], 0)) == CONST_INT
598 && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
599 return \"fmov %D1, %D0\";
600 else
601 return \"fmov %L1, %L0\;fmov %H1, %H0\";
69bc71fa 602 default:
dc759020 603 gcc_unreachable ();
862bff88
JL
604 }
605}"
fe7496dd
AO
606 [(set (attr "cc")
607 (cond
608 [
18e9d2f9
AO
609 (ior (lt (symbol_ref "which_alternative") (const_int 2))
610 (eq (symbol_ref "which_alternative") (const_int 12))
611 ) (const_string "none")
fe7496dd
AO
612 (eq (symbol_ref "which_alternative") (const_int 2)
613 ) (const_string "clobber")
614 (eq (symbol_ref "which_alternative") (const_int 3)
615 ) (if_then_else
616 (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
617 (const_int 0)) (const_string "clobber")
618 (const_string "none_0hit"))
619 (ior (eq (symbol_ref "which_alternative") (const_int 8))
620 (eq (symbol_ref "which_alternative") (const_int 9))
621 ) (if_then_else
622 (ne (symbol_ref "mn10300_wide_const_load_uses_clr
623 (operands)")
624 (const_int 0)) (const_string "clobber")
625 (const_string "none_0hit"))
626 ] (const_string "none_0hit")))])
38c37a0e
JL
627
628(define_expand "movdf"
629 [(set (match_operand:DF 0 "general_operand" "")
630 (match_operand:DF 1 "general_operand" ""))]
631 ""
632 "
633{
634 /* One of the ops has to be in a register */
635 if (!register_operand (operand1, DFmode)
636 && !register_operand (operand0, DFmode))
637 operands[1] = copy_to_mode_reg (DFmode, operand1);
638}")
639
640(define_insn ""
f3d6a3cb 641 [(set (match_operand:DF 0 "nonimmediate_operand"
18e9d2f9 642 "=f,dx,ax,dx,f,f,dxa,f,Q,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
74452ac3 643 (match_operand:DF 1 "general_operand"
18e9d2f9 644 "0,0,0,G,f,dxaF,f,Q,f,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
38c37a0e
JL
645 "register_operand (operands[0], DFmode)
646 || register_operand (operands[1], DFmode)"
862bff88
JL
647 "*
648{
22ef4e9b
JL
649 long val[2];
650 REAL_VALUE_TYPE rv;
651
862bff88
JL
652 switch (which_alternative)
653 {
654 case 0:
655 case 1:
18e9d2f9 656 case 2:
862bff88
JL
657 return \"nop\";
658
18e9d2f9 659 case 3:
862bff88
JL
660 return \"clr %L0\;clr %H0\";
661
862bff88
JL
662 case 4:
663 case 5:
664 case 6:
18e9d2f9
AO
665 return \"fmov %L1, %L0\;fmov %H1, %H0\";
666
862bff88 667 case 7:
18e9d2f9
AO
668 if (GET_CODE (operands[1]) == MEM
669 && GET_CODE (XEXP (operands[1], 0)) == CONST_INT
670 && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
671 return \"fmov %D1, %D0\";
672 else
673 return \"fmov %L1, %L0\;fmov %H1, %H0\";
674
862bff88 675 case 8:
18e9d2f9
AO
676 if (GET_CODE (operands[0]) == MEM
677 && GET_CODE (XEXP (operands[0], 0)) == CONST_INT
678 && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
679 return \"fmov %D1, %D0\";
680 else
681 return \"fmov %L1, %L0\;fmov %H1, %H0\";
682
862bff88 683 case 9:
18e9d2f9
AO
684 if (rtx_equal_p (operands[0], operands[1]))
685 return \"sub %L1,%L0\;mov %L0,%H0\";
686 else
687 return \"mov %1,%L0\;mov %L0,%H0\";
862bff88 688 case 10:
74452ac3 689 case 11:
18e9d2f9
AO
690 case 12:
691 case 13:
692 case 14:
693 case 15:
694 case 16:
695 case 17:
22ef4e9b
JL
696 if (GET_CODE (operands[1]) == CONST_INT)
697 {
212bc5fa
AO
698 rtx low, high;
699 split_double (operands[1], &low, &high);
700 val[0] = INTVAL (low);
701 val[1] = INTVAL (high);
22ef4e9b
JL
702 }
703 if (GET_CODE (operands[1]) == CONST_DOUBLE)
704 {
705 if (GET_MODE (operands[1]) == DFmode)
706 {
707 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
708 REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
709 }
710 else if (GET_MODE (operands[1]) == VOIDmode
711 || GET_MODE (operands[1]) == DImode)
712 {
713 val[0] = CONST_DOUBLE_LOW (operands[1]);
714 val[1] = CONST_DOUBLE_HIGH (operands[1]);
715 }
716 }
717
862bff88
JL
718 if (GET_CODE (operands[1]) == MEM
719 && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
720 {
721 rtx temp = operands[0];
722
723 while (GET_CODE (temp) == SUBREG)
724 temp = SUBREG_REG (temp);
725
dc759020 726 gcc_assert (GET_CODE (temp) == REG);
862bff88 727
c5c76735 728 if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
862bff88
JL
729 XEXP (operands[1], 0)))
730 return \"mov %H1,%H0\;mov %L1,%L0\";
731 else
732 return \"mov %L1,%L0\;mov %H1,%H0\";
5abc5de9 733
862bff88 734 }
74452ac3
JL
735 else if (GET_CODE (operands[1]) == MEM
736 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
737 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
738 {
739 rtx xoperands[2];
740
741 xoperands[0] = operands[0];
742 xoperands[1] = XEXP (operands[1], 0);
743
744 output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
745 xoperands);
746 return \"\";
747 }
862bff88 748 else
22ef4e9b
JL
749 {
750 if ((GET_CODE (operands[1]) == CONST_INT
751 || GET_CODE (operands[1]) == CONST_DOUBLE)
74452ac3
JL
752 && val[0] == 0)
753 {
754 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
755 output_asm_insn (\"clr %L0\", operands);
74452ac3
JL
756 else
757 output_asm_insn (\"mov %L1,%L0\", operands);
758 }
8ca17330
AO
759 else if ((GET_CODE (operands[1]) == CONST_INT
760 || GET_CODE (operands[1]) == CONST_DOUBLE)
761 && (REGNO_REG_CLASS (true_regnum (operands[0]))
762 == EXTENDED_REGS)
705ac34f
JL
763 && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
764 || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
6bb1041e 765 output_asm_insn (\"movu %L1,%L0\", operands);
22ef4e9b
JL
766 else
767 output_asm_insn (\"mov %L1,%L0\", operands);
768
769 if ((GET_CODE (operands[1]) == CONST_INT
770 || GET_CODE (operands[1]) == CONST_DOUBLE)
74452ac3
JL
771 && val[1] == 0)
772 {
773 if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
774 output_asm_insn (\"clr %H0\", operands);
74452ac3
JL
775 else
776 output_asm_insn (\"mov %H1,%H0\", operands);
777 }
778 else if ((GET_CODE (operands[1]) == CONST_INT
779 || GET_CODE (operands[1]) == CONST_DOUBLE)
780 && val[0] == val[1])
781 output_asm_insn (\"mov %L0,%H0\", operands);
8ca17330
AO
782 else if ((GET_CODE (operands[1]) == CONST_INT
783 || GET_CODE (operands[1]) == CONST_DOUBLE)
784 && (REGNO_REG_CLASS (true_regnum (operands[0]))
785 == EXTENDED_REGS)
705ac34f
JL
786 && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
787 || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
6bb1041e 788 output_asm_insn (\"movu %H1,%H0\", operands);
22ef4e9b
JL
789 else
790 output_asm_insn (\"mov %H1,%H0\", operands);
791 return \"\";
792 }
69bc71fa 793 default:
dc759020 794 gcc_unreachable ();
862bff88
JL
795 }
796}"
fe7496dd
AO
797 [(set (attr "cc")
798 (cond
799 [
18e9d2f9 800 (lt (symbol_ref "which_alternative") (const_int 3)
fe7496dd 801 ) (const_string "none")
fe7496dd 802 (eq (symbol_ref "which_alternative") (const_int 3)
18e9d2f9
AO
803 ) (const_string "clobber")
804 (eq (symbol_ref "which_alternative") (const_int 9)
fe7496dd
AO
805 ) (if_then_else
806 (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
807 (const_int 0)) (const_string "clobber")
808 (const_string "none_0hit"))
18e9d2f9
AO
809 (ior (eq (symbol_ref "which_alternative") (const_int 14))
810 (eq (symbol_ref "which_alternative") (const_int 15))
fe7496dd
AO
811 ) (if_then_else
812 (ne (symbol_ref "mn10300_wide_const_load_uses_clr
813 (operands)")
814 (const_int 0)) (const_string "clobber")
815 (const_string "none_0hit"))
816 ] (const_string "none_0hit")))])
b32eba4a 817
38c37a0e 818
11bb1f11
JL
819\f
820;; ----------------------------------------------------------------------
821;; TEST INSTRUCTIONS
822;; ----------------------------------------------------------------------
823
824;; Go ahead and define tstsi so we can eliminate redundant tst insns
825;; when we start trying to optimize this port.
826(define_insn "tstsi"
4d1a91c2 827 [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
11bb1f11 828 ""
22ef4e9b 829 "* return output_tst (operands[0], insn);"
d116300b 830 [(set_attr "cc" "set_znv")])
22ef4e9b 831
705ac34f
JL
832(define_insn ""
833 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))]
834 "TARGET_AM33"
835 "* return output_tst (operands[0], insn);"
836 [(set_attr "cc" "set_znv")])
837
22ef4e9b 838(define_insn ""
4d1a91c2 839 [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
22ef4e9b
JL
840 ""
841 "* return output_tst (operands[0], insn);"
d116300b 842 [(set_attr "cc" "set_znv")])
22ef4e9b 843
705ac34f
JL
844(define_insn ""
845 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))]
846 "TARGET_AM33"
847 "* return output_tst (operands[0], insn);"
848 [(set_attr "cc" "set_znv")])
849
22ef4e9b 850(define_insn ""
4d1a91c2 851 [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
22ef4e9b
JL
852 ""
853 "* return output_tst (operands[0], insn);"
d116300b 854 [(set_attr "cc" "set_znv")])
11bb1f11 855
498cf3d0
MH
856;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
857;; its operands hold equal values, but the operands of a cmp
858;; instruction must be distinct registers. In the case where we'd
859;; like to compare a register to itself, we can achieve this effect
860;; with a btst 0,d0 instead. (This will not alter the contents of d0
861;; but will have the proper effect on cc0. Using d0 is arbitrary; any
862;; data register would work.)
863
2067c116 864;; Even though the first alternative would be preferable if it can
81df85c4
AO
865;; possibly match, reload must not be given the opportunity to attempt
866;; to use it. It assumes that such matches can only occur when one of
867;; the operands is used for input and the other for output. Since
868;; this is not the case, it abort()s. Indeed, such a reload cannot be
869;; possibly satisfied, so just mark the alternative with a `!', so
870;; that it is not considered by reload.
871
11bb1f11
JL
872(define_insn "cmpsi"
873 [(set (cc0)
81df85c4 874 (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
498cf3d0 875 (match_operand:SI 1 "nonmemory_operand" "*0,daxi")))]
11bb1f11 876 ""
3b800f71 877 "@
498cf3d0 878 btst 0,d0
3b800f71 879 cmp %1,%0"
498cf3d0 880 [(set_attr "cc" "compare,compare")])
18e9d2f9
AO
881
882(define_insn "cmpsf"
883 [(set (cc0)
884 (compare (match_operand:SF 0 "register_operand" "f,f")
885 (match_operand:SF 1 "nonmemory_operand" "f,F")))]
886 "TARGET_AM33_2"
887 "fcmp %1,%0"
888 [(set_attr "cc" "compare,compare")])
11bb1f11
JL
889\f
890;; ----------------------------------------------------------------------
891;; ADD INSTRUCTIONS
892;; ----------------------------------------------------------------------
893
894(define_expand "addsi3"
38c37a0e
JL
895 [(set (match_operand:SI 0 "register_operand" "")
896 (plus:SI (match_operand:SI 1 "register_operand" "")
897 (match_operand:SI 2 "nonmemory_operand" "")))]
11bb1f11 898 ""
d25ed420 899 "")
11bb1f11 900
705ac34f 901(define_insn ""
d25ed420 902 [(set (match_operand:SI 0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
8b2cfbe6
AO
903 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,dax")
904 (match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))]
705ac34f
JL
905 "TARGET_AM33"
906 "*
907{
908 switch (which_alternative)
909 {
910 case 0:
911 case 1:
912 return \"inc %0\";
913 case 2:
705ac34f 914 case 3:
8b2cfbe6 915 return \"inc4 %0\";
705ac34f 916 case 4:
705ac34f 917 case 5:
8b2cfbe6
AO
918 return \"add %2,%0\";
919 case 6:
705ac34f
JL
920 {
921 enum reg_class src1_class, src2_class, dst_class;
922
923 src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
924 src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
925 dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
5abc5de9 926
705ac34f
JL
927 /* I'm not sure if this can happen or not. Might as well be prepared
928 and generate the best possible code if it does happen. */
929 if (true_regnum (operands[0]) == true_regnum (operands[1]))
930 return \"add %2,%0\";
931 if (true_regnum (operands[0]) == true_regnum (operands[2]))
932 return \"add %1,%0\";
933
934 /* Catch cases where no extended register was used. These should be
935 handled just like the mn10300. */
936 if (src1_class != EXTENDED_REGS
937 && src2_class != EXTENDED_REGS
938 && dst_class != EXTENDED_REGS)
939 {
940 /* We have to copy one of the sources into the destination, then
941 add the other source to the destination.
942
943 Carefully select which source to copy to the destination; a naive
5abc5de9 944 implementation will waste a byte when the source classes are
705ac34f
JL
945 different and the destination is an address register. Selecting
946 the lowest cost register copy will optimize this sequence. */
947 if (REGNO_REG_CLASS (true_regnum (operands[1]))
948 == REGNO_REG_CLASS (true_regnum (operands[0])))
949 return \"mov %1,%0\;add %2,%0\";
950 return \"mov %2,%0\;add %1,%0\";
951 }
952
953 /* At least one register is an extended register. */
954
955 /* The three operand add instruction on the am33 is a win iff the
956 output register is an extended register, or if both source
957 registers are extended registers. */
958 if (dst_class == EXTENDED_REGS
959 || src1_class == src2_class)
960 return \"add %2,%1,%0\";
961
962 /* It is better to copy one of the sources to the destination, then
963 perform a 2 address add. The destination in this case must be
964 an address or data register and one of the sources must be an
965 extended register and the remaining source must not be an extended
966 register.
967
968 The best code for this case is to copy the extended reg to the
969 destination, then emit a two address add. */
970 if (src1_class == EXTENDED_REGS)
971 return \"mov %1,%0\;add %2,%0\";
972 return \"mov %2,%0\;add %1,%0\";
973 }
69bc71fa 974 default:
dc759020 975 gcc_unreachable ();
705ac34f
JL
976 }
977}"
8b2cfbe6 978 [(set_attr "cc" "set_zn,none_0hit,set_zn,none_0hit,set_zn,none_0hit,set_zn")])
705ac34f 979
11bb1f11 980(define_insn ""
d25ed420 981 [(set (match_operand:SI 0 "register_operand" "=dx,a,a,dax,!*y,!dax")
4d1a91c2
JL
982 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
983 (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
11bb1f11 984 ""
4d1a91c2
JL
985 "*
986{
987 switch (which_alternative)
988 {
989 case 0:
990 case 1:
991 return \"inc %0\";
992 case 2:
993 return \"inc4 %0\";
994 case 3:
995 case 4:
996 return \"add %2,%0\";
997 case 5:
998 /* I'm not sure if this can happen or not. Might as well be prepared
999 and generate the best possible code if it does happen. */
1000 if (true_regnum (operands[0]) == true_regnum (operands[1]))
1001 return \"add %2,%0\";
1002 if (true_regnum (operands[0]) == true_regnum (operands[2]))
1003 return \"add %1,%0\";
1004
1005 /* We have to copy one of the sources into the destination, then add
1006 the other source to the destination.
1007
1008 Carefully select which source to copy to the destination; a naive
1009 implementation will waste a byte when the source classes are different
1010 and the destination is an address register. Selecting the lowest
1011 cost register copy will optimize this sequence. */
1012 if (REGNO_REG_CLASS (true_regnum (operands[1]))
1013 == REGNO_REG_CLASS (true_regnum (operands[0])))
1014 return \"mov %1,%0\;add %2,%0\";
1015 return \"mov %2,%0\;add %1,%0\";
69bc71fa 1016 default:
dc759020 1017 gcc_unreachable ();
4d1a91c2
JL
1018 }
1019}"
d116300b 1020 [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
11bb1f11
JL
1021
1022;; ----------------------------------------------------------------------
1023;; SUBTRACT INSTRUCTIONS
1024;; ----------------------------------------------------------------------
1025
4d1a91c2
JL
1026(define_expand "subsi3"
1027 [(set (match_operand:SI 0 "register_operand" "")
1028 (minus:SI (match_operand:SI 1 "register_operand" "")
1029 (match_operand:SI 2 "nonmemory_operand" "")))]
1030 ""
1031 "")
1032
705ac34f
JL
1033(define_insn ""
1034 [(set (match_operand:SI 0 "register_operand" "=dax,!dax")
1035 (minus:SI (match_operand:SI 1 "register_operand" "0,dax")
1036 (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
1037 "TARGET_AM33"
1038 "*
1039{
1040 if (true_regnum (operands[0]) == true_regnum (operands[1]))
1041 return \"sub %2,%0\";
1042 else
1043 {
1044 enum reg_class src1_class, src2_class, dst_class;
1045
1046 src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
1047 src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
1048 dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
1049
1050 /* If no extended registers are used, then the best way to handle
1051 this is to copy the first source operand into the destination
1052 and emit a two address subtraction. */
1053 if (src1_class != EXTENDED_REGS
1054 && src2_class != EXTENDED_REGS
1055 && dst_class != EXTENDED_REGS
1056 && true_regnum (operands[0]) != true_regnum (operands[2]))
1057 return \"mov %1,%0\;sub %2,%0\";
1058 return \"sub %2,%1,%0\";
1059 }
1060}"
1061 [(set_attr "cc" "set_zn")])
1062
4d1a91c2
JL
1063(define_insn ""
1064 [(set (match_operand:SI 0 "register_operand" "=dax")
11bb1f11 1065 (minus:SI (match_operand:SI 1 "register_operand" "0")
4d1a91c2 1066 (match_operand:SI 2 "nonmemory_operand" "daxi")))]
11bb1f11
JL
1067 ""
1068 "sub %2,%0"
d116300b 1069 [(set_attr "cc" "set_zn")])
11bb1f11
JL
1070
1071(define_expand "negsi2"
1072 [(set (match_operand:SI 0 "register_operand" "")
1073 (neg:SI (match_operand:SI 1 "register_operand" "")))]
1074 ""
1075 "
1076{
1077 rtx target = gen_reg_rtx (SImode);
1078
a556fd39 1079 emit_move_insn (target, const0_rtx);
11bb1f11
JL
1080 emit_insn (gen_subsi3 (target, target, operands[1]));
1081 emit_move_insn (operands[0], target);
1082 DONE;
1083}")
1084
11bb1f11
JL
1085;; ----------------------------------------------------------------------
1086;; MULTIPLY INSTRUCTIONS
1087;; ----------------------------------------------------------------------
1088
705ac34f
JL
1089(define_insn "mulsidi3"
1090 [(set (match_operand:DI 0 "register_operand" "=dax")
1091 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1092 (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1093 "TARGET_AM33"
1094 "mul %1,%2,%H0,%L0"
1095 [(set_attr "cc" "set_zn")])
1096
1097(define_insn "umulsidi3"
1098 [(set (match_operand:DI 0 "register_operand" "=dax")
1099 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1100 (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1101 "TARGET_AM33"
1102 "mulu %1,%2,%H0,%L0"
1103 [(set_attr "cc" "set_zn")])
1104
284280b5
JL
1105(define_expand "mulsi3"
1106 [(set (match_operand:SI 0 "register_operand" "")
1107 (mult:SI (match_operand:SI 1 "register_operand" "")
1108 (match_operand:SI 2 "register_operand" "")))]
1109 ""
1110 "")
1111
705ac34f
JL
1112(define_insn ""
1113 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1114 (mult:SI (match_operand:SI 1 "register_operand" "%0,0")
1115 (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
1116 "TARGET_AM33"
1117 "*
1118{
1119 if (TARGET_MULT_BUG)
1120 return \"nop\;nop\;mul %2,%0\";
1121 else
1122 return \"mul %2,%0\";
1123}"
1124 [(set_attr "cc" "set_zn")])
5abc5de9 1125
284280b5 1126(define_insn ""
4d1a91c2 1127 [(set (match_operand:SI 0 "register_operand" "=dx")
11bb1f11 1128 (mult:SI (match_operand:SI 1 "register_operand" "%0")
4d1a91c2 1129 (match_operand:SI 2 "register_operand" "dx")))]
11bb1f11 1130 ""
a6f7ba17
JL
1131 "*
1132{
1133 if (TARGET_MULT_BUG)
1134 return \"nop\;nop\;mul %2,%0\";
1135 else
1136 return \"mul %2,%0\";
1137}"
d116300b 1138 [(set_attr "cc" "set_zn")])
11bb1f11 1139
6f54921d 1140(define_insn "udivmodsi4"
f3d6a3cb 1141 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
22ef4e9b 1142 (udiv:SI (match_operand:SI 1 "general_operand" "0")
4d1a91c2 1143 (match_operand:SI 2 "general_operand" "dx")))
f3d6a3cb 1144 (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
22ef4e9b 1145 (umod:SI (match_dup 1) (match_dup 2)))]
11bb1f11 1146 ""
22ef4e9b
JL
1147 "*
1148{
6e755043 1149 output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
6f54921d 1150
22ef4e9b
JL
1151 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1152 return \"divu %2,%0\";
1153 else
1154 return \"divu %2,%0\;mov mdr,%3\";
1155}"
d116300b 1156 [(set_attr "cc" "set_zn")])
22ef4e9b 1157
6f54921d 1158(define_insn "divmodsi4"
f3d6a3cb 1159 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
22ef4e9b 1160 (div:SI (match_operand:SI 1 "general_operand" "0")
4d1a91c2 1161 (match_operand:SI 2 "general_operand" "dx")))
f3d6a3cb 1162 (set (match_operand:SI 3 "nonimmediate_operand" "=d")
22ef4e9b
JL
1163 (mod:SI (match_dup 1) (match_dup 2)))]
1164 ""
1165 "*
1166{
1167 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1168 return \"ext %0\;div %2,%0\";
1169 else
1170 return \"ext %0\;div %2,%0\;mov mdr,%3\";
1171}"
d116300b 1172 [(set_attr "cc" "set_zn")])
11bb1f11 1173
11bb1f11
JL
1174\f
1175;; ----------------------------------------------------------------------
1176;; AND INSTRUCTIONS
1177;; ----------------------------------------------------------------------
1178
fed2012b
JL
1179(define_expand "andsi3"
1180 [(set (match_operand:SI 0 "register_operand" "")
1181 (and:SI (match_operand:SI 1 "register_operand" "")
1182 (match_operand:SI 2 "nonmemory_operand" "")))]
1183 ""
1184 "")
1185
705ac34f
JL
1186(define_insn ""
1187 [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
1188 (and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
1189 (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
1190 "TARGET_AM33"
1191 "*
1192{
1193 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1194 return \"extbu %0\";
1195 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1196 return \"exthu %0\";
1197 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1198 return \"add %0,%0\;lsr 1,%0\";
1199 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1200 return \"asl2 %0\;lsr 2,%0\";
1201 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1202 return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1203 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1204 return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1205 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1206 return \"lsr 1,%0\;add %0,%0\";
1207 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1208 return \"lsr 2,%0\;asl2 %0\";
1209 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1210 return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1211 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1212 return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1213 if (REG_P (operands[2]) && REG_P (operands[1])
1214 && true_regnum (operands[0]) != true_regnum (operands[1])
1215 && true_regnum (operands[0]) != true_regnum (operands[2])
1216 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1217 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1218 && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1219 return \"mov %1,%0\;and %2,%0\";
1220 if (REG_P (operands[2]) && REG_P (operands[1])
1221 && true_regnum (operands[0]) != true_regnum (operands[1])
1222 && true_regnum (operands[0]) != true_regnum (operands[2]))
1223 return \"and %1,%2,%0\";
1224 if (REG_P (operands[2]) && REG_P (operands[0])
1225 && true_regnum (operands[2]) == true_regnum (operands[0]))
1226 return \"and %1,%0\";
1227 return \"and %2,%0\";
1228}"
4d76fdaa
AO
1229 [(set (attr "cc")
1230 (cond
1231 [
1232 (eq (symbol_ref "which_alternative") (const_int 0)
1233 ) (const_string "none_0hit")
1234 (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1235 && (INTVAL (operands[2]) == 0x7fffffff
1236 || INTVAL (operands[2]) == 0x3fffffff
1237 || INTVAL (operands[2]) == 0x1fffffff
1238 || INTVAL (operands[2]) == 0x0fffffff
45adea50 1239 || INTVAL (operands[2]) == 0xfffffffe
4d76fdaa
AO
1240 || INTVAL (operands[2]) == 0xfffffffc
1241 || INTVAL (operands[2]) == 0xfffffff8
1242 || INTVAL (operands[2]) == 0xfffffff0)")
1243 (const_int 0)) (const_string "set_zn")
1244 ] (const_string "set_znv")))])
705ac34f 1245
fed2012b 1246(define_insn ""
4d1a91c2 1247 [(set (match_operand:SI 0 "register_operand" "=dx,dx")
38c37a0e 1248 (and:SI (match_operand:SI 1 "register_operand" "%0,0")
4d1a91c2 1249 (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
11bb1f11 1250 ""
38c37a0e
JL
1251 "*
1252{
1253 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1254 return \"extbu %0\";
1255 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1256 return \"exthu %0\";
22ef4e9b
JL
1257 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1258 return \"add %0,%0\;lsr 1,%0\";
1259 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1260 return \"asl2 %0\;lsr 2,%0\";
1261 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1262 return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1263 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1b357872 1264 return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
22ef4e9b
JL
1265 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1266 return \"lsr 1,%0\;add %0,%0\";
1267 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1268 return \"lsr 2,%0\;asl2 %0\";
1269 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1270 return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1271 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1272 return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
38c37a0e
JL
1273 return \"and %2,%0\";
1274}"
4d76fdaa
AO
1275 [(set (attr "cc")
1276 (cond
1277 [
1278 (eq (symbol_ref "which_alternative") (const_int 0)
1279 ) (const_string "none_0hit")
1280 ;; Shifts don't set the V flag, but bitwise operations clear
1281 ;; it (which correctly reflects the absence of overflow in a
1282 ;; compare-with-zero that might follow). As for the
1283 ;; 0xfffffffe case, the add may overflow, so we can't use the
1284 ;; V flag.
1285 (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1286 && (INTVAL (operands[2]) == 0x7fffffff
1287 || INTVAL (operands[2]) == 0x3fffffff
1288 || INTVAL (operands[2]) == 0x1fffffff
1289 || INTVAL (operands[2]) == 0x0fffffff
45adea50 1290 || INTVAL (operands[2]) == 0xfffffffe
4d76fdaa
AO
1291 || INTVAL (operands[2]) == 0xfffffffc
1292 || INTVAL (operands[2]) == 0xfffffff8
1293 || INTVAL (operands[2]) == 0xfffffff0)")
1294 (const_int 0)) (const_string "set_zn")
1295 ] (const_string "set_znv")))])
11bb1f11
JL
1296
1297;; ----------------------------------------------------------------------
1298;; OR INSTRUCTIONS
1299;; ----------------------------------------------------------------------
1300
fed2012b
JL
1301(define_expand "iorsi3"
1302 [(set (match_operand:SI 0 "register_operand" "")
1303 (ior:SI (match_operand:SI 1 "register_operand" "")
1304 (match_operand:SI 2 "nonmemory_operand" "")))]
1305 ""
1306 "")
1307
705ac34f
JL
1308(define_insn ""
1309 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1310 (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
1311 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1312 "TARGET_AM33"
1313 "*
1314{
1315 if (REG_P (operands[2]) && REG_P (operands[1])
1316 && true_regnum (operands[0]) != true_regnum (operands[1])
1317 && true_regnum (operands[0]) != true_regnum (operands[2])
1318 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1319 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1320 && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1321 return \"mov %1,%0\;or %2,%0\";
1322 if (REG_P (operands[2]) && REG_P (operands[1])
1323 && true_regnum (operands[0]) != true_regnum (operands[1])
1324 && true_regnum (operands[0]) != true_regnum (operands[2]))
1325 return \"or %1,%2,%0\";
1326 if (REG_P (operands[2]) && REG_P (operands[0])
1327 && true_regnum (operands[2]) == true_regnum (operands[0]))
1328 return \"or %1,%0\";
1329 return \"or %2,%0\";
1330}"
4d76fdaa 1331 [(set_attr "cc" "set_znv")])
705ac34f 1332
fed2012b 1333(define_insn ""
4d1a91c2 1334 [(set (match_operand:SI 0 "register_operand" "=dx")
11bb1f11 1335 (ior:SI (match_operand:SI 1 "register_operand" "%0")
4d1a91c2 1336 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
11bb1f11
JL
1337 ""
1338 "or %2,%0"
4d76fdaa 1339 [(set_attr "cc" "set_znv")])
11bb1f11
JL
1340
1341;; ----------------------------------------------------------------------
1342;; XOR INSTRUCTIONS
1343;; ----------------------------------------------------------------------
1344
fed2012b
JL
1345(define_expand "xorsi3"
1346 [(set (match_operand:SI 0 "register_operand" "")
1347 (xor:SI (match_operand:SI 1 "register_operand" "")
1348 (match_operand:SI 2 "nonmemory_operand" "")))]
1349 ""
1350 "")
1351
705ac34f
JL
1352(define_insn ""
1353 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1354 (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
1355 (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1356 "TARGET_AM33"
1357 "*
1358{
1359 if (REG_P (operands[2]) && REG_P (operands[1])
1360 && true_regnum (operands[0]) != true_regnum (operands[1])
1361 && true_regnum (operands[0]) != true_regnum (operands[2])
1362 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1363 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1364 && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1365 return \"mov %1,%0\;xor %2,%0\";
1366 if (REG_P (operands[2]) && REG_P (operands[1])
1367 && true_regnum (operands[0]) != true_regnum (operands[1])
1368 && true_regnum (operands[0]) != true_regnum (operands[2]))
1369 return \"xor %1,%2,%0\";
1370 if (REG_P (operands[2]) && REG_P (operands[0])
1371 && true_regnum (operands[2]) == true_regnum (operands[0]))
1372 return \"xor %1,%0\";
1373 return \"xor %2,%0\";
1374}"
4d76fdaa 1375 [(set_attr "cc" "set_znv")])
705ac34f 1376
fed2012b 1377(define_insn ""
4d1a91c2 1378 [(set (match_operand:SI 0 "register_operand" "=dx")
11bb1f11 1379 (xor:SI (match_operand:SI 1 "register_operand" "%0")
4d1a91c2 1380 (match_operand:SI 2 "nonmemory_operand" "dxi")))]
11bb1f11
JL
1381 ""
1382 "xor %2,%0"
4d76fdaa 1383 [(set_attr "cc" "set_znv")])
11bb1f11
JL
1384
1385;; ----------------------------------------------------------------------
1386;; NOT INSTRUCTIONS
1387;; ----------------------------------------------------------------------
1388
fed2012b
JL
1389(define_expand "one_cmplsi2"
1390 [(set (match_operand:SI 0 "register_operand" "")
1391 (not:SI (match_operand:SI 1 "register_operand" "")))]
1392 ""
1393 "")
705ac34f
JL
1394
1395(define_insn ""
1396 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1397 (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
1398 "TARGET_AM33"
1399 "not %0"
4d76fdaa 1400 [(set_attr "cc" "set_znv")])
705ac34f 1401
fed2012b 1402(define_insn ""
4d1a91c2 1403 [(set (match_operand:SI 0 "register_operand" "=dx")
11bb1f11
JL
1404 (not:SI (match_operand:SI 1 "register_operand" "0")))]
1405 ""
1406 "not %0"
4d76fdaa 1407 [(set_attr "cc" "set_znv")])
11bb1f11
JL
1408\f
1409;; -----------------------------------------------------------------
1410;; BIT FIELDS
1411;; -----------------------------------------------------------------
11bb1f11 1412
38c37a0e
JL
1413
1414;; These set/clear memory in byte sized chunks.
1415;;
1416;; They are no smaller/faster than loading the value into a register
1417;; and storing the register, but they don't need a scratch register
1418;; which may allow for better code generation.
1419(define_insn ""
f3d6a3cb 1420 [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))]
38c37a0e
JL
1421 ""
1422 "@
1423 bclr 255,%A0
1424 clr %0"
1425 [(set_attr "cc" "clobber")])
1426
1427(define_insn ""
f3d6a3cb 1428 [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))]
38c37a0e
JL
1429 ""
1430 "@
1431 bset 255,%A0
1432 mov -1,%0"
1433 [(set_attr "cc" "clobber,none_0hit")])
1434
1435(define_insn ""
f3d6a3cb 1436 [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
38c37a0e
JL
1437 (subreg:QI
1438 (and:SI (subreg:SI (match_dup 0) 0)
1439 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1440 ""
1441 "@
1442 bclr %N1,%A0
1443 and %1,%0"
4d76fdaa 1444 [(set_attr "cc" "clobber,set_znv")])
38c37a0e 1445
a58be199
AO
1446(define_insn ""
1447 [(set (match_operand:QI 0 "memory_operand" "=R,T")
1448 (and:QI
1449 (match_dup 0)
1450 (not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))]
1451 ""
1452 "@
1453 bclr %U1,%A0
1454 bclr %1,%0"
1455 [(set_attr "cc" "clobber,clobber")])
1456
38c37a0e 1457(define_insn ""
f3d6a3cb 1458 [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
38c37a0e
JL
1459 (subreg:QI
1460 (ior:SI (subreg:SI (match_dup 0) 0)
1461 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1462 ""
1463 "@
a58be199 1464 bset %U1,%A0
38c37a0e 1465 or %1,%0"
4d76fdaa 1466 [(set_attr "cc" "clobber,set_znv")])
38c37a0e 1467
a58be199
AO
1468(define_expand "iorqi3"
1469 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1470 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
1471 (match_operand:QI 2 "nonmemory_operand" "")))]
1472 ""
1473 "")
1474
1475(define_insn ""
1476 [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,r")
1477 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1478 ;; This constraint should really be nonmemory_operand,
1479 ;; but making it general_operand, along with the
1480 ;; condition that not both input operands are MEMs, it
1481 ;; here helps combine do a better job.
1482 (match_operand:QI 2 "general_operand" "i,d,ir")))]
1483 "TARGET_AM33 &&
1484 (GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM)"
1485 "@
1486 bset %U2,%A0
1487 bset %2,%0
1488 or %2,%0"
4d76fdaa 1489 [(set_attr "cc" "clobber,clobber,set_znv")])
a58be199
AO
1490
1491(define_insn ""
1492 [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,d")
1493 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1494 ;; This constraint should really be nonmemory_operand,
1495 ;; but making it general_operand, along with the
1496 ;; condition that not both input operands are MEMs, it
1497 ;; here helps combine do a better job.
1498 (match_operand:QI 2 "general_operand" "i,d,id")))]
1499 "GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM"
1500 "@
1501 bset %U2,%A0
1502 bset %2,%0
1503 or %2,%0"
4d76fdaa 1504 [(set_attr "cc" "clobber,clobber,set_znv")])
a58be199 1505
38c37a0e
JL
1506(define_insn ""
1507 [(set (cc0)
4d1a91c2 1508 (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
38c37a0e
JL
1509 (match_operand 1 "const_int_operand" "")
1510 (match_operand 2 "const_int_operand" "")))]
1511 ""
1512 "*
1513{
1514 int len = INTVAL (operands[1]);
1515 int bit = INTVAL (operands[2]);
1516 int mask = 0;
1517 rtx xoperands[2];
1518
1519 while (len > 0)
1520 {
1521 mask |= (1 << bit);
1522 bit++;
1523 len--;
1524 }
1525
1526 xoperands[0] = operands[0];
776716da 1527 xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
38c37a0e
JL
1528 output_asm_insn (\"btst %1,%0\", xoperands);
1529 return \"\";
1530}"
d750f6f7 1531 [(set_attr "cc" "clobber")])
38c37a0e
JL
1532
1533(define_insn ""
1534 [(set (cc0)
4d1a91c2 1535 (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
38c37a0e
JL
1536 (match_operand 1 "const_int_operand" "")
1537 (match_operand 2 "const_int_operand" "")))]
f8912297 1538 "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
38c37a0e
JL
1539 "*
1540{
1541 int len = INTVAL (operands[1]);
1542 int bit = INTVAL (operands[2]);
1543 int mask = 0;
1544 rtx xoperands[2];
1545
1546 while (len > 0)
1547 {
1548 mask |= (1 << bit);
1549 bit++;
1550 len--;
1551 }
1552
112cdef5 1553 /* If the source operand is not a reg (i.e. it is memory), then extract the
f8912297
JL
1554 bits from mask that we actually want to test. Note that the mask will
1555 never cross a byte boundary. */
1556 if (!REG_P (operands[0]))
1557 {
1558 if (mask & 0xff)
1559 mask = mask & 0xff;
1560 else if (mask & 0xff00)
1561 mask = (mask >> 8) & 0xff;
1562 else if (mask & 0xff0000)
1563 mask = (mask >> 16) & 0xff;
1564 else if (mask & 0xff000000)
1565 mask = (mask >> 24) & 0xff;
1566 }
5abc5de9 1567
38c37a0e 1568 xoperands[0] = operands[0];
776716da 1569 xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
38c37a0e
JL
1570 if (GET_CODE (operands[0]) == REG)
1571 output_asm_insn (\"btst %1,%0\", xoperands);
1572 else
a58be199 1573 output_asm_insn (\"btst %U1,%A0\", xoperands);
38c37a0e
JL
1574 return \"\";
1575}"
d750f6f7 1576 [(set_attr "cc" "clobber")])
38c37a0e
JL
1577
1578(define_insn ""
4d1a91c2 1579 [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
38c37a0e
JL
1580 (match_operand:SI 1 "const_int_operand" "")))]
1581 ""
1582 "btst %1,%0"
d750f6f7 1583 [(set_attr "cc" "clobber")])
38c37a0e
JL
1584
1585(define_insn ""
1586 [(set (cc0)
1587 (and:SI
4d1a91c2 1588 (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
f8912297 1589 (match_operand:SI 1 "const_8bit_operand" "")))]
38c37a0e
JL
1590 ""
1591 "@
a58be199 1592 btst %U1,%A0
38c37a0e 1593 btst %1,%0"
d750f6f7 1594 [(set_attr "cc" "clobber")])
38c37a0e 1595
11bb1f11
JL
1596\f
1597;; ----------------------------------------------------------------------
1598;; JUMP INSTRUCTIONS
1599;; ----------------------------------------------------------------------
1600
1601;; Conditional jump instructions
1602
1603(define_expand "ble"
1604 [(set (pc)
1605 (if_then_else (le (cc0)
1606 (const_int 0))
1607 (label_ref (match_operand 0 "" ""))
1608 (pc)))]
1609 ""
1610 "")
1611
1612(define_expand "bleu"
1613 [(set (pc)
1614 (if_then_else (leu (cc0)
1615 (const_int 0))
1616 (label_ref (match_operand 0 "" ""))
1617 (pc)))]
1618 ""
1619 "")
1620
1621(define_expand "bge"
1622 [(set (pc)
1623 (if_then_else (ge (cc0)
1624 (const_int 0))
1625 (label_ref (match_operand 0 "" ""))
1626 (pc)))]
1627 ""
1628 "")
1629
1630(define_expand "bgeu"
1631 [(set (pc)
1632 (if_then_else (geu (cc0)
1633 (const_int 0))
1634 (label_ref (match_operand 0 "" ""))
1635 (pc)))]
1636 ""
1637 "")
1638
1639(define_expand "blt"
1640 [(set (pc)
1641 (if_then_else (lt (cc0)
1642 (const_int 0))
1643 (label_ref (match_operand 0 "" ""))
1644 (pc)))]
1645 ""
1646 "")
1647
1648(define_expand "bltu"
1649 [(set (pc)
1650 (if_then_else (ltu (cc0)
1651 (const_int 0))
1652 (label_ref (match_operand 0 "" ""))
1653 (pc)))]
1654 ""
1655 "")
1656
1657(define_expand "bgt"
1658 [(set (pc)
1659 (if_then_else (gt (cc0)
1660 (const_int 0))
1661 (label_ref (match_operand 0 "" ""))
1662 (pc)))]
1663 ""
1664 "")
1665
1666(define_expand "bgtu"
1667 [(set (pc)
1668 (if_then_else (gtu (cc0)
1669 (const_int 0))
1670 (label_ref (match_operand 0 "" ""))
1671 (pc)))]
1672 ""
1673 "")
1674
1675(define_expand "beq"
1676 [(set (pc)
1677 (if_then_else (eq (cc0)
1678 (const_int 0))
1679 (label_ref (match_operand 0 "" ""))
1680 (pc)))]
1681 ""
1682 "")
1683
1684(define_expand "bne"
1685 [(set (pc)
1686 (if_then_else (ne (cc0)
1687 (const_int 0))
1688 (label_ref (match_operand 0 "" ""))
1689 (pc)))]
1690 ""
1691 "")
1692
1693(define_insn ""
1694 [(set (pc)
1695 (if_then_else (match_operator 1 "comparison_operator"
1696 [(cc0) (const_int 0)])
1697 (label_ref (match_operand 0 "" ""))
1698 (pc)))]
1699 ""
82c6faa8
JL
1700 "*
1701{
18e9d2f9
AO
1702 if (cc_status.mdep.fpCC)
1703 return \"fb%b1 %0\";
82c6faa8
JL
1704 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1705 && (GET_CODE (operands[1]) == GT
1706 || GET_CODE (operands[1]) == GE
1707 || GET_CODE (operands[1]) == LE
1708 || GET_CODE (operands[1]) == LT))
1709 return 0;
6e86170d 1710 return \"b%b1 %0\";
82c6faa8 1711}"
11bb1f11
JL
1712 [(set_attr "cc" "none")])
1713
1714(define_insn ""
1715 [(set (pc)
1716 (if_then_else (match_operator 1 "comparison_operator"
1717 [(cc0) (const_int 0)])
1718 (pc)
1719 (label_ref (match_operand 0 "" ""))))]
1720 ""
82c6faa8
JL
1721 "*
1722{
18e9d2f9
AO
1723 if (cc_status.mdep.fpCC)
1724 return \"fb%B1 %0\";
82c6faa8
JL
1725 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1726 && (GET_CODE (operands[1]) == GT
1727 || GET_CODE (operands[1]) == GE
1728 || GET_CODE (operands[1]) == LE
1729 || GET_CODE (operands[1]) == LT))
1730 return 0;
6e86170d 1731 return \"b%B1 %0\";
82c6faa8 1732}"
11bb1f11
JL
1733 [(set_attr "cc" "none")])
1734
1735;; Unconditional and other jump instructions.
1736
1737(define_insn "jump"
1738 [(set (pc)
1739 (label_ref (match_operand 0 "" "")))]
1740 ""
1741 "jmp %l0"
1742 [(set_attr "cc" "none")])
1743
1744(define_insn "indirect_jump"
1745 [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1746 ""
1747 "jmp (%0)"
1748 [(set_attr "cc" "none")])
1749
d1776069
AO
1750(define_expand "builtin_setjmp_receiver"
1751 [(match_operand 0 "" "")]
1752 "flag_pic"
1753 "
1754{
1755 if (flag_pic)
1756 emit_insn (gen_GOTaddr2picreg ());
1757
1758 DONE;
1759}")
1760
1761(define_expand "casesi"
1762 [(match_operand:SI 0 "register_operand" "")
1763 (match_operand:SI 1 "immediate_operand" "")
1764 (match_operand:SI 2 "immediate_operand" "")
1765 (match_operand 3 "" "") (match_operand 4 "" "")]
1766 ""
1767 "
1768{
1769 rtx table = gen_reg_rtx (SImode);
1770 rtx index = gen_reg_rtx (SImode);
1771 rtx addr = gen_reg_rtx (Pmode);
1772
1773 emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
1774 emit_move_insn (index, plus_constant (operands[0], - INTVAL (operands[1])));
1775 emit_insn (gen_cmpsi (index, operands[2]));
1776 emit_jump_insn (gen_bgtu (operands[4]));
a556fd39 1777 emit_move_insn (index, gen_rtx_ASHIFT (SImode, index, const2_rtx));
d1776069
AO
1778 emit_move_insn (addr, gen_rtx_MEM (SImode,
1779 gen_rtx_PLUS (SImode, table, index)));
1780 if (flag_pic)
1781 emit_move_insn (addr, gen_rtx_PLUS (SImode, addr, table));
1782
1783 emit_jump_insn (gen_tablejump (addr, operands[3]));
1784 DONE;
1785}")
1786
11bb1f11
JL
1787(define_insn "tablejump"
1788 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1789 (use (label_ref (match_operand 1 "" "")))]
1790 ""
4f28f058 1791 "jmp (%0)"
11bb1f11
JL
1792 [(set_attr "cc" "none")])
1793
1794;; Call subroutine with no return value.
1795
1796(define_expand "call"
1797 [(call (match_operand:QI 0 "general_operand" "")
1798 (match_operand:SI 1 "general_operand" ""))]
1799 ""
1800 "
1801{
d1776069
AO
1802 if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
1803 {
1804 if (MN10300_GLOBAL_P (XEXP (operands[0], 0)))
1805 {
1806 /* The PLT code won't run on AM30, but then, there's no
1807 shared library support for AM30 either, so we just assume
1808 the linker is going to adjust all @PLT relocs to the
1809 actual symbols. */
c41c1387 1810 emit_use (pic_offset_table_rtx);
d1776069
AO
1811 XEXP (operands[0], 0) = gen_sym2PLT (XEXP (operands[0], 0));
1812 }
1813 else
1814 XEXP (operands[0], 0) = gen_sym2PIC (XEXP (operands[0], 0));
1815 }
69bc71fa 1816 if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
11bb1f11
JL
1817 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1818 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
11bb1f11
JL
1819 DONE;
1820}")
1821
f6284d97
NC
1822;; NB: Mode on match_operand 0 deliberately omitted in
1823;; order to be able to match UNSPECs in PIC mode.
11bb1f11 1824(define_insn "call_internal"
f6284d97 1825 [(call (mem:QI (match_operand 0 "call_address_operand" "aS"))
11bb1f11
JL
1826 (match_operand:SI 1 "general_operand" "g"))]
1827 ""
e5ffb50c
JL
1828 "*
1829{
1830 if (REG_P (operands[0]))
1831 return \"calls %C0\";
1832 else
1833 return \"call %C0,[],0\";
1834}"
11bb1f11
JL
1835 [(set_attr "cc" "clobber")])
1836
1837;; Call subroutine, returning value in operand 0
1838;; (which must be a hard register).
1839
1840(define_expand "call_value"
1841 [(set (match_operand 0 "" "")
1842 (call (match_operand:QI 1 "general_operand" "")
1843 (match_operand:SI 2 "general_operand" "")))]
1844 ""
1845 "
1846{
d1776069
AO
1847 if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
1848 {
1849 if (MN10300_GLOBAL_P (XEXP (operands[1], 0)))
1850 {
1851 /* The PLT code won't run on AM30, but then, there's no
1852 shared library support for AM30 either, so we just assume
1853 the linker is going to adjust all @PLT relocs to the
1854 actual symbols. */
c41c1387 1855 emit_use (pic_offset_table_rtx);
d1776069
AO
1856 XEXP (operands[1], 0) = gen_sym2PLT (XEXP (operands[1], 0));
1857 }
1858 else
1859 XEXP (operands[1], 0) = gen_sym2PIC (XEXP (operands[1], 0));
1860 }
69bc71fa 1861 if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
11bb1f11
JL
1862 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1863 emit_call_insn (gen_call_value_internal (operands[0],
1864 XEXP (operands[1], 0),
1865 operands[2]));
11bb1f11
JL
1866 DONE;
1867}")
1868
f6284d97
NC
1869;; NB: Mode on match_operands 0 and 1 deliberately omitted
1870;; in order to be able to match UNSPECs in PIC mode.
11bb1f11 1871(define_insn "call_value_internal"
f6284d97
NC
1872 [(set (match_operand 0 "register_operand" "=dax")
1873 (call (mem:QI (match_operand 1 "call_address_operand" "aS"))
1874 (match_operand:SI 2 "general_operand" "g")))]
11bb1f11 1875 ""
e5ffb50c
JL
1876 "*
1877{
1878 if (REG_P (operands[1]))
1879 return \"calls %C1\";
1880 else
1881 return \"call %C1,[],0\";
1882}"
11bb1f11
JL
1883 [(set_attr "cc" "clobber")])
1884
6c0870b8
JL
1885(define_expand "untyped_call"
1886 [(parallel [(call (match_operand 0 "" "")
1887 (const_int 0))
1888 (match_operand 1 "" "")
1889 (match_operand 2 "" "")])]
1890 ""
1891 "
1892{
1893 int i;
1894
1895 emit_call_insn (gen_call (operands[0], const0_rtx));
1896
1897 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1898 {
1899 rtx set = XVECEXP (operands[2], 0, i);
1900 emit_move_insn (SET_DEST (set), SET_SRC (set));
1901 }
1902 DONE;
1903}")
1904
11bb1f11
JL
1905(define_insn "nop"
1906 [(const_int 0)]
1907 ""
1908 "nop"
1909 [(set_attr "cc" "none")])
1910\f
1911;; ----------------------------------------------------------------------
1912;; EXTEND INSTRUCTIONS
1913;; ----------------------------------------------------------------------
1914
fed2012b
JL
1915(define_expand "zero_extendqisi2"
1916 [(set (match_operand:SI 0 "general_operand" "")
1917 (zero_extend:SI
1918 (match_operand:QI 1 "general_operand" "")))]
1919 ""
1920 "")
1921
705ac34f 1922(define_insn ""
f3d6a3cb 1923 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
705ac34f
JL
1924 (zero_extend:SI
1925 (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1926 "TARGET_AM33"
1927 "@
1928 extbu %0
1929 mov %1,%0\;extbu %0
1930 movbu %1,%0
1931 extbu %0
1932 mov %1,%0\;extbu %0
1933 movbu %1,%0"
1934 [(set_attr "cc" "none_0hit")])
1935
fed2012b 1936(define_insn ""
f3d6a3cb 1937 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
11bb1f11 1938 (zero_extend:SI
777fbf09 1939 (match_operand:QI 1 "general_operand" "0,d,m")))]
11bb1f11 1940 ""
777fbf09
JL
1941 "@
1942 extbu %0
1943 mov %1,%0\;extbu %0
1944 movbu %1,%0"
82c6faa8 1945 [(set_attr "cc" "none_0hit")])
11bb1f11 1946
fed2012b
JL
1947(define_expand "zero_extendhisi2"
1948 [(set (match_operand:SI 0 "general_operand" "")
1949 (zero_extend:SI
1950 (match_operand:HI 1 "general_operand" "")))]
1951 ""
1952 "")
1953
705ac34f 1954(define_insn ""
f3d6a3cb 1955 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
705ac34f
JL
1956 (zero_extend:SI
1957 (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1958 "TARGET_AM33"
1959 "@
1960 exthu %0
1961 mov %1,%0\;exthu %0
1962 movhu %1,%0
1963 exthu %0
1964 mov %1,%0\;exthu %0
1965 movhu %1,%0"
1966 [(set_attr "cc" "none_0hit")])
1967
fed2012b 1968(define_insn ""
f3d6a3cb 1969 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
11bb1f11 1970 (zero_extend:SI
4d1a91c2 1971 (match_operand:HI 1 "general_operand" "0,dx,m")))]
11bb1f11 1972 ""
777fbf09
JL
1973 "@
1974 exthu %0
1975 mov %1,%0\;exthu %0
1976 movhu %1,%0"
82c6faa8 1977 [(set_attr "cc" "none_0hit")])
11bb1f11
JL
1978
1979;;- sign extension instructions
1980
fed2012b
JL
1981(define_expand "extendqisi2"
1982 [(set (match_operand:SI 0 "general_operand" "")
1983 (sign_extend:SI
1984 (match_operand:QI 1 "general_operand" "")))]
1985 ""
1986 "")
1987
705ac34f 1988(define_insn ""
f3d6a3cb 1989 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
705ac34f
JL
1990 (sign_extend:SI
1991 (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1992 "TARGET_AM33"
1993 "@
1994 extb %0
1995 mov %1,%0\;extb %0
1996 extb %0
1997 mov %1,%0\;extb %0"
1998 [(set_attr "cc" "none_0hit")])
1999
fed2012b 2000(define_insn ""
f3d6a3cb 2001 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
11bb1f11 2002 (sign_extend:SI
4d1a91c2 2003 (match_operand:QI 1 "general_operand" "0,dx")))]
11bb1f11 2004 ""
777fbf09
JL
2005 "@
2006 extb %0
38c37a0e 2007 mov %1,%0\;extb %0"
82c6faa8 2008 [(set_attr "cc" "none_0hit")])
11bb1f11 2009
fed2012b
JL
2010(define_expand "extendhisi2"
2011 [(set (match_operand:SI 0 "general_operand" "")
2012 (sign_extend:SI
2013 (match_operand:HI 1 "general_operand" "")))]
2014 ""
2015 "")
2016
705ac34f 2017(define_insn ""
f3d6a3cb 2018 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
705ac34f
JL
2019 (sign_extend:SI
2020 (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
2021 "TARGET_AM33"
2022 "@
2023 exth %0
2024 mov %1,%0\;exth %0
2025 exth %0
2026 mov %1,%0\;exth %0"
2027 [(set_attr "cc" "none_0hit")])
2028
fed2012b 2029(define_insn ""
f3d6a3cb 2030 [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
11bb1f11 2031 (sign_extend:SI
4d1a91c2 2032 (match_operand:HI 1 "general_operand" "0,dx")))]
11bb1f11 2033 ""
777fbf09
JL
2034 "@
2035 exth %0
38c37a0e 2036 mov %1,%0\;exth %0"
82c6faa8 2037 [(set_attr "cc" "none_0hit")])
11bb1f11
JL
2038\f
2039;; ----------------------------------------------------------------------
2040;; SHIFTS
2041;; ----------------------------------------------------------------------
2042
fed2012b
JL
2043(define_expand "ashlsi3"
2044 [(set (match_operand:SI 0 "register_operand" "")
2045 (ashift:SI
2046 (match_operand:SI 1 "register_operand" "")
2047 (match_operand:QI 2 "nonmemory_operand" "")))]
2048 ""
2049 "")
2050
705ac34f
JL
2051(define_insn ""
2052 [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
2053 (ashift:SI
2054 (match_operand:SI 1 "register_operand" "0,0,dax")
2055 (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
2056 "TARGET_AM33"
2057 "*
2058{
2059 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
2060 return \"add %0,%0\";
2061
2062 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
2063 return \"asl2 %0\";
2064
2065 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
2066 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2067 return \"asl2 %0\;add %0,%0\";
2068
2069 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
2070 && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2071 return \"asl2 %0\;asl2 %0\";
2072
2073 if (true_regnum (operands[1]) == true_regnum (operands[0]))
2074 return \"asl %S2,%0\";
2075
2076 if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2077 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2078 && true_regnum (operands[0]) != true_regnum (operands[2]))
2079 return \"mov %1,%0\;asl %S2,%0\";
2080 return \"asl %2,%1,%0\";
2081}"
2082 [(set_attr "cc" "set_zn")])
2083
fed2012b 2084(define_insn ""
4d1a91c2 2085 [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
11bb1f11 2086 (ashift:SI
3dbc43d1 2087 (match_operand:SI 1 "register_operand" "0,0,0,0,0")
4d1a91c2 2088 (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
11bb1f11
JL
2089 ""
2090 "@
777fbf09 2091 add %0,%0
11bb1f11 2092 asl2 %0
777fbf09 2093 asl2 %0\;add %0,%0
777fbf09 2094 asl2 %0\;asl2 %0
576e5acc 2095 asl %S2,%0"
d116300b 2096 [(set_attr "cc" "set_zn")])
11bb1f11 2097
fed2012b
JL
2098(define_expand "lshrsi3"
2099 [(set (match_operand:SI 0 "register_operand" "")
2100 (lshiftrt:SI
2101 (match_operand:SI 1 "register_operand" "")
2102 (match_operand:QI 2 "nonmemory_operand" "")))]
2103 ""
2104 "")
2105
705ac34f
JL
2106(define_insn ""
2107 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2108 (lshiftrt:SI
2109 (match_operand:SI 1 "register_operand" "0,dax")
2110 (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2111 "TARGET_AM33"
2112 "*
2113{
2114 if (true_regnum (operands[1]) == true_regnum (operands[0]))
2115 return \"lsr %S2,%0\";
2116
2117 if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2118 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2119 && true_regnum (operands[0]) != true_regnum (operands[2]))
2120 return \"mov %1,%0\;lsr %S2,%0\";
2121 return \"lsr %2,%1,%0\";
2122}"
2123 [(set_attr "cc" "set_zn")])
2124
fed2012b 2125(define_insn ""
4d1a91c2 2126 [(set (match_operand:SI 0 "register_operand" "=dx")
11bb1f11
JL
2127 (lshiftrt:SI
2128 (match_operand:SI 1 "register_operand" "0")
4d1a91c2 2129 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
11bb1f11 2130 ""
576e5acc 2131 "lsr %S2,%0"
d116300b 2132 [(set_attr "cc" "set_zn")])
11bb1f11 2133
fed2012b
JL
2134(define_expand "ashrsi3"
2135 [(set (match_operand:SI 0 "register_operand" "")
2136 (ashiftrt:SI
2137 (match_operand:SI 1 "register_operand" "")
2138 (match_operand:QI 2 "nonmemory_operand" "")))]
2139 ""
2140 "")
2141
705ac34f
JL
2142(define_insn ""
2143 [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2144 (ashiftrt:SI
2145 (match_operand:SI 1 "register_operand" "0,dax")
2146 (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2147 "TARGET_AM33"
2148 "*
2149{
2150 if (true_regnum (operands[1]) == true_regnum (operands[0]))
2151 return \"asr %S2,%0\";
2152
2153 if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2154 && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2155 && true_regnum (operands[0]) != true_regnum (operands[2]))
2156 return \"mov %1,%0\;asr %S2,%0\";
2157 return \"asr %2,%1,%0\";
2158}"
2159 [(set_attr "cc" "set_zn")])
2160
fed2012b 2161(define_insn ""
4d1a91c2 2162 [(set (match_operand:SI 0 "register_operand" "=dx")
11bb1f11
JL
2163 (ashiftrt:SI
2164 (match_operand:SI 1 "register_operand" "0")
4d1a91c2 2165 (match_operand:QI 2 "nonmemory_operand" "dxi")))]
11bb1f11 2166 ""
576e5acc 2167 "asr %S2,%0"
d116300b 2168 [(set_attr "cc" "set_zn")])
11bb1f11 2169
9c907d54
JL
2170;; ----------------------------------------------------------------------
2171;; FP INSTRUCTIONS
2172;; ----------------------------------------------------------------------
2173;;
2174;; The mn103 series does not have floating point instructions, but since
2175;; FP values are held in integer regs, we can clear the high bit easily
2176;; which gives us an efficient inline floating point absolute value.
2177;;
2178;; Similarly for negation of a FP value.
2179;;
2180
2181(define_expand "absdf2"
2182 [(set (match_operand:DF 0 "register_operand" "")
2183 (abs:DF (match_operand:DF 1 "register_operand" "")))]
2184 ""
2185 "
2186{
2187 rtx target, result, insns;
2188
2189 start_sequence ();
ebc5a9c1 2190 target = operand_subword (operands[0], 1, 1, DFmode);
9c907d54 2191 result = expand_binop (SImode, and_optab,
ebc5a9c1 2192 operand_subword_force (operands[1], 1, DFmode),
776716da 2193 GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
9c907d54 2194
dc759020 2195 gcc_assert (result);
9c907d54
JL
2196
2197 if (result != target)
2198 emit_move_insn (result, target);
2199
ebc5a9c1
JL
2200 emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2201 operand_subword_force (operands[1], 0, DFmode));
9c907d54
JL
2202
2203 insns = get_insns ();
2204 end_sequence ();
2205
d70dcf29 2206 emit_insn (insns);
9c907d54
JL
2207 DONE;
2208}")
2209
2210(define_expand "abssf2"
2211 [(set (match_operand:SF 0 "register_operand" "")
2212 (abs:SF (match_operand:SF 1 "register_operand" "")))]
2213 ""
2214 "
2215{
2216 rtx result;
2217 rtx target;
2218
18e9d2f9
AO
2219 if (TARGET_AM33_2)
2220 {
2221 emit_insn (gen_abssf2_am33_2 (operands[0], operands[1]));
2222 DONE;
2223 }
2224
9c907d54
JL
2225 target = operand_subword_force (operands[0], 0, SFmode);
2226 result = expand_binop (SImode, and_optab,
2227 operand_subword_force (operands[1], 0, SFmode),
776716da 2228 GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
dc759020 2229 gcc_assert (result);
9c907d54
JL
2230
2231 if (result != target)
2232 emit_move_insn (result, target);
2233
2234 /* Make a place for REG_EQUAL. */
2235 emit_move_insn (operands[0], operands[0]);
2236 DONE;
2237}")
2238
2239
18e9d2f9
AO
2240(define_insn "abssf2_am33_2"
2241 [(set (match_operand:SF 0 "register_operand" "=f,f")
2242 (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2243 "TARGET_AM33_2"
2244 "@
2245 fabs %0
2246 fabs %1, %0"
2247 [(set_attr "cc" "none_0hit")])
2248
9c907d54
JL
2249(define_expand "negdf2"
2250 [(set (match_operand:DF 0 "register_operand" "")
2251 (neg:DF (match_operand:DF 1 "register_operand" "")))]
2252 ""
2253 "
2254{
2255 rtx target, result, insns;
2256
2257 start_sequence ();
ebc5a9c1 2258 target = operand_subword (operands[0], 1, 1, DFmode);
9c907d54 2259 result = expand_binop (SImode, xor_optab,
ebc5a9c1 2260 operand_subword_force (operands[1], 1, DFmode),
776716da
AO
2261 GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2262 target, 0, OPTAB_WIDEN);
9c907d54 2263
dc759020 2264 gcc_assert (result);
9c907d54
JL
2265
2266 if (result != target)
2267 emit_move_insn (result, target);
2268
ebc5a9c1
JL
2269 emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2270 operand_subword_force (operands[1], 0, DFmode));
9c907d54
JL
2271
2272 insns = get_insns ();
2273 end_sequence ();
2274
d70dcf29 2275 emit_insn (insns);
9c907d54
JL
2276 DONE;
2277}")
2278
2279(define_expand "negsf2"
2280 [(set (match_operand:SF 0 "register_operand" "")
2281 (neg:SF (match_operand:SF 1 "register_operand" "")))]
2282 ""
2283 "
2284{
2285 rtx result;
2286 rtx target;
2287
18e9d2f9
AO
2288 if (TARGET_AM33_2)
2289 {
2290 emit_insn (gen_negsf2_am33_2 (operands[0], operands[1]));
2291 DONE;
2292 }
2293
9c907d54
JL
2294 target = operand_subword_force (operands[0], 0, SFmode);
2295 result = expand_binop (SImode, xor_optab,
2296 operand_subword_force (operands[1], 0, SFmode),
776716da
AO
2297 GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2298 target, 0, OPTAB_WIDEN);
dc759020 2299 gcc_assert (result);
9c907d54
JL
2300
2301 if (result != target)
2302 emit_move_insn (result, target);
2303
2304 /* Make a place for REG_EQUAL. */
2305 emit_move_insn (operands[0], operands[0]);
2306 DONE;
2307}")
2308
18e9d2f9
AO
2309(define_insn "negsf2_am33_2"
2310 [(set (match_operand:SF 0 "register_operand" "=f,f")
2311 (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2312 "TARGET_AM33_2"
2313 "@
2314 fneg %0
2315 fneg %1, %0"
2316 [(set_attr "cc" "none_0hit")])
2317
2318(define_expand "sqrtsf2"
2319 [(set (match_operand:SF 0 "register_operand" "")
2320 (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
2321 "TARGET_AM33_2 && flag_unsafe_math_optimizations"
2322 "
2323{
2324 rtx scratch = gen_reg_rtx (SFmode);
2325 emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
2326 emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
2327 scratch));
2328 DONE;
2329}")
2330
2331(define_insn "rsqrtsf2"
2332 [(set (match_operand:SF 0 "register_operand" "=f,f")
2333 (div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
2334 (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))]
2335 "TARGET_AM33_2"
2336 "@
2337 frsqrt %0
2338 frsqrt %1, %0"
2339 [(set_attr "cc" "none_0hit")])
2340
2341(define_insn "addsf3"
2342 [(set (match_operand:SF 0 "register_operand" "=f,f")
2343 (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
2344 (match_operand:SF 2 "general_operand" "f,?fF")))]
2345 "TARGET_AM33_2"
2346 "@
2347 fadd %2, %0
2348 fadd %2, %1, %0"
2349 [(set_attr "cc" "none_0hit")])
2350
2351(define_insn "subsf3"
2352 [(set (match_operand:SF 0 "register_operand" "=f,f")
2353 (minus:SF (match_operand:SF 1 "register_operand" "0,f")
2354 (match_operand:SF 2 "general_operand" "f,?fF")))]
2355 "TARGET_AM33_2"
2356 "@
2357 fsub %2, %0
2358 fsub %2, %1, %0"
2359 [(set_attr "cc" "none_0hit")])
2360
2361(define_insn "mulsf3"
2362 [(set (match_operand:SF 0 "register_operand" "=f,f")
2363 (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
2364 (match_operand:SF 2 "general_operand" "f,?fF")))]
2365 "TARGET_AM33_2"
2366 "@
2367 fmul %2, %0
2368 fmul %2, %1, %0"
2369 [(set_attr "cc" "none_0hit")])
2370
2371(define_insn "divsf3"
2372 [(set (match_operand:SF 0 "register_operand" "=f,f")
2373 (div:SF (match_operand:SF 1 "register_operand" "0,f")
2374 (match_operand:SF 2 "general_operand" "f,?fF")))]
2375 "TARGET_AM33_2"
2376 "@
2377 fdiv %2, %0
2378 fdiv %2, %1, %0"
2379 [(set_attr "cc" "none_0hit")])
2380
2381(define_insn "fmaddsf4"
2382 [(set (match_operand:SF 0 "register_operand" "=A")
2383 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2384 (match_operand:SF 2 "register_operand" "f"))
2385 (match_operand:SF 3 "register_operand" "f")))]
2386 "TARGET_AM33_2"
2387 "fmadd %1, %2, %3, %0"
2388 [(set_attr "cc" "none_0hit")])
2389
2390(define_insn "fmsubsf4"
2391 [(set (match_operand:SF 0 "register_operand" "=A")
2392 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2393 (match_operand:SF 2 "register_operand" "f"))
2394 (match_operand:SF 3 "register_operand" "f")))]
2395 "TARGET_AM33_2"
2396 "fmsub %1, %2, %3, %0"
2397 [(set_attr "cc" "none_0hit")])
2398
2399(define_insn "fnmaddsf4"
2400 [(set (match_operand:SF 0 "register_operand" "=A")
2401 (minus:SF (match_operand:SF 3 "register_operand" "f")
2402 (mult:SF (match_operand:SF 1 "register_operand" "%f")
2403 (match_operand:SF 2 "register_operand" "f"))))]
2404 "TARGET_AM33_2"
2405 "fnmadd %1, %2, %3, %0"
2406 [(set_attr "cc" "none_0hit")])
2407
2408(define_insn "fnmsubsf4"
2409 [(set (match_operand:SF 0 "register_operand" "=A")
2410 (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2411 (match_operand:SF 2 "register_operand" "f")))
2412 (match_operand:SF 3 "register_operand" "f")))]
2413 "TARGET_AM33_2"
2414 "fnmsub %1, %2, %3, %0"
2415 [(set_attr "cc" "none_0hit")])
2416
9c907d54 2417
11bb1f11
JL
2418;; ----------------------------------------------------------------------
2419;; PROLOGUE/EPILOGUE
2420;; ----------------------------------------------------------------------
2421(define_expand "prologue"
2422 [(const_int 0)]
2423 ""
2424 "expand_prologue (); DONE;")
2425
2426(define_expand "epilogue"
2427 [(return)]
2428 ""
2429 "
2430{
2431 expand_epilogue ();
2432 DONE;
2433}")
2434
777fbf09 2435(define_insn "return_internal"
87b5c7e5
JL
2436 [(const_int 2)
2437 (return)]
777fbf09 2438 ""
11bb1f11
JL
2439 "rets"
2440 [(set_attr "cc" "clobber")])
2441
4246e0c5
JL
2442;; This insn restores the callee saved registers and does a return, it
2443;; can also deallocate stack space.
777fbf09 2444(define_insn "return_internal_regs"
11bb1f11 2445 [(const_int 0)
4246e0c5 2446 (match_operand:SI 0 "const_int_operand" "i")
11bb1f11
JL
2447 (return)]
2448 ""
4d1a91c2
JL
2449 "*
2450{
f6cd7c62
RS
2451 fputs (\"\\tret \", asm_out_file);
2452 mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2453 fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
980d0e81 2454 return \"\";
4d1a91c2 2455}"
11bb1f11
JL
2456 [(set_attr "cc" "clobber")])
2457
f6cd7c62 2458;; This instruction matches one generated by mn10300_gen_multiple_store()
11bb1f11 2459(define_insn "store_movm"
f6cd7c62
RS
2460 [(match_parallel 0 "store_multiple_operation"
2461 [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
11bb1f11 2462 ""
4d1a91c2
JL
2463 "*
2464{
f6cd7c62
RS
2465 fputs (\"\\tmovm \", asm_out_file);
2466 mn10300_print_reg_list (asm_out_file,
2467 store_multiple_operation (operands[0], VOIDmode));
2468 fprintf (asm_out_file, \",(sp)\\n\");
980d0e81 2469 return \"\";
4d1a91c2 2470}"
82c6faa8 2471 [(set_attr "cc" "clobber")])
5abc5de9 2472
38c37a0e
JL
2473(define_insn "return"
2474 [(return)]
2475 "can_use_return_insn ()"
74452ac3
JL
2476 "*
2477{
2478 rtx next = next_active_insn (insn);
2479
2480 if (next
2481 && GET_CODE (next) == JUMP_INSN
2482 && GET_CODE (PATTERN (next)) == RETURN)
2483 return \"\";
2484 else
2485 return \"rets\";
2486}"
38c37a0e
JL
2487 [(set_attr "cc" "clobber")])
2488
777fbf09
JL
2489;; Try to combine consecutive updates of the stack pointer (or any
2490;; other register for that matter).
2491(define_peephole
4d1a91c2 2492 [(set (match_operand:SI 0 "register_operand" "=dxay")
777fbf09
JL
2493 (plus:SI (match_dup 0)
2494 (match_operand 1 "const_int_operand" "")))
2495 (set (match_dup 0)
2496 (plus:SI (match_dup 0)
2497 (match_operand 2 "const_int_operand" "")))]
2498 ""
2499 "*
2500{
2501 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2502 return \"add %1,%0\";
2503}"
2504 [(set_attr "cc" "clobber")])
38c37a0e
JL
2505
2506;;
2507;; We had patterns to check eq/ne, but the they don't work because
2508;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2509;;
2510;; The Z flag and C flag would be set, and we have no way to
2511;; check for the Z flag set and C flag clear.
2512;;
2513;; This will work on the mn10200 because we can check the ZX flag
2514;; if the comparison is in HImode.
2515(define_peephole
4d1a91c2 2516 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
38c37a0e
JL
2517 (set (pc) (if_then_else (ge (cc0) (const_int 0))
2518 (match_operand 1 "" "")
2519 (pc)))]
2520 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2521 "add %0,%0\;bcc %1"
2522 [(set_attr "cc" "clobber")])
2523
2524(define_peephole
4d1a91c2 2525 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
38c37a0e
JL
2526 (set (pc) (if_then_else (lt (cc0) (const_int 0))
2527 (match_operand 1 "" "")
2528 (pc)))]
2529 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2530 "add %0,%0\;bcs %1"
2531 [(set_attr "cc" "clobber")])
2532
2533(define_peephole
4d1a91c2 2534 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
38c37a0e
JL
2535 (set (pc) (if_then_else (ge (cc0) (const_int 0))
2536 (pc)
2537 (match_operand 1 "" "")))]
2538 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2539 "add %0,%0\;bcs %1"
2540 [(set_attr "cc" "clobber")])
2541
2542(define_peephole
4d1a91c2 2543 [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
38c37a0e
JL
2544 (set (pc) (if_then_else (lt (cc0) (const_int 0))
2545 (pc)
2546 (match_operand 1 "" "")))]
2547 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2548 "add %0,%0\;bcc %1"
2549 [(set_attr "cc" "clobber")])
460f4b9d 2550
d1776069
AO
2551(define_expand "int_label"
2552 [(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)]
2553 "" "")
2554
2555(define_expand "GOTaddr2picreg"
2556 [(match_dup 0)]
2557 "" "
2558{
2559 /* It would be nice to be able to have int_label keep track of the
2560 counter and all, but if we add C code to it, we'll get an insn
2561 back, and we just want the pattern. */
2562 operands[0] = gen_int_label (GEN_INT (mn10300_unspec_int_label_counter++));
2563 if (TARGET_AM33)
2564 emit_insn (gen_am33_loadPC (operands[0]));
2565 else
2566 emit_insn (gen_mn10300_loadPC (operands[0]));
f6284d97 2567 emit_insn (gen_add_GOT_to_pic_reg (copy_rtx (operands[0])));
d1776069
AO
2568 DONE;
2569}
2570")
2571
2572(define_insn "am33_loadPC"
2573 [(parallel
2574 [(set (reg:SI PIC_REG) (pc))
2575 (use (match_operand 0 "" ""))])]
2576 "TARGET_AM33"
2577 "%0:\;mov pc,a2")
2578
2579
2580(define_insn_and_split "mn10300_loadPC"
2581 [(parallel
2582 [(set (reg:SI PIC_REG) (pc))
2583 (use (match_operand 0 "" ""))])]
2584 ""
2585 "#"
2586 "reload_completed"
2587 [(match_operand 0 "" "")]
2588 "
2589{
2590 rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
2591 int need_stack_space = (get_frame_size () == 0
38173d38 2592 && crtl->outgoing_args_size == 0);
d1776069
AO
2593
2594 if (need_stack_space)
2595 emit_move_insn (sp_reg, plus_constant (sp_reg, -4));
2596
2597 emit_insn (gen_call_next_insn (operands[0]));
2598
2599 if (need_stack_space)
2600 emit_insn (gen_pop_pic_reg ());
2601 else
2602 emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
2603
2604 DONE;
2605}")
2606
2607(define_insn "call_next_insn"
2608 [(parallel
2609 [(set (mem:SI (reg:SI SP_REG)) (pc))
2610 (use (match_operand 0 "" ""))])]
2611 "reload_completed"
2612 "calls %0\;%0:")
2613
2614(define_expand "add_GOT_to_pic_reg"
2615 [(set (reg:SI PIC_REG)
2616 (plus:SI
2617 (reg:SI PIC_REG)
2618 (const
2619 (unspec [(minus:SI
2620 (match_dup 1)
2621 (const (minus:SI
2622 (const (match_operand:SI 0 "" ""))
2623 (pc))))
2624 ] UNSPEC_PIC))))]
2625 ""
2626 "
2627{
2628 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2629}")
2630
2631(define_expand "symGOT2reg"
2632 [(match_operand:SI 0 "" "")
2633 (match_operand:SI 1 "" "")]
2634 ""
2635 "
2636{
2637 rtx insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1]));
2638
389fdba0 2639 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
d1776069 2640
bd94cb6e 2641 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
d1776069
AO
2642
2643 DONE;
2644}")
2645
2646(define_expand "symGOT2reg_i"
2647 [(set (match_operand:SI 0 "" "")
2648 (mem:SI (plus:SI (reg:SI PIC_REG)
2649 (const (unspec [(match_operand:SI 1 "" "")]
2650 UNSPEC_GOT)))))]
2651 ""
2652 "")
2653
2654(define_expand "symGOTOFF2reg"
2655 [(match_operand:SI 0 "" "") (match_operand:SI 1 "" "")]
2656 ""
2657 "
2658{
2659 rtx insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1]));
2660
bd94cb6e 2661 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
d1776069
AO
2662
2663 DONE;
2664}")
2665
2666(define_expand "symGOTOFF2reg_i"
2667 [(set (match_operand:SI 0 "" "")
2668 (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOTOFF)))
2669 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI PIC_REG)))]
2670 ""
2671 "")
2672
2673(define_expand "sym2PIC"
2674 [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC)]
2675 "" "")
2676
2677(define_expand "sym2PLT"
2678 [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT)]
2679 "" "")