]> gcc.gnu.org Git - gcc.git/blame - gcc/config/mn10300/mn10300.md
c++: if consteval and consteval propagation [PR115583]
[gcc.git] / gcc / config / mn10300 / mn10300.md
CommitLineData
956d6950 1;; GCC machine description for Matsushita MN10300
a945c346 2;; Copyright (C) 1996-2024 Free Software Foundation, Inc.
c5c76735 3;; Contributed by Jeff Law (law@cygnus.com).
11bb1f11 4
7ec022b2 5;; This file is part of GCC.
11bb1f11 6
7ec022b2 7;; GCC is free software; you can redistribute it and/or modify
11bb1f11 8;; it under the terms of the GNU General Public License as published by
2f83c7d6 9;; the Free Software Foundation; either version 3, or (at your option)
11bb1f11
JL
10;; any later version.
11
7ec022b2 12;; GCC is distributed in the hope that it will be useful,
11bb1f11
JL
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
2f83c7d6
NC
18;; along with GCC; see the file COPYING3. If not see
19;; <http://www.gnu.org/licenses/>.
11bb1f11
JL
20
21;; The original PO technology requires these to be ordered by speed,
22;; so that assigner will pick the fastest.
23
24;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
25
d1776069 26(define_constants [
c25a21f5
RH
27 (PIC_REG 6)
28 (SP_REG 9)
29 (MDR_REG 50)
30 (CC_REG 51)
d1776069 31
d1776069
AO
32 (UNSPEC_PIC 1)
33 (UNSPEC_GOT 2)
34 (UNSPEC_GOTOFF 3)
35 (UNSPEC_PLT 4)
d4e2d7d2 36 (UNSPEC_GOTSYM_OFF 5)
f3d9d2e0 37
9efb4993 38 (UNSPEC_EXT 6)
f3d9d2e0 39 (UNSPEC_BSCH 7)
298362c8
NC
40
41 ;; This is used to encode LIW patterns.
42 (UNSPEC_LIW 8)
662c03f4
NC
43 ;; This is for the low overhead loop instructions.
44 (UNSPEC_SETLB 9)
d1776069 45])
14755fb0
KH
46
47(include "predicates.md")
5abc5de9 48(include "constraints.md")
f3f63737
NC
49
50;; Processor type. This attribute must exactly match the processor_type
51;; enumeration in mn10300.h.
52(define_attr "cpu" "mn10300,am33,am33_2,am34"
f4a88680 53 (const (symbol_ref "(enum attr_cpu) mn10300_tune_cpu")))
f3f63737 54
a5c727e3
RH
55;; Used to control the "enabled" attribute on a per-instruction basis.
56(define_attr "isa" "base,am33,am33_2,am34"
57 (const_string "base"))
58
59(define_attr "enabled" ""
60 (cond [(eq_attr "isa" "base")
61 (const_int 1)
62
63 (and (eq_attr "isa" "am33")
129043ff 64 (match_test "TARGET_AM33"))
a5c727e3
RH
65 (const_int 1)
66
67 (and (eq_attr "isa" "am33_2")
129043ff 68 (match_test "TARGET_AM33_2"))
a5c727e3
RH
69 (const_int 1)
70
71 (and (eq_attr "isa" "am34")
129043ff 72 (match_test "TARGET_AM34"))
a5c727e3
RH
73 (const_int 1)
74 ]
75 (const_int 0))
76)
d84760c9
RH
77
78(define_mode_iterator INT [QI HI SI])
79
298362c8
NC
80\f
81;; Bundling of smaller insns into a long instruction word (LIW)
82(define_automaton "liw_bundling")
83(automata_option "ndfa")
84
85(define_cpu_unit "liw_op1_u,liw_op2_u" "liw_bundling")
86
87(define_attr "liw" "op1,op2,both,either"
88 (const_string "both"))
89;; Note: this list must match the one defined for liw_op_names[].
90(define_attr "liw_op" "add,cmp,sub,mov,and,or,xor,asr,lsr,asl,none,max"
91 (const_string "none"))
92
93(define_insn_reservation "liw_op1" 1
94 (and (ior (eq_attr "cpu" "am33")
95 (eq_attr "cpu" "am33_2")
96 (eq_attr "cpu" "am34"))
97 (eq_attr "liw" "op1"))
98 "liw_op1_u");
99(define_insn_reservation "liw_op2" 1
100 (and (ior (eq_attr "cpu" "am33")
101 (eq_attr "cpu" "am33_2")
102 (eq_attr "cpu" "am34"))
103 (eq_attr "liw" "op2"))
104 "liw_op2_u");
105(define_insn_reservation "liw_both" 1
106 (and (ior (eq_attr "cpu" "am33")
107 (eq_attr "cpu" "am33_2")
108 (eq_attr "cpu" "am34"))
109 (eq_attr "liw" "both"))
110 "liw_op1_u + liw_op2_u");
111(define_insn_reservation "liw_either" 1
112 (and (ior (eq_attr "cpu" "am33")
113 (eq_attr "cpu" "am33_2")
114 (eq_attr "cpu" "am34"))
115 (eq_attr "liw" "either"))
116 "liw_op1_u | liw_op2_u");
f3f63737 117\f
d84760c9 118;; ----------------------------------------------------------------------
f3f63737 119;; Pipeline description.
d84760c9 120;; ----------------------------------------------------------------------
f3f63737
NC
121
122;; The AM33 only has a single pipeline. It has five stages (fetch,
123;; decode, execute, memory access, writeback) each of which normally
124;; takes a single CPU clock cycle.
125
126;; The timings attribute consists of two numbers, the first is the
127;; throughput, which is the number of cycles the instruction takes
128;; to execute and generate a result. The second is the latency
129;; which is the effective number of cycles the instruction takes to
130;; execute if its result is used by the following instruction. The
131;; latency is always greater than or equal to the throughput.
132;; These values were taken from the Appendix of the "MN103E Series
133;; Instruction Manual" and the timings for the AM34.
134
135;; Note - it would be nice to use strings rather than integers for
136;; the possible values of this attribute, so that we can have the
137;; gcc build mechanism check for values that are not supported by
138;; the reservations below. But this will not work because the code
139;; in mn10300_adjust_sched_cost() needs integers not strings.
140
141(define_attr "timings" "" (const_int 11))
142
143(define_automaton "pipelining")
144(define_cpu_unit "throughput" "pipelining")
145
146(define_insn_reservation "throughput__1_latency__1" 1
147 (eq_attr "timings" "11") "throughput")
148(define_insn_reservation "throughput__1_latency__2" 2
149 (eq_attr "timings" "12") "throughput,nothing")
150(define_insn_reservation "throughput__1_latency__3" 3
151 (eq_attr "timings" "13") "throughput,nothing*2")
152(define_insn_reservation "throughput__1_latency__4" 4
153 (eq_attr "timings" "14") "throughput,nothing*3")
154(define_insn_reservation "throughput__2_latency__2" 2
155 (eq_attr "timings" "22") "throughput*2")
156(define_insn_reservation "throughput__2_latency__3" 3
157 (eq_attr "timings" "23") "throughput*2,nothing")
158(define_insn_reservation "throughput__2_latency__4" 4
159 (eq_attr "timings" "24") "throughput*2,nothing*2")
160(define_insn_reservation "throughput__2_latency__5" 5
161 (eq_attr "timings" "25") "throughput*2,nothing*3")
162(define_insn_reservation "throughput__3_latency__3" 3
163 (eq_attr "timings" "33") "throughput*3")
164(define_insn_reservation "throughput__3_latency__7" 7
165 (eq_attr "timings" "37") "throughput*3,nothing*4")
166(define_insn_reservation "throughput__4_latency__4" 4
167 (eq_attr "timings" "44") "throughput*4")
168(define_insn_reservation "throughput__4_latency__7" 7
169 (eq_attr "timings" "47") "throughput*4,nothing*3")
170(define_insn_reservation "throughput__4_latency__8" 8
171 (eq_attr "timings" "48") "throughput*4,nothing*4")
172(define_insn_reservation "throughput__5_latency__5" 5
173 (eq_attr "timings" "55") "throughput*5")
174(define_insn_reservation "throughput__6_latency__6" 6
175 (eq_attr "timings" "66") "throughput*6")
176(define_insn_reservation "throughput__7_latency__7" 7
177 (eq_attr "timings" "77") "throughput*7")
178(define_insn_reservation "throughput__7_latency__8" 8
179 (eq_attr "timings" "78") "throughput*7,nothing")
180(define_insn_reservation "throughput__8_latency__8" 8
181 (eq_attr "timings" "88") "throughput*8")
182(define_insn_reservation "throughput__9_latency__9" 9
183 (eq_attr "timings" "99") "throughput*9")
184(define_insn_reservation "throughput__8_latency_14" 14
185 (eq_attr "timings" "814") "throughput*8,nothing*6")
186(define_insn_reservation "throughput__9_latency_10" 10
187 (eq_attr "timings" "910") "throughput*9,nothing")
188(define_insn_reservation "throughput_10_latency_10" 10
189 (eq_attr "timings" "1010") "throughput*10")
190(define_insn_reservation "throughput_12_latency_16" 16
191 (eq_attr "timings" "1216") "throughput*12,nothing*4")
192(define_insn_reservation "throughput_13_latency_13" 13
193 (eq_attr "timings" "1313") "throughput*13")
194(define_insn_reservation "throughput_14_latency_14" 14
195 (eq_attr "timings" "1414") "throughput*14")
196(define_insn_reservation "throughput_13_latency_17" 17
197 (eq_attr "timings" "1317") "throughput*13,nothing*4")
198(define_insn_reservation "throughput_23_latency_27" 27
199 (eq_attr "timings" "2327") "throughput*23,nothing*4")
200(define_insn_reservation "throughput_25_latency_31" 31
201 (eq_attr "timings" "2531") "throughput*25,nothing*6")
202(define_insn_reservation "throughput_38_latency_39" 39
203 (eq_attr "timings" "3839") "throughput*38,nothing")
204(define_insn_reservation "throughput_39_latency_40" 40
205 (eq_attr "timings" "3940") "throughput*39,nothing")
206(define_insn_reservation "throughput_40_latency_40" 40
207 (eq_attr "timings" "4040") "throughput*40")
208(define_insn_reservation "throughput_41_latency_42" 42
209 (eq_attr "timings" "4142") "throughput*41,nothing")
9efb4993
RH
210(define_insn_reservation "throughput_42_latency_43" 44
211 (eq_attr "timings" "4243") "throughput*42,nothing")
f3f63737
NC
212(define_insn_reservation "throughput_43_latency_44" 44
213 (eq_attr "timings" "4344") "throughput*43,nothing")
214(define_insn_reservation "throughput_45_latency_46" 46
215 (eq_attr "timings" "4546") "throughput*45,nothing")
216(define_insn_reservation "throughput_47_latency_53" 53
217 (eq_attr "timings" "4753") "throughput*47,nothing*6")
218
219;; Note - the conflict between memory load/store instructions
220;; and floating point instructions described in section 1-7-4
221;; of Chapter 3 of the MN103E Series Instruction Manual is
222;; handled by the mn10300_adjust_sched_cost function.
11bb1f11
JL
223\f
224;; ----------------------------------------------------------------------
225;; MOVE INSTRUCTIONS
226;; ----------------------------------------------------------------------
227
228;; movqi
229
230(define_expand "movqi"
f3f63737 231 [(set (match_operand:QI 0 "nonimmediate_operand")
4af476d7 232 (match_operand:QI 1 "general_operand"))]
11bb1f11 233 ""
11bb1f11 234{
4af476d7 235 /* One of the ops has to be in a register. */
11bb1f11
JL
236 if (!register_operand (operand0, QImode)
237 && !register_operand (operand1, QImode))
b1efde2a
RH
238 operands[1] = force_reg (QImode, operand1);
239})
240
241(define_insn "*movqi_internal"
5a10b0a9
NC
242 [(set (match_operand:QI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m,*z,d")
243 (match_operand:QI 1 "general_operand" " 0,D*r, i,m,D,d,*z"))]
b1efde2a
RH
244 "(register_operand (operands[0], QImode)
245 || register_operand (operands[1], QImode))"
74452ac3
JL
246{
247 switch (which_alternative)
248 {
249 case 0:
b1efde2a 250 return "";
5e849f6e 251 case 1:
5e849f6e 252 case 2:
5a10b0a9
NC
253 case 5:
254 case 6:
b1efde2a 255 return "mov %1,%0";
5d2b84f8
JL
256 case 3:
257 case 4:
b1efde2a 258 return "movbu %1,%0";
69bc71fa 259 default:
dc759020 260 gcc_unreachable ();
74452ac3 261 }
b1efde2a 262}
f3f63737 263 [(set_attr_alternative "timings"
b1efde2a
RH
264 [(const_int 11)
265 (const_int 11)
266 (const_int 11)
267 (if_then_else (eq_attr "cpu" "am34")
268 (const_int 13) (const_int 24))
269 (if_then_else (eq_attr "cpu" "am34")
270 (const_int 11) (const_int 22))
5a10b0a9
NC
271 (const_int 11)
272 (const_int 11)
b1efde2a 273 ])]
4af476d7 274)
11bb1f11
JL
275
276;; movhi
277
278(define_expand "movhi"
f3f63737 279 [(set (match_operand:HI 0 "nonimmediate_operand")
4af476d7 280 (match_operand:HI 1 "general_operand"))]
11bb1f11 281 ""
11bb1f11 282{
4af476d7 283 /* One of the ops has to be in a register. */
11bb1f11
JL
284 if (!register_operand (operand1, HImode)
285 && !register_operand (operand0, HImode))
b1efde2a
RH
286 operands[1] = force_reg (HImode, operand1);
287})
288
289(define_insn "*movhi_internal"
5a10b0a9
NC
290 [(set (match_operand:HI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m,*z,d")
291 (match_operand:HI 1 "general_operand" " 0, i,D*r,m,D,d,*z"))]
b1efde2a
RH
292 "(register_operand (operands[0], HImode)
293 || register_operand (operands[1], HImode))"
74452ac3
JL
294{
295 switch (which_alternative)
296 {
297 case 0:
b1efde2a 298 return "";
b340d2b8 299 case 1:
b1efde2a
RH
300 /* Note that "MOV imm8,An" is already zero-extending, and is 2 bytes.
301 We have "MOV imm16,Dn" at 3 bytes. The only win for the 4 byte
302 movu is for an 8-bit unsigned move into Rn. */
303 if (TARGET_AM33
304 && CONST_INT_P (operands[1])
305 && IN_RANGE (INTVAL (operands[1]), 0x80, 0xff)
306 && REGNO_EXTENDED_P (REGNO (operands[0]), 1))
307 return "movu %1,%0";
308 /* FALLTHRU */
5a10b0a9
NC
309 case 5:
310 case 6:
b340d2b8 311 case 2:
b1efde2a 312 return "mov %1,%0";
5d2b84f8
JL
313 case 3:
314 case 4:
b1efde2a 315 return "movhu %1,%0";
69bc71fa 316 default:
dc759020 317 gcc_unreachable ();
74452ac3 318 }
b1efde2a 319}
f3f63737 320 [(set_attr_alternative "timings"
b1efde2a
RH
321 [(const_int 11)
322 (const_int 11)
323 (if_then_else (eq_attr "cpu" "am34")
324 (const_int 11) (const_int 22))
325 (if_then_else (eq_attr "cpu" "am34")
326 (const_int 13) (const_int 24))
327 (if_then_else (eq_attr "cpu" "am34")
328 (const_int 11) (const_int 22))
5a10b0a9
NC
329 (if_then_else (eq_attr "cpu" "am34")
330 (const_int 11) (const_int 22))
331 (if_then_else (eq_attr "cpu" "am34")
332 (const_int 11) (const_int 22))
b1efde2a 333 ])]
4af476d7 334)
11bb1f11
JL
335
336;; movsi and helpers
337
460f4b9d
JL
338;; We use this to handle addition of two values when one operand is the
339;; stack pointer and the other is a memory reference of some kind. Reload
340;; does not handle them correctly without this expander.
8b119bb6
RH
341(define_expand "reload_plus_sp_const"
342 [(set (match_operand:SI 0 "register_operand" "=r")
4af476d7 343 (match_operand:SI 1 "impossible_plus_operand" ""))
8b119bb6 344 (clobber (match_operand:SI 2 "register_operand" "=&A"))]
460f4b9d 345 ""
460f4b9d 346{
8b119bb6 347 rtx dest, scratch, other;
4af476d7 348
8b119bb6
RH
349 dest = operands[0];
350 scratch = operands[2];
351
352 other = XEXP (operands[1], 1);
353 if (other == stack_pointer_rtx)
354 other = XEXP (operands[1], 0);
355
356 if (true_regnum (other) == true_regnum (dest))
4c742813 357 {
8b119bb6
RH
358 gcc_assert (true_regnum (scratch) != true_regnum (dest));
359 emit_move_insn (scratch, stack_pointer_rtx);
360 emit_insn (gen_addsi3 (dest, dest, scratch));
361 }
362 else if (TARGET_AM33 || REGNO_REG_CLASS (true_regnum (dest)) == ADDRESS_REGS)
363 {
364 emit_move_insn (dest, stack_pointer_rtx);
365 if (other == stack_pointer_rtx)
366 emit_insn (gen_addsi3 (dest, dest, dest));
367 else if (other != const0_rtx)
368 emit_insn (gen_addsi3 (dest, dest, other));
4c742813
JL
369 }
370 else
371 {
8b119bb6
RH
372 emit_move_insn (scratch, stack_pointer_rtx);
373 if (other == stack_pointer_rtx)
374 {
375 emit_move_insn (dest, scratch);
376 emit_insn (gen_addsi3 (dest, dest, dest));
377 }
378 else if (other != const0_rtx)
379 {
380 emit_move_insn (dest, other);
381 emit_insn (gen_addsi3 (dest, dest, scratch));
382 }
bb75a000 383 else
8b119bb6 384 emit_move_insn (dest, scratch);
4c742813 385 }
460f4b9d 386 DONE;
040c5757 387})
d1776069 388
11bb1f11 389(define_expand "movsi"
f3f63737 390 [(set (match_operand:SI 0 "nonimmediate_operand")
4af476d7 391 (match_operand:SI 1 "general_operand"))]
11bb1f11 392 ""
11bb1f11 393{
4af476d7 394 /* One of the ops has to be in a register. */
11bb1f11
JL
395 if (!register_operand (operand1, SImode)
396 && !register_operand (operand0, SImode))
b1efde2a 397 operands[1] = force_reg (SImode, operand1);
d1776069
AO
398 if (flag_pic)
399 {
400 rtx temp;
401 if (SYMBOLIC_CONST_P (operands[1]))
402 {
e7ab5593 403 if (MEM_P (operands[0]))
d1776069
AO
404 operands[1] = force_reg (Pmode, operands[1]);
405 else
406 {
b3a13419
ILT
407 temp = (!can_create_pseudo_p ()
408 ? operands[0]
409 : gen_reg_rtx (Pmode));
e7ab5593 410 operands[1] = mn10300_legitimize_pic_address (operands[1], temp);
d1776069
AO
411 }
412 }
413 else if (GET_CODE (operands[1]) == CONST
414 && GET_CODE (XEXP (operands[1], 0)) == PLUS
415 && SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0)))
416 {
b3a13419 417 temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
e7ab5593
NC
418 temp = mn10300_legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0),
419 temp);
d1776069
AO
420 operands[1] = expand_binop (SImode, add_optab, temp,
421 XEXP (XEXP (operands[1], 0), 1),
b3a13419
ILT
422 (!can_create_pseudo_p ()
423 ? temp
424 : gen_reg_rtx (Pmode)),
d1776069
AO
425 0, OPTAB_LIB_WIDEN);
426 }
427 }
b1efde2a 428})
11bb1f11 429
4af476d7 430(define_insn "*movsi_internal"
f3d6a3cb 431 [(set (match_operand:SI 0 "nonimmediate_operand"
a45d420a 432 "=r,r,r,r,m,r, A,*y,*y,*z,*d")
74452ac3 433 (match_operand:SI 1 "general_operand"
a45d420a 434 " 0,O,i,r,r,m,*y, A, i,*d,*z"))]
11bb1f11
JL
435 "register_operand (operands[0], SImode)
436 || register_operand (operands[1], SImode)"
b1efde2a
RH
437{
438 switch (which_alternative)
439 {
440 case 0:
441 return "";
a45d420a
NC
442 case 1: /* imm-reg. */
443 case 2:
b1efde2a
RH
444 /* See movhi for a discussion of sizes for 8-bit movu. Note that the
445 24-bit movu is 6 bytes, which is the same size as the full 32-bit
446 mov form for An and Dn. So again movu is only a win for Rn. */
447 if (TARGET_AM33
448 && CONST_INT_P (operands[1])
449 && REGNO_EXTENDED_P (REGNO (operands[0]), 1))
450 {
451 HOST_WIDE_INT val = INTVAL (operands[1]);
452 if (IN_RANGE (val, 0x80, 0xff)
453 || IN_RANGE (val, 0x800000, 0xffffff))
454 return "movu %1,%0";
455 }
456 /* FALLTHRU */
a45d420a
NC
457 case 3: /* reg-reg */
458 case 4: /* reg-mem */
459 case 5: /* mem-reg */
460 case 6: /* sp-reg */
461 case 7: /* reg-sp */
462 case 8: /* imm-sp */
463 case 9: /* reg-mdr */
464 case 10: /* mdr-reg */
b1efde2a
RH
465 return "mov %1,%0";
466 default:
467 gcc_unreachable ();
468 }
469}
a45d420a
NC
470 [(set_attr "isa" "*,*,*,*,*,*,*,*,am33,*,*")
471 (set_attr "liw" "*,either,*,either,*,*,*,*,*,*,*")
298362c8 472 (set_attr "liw_op" "mov")
b1efde2a
RH
473 (set_attr_alternative "timings"
474 [(const_int 11)
a45d420a 475 (const_int 22)
b1efde2a
RH
476 (const_int 22)
477 (const_int 11)
478 (if_then_else (eq_attr "cpu" "am34")
479 (const_int 11) (const_int 22))
480 (if_then_else (eq_attr "cpu" "am34")
481 (const_int 13) (const_int 24))
482 (if_then_else (eq_attr "cpu" "am34")
483 (const_int 11) (const_int 22))
484 (if_then_else (eq_attr "cpu" "am34")
485 (const_int 13) (const_int 24))
486 (const_int 11)
c25a21f5
RH
487 (const_int 11)
488 (const_int 11)
b1efde2a 489 ])]
4af476d7 490)
11bb1f11
JL
491
492(define_expand "movsf"
f3f63737 493 [(set (match_operand:SF 0 "nonimmediate_operand")
4af476d7 494 (match_operand:SF 1 "general_operand"))]
b1efde2a 495 "TARGET_AM33_2"
11bb1f11 496{
4af476d7 497 /* One of the ops has to be in a register. */
11bb1f11
JL
498 if (!register_operand (operand1, SFmode)
499 && !register_operand (operand0, SFmode))
b1efde2a
RH
500 operands[1] = force_reg (SFmode, operand1);
501})
11bb1f11 502
4af476d7 503(define_insn "*movsf_internal"
662c03f4
NC
504 [(set (match_operand:SF 0 "nonimmediate_operand" "=rf,r,f,r,f,r,f,r,m,f,Q,z,d")
505 (match_operand:SF 1 "general_operand" " 0,F,F,r,f,f,r,m,r,Q,f,d,z"))]
b1efde2a
RH
506 "TARGET_AM33_2
507 && (register_operand (operands[0], SFmode)
508 || register_operand (operands[1], SFmode))"
862bff88
JL
509{
510 switch (which_alternative)
511 {
b1efde2a
RH
512 case 0:
513 return "";
514 case 1:
515 case 3:
516 case 7:
517 case 8:
662c03f4
NC
518 case 11:
519 case 12:
b1efde2a
RH
520 return "mov %1,%0";
521 case 2:
522 case 4:
523 case 5:
524 case 6:
525 case 9:
526 case 10:
527 return "fmov %1,%0";
69bc71fa 528 default:
dc759020 529 gcc_unreachable ();
862bff88 530 }
b1efde2a 531}
f3f63737 532 [(set_attr_alternative "timings"
b1efde2a
RH
533 [(const_int 11)
534 (const_int 22)
535 (if_then_else (eq_attr "cpu" "am34")
536 (const_int 47) (const_int 25))
537 (const_int 11)
538 (if_then_else (eq_attr "cpu" "am34")
539 (const_int 13) (const_int 14))
540 (if_then_else (eq_attr "cpu" "am34")
541 (const_int 13) (const_int 12))
542 (if_then_else (eq_attr "cpu" "am34")
543 (const_int 13) (const_int 14))
544 (if_then_else (eq_attr "cpu" "am34")
545 (const_int 13) (const_int 24))
546 (if_then_else (eq_attr "cpu" "am34")
547 (const_int 13) (const_int 24))
548 (if_then_else (eq_attr "cpu" "am34")
549 (const_int 13) (const_int 24))
550 (if_then_else (eq_attr "cpu" "am34")
551 (const_int 13) (const_int 24))
662c03f4
NC
552 (const_int 22)
553 (const_int 22)
b1efde2a 554 ])]
4af476d7 555)
b32eba4a 556
d84760c9
RH
557;; If the flags register is not live, generate CLR instead of MOV 0.
558;; For MN103, this is only legal for DATA_REGS; for AM33 this is legal
559;; but not a win for ADDRESS_REGS.
560(define_peephole2
561 [(set (match_operand:INT 0 "register_operand" "") (const_int 0))]
562 "peep2_regno_dead_p (0, CC_REG)
563 && (REGNO_DATA_P (REGNO (operands[0]), 1)
564 || REGNO_EXTENDED_P (REGNO (operands[0]), 1))"
565 [(parallel [(set (match_dup 0) (const_int 0))
566 (clobber (reg:CC CC_REG))])]
567)
568
569(define_insn "*mov<mode>_clr"
570 [(set (match_operand:INT 0 "register_operand" "=D")
571 (const_int 0))
572 (clobber (reg:CC CC_REG))]
573 ""
574 "clr %0"
575)
576\f
577;; ----------------------------------------------------------------------
578;; ADD INSTRUCTIONS
579;; ----------------------------------------------------------------------
580
bad41521 581(define_insn "addsi3"
a45d420a
NC
582 [(set (match_operand:SI 0 "register_operand" "=r,r,r,!*y,!r")
583 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0, 0, r")
584 (match_operand:SI 2 "nonmemory_operand" "r,O,i, i, r")))
bad41521 585 (clobber (reg:CC CC_REG))]
11bb1f11 586 ""
bad41521 587 { return mn10300_output_add (operands, false); }
a45d420a
NC
588 [(set_attr "timings" "11,11,11,11,22")
589 (set_attr "liw" "either,either,*,*,*")
298362c8 590 (set_attr "liw_op" "add")]
bad41521
RH
591)
592
593;; Note that ADD IMM,SP does not set the flags, so omit that here.
594(define_insn "*addsi3_flags"
65fdd5e9
JL
595 [(set (reg CC_REG)
596 (compare (plus:SI (match_operand:SI 1 "register_operand" "%0, r")
597 (match_operand:SI 2 "nonmemory_operand" "ri, r"))
598 (const_int 0)))
599 (set (match_operand:SI 0 "register_operand" "=r,!r")
600 (plus:SI (match_dup 1) (match_dup 2)))]
bad41521
RH
601 "reload_completed && mn10300_match_ccmode (insn, CCZNCmode)"
602 { return mn10300_output_add (operands, true); }
603 [(set_attr "timings" "11,22")]
4af476d7 604)
11bb1f11 605
44217823
RH
606;; A helper to expand the above, with the CC_MODE filled in.
607(define_expand "addsi3_flags"
65fdd5e9 608 [(parallel [(set (reg:CCZNC CC_REG)
44217823 609 (compare:CCZNC (plus:SI (match_dup 1) (match_dup 2))
65fdd5e9
JL
610 (const_int 0)))
611 (set (match_operand:SI 0 "register_operand")
612 (plus:SI (match_operand:SI 1 "register_operand")
613 (match_operand:SI 2 "nonmemory_operand")))])]
44217823
RH
614 ""
615)
616
617(define_insn "addc_internal"
618 [(set (match_operand:SI 0 "register_operand" "=D,r,r")
619 (plus:SI
620 (plus:SI
621 (ltu:SI (reg:CC CC_REG) (const_int 0))
622 (match_operand:SI 1 "register_operand" "%0,0,r"))
623 (match_operand:SI 2 "reg_or_am33_const_operand" " D,i,r")))
624 (clobber (reg:CC CC_REG))]
625 "reload_completed"
626 "@
627 addc %2,%0
628 addc %2,%0
629 addc %2,%1,%0"
630 [(set_attr "isa" "*,am33,am33")]
631)
632
633(define_expand "adddi3"
634 [(set (match_operand:DI 0 "register_operand" "")
635 (plus:DI (match_operand:DI 1 "register_operand" "")
636 (match_operand:DI 2 "nonmemory_operand" "")))]
637 ""
638{
639 rtx op0l, op0h, op1l, op1h, op2l, op2h;
640
641 op0l = gen_lowpart (SImode, operands[0]);
642 op1l = gen_lowpart (SImode, operands[1]);
643 op2l = gen_lowpart (SImode, operands[2]);
644 op0h = gen_highpart (SImode, operands[0]);
645 op1h = gen_highpart (SImode, operands[1]);
646 op2h = gen_highpart_mode (SImode, DImode, operands[2]);
647
648 if (!reg_or_am33_const_operand (op2h, SImode))
649 op2h = force_reg (SImode, op2h);
650
651 emit_insn (gen_adddi3_internal (op0l, op0h, op1l, op2l, op1h, op2h));
652 DONE;
653})
654
655;; Note that reload only supports one commutative operand. Thus we cannot
656;; auto-swap both the high and low outputs with their matching constraints.
657;; For MN103, we're strapped for registers but thankfully the alternatives
658;; are few. For AM33, it becomes much easier to not represent the early
659;; clobber and 6 permutations of immediate and three-operand adds, but
660;; instead allocate a scratch register and do the expansion by hand.
661
662(define_insn_and_split "adddi3_internal"
663 [(set (match_operand:SI 0 "register_operand" "=r, r, r")
664 (plus:SI (match_operand:SI 2 "register_operand" "%0, 0, r")
665 (match_operand:SI 3 "nonmemory_operand" "ri,ri,ri")))
666 (set (match_operand:SI 1 "register_operand" "=D, D, r")
667 (plus:SI
668 (plus:SI
669 (ltu:SI (plus:SI (match_dup 2) (match_dup 3)) (match_dup 2))
670 (match_operand:SI 4 "register_operand" " 1, D, r"))
671 (match_operand:SI 5 "reg_or_am33_const_operand" " D, 1,ri")))
672 (clobber (match_scratch:SI 6 "=X, X,&r"))
673 (clobber (reg:CC CC_REG))]
674 ""
675 "#"
676 "reload_completed"
677 [(const_int 0)]
678{
679 rtx op0l = operands[0];
680 rtx op0h = operands[1];
681 rtx op1l = operands[2];
682 rtx op2l = operands[3];
683 rtx op1h = operands[4];
684 rtx op2h = operands[5];
685 rtx scratch = operands[6];
686 rtx x;
687
688 if (reg_overlap_mentioned_p (op0l, op1h))
689 {
690 emit_move_insn (scratch, op0l);
691 op1h = scratch;
692 if (reg_overlap_mentioned_p (op0l, op2h))
693 op2h = scratch;
694 }
695 else if (reg_overlap_mentioned_p (op0l, op2h))
696 {
697 emit_move_insn (scratch, op0l);
698 op2h = scratch;
699 }
700
701 if (rtx_equal_p (op0l, op1l))
702 ;
703 else if (rtx_equal_p (op0l, op2l))
704 x = op1l, op1l = op2l, op2l = x;
705 else
706 {
707 gcc_assert (TARGET_AM33);
708 if (!REG_P (op2l))
709 {
710 emit_move_insn (op0l, op2l);
711 op2l = op1l;
712 op1l = op0l;
713 }
714 }
715 emit_insn (gen_addsi3_flags (op0l, op1l, op2l));
716
717 if (rtx_equal_p (op0h, op1h))
718 ;
719 else if (rtx_equal_p (op0h, op2h))
720 x = op1h, op1h = op2h, op2h = x;
721 else
722 {
723 gcc_assert (TARGET_AM33);
724 if (!REG_P (op2h))
725 {
726 emit_move_insn (op0h, op2h);
727 op2h = op1h;
728 op1h = op0h;
729 }
730 }
731 emit_insn (gen_addc_internal (op0h, op1h, op2h));
732 DONE;
733}
734 [(set_attr "isa" "*,*,am33")]
735)
736
737;; The following pattern is generated by combine when it proves that one
738;; of the inputs to the low-part of the double-word add is zero, and thus
739;; no carry is generated into the high-part.
740
741(define_insn_and_split "*adddi3_degenerate"
742 [(set (match_operand:SI 0 "register_operand" "=&r,&r")
743 (match_operand:SI 2 "nonmemory_operand" " 0, 0"))
744 (set (match_operand:SI 1 "register_operand" "=r , r")
745 (plus:SI (match_operand:SI 3 "register_operand" "%1 , r")
746 (match_operand:SI 4 "nonmemory_operand" "ri, r")))
747 (clobber (reg:CC CC_REG))]
748 ""
749 "#"
750 ""
751 [(const_int 0)]
752{
753 rtx scratch = NULL_RTX;
754 if (!rtx_equal_p (operands[0], operands[2]))
755 {
44217823
RH
756 if (reg_overlap_mentioned_p (operands[0], operands[3])
757 || reg_overlap_mentioned_p (operands[0], operands[4]))
758 {
759 scratch = gen_reg_rtx (SImode);
760 emit_move_insn (scratch, operands[2]);
761 }
762 else
763 emit_move_insn (operands[0], operands[2]);
764 }
765 emit_insn (gen_addsi3 (operands[1], operands[3], operands[4]));
766 if (scratch)
767 emit_move_insn (operands[0], scratch);
768 DONE;
769})
770
11bb1f11
JL
771;; ----------------------------------------------------------------------
772;; SUBTRACT INSTRUCTIONS
773;; ----------------------------------------------------------------------
774
bad41521 775(define_insn "subsi3"
a45d420a
NC
776 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
777 (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r")
778 (match_operand:SI 2 "nonmemory_operand" "r,O,i,r")))
bad41521 779 (clobber (reg:CC CC_REG))]
4d1a91c2 780 ""
bad41521 781 "@
a45d420a 782 sub %2,%0
298362c8 783 sub %2,%0
bad41521
RH
784 sub %2,%0
785 sub %2,%1,%0"
a45d420a
NC
786 [(set_attr "isa" "*,*,*,am33")
787 (set_attr "liw" "either,either,*,*")
298362c8 788 (set_attr "liw_op" "sub")
a45d420a 789 (set_attr "timings" "11,11,11,22")]
4af476d7 790)
705ac34f 791
bad41521 792(define_insn "*subsi3_flags"
65fdd5e9
JL
793 [(set (reg CC_REG)
794 (compare (minus:SI (match_operand:SI 1 "register_operand" "0, r")
795 (match_operand:SI 2 "nonmemory_operand" "ri,r"))
796 (const_int 0)))
797 (set (match_operand:SI 0 "register_operand" "=r, r")
798 (minus:SI (match_dup 1) (match_dup 2)))]
bad41521
RH
799 "reload_completed && mn10300_match_ccmode (insn, CCZNCmode)"
800 "@
801 sub %2,%0
802 sub %2,%1,%0"
803 [(set_attr "isa" "*,am33")
804 (set_attr "timings" "11,22")]
4af476d7 805)
11bb1f11 806
44217823
RH
807;; A helper to expand the above, with the CC_MODE filled in.
808(define_expand "subsi3_flags"
65fdd5e9 809 [(parallel [(set (reg:CCZNC CC_REG)
44217823 810 (compare:CCZNC (minus:SI (match_dup 1) (match_dup 2))
65fdd5e9
JL
811 (const_int 0)))
812 (set (match_operand:SI 0 "register_operand")
813 (minus:SI (match_operand:SI 1 "register_operand")
814 (match_operand:SI 2 "nonmemory_operand")))])]
44217823
RH
815 ""
816)
817
818(define_insn "subc_internal"
819 [(set (match_operand:SI 0 "register_operand" "=D,r,r")
820 (minus:SI
821 (minus:SI (match_operand:SI 1 "register_operand" " 0,0,r")
822 (match_operand:SI 2 "reg_or_am33_const_operand" " D,i,r"))
823 (geu:SI (reg:CC CC_REG) (const_int 0))))
824 (clobber (reg:CC CC_REG))]
825 "reload_completed"
826 "@
827 subc %2,%0
828 subc %2,%0
829 subc %2,%1,%0"
830 [(set_attr "isa" "*,am33,am33")]
831)
832
833(define_expand "subdi3"
834 [(set (match_operand:DI 0 "register_operand" "")
835 (minus:DI (match_operand:DI 1 "register_operand" "")
836 (match_operand:DI 2 "nonmemory_operand" "")))]
837 ""
838{
839 rtx op0l, op0h, op1l, op1h, op2l, op2h;
840
841 op0l = gen_lowpart (SImode, operands[0]);
842 op1l = gen_lowpart (SImode, operands[1]);
843 op2l = gen_lowpart (SImode, operands[2]);
844 op0h = gen_highpart (SImode, operands[0]);
845 op1h = gen_highpart (SImode, operands[1]);
846 op2h = gen_highpart_mode (SImode, DImode, operands[2]);
847
848 if (!reg_or_am33_const_operand (op2h, SImode))
849 op2h = force_reg (SImode, op2h);
850
851 emit_insn (gen_subdi3_internal (op0l, op0h, op1l, op1h, op2l, op2h));
852 DONE;
853})
854
855;; As with adddi3, the use of the scratch register helps reduce the
856;; number of permutations for AM33.
857;; ??? The early clobber on op0 avoids a reload bug wherein both output
858;; registers are set the same. Consider negate, where both op2 and op3
859;; are 0, are csed to the same input register, and reload fails to undo
860;; the cse when satisfying the matching constraints.
861
862(define_insn_and_split "subdi3_internal"
863 [(set (match_operand:SI 0 "register_operand" "=&r, r")
864 (minus:SI
865 (match_operand:SI 2 "register_operand" " 0, r")
866 (match_operand:SI 4 "nonmemory_operand" " ri,ri")))
867 (set (match_operand:SI 1 "register_operand" "=D , r")
868 (minus:SI
869 (minus:SI
870 (match_operand:SI 3 "register_operand" " 1, r")
871 (match_operand:SI 5 "reg_or_am33_const_operand" " D,ri"))
872 (ltu:SI (match_dup 2) (match_dup 4))))
873 (clobber (match_scratch:SI 6 "=X ,&r"))
874 (clobber (reg:CC CC_REG))]
875 ""
876 "#"
877 "reload_completed"
878 [(const_int 0)]
879{
880 rtx op0l = operands[0];
881 rtx op0h = operands[1];
882 rtx op1l = operands[2];
883 rtx op1h = operands[3];
884 rtx op2l = operands[4];
885 rtx op2h = operands[5];
886 rtx scratch = operands[6];
887
888 if (reg_overlap_mentioned_p (op0l, op1h))
889 {
890 emit_move_insn (scratch, op0l);
891 op1h = scratch;
892 if (reg_overlap_mentioned_p (op0l, op2h))
893 op2h = scratch;
894 }
895 else if (reg_overlap_mentioned_p (op0l, op2h))
896 {
897 emit_move_insn (scratch, op0l);
898 op2h = scratch;
899 }
900
901 if (!rtx_equal_p (op0l, op1l))
902 {
903 gcc_assert (TARGET_AM33);
904 if (!REG_P (op2l))
905 {
906 emit_move_insn (op0l, op1l);
907 op1l = op0l;
908 }
909 }
910 emit_insn (gen_subsi3_flags (op0l, op1l, op2l));
911
912 if (!rtx_equal_p (op0h, op1h))
913 {
914 gcc_assert (TARGET_AM33);
915 if (!REG_P (op2h))
916 {
917 emit_move_insn (op0h, op1h);
918 op1h = op0h;
919 }
920 }
921 emit_insn (gen_subc_internal (op0h, op1h, op2h));
922 DONE;
923}
924 [(set_attr "isa" "*,am33")]
925)
926
927;; The following pattern is generated by combine when it proves that one
928;; of the inputs to the low-part of the double-word sub is zero, and thus
929;; no carry is generated into the high-part.
930
931(define_insn_and_split "*subdi3_degenerate"
932 [(set (match_operand:SI 0 "register_operand" "=&r,&r")
933 (match_operand:SI 2 "nonmemory_operand" " 0, 0"))
934 (set (match_operand:SI 1 "register_operand" "=r , r")
935 (minus:SI (match_operand:SI 3 "register_operand" " 1, r")
936 (match_operand:SI 4 "nonmemory_operand" " ri, r")))
937 (clobber (reg:CC CC_REG))]
938 ""
939 "#"
940 ""
941 [(const_int 0)]
942{
943 rtx scratch = NULL_RTX;
944 if (!rtx_equal_p (operands[0], operands[2]))
945 {
946 gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[1]));
947 if (reg_overlap_mentioned_p (operands[0], operands[3])
948 || reg_overlap_mentioned_p (operands[0], operands[4]))
949 {
950 scratch = gen_reg_rtx (SImode);
951 emit_move_insn (scratch, operands[2]);
952 }
953 else
954 emit_move_insn (operands[0], operands[2]);
955 }
956 emit_insn (gen_subsi3 (operands[1], operands[3], operands[4]));
957 if (scratch)
958 emit_move_insn (operands[0], scratch);
959 DONE;
9aaed2c1
RS
960}
961 [(set_attr "isa" "*,am33")])
962
44217823 963
bad41521
RH
964(define_insn_and_split "negsi2"
965 [(set (match_operand:SI 0 "register_operand" "=D,&r")
966 (neg:SI (match_operand:SI 1 "register_operand" " 0, r")))
967 (clobber (reg:CC CC_REG))]
11bb1f11 968 ""
bad41521
RH
969 "#"
970 "&& reload_completed"
971 [(const_int 0)]
11bb1f11 972{
bad41521
RH
973 /* Recall that twos-compliment is ones-compliment plus one. When
974 allocated in DATA_REGS this is 2+1 bytes; otherwise (for am33)
975 this is 3+3 bytes.
976
977 For AM33, it would have been possible to load zero and use the
978 three-address subtract to have a total size of 3+4*N bytes for
979 multiple negations, plus increased throughput. Not attempted here. */
980
981 if (true_regnum (operands[0]) == true_regnum (operands[1]))
982 {
983 emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
984 emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx));
985 }
986 else
987 {
988 emit_move_insn (operands[0], const0_rtx);
989 emit_insn (gen_subsi3 (operands[0], operands[0], operands[1]));
990 }
11bb1f11 991 DONE;
bad41521 992})
11bb1f11 993
11bb1f11
JL
994;; ----------------------------------------------------------------------
995;; MULTIPLY INSTRUCTIONS
996;; ----------------------------------------------------------------------
997
9efb4993
RH
998;; ??? Note that AM33 has a third multiply variant that puts the high part
999;; into the MDRQ register, however this variant also constrains the inputs
1000;; to be in DATA_REGS and thus isn't as helpful as it might be considering
073a8998 1001;; the existence of the 4-operand multiply. Nor is there a set of divide
9efb4993
RH
1002;; insns that use MDRQ. Given that there is an IMM->MDRQ insn, this would
1003;; have been very handy for starting udivmodsi4...
1004
1005(define_expand "mulsidi3"
1006 [(set (match_operand:DI 0 "register_operand" "")
1007 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1008 (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))]
1009 ""
1010{
1011 emit_insn (gen_mulsidi3_internal (gen_lowpart (SImode, operands[0]),
1012 gen_highpart (SImode, operands[0]),
1013 operands[1], operands[2]));
1014 DONE;
1015})
705ac34f 1016
9efb4993
RH
1017(define_insn "mulsidi3_internal"
1018 [(set (match_operand:SI 0 "register_operand" "=D,r")
1019 (mult:SI (match_operand:SI 2 "register_operand" "%0,r")
1020 (match_operand:SI 3 "register_operand" " D,r")))
1021 (set (match_operand:SI 1 "register_operand" "=z,r")
1022 (truncate:SI
1023 (ashiftrt:DI
1024 (mult:DI (sign_extend:DI (match_dup 2))
1025 (sign_extend:DI (match_dup 3)))
1026 (const_int 32))))
1027 (clobber (reg:CC CC_REG))]
1028 ""
1029{
1030 if (which_alternative == 1)
1031 return "mul %2,%3,%1,%0";
1032 else if (TARGET_MULT_BUG)
1033 return "nop\;nop\;mul %3,%0";
1034 else
1035 return "mul %3,%0";
1036}
1037 [(set_attr "isa" "*,am33")
1038 (set (attr "timings")
1039 (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))]
4af476d7 1040)
705ac34f 1041
9efb4993
RH
1042(define_expand "umulsidi3"
1043 [(set (match_operand:DI 0 "register_operand" "")
1044 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1045 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
1046 (clobber (reg:CC CC_REG))]
284280b5 1047 ""
9efb4993
RH
1048{
1049 emit_insn (gen_umulsidi3_internal (gen_lowpart (SImode, operands[0]),
1050 gen_highpart (SImode, operands[0]),
1051 operands[1], operands[2]));
1052 DONE;
1053})
284280b5 1054
9efb4993
RH
1055(define_insn "umulsidi3_internal"
1056 [(set (match_operand:SI 0 "register_operand" "=D,r")
1057 (mult:SI (match_operand:SI 2 "register_operand" "%0,r")
1058 (match_operand:SI 3 "register_operand" " D,r")))
1059 (set (match_operand:SI 1 "register_operand" "=z,r")
1060 (truncate:SI
1061 (lshiftrt:DI
1062 (mult:DI (zero_extend:DI (match_dup 2))
1063 (zero_extend:DI (match_dup 3)))
1064 (const_int 32))))
1065 (clobber (reg:CC CC_REG))]
1066 ""
705ac34f 1067{
9efb4993
RH
1068 if (which_alternative == 1)
1069 return "mulu %2,%3,%1,%0";
1070 else if (TARGET_MULT_BUG)
1071 return "nop\;nop\;mulu %3,%0";
705ac34f 1072 else
9efb4993
RH
1073 return "mulu %3,%0";
1074}
1075 [(set_attr "isa" "*,am33")
1076 (set (attr "timings")
1077 (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))]
4af476d7 1078)
5abc5de9 1079
9efb4993 1080(define_expand "mulsi3"
e0d1958f
RH
1081 [(parallel [(set (match_operand:SI 0 "register_operand")
1082 (mult:SI (match_operand:SI 1 "register_operand")
1083 (match_operand:SI 2 "reg_or_am33_const_operand")))
1084 (clobber (match_scratch:SI 3))
9efb4993 1085 (clobber (reg:CC CC_REG))])]
11bb1f11 1086 ""
4af476d7
NC
1087)
1088
9efb4993 1089(define_insn "*mulsi3"
e0d1958f
RH
1090 [(set (match_operand:SI 0 "register_operand" "=D, r,r")
1091 (mult:SI (match_operand:SI 2 "register_operand" "%0, 0,r")
1092 (match_operand:SI 3 "reg_or_am33_const_operand" " D,ri,r")))
1093 (clobber (match_scratch:SI 1 "=z, z,r"))
b1efde2a 1094 (clobber (reg:CC CC_REG))]
9efb4993 1095 ""
22ef4e9b 1096{
9efb4993
RH
1097 if (which_alternative == 2)
1098 return "mul %2,%3,%1,%0";
1099 else if (TARGET_MULT_BUG)
1100 return "nop\;nop\;mul %3,%0";
22ef4e9b 1101 else
9efb4993 1102 return "mul %3,%0";
b1efde2a 1103}
9efb4993
RH
1104 [(set_attr "isa" "*,am33,am33")
1105 (set (attr "timings")
1106 (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))]
4af476d7 1107)
22ef4e9b 1108
9efb4993
RH
1109(define_expand "udivmodsi4"
1110 [(parallel [(set (match_operand:SI 0 "register_operand")
1111 (udiv:SI (match_operand:SI 1 "register_operand")
1112 (match_operand:SI 2 "register_operand")))
1113 (set (match_operand:SI 3 "register_operand")
1114 (umod:SI (match_dup 1) (match_dup 2)))
1115 (use (const_int 0))
1116 (clobber (reg:CC CC_REG))])]
1117 ""
b1efde2a
RH
1118)
1119
9efb4993
RH
1120;; Note the trick to get reload to put the zero into the MDR register,
1121;; rather than exposing the load early and letting CSE or someone try
1122;; to share the zeros between division insns. Which tends to result
1123;; in sequences like 0->r0->d0->mdr.
1124
1125(define_insn "*udivmodsi4"
1126 [(set (match_operand:SI 0 "register_operand" "=D")
1127 (udiv:SI (match_operand:SI 2 "register_operand" " 0")
1128 (match_operand:SI 3 "register_operand" " D")))
1129 (set (match_operand:SI 1 "register_operand" "=z")
1130 (umod:SI (match_dup 2) (match_dup 3)))
1131 (use (match_operand:SI 4 "nonmemory_operand" " 1"))
b1efde2a 1132 (clobber (reg:CC CC_REG))]
9efb4993
RH
1133 ""
1134 "divu %3,%0"
1135 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1136 (const_int 3839) (const_int 4243)))]
b1efde2a
RH
1137)
1138
9efb4993
RH
1139(define_expand "divmodsi4"
1140 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1141 (div:SI (match_operand:SI 1 "register_operand" "")
1142 (match_operand:SI 2 "register_operand" "")))
1143 (set (match_operand:SI 3 "register_operand" "")
1144 (mod:SI (match_dup 1) (match_dup 2)))
1145 (use (match_dup 4))
1146 (clobber (reg:CC CC_REG))])]
22ef4e9b 1147 ""
22ef4e9b 1148{
9efb4993
RH
1149 operands[4] = gen_reg_rtx (SImode);
1150 emit_insn (gen_ext_internal (operands[4], operands[1]));
1151})
1152
1153;; ??? Ideally we'd represent this via shift, but it seems like adding a
1154;; special-case pattern for (ashiftrt x 31) is just as likely to result
1155;; in poor register allocation choices.
1156(define_insn "ext_internal"
1157 [(set (match_operand:SI 0 "register_operand" "=z")
1158 (unspec:SI [(match_operand:SI 1 "register_operand" "D")] UNSPEC_EXT))]
1159 ""
1160 "ext %1"
1161)
1162
1163(define_insn "*divmodsi4"
1164 [(set (match_operand:SI 0 "register_operand" "=D")
1165 (div:SI (match_operand:SI 2 "register_operand" " 0")
1166 (match_operand:SI 3 "register_operand" " D")))
1167 (set (match_operand:SI 1 "register_operand" "=z")
1168 (mod:SI (match_dup 2) (match_dup 3)))
1169 (use (match_operand:SI 4 "register_operand" " 1"))
1170 (clobber (reg:CC CC_REG))]
1171 ""
1172 "div %3,%0";
f3f63737 1173 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
9efb4993 1174 (const_int 3839) (const_int 4243)))]
4af476d7 1175)
11bb1f11 1176
11bb1f11
JL
1177\f
1178;; ----------------------------------------------------------------------
1179;; AND INSTRUCTIONS
1180;; ----------------------------------------------------------------------
1181
bad41521
RH
1182(define_insn "andsi3"
1183 [(set (match_operand:SI 0 "register_operand" "=D,D,r")
1184 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1185 (match_operand:SI 2 "nonmemory_operand" " i,D,r")))
1186 (clobber (reg:CC CC_REG))]
fed2012b 1187 ""
bad41521
RH
1188 "@
1189 and %2,%0
1190 and %2,%0
1191 and %2,%1,%0"
1192 [(set_attr "isa" "*,*,am33")
298362c8
NC
1193 (set_attr "liw" "*,op1,*")
1194 (set_attr "liw_op" "and")
bad41521
RH
1195 (set_attr "timings" "22,11,11")]
1196)
1197
1198(define_insn "*andsi3_flags"
65fdd5e9
JL
1199 [(set (reg CC_REG)
1200 (compare (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1201 (match_operand:SI 2 "nonmemory_operand" " i,D,r"))
1202 (const_int 0)))
1203 (set (match_operand:SI 0 "register_operand" "=D,D,r")
1204 (and:SI (match_dup 1) (match_dup 2)))]
bad41521
RH
1205 "reload_completed && mn10300_match_ccmode (insn, CCZNmode)"
1206 "@
1207 and %2,%0
1208 and %2,%0
1209 and %2,%1,%0"
1210 [(set_attr "isa" "*,*,am33")
1211 (set_attr "timings" "22,11,11")]
1212)
fed2012b 1213
bad41521
RH
1214;; Make sure we generate extensions instead of ANDs.
1215
1216(define_split
1217 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1218 (and:SI (match_operand:SI 1 "register_operand" "")
1219 (const_int 255)))
1220 (clobber (reg:CC CC_REG))])]
11bb1f11 1221 ""
bad41521
RH
1222 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
1223 { operands[1] = gen_lowpart (QImode, operands[1]); }
1224)
f3f63737 1225
bad41521
RH
1226(define_split
1227 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1228 (and:SI (match_operand:SI 1 "register_operand" "")
1229 (const_int 65535)))
1230 (clobber (reg:CC CC_REG))])]
1231 ""
1232 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
1233 { operands[1] = gen_lowpart (HImode, operands[1]); }
4af476d7 1234)
11bb1f11 1235
bad41521
RH
1236;; Split AND by an appropriate constant into two shifts. Recall that
1237;; operations with a full 32-bit immediate require an extra cycle, so
1238;; this is a size optimization with no speed penalty. This only applies
1239;; do DATA_REGS; the shift insns that AM33 adds are too large for a win.
1240
1241(define_split
1242 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1243 (and:SI (match_dup 0)
1244 (match_operand:SI 1 "const_int_operand" "")))
1245 (clobber (reg:CC CC_REG))])]
1246 "reload_completed
1247 && REGNO_DATA_P (true_regnum (operands[0]), 1)
1248 && mn10300_split_and_operand_count (operands[1]) != 0"
1249 [(const_int 0)]
1250{
1251 int count = mn10300_split_and_operand_count (operands[1]);
1252 if (count > 0)
1253 {
1254 emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (count)));
1255 emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (count)));
1256 }
1257 else
1258 {
1259 emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (-count)));
1260 emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (-count)));
1261 }
1262 DONE;
1263})
1264
11bb1f11
JL
1265;; ----------------------------------------------------------------------
1266;; OR INSTRUCTIONS
1267;; ----------------------------------------------------------------------
1268
bad41521
RH
1269(define_insn "iorsi3"
1270 [(set (match_operand:SI 0 "register_operand" "=D,D,r")
1271 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1272 (match_operand:SI 2 "nonmemory_operand" " i,D,r")))
1273 (clobber (reg:CC CC_REG))]
11bb1f11 1274 ""
bad41521
RH
1275 "@
1276 or %2,%0
1277 or %2,%0
1278 or %2,%1,%0"
1279 [(set_attr "isa" "*,*,am33")
298362c8
NC
1280 (set_attr "liw" "*,op1,*")
1281 (set_attr "liw_op" "or")
bad41521
RH
1282 (set_attr "timings" "22,11,11")]
1283)
1284
1285(define_insn "*iorsi3_flags"
65fdd5e9
JL
1286 [(set (reg CC_REG)
1287 (compare (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1288 (match_operand:SI 2 "nonmemory_operand" " i,D,r"))
1289 (const_int 0)))
1290 (set (match_operand:SI 0 "register_operand" "=D,D,r")
1291 (ior:SI (match_dup 1) (match_dup 2)))]
bad41521
RH
1292 "reload_completed && mn10300_match_ccmode (insn, CCZNmode)"
1293 "@
1294 or %2,%0
1295 or %2,%0
1296 or %2,%1,%0"
1297 [(set_attr "isa" "*,*,am33")
1298 (set_attr "timings" "22,11,11")]
4af476d7 1299)
11bb1f11
JL
1300
1301;; ----------------------------------------------------------------------
1302;; XOR INSTRUCTIONS
1303;; ----------------------------------------------------------------------
1304
bad41521
RH
1305(define_insn "xorsi3"
1306 [(set (match_operand:SI 0 "register_operand" "=D,D,r")
1307 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1308 (match_operand:SI 2 "nonmemory_operand" " i,D,r")))
1309 (clobber (reg:CC CC_REG))]
11bb1f11 1310 ""
bad41521
RH
1311 "@
1312 xor %2,%0
1313 xor %2,%0
1314 xor %2,%1,%0"
1315 [(set_attr "isa" "*,*,am33")
298362c8
NC
1316 (set_attr "liw" "*,op1,*")
1317 (set_attr "liw_op" "xor")
bad41521
RH
1318 (set_attr "timings" "22,11,11")]
1319)
1320
1321(define_insn "*xorsi3_flags"
65fdd5e9
JL
1322 [(set (reg CC_REG)
1323 (compare (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1324 (match_operand:SI 2 "nonmemory_operand" " i,D,r"))
1325 (const_int 0)))
1326 (set (match_operand:SI 0 "register_operand" "=D,D,r")
1327 (xor:SI (match_dup 1) (match_dup 2)))]
bad41521
RH
1328 "reload_completed && mn10300_match_ccmode (insn, CCZNmode)"
1329 "@
1330 xor %2,%0
1331 xor %2,%0
1332 xor %2,%1,%0"
1333 [(set_attr "isa" "*,*,am33")
1334 (set_attr "timings" "22,11,11")]
4af476d7 1335)
11bb1f11
JL
1336
1337;; ----------------------------------------------------------------------
1338;; NOT INSTRUCTIONS
1339;; ----------------------------------------------------------------------
1340
bad41521
RH
1341(define_insn "one_cmplsi2"
1342 [(set (match_operand:SI 0 "register_operand" "=D")
1343 (not:SI (match_operand:SI 1 "register_operand" " 0")))
1344 (clobber (reg:CC CC_REG))]
fed2012b 1345 ""
705ac34f 1346 "not %0"
4af476d7 1347)
705ac34f 1348
bad41521 1349(define_insn "*one_cmplsi2_flags"
65fdd5e9
JL
1350 [(set (reg CC_REG)
1351 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
1352 (const_int 0)))
1353 (set (match_operand:SI 0 "register_operand" "=D")
1354 (not:SI (match_dup 1)))]
bad41521 1355 "reload_completed && mn10300_match_ccmode (insn, CCZNmode)"
11bb1f11 1356 "not %0"
4af476d7 1357)
11bb1f11
JL
1358\f
1359;; ----------------------------------------------------------------------
4af476d7 1360;; COMPARE AND BRANCH INSTRUCTIONS
11bb1f11
JL
1361;; ----------------------------------------------------------------------
1362
4af476d7
NC
1363;; We expand the comparison into a single insn so that it will not be split
1364;; up by reload.
f90b7a5a 1365(define_expand "cbranchsi4"
4af476d7
NC
1366 [(set (pc)
1367 (if_then_else
1368 (match_operator 0 "ordered_comparison_operator"
1369 [(match_operand:SI 1 "register_operand")
1370 (match_operand:SI 2 "nonmemory_operand")])
bad41521 1371 (label_ref (match_operand 3 ""))
f90b7a5a 1372 (pc)))]
11bb1f11 1373 ""
4af476d7
NC
1374 ""
1375)
11bb1f11 1376
bad41521 1377(define_insn_and_split "*cbranchsi4_cmp"
4af476d7
NC
1378 [(set (pc)
1379 (if_then_else (match_operator 3 "ordered_comparison_operator"
bad41521
RH
1380 [(match_operand:SI 0 "register_operand" "r")
1381 (match_operand:SI 1 "nonmemory_operand" "ri")])
1382 (match_operand 2 "label_ref_operand" "")
1383 (pc)))]
4af476d7
NC
1384 ""
1385 "#"
1386 "reload_completed"
1387 [(const_int 0)]
bad41521
RH
1388{
1389 mn10300_split_cbranch (CCmode, operands[3], operands[2]);
1390 DONE;
1391})
4af476d7 1392
662c03f4 1393(define_insn "cmpsi"
bad41521 1394 [(set (reg CC_REG)
a45d420a
NC
1395 (compare (match_operand:SI 0 "register_operand" "r,r,r")
1396 (match_operand:SI 1 "nonmemory_operand" "r,O,i")))]
bad41521
RH
1397 "reload_completed"
1398{
1399 /* The operands of CMP must be distinct registers. In the case where
1400 we've failed to optimize the comparison of a register to itself, we
1401 must use another method to set the Z flag. We can achieve this
1402 effect with a BTST 0,D0. This will not alter the contents of D0;
1403 the use of d0 is arbitrary; any data register would work. */
1404 if (rtx_equal_p (operands[0], operands[1]))
1405 return "btst 0,d0";
1406 else
1407 return "cmp %1,%0";
1408}
f3f63737 1409 [(set_attr_alternative "timings"
298362c8 1410 [(if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))
a45d420a 1411 (if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))
298362c8 1412 (if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))])
a45d420a 1413 (set_attr "liw" "either,either,*")
298362c8 1414 (set_attr "liw_op" "cmp")]
4af476d7 1415)
11bb1f11 1416
bad41521 1417(define_insn "*integer_conditional_branch"
11bb1f11 1418 [(set (pc)
f3f63737 1419 (if_then_else (match_operator 0 "comparison_operator"
bad41521
RH
1420 [(match_operand 2 "int_mode_flags" "")
1421 (const_int 0)])
4af476d7 1422 (label_ref (match_operand 1 "" ""))
11bb1f11 1423 (pc)))]
bad41521 1424 "reload_completed"
4af476d7
NC
1425 "b%b0 %1"
1426)
11bb1f11 1427
bad41521
RH
1428(define_insn_and_split "*cbranchsi4_btst"
1429 [(set (pc)
1430 (if_then_else
1431 (match_operator 3 "CCZN_comparison_operator"
1432 [(and:SI (match_operand:SI 0 "register_operand" "D")
1433 (match_operand:SI 1 "immediate_operand" "i"))
1434 (const_int 0)])
1435 (match_operand 2 "label_ref_operand" "")
1436 (pc)))]
1437 ""
1438 "#"
1439 "reload_completed"
1440 [(const_int 0)]
1441{
1442 mn10300_split_cbranch (CCZNmode, operands[3], operands[2]);
1443 DONE;
1444})
1445
1446(define_insn "*btstsi"
1447 [(set (reg:CCZN CC_REG)
1448 (compare:CCZN
1449 (and:SI (match_operand:SI 0 "register_operand" "D")
1450 (match_operand:SI 1 "immediate_operand" "i"))
1451 (const_int 0)))]
1452 "reload_completed"
1453 "btst %1,%0"
1454)
1455
4af476d7 1456(define_expand "cbranchsf4"
11bb1f11 1457 [(set (pc)
4af476d7
NC
1458 (if_then_else
1459 (match_operator 0 "ordered_comparison_operator"
1460 [(match_operand:SF 1 "register_operand")
1461 (match_operand:SF 2 "nonmemory_operand")])
bad41521 1462 (label_ref (match_operand 3 ""))
4af476d7
NC
1463 (pc)))]
1464 "TARGET_AM33_2"
11bb1f11 1465 ""
4af476d7
NC
1466)
1467
bad41521 1468(define_insn_and_split "*cbranchsf4_cmp"
4af476d7
NC
1469 [(set (pc)
1470 (if_then_else (match_operator 3 "ordered_comparison_operator"
1471 [(match_operand:SF 0 "register_operand" "f")
1472 (match_operand:SF 1 "nonmemory_operand" "fF")])
bad41521 1473 (match_operand 2 "label_ref_operand" "")
4af476d7
NC
1474 (pc)))
1475 ]
1476 "TARGET_AM33_2"
1477 "#"
1478 "&& reload_completed"
1479 [(const_int 0)]
bad41521
RH
1480{
1481 mn10300_split_cbranch (CC_FLOATmode, operands[3], operands[2]);
1482 DONE;
1483})
4af476d7 1484
bad41521 1485(define_insn "*am33_cmpsf"
4af476d7
NC
1486 [(set (reg:CC_FLOAT CC_REG)
1487 (compare:CC_FLOAT (match_operand:SF 0 "register_operand" "f")
1488 (match_operand:SF 1 "nonmemory_operand" "fF")))]
bad41521 1489 "TARGET_AM33_2 && reload_completed"
4af476d7 1490 "fcmp %1, %0"
f3f63737
NC
1491 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1492 (const_int 17) (const_int 25)))]
4af476d7
NC
1493)
1494
bad41521 1495(define_insn "*float_conditional_branch"
4af476d7 1496 [(set (pc)
e7ab5593
NC
1497 (if_then_else (match_operator 0 "comparison_operator"
1498 [(reg:CC_FLOAT CC_REG) (const_int 0)])
4af476d7
NC
1499 (label_ref (match_operand 1 "" ""))
1500 (pc)))]
bad41521 1501 "TARGET_AM33_2 && reload_completed"
4af476d7 1502 "fb%b0 %1"
f3f63737
NC
1503 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1504 (const_int 44) (const_int 33)))]
4af476d7 1505)
11bb1f11
JL
1506
1507;; Unconditional and other jump instructions.
1508
1509(define_insn "jump"
1510 [(set (pc)
1511 (label_ref (match_operand 0 "" "")))]
1512 ""
1513 "jmp %l0"
f3f63737
NC
1514 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1515 (const_int 11) (const_int 44)))]
4af476d7 1516)
11bb1f11
JL
1517
1518(define_insn "indirect_jump"
1519 [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1520 ""
1521 "jmp (%0)"
f3f63737
NC
1522 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1523 (const_int 11) (const_int 33)))]
4af476d7 1524)
11bb1f11 1525
d1776069
AO
1526(define_expand "builtin_setjmp_receiver"
1527 [(match_operand 0 "" "")]
1528 "flag_pic"
d1776069 1529{
040c5757 1530 emit_insn (gen_load_pic ());
d1776069 1531 DONE;
040c5757 1532})
d1776069
AO
1533
1534(define_expand "casesi"
4af476d7
NC
1535 [(match_operand:SI 0 "register_operand")
1536 (match_operand:SI 1 "immediate_operand")
1537 (match_operand:SI 2 "immediate_operand")
1538 (match_operand 3 "" "") (match_operand 4 "")]
d1776069 1539 ""
d1776069
AO
1540{
1541 rtx table = gen_reg_rtx (SImode);
1542 rtx index = gen_reg_rtx (SImode);
1543 rtx addr = gen_reg_rtx (Pmode);
f90b7a5a 1544 rtx test;
d1776069
AO
1545
1546 emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
4af476d7 1547 emit_insn (gen_addsi3 (index, operands[0], GEN_INT (- INTVAL (operands[1]))));
f90b7a5a
PB
1548 test = gen_rtx_fmt_ee (GTU, VOIDmode, index, operands[2]);
1549 emit_jump_insn (gen_cbranchsi4 (test, index, operands[2], operands[4]));
1550
4af476d7 1551 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
d1776069
AO
1552 emit_move_insn (addr, gen_rtx_MEM (SImode,
1553 gen_rtx_PLUS (SImode, table, index)));
1554 if (flag_pic)
4af476d7 1555 emit_insn (gen_addsi3 (addr, addr, table));
d1776069
AO
1556
1557 emit_jump_insn (gen_tablejump (addr, operands[3]));
1558 DONE;
bad41521 1559})
d1776069 1560
11bb1f11
JL
1561(define_insn "tablejump"
1562 [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1563 (use (label_ref (match_operand 1 "" "")))]
1564 ""
4f28f058 1565 "jmp (%0)"
f3f63737
NC
1566 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1567 (const_int 11) (const_int 33)))]
4af476d7 1568)
11bb1f11
JL
1569
1570;; Call subroutine with no return value.
1571
1572(define_expand "call"
4af476d7
NC
1573 [(call (match_operand:QI 0 "general_operand")
1574 (match_operand:SI 1 "general_operand"))]
11bb1f11 1575 ""
11bb1f11 1576{
53855940
RH
1577 rtx fn = XEXP (operands[0], 0);
1578
1579 if (flag_pic && GET_CODE (fn) == SYMBOL_REF)
d1776069 1580 {
53855940 1581 if (MN10300_GLOBAL_P (fn))
d1776069
AO
1582 {
1583 /* The PLT code won't run on AM30, but then, there's no
1584 shared library support for AM30 either, so we just assume
1585 the linker is going to adjust all @PLT relocs to the
1586 actual symbols. */
c41c1387 1587 emit_use (pic_offset_table_rtx);
53855940 1588 fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT);
d1776069
AO
1589 }
1590 else
53855940 1591 fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC);
d1776069 1592 }
53855940
RH
1593 if (! call_address_operand (fn, VOIDmode))
1594 fn = force_reg (SImode, fn);
1595
1596 XEXP (operands[0], 0) = fn;
1597})
11bb1f11 1598
53855940
RH
1599(define_insn "*call_internal"
1600 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "a,S"))
1601 (match_operand:SI 1 "" ""))]
11bb1f11 1602 ""
f3f63737
NC
1603 "@
1604 calls %C0
1605 call %C0,[],0"
1606 [(set_attr_alternative "timings"
1607 [(if_then_else (eq_attr "cpu" "am34")
1608 (const_int 33) (const_int 44))
1609 (if_then_else (eq_attr "cpu" "am34")
1610 (const_int 55) (const_int 33))
1611 ])
1612 ]
4af476d7 1613)
11bb1f11
JL
1614
1615;; Call subroutine, returning value in operand 0
1616;; (which must be a hard register).
1617
1618(define_expand "call_value"
4af476d7
NC
1619 [(set (match_operand 0 "")
1620 (call (match_operand:QI 1 "general_operand")
1621 (match_operand:SI 2 "general_operand")))]
11bb1f11 1622 ""
11bb1f11 1623{
53855940
RH
1624 rtx fn = XEXP (operands[1], 0);
1625
1626 if (flag_pic && GET_CODE (fn) == SYMBOL_REF)
d1776069 1627 {
53855940 1628 if (MN10300_GLOBAL_P (fn))
d1776069
AO
1629 {
1630 /* The PLT code won't run on AM30, but then, there's no
1631 shared library support for AM30 either, so we just assume
1632 the linker is going to adjust all @PLT relocs to the
1633 actual symbols. */
c41c1387 1634 emit_use (pic_offset_table_rtx);
53855940 1635 fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT);
d1776069
AO
1636 }
1637 else
53855940 1638 fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC);
d1776069 1639 }
53855940
RH
1640 if (! call_address_operand (fn, VOIDmode))
1641 fn = force_reg (SImode, fn);
1642
1643 XEXP (operands[1], 0) = fn;
1644})
11bb1f11
JL
1645
1646(define_insn "call_value_internal"
53855940
RH
1647 [(set (match_operand 0 "" "")
1648 (call (mem:QI (match_operand:SI 1 "call_address_operand" "a,S"))
1649 (match_operand:SI 2 "" "")))]
11bb1f11 1650 ""
f3f63737
NC
1651 "@
1652 calls %C1
1653 call %C1,[],0"
1654 [(set_attr_alternative "timings"
1655 [(if_then_else (eq_attr "cpu" "am34")
1656 (const_int 33) (const_int 44))
1657 (if_then_else (eq_attr "cpu" "am34")
1658 (const_int 55) (const_int 33))
1659 ])
1660 ]
4af476d7 1661)
11bb1f11 1662
6c0870b8 1663(define_expand "untyped_call"
4af476d7 1664 [(parallel [(call (match_operand 0 "")
6c0870b8 1665 (const_int 0))
4af476d7
NC
1666 (match_operand 1 "")
1667 (match_operand 2 "")])]
6c0870b8 1668 ""
6c0870b8
JL
1669{
1670 int i;
1671
1672 emit_call_insn (gen_call (operands[0], const0_rtx));
1673
1674 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1675 {
1676 rtx set = XVECEXP (operands[2], 0, i);
1677 emit_move_insn (SET_DEST (set), SET_SRC (set));
1678 }
1679 DONE;
bad41521 1680})
6c0870b8 1681
11bb1f11
JL
1682(define_insn "nop"
1683 [(const_int 0)]
1684 ""
1685 "nop"
4af476d7 1686)
11bb1f11
JL
1687\f
1688;; ----------------------------------------------------------------------
1689;; EXTEND INSTRUCTIONS
1690;; ----------------------------------------------------------------------
1691
bad41521
RH
1692(define_insn "zero_extendqisi2"
1693 [(set (match_operand:SI 0 "register_operand" "=D,D,r")
fed2012b 1694 (zero_extend:SI
bad41521 1695 (match_operand:QI 1 "nonimmediate_operand" " 0,m,r")))]
fed2012b 1696 ""
705ac34f 1697 "@
bad41521
RH
1698 extbu %0
1699 movbu %1,%0
1700 extbu %1,%0"
1701 [(set_attr "isa" "*,*,am33")
1702 (set_attr_alternative "timings"
1703 [(const_int 11)
1704 (if_then_else (eq_attr "cpu" "am34")
1705 (const_int 13) (const_int 24))
1706 (const_int 11)
1707 ])]
4af476d7 1708)
705ac34f 1709
bad41521
RH
1710(define_insn "zero_extendhisi2"
1711 [(set (match_operand:SI 0 "register_operand" "=D,D,r")
11bb1f11 1712 (zero_extend:SI
bad41521 1713 (match_operand:HI 1 "nonimmediate_operand" " 0,m,r")))]
11bb1f11 1714 ""
777fbf09 1715 "@
bad41521
RH
1716 exthu %0
1717 movhu %1,%0
1718 exthu %1,%0"
1719 [(set_attr "isa" "*,*,am33")
1720 (set_attr_alternative "timings"
1721 [(const_int 11)
1722 (if_then_else (eq_attr "cpu" "am34")
1723 (const_int 13) (const_int 24))
1724 (const_int 11)])]
4af476d7 1725)
11bb1f11 1726
bad41521
RH
1727(define_insn "extendqisi2"
1728 [(set (match_operand:SI 0 "register_operand" "=D,r")
fed2012b 1729 (sign_extend:SI
bad41521 1730 (match_operand:QI 1 "register_operand" "0,r")))]
fed2012b 1731 ""
705ac34f 1732 "@
bad41521
RH
1733 extb %0
1734 extb %1,%0"
1735 [(set_attr "isa" "*,am33")]
4af476d7 1736)
705ac34f 1737
bad41521
RH
1738(define_insn "extendhisi2"
1739 [(set (match_operand:SI 0 "register_operand" "=D,r")
11bb1f11 1740 (sign_extend:SI
bad41521 1741 (match_operand:HI 1 "register_operand" "0,r")))]
11bb1f11 1742 ""
777fbf09 1743 "@
bad41521
RH
1744 exth %0
1745 exth %1,%0"
1746 [(set_attr "isa" "*,am33")]
4af476d7 1747)
11bb1f11
JL
1748\f
1749;; ----------------------------------------------------------------------
1750;; SHIFTS
1751;; ----------------------------------------------------------------------
1752
bad41521 1753(define_insn "ashlsi3"
a45d420a 1754 [(set (match_operand:SI 0 "register_operand" "=r,D,d,d,D,D,D,r")
705ac34f 1755 (ashift:SI
a45d420a
NC
1756 (match_operand:SI 1 "register_operand" " 0,0,0,0,0,0,0,r")
1757 (match_operand:QI 2 "nonmemory_operand" " J,K,M,L,D,O,i,r")))
bad41521 1758 (clobber (reg:CC CC_REG))]
11bb1f11
JL
1759 ""
1760 "@
bad41521
RH
1761 add %0,%0
1762 asl2 %0
1763 asl2 %0\;add %0,%0
1764 asl2 %0\;asl2 %0
1765 asl %S2,%0
298362c8 1766 asl %S2,%0
a45d420a 1767 asl %S2,%0
bad41521 1768 asl %2,%1,%0"
a45d420a
NC
1769 [(set_attr "isa" "*,*,*,*,*,*,*,am33")
1770 (set_attr "liw" "op2,op2,op2,op2,op2,op2,*,*")
298362c8 1771 (set_attr "liw_op" "asl")
a45d420a 1772 (set_attr "timings" "11,11,22,22,11,11,11,11")]
bad41521
RH
1773)
1774
1775(define_insn "lshrsi3"
a45d420a 1776 [(set (match_operand:SI 0 "register_operand" "=D,D,D,r")
705ac34f 1777 (lshiftrt:SI
a45d420a
NC
1778 (match_operand:SI 1 "register_operand" "0,0,0,r")
1779 (match_operand:QI 2 "nonmemory_operand" "D,O,i,r")))
bad41521 1780 (clobber (reg:CC CC_REG))]
fed2012b 1781 ""
bad41521 1782 "@
a45d420a 1783 lsr %S2,%0
298362c8 1784 lsr %S2,%0
bad41521
RH
1785 lsr %S2,%0
1786 lsr %2,%1,%0"
a45d420a
NC
1787 [(set_attr "isa" "*,*,*,am33")
1788 (set_attr "liw" "op2,op2,*,*")
298362c8 1789 (set_attr "liw_op" "lsr")]
4af476d7 1790)
705ac34f 1791
bad41521 1792(define_insn "ashrsi3"
a45d420a 1793 [(set (match_operand:SI 0 "register_operand" "=D,D,D,r")
11bb1f11 1794 (ashiftrt:SI
a45d420a
NC
1795 (match_operand:SI 1 "register_operand" "0,0,0,r")
1796 (match_operand:QI 2 "nonmemory_operand" "D,O,i,r")))
bad41521 1797 (clobber (reg:CC CC_REG))]
11bb1f11 1798 ""
bad41521 1799 "@
a45d420a 1800 asr %S2,%0
298362c8 1801 asr %S2,%0
bad41521
RH
1802 asr %S2,%0
1803 asr %2,%1,%0"
a45d420a
NC
1804 [(set_attr "isa" "*,*,*,am33")
1805 (set_attr "liw" "op2,op2,*,*")
298362c8 1806 (set_attr "liw_op" "asr")]
4af476d7 1807)
11bb1f11 1808
f3d9d2e0 1809;; ----------------------------------------------------------------------
073a8998 1810;; MISCELLANEOUS
f3d9d2e0
RH
1811;; ----------------------------------------------------------------------
1812
bebd619e
NC
1813;; Note the use of the (const_int 0) when generating the insn that matches
1814;; the bsch pattern. This ensures that the destination register is
1815;; initialised with 0 which will make the BSCH instruction set searching
1816;; at bit 31.
1817;;
1818;; The XOR in the instruction sequence below is there because the BSCH
1819;; instruction returns the bit number of the highest set bit and we want
1820;; the number of zero bits above that bit. The AM33 does not have a
1821;; reverse subtraction instruction, but we can use a simple xor instead
1822;; since we know that the top 27 bits are clear.
f3d9d2e0 1823(define_expand "clzsi2"
bebd619e
NC
1824 [(parallel [(set (match_operand:SI 0 "register_operand")
1825 (unspec:SI [(match_operand:SI 1 "register_operand")
f3d9d2e0 1826 (const_int 0)] UNSPEC_BSCH))
bebd619e
NC
1827 (clobber (reg:CC CC_REG))])
1828 (parallel [(set (match_dup 0)
1829 (xor:SI (match_dup 0)
1830 (const_int 31)))
f3d9d2e0
RH
1831 (clobber (reg:CC CC_REG))])]
1832 "TARGET_AM33"
1833)
1834
1835(define_insn "*bsch"
1836 [(set (match_operand:SI 0 "register_operand" "=r")
1837 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1838 (match_operand:SI 2 "nonmemory_operand" "0")]
1839 UNSPEC_BSCH))
1840 (clobber (reg:CC CC_REG))]
1841 "TARGET_AM33"
bebd619e 1842 "bsch %1, %0"
f3d9d2e0
RH
1843)
1844
9c907d54
JL
1845;; ----------------------------------------------------------------------
1846;; FP INSTRUCTIONS
1847;; ----------------------------------------------------------------------
9c907d54 1848
0d9e23f4 1849(define_insn "abssf2"
4af476d7 1850 [(set (match_operand:SF 0 "register_operand" "=f,f")
18e9d2f9
AO
1851 (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
1852 "TARGET_AM33_2"
1853 "@
1854 fabs %0
1855 fabs %1, %0"
f3f63737
NC
1856 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1857 (const_int 17) (const_int 14)))]
4af476d7 1858)
18e9d2f9 1859
0d9e23f4 1860(define_insn "negsf2"
4af476d7 1861 [(set (match_operand:SF 0 "register_operand" "=f,f")
18e9d2f9
AO
1862 (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
1863 "TARGET_AM33_2"
1864 "@
1865 fneg %0
1866 fneg %1, %0"
f3f63737
NC
1867 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1868 (const_int 17) (const_int 14)))]
4af476d7 1869)
18e9d2f9
AO
1870
1871(define_expand "sqrtsf2"
0d9e23f4
RH
1872 [(set (match_operand:SF 0 "register_operand" "")
1873 (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
18e9d2f9 1874 "TARGET_AM33_2 && flag_unsafe_math_optimizations"
0d9e23f4
RH
1875{
1876 rtx scratch = gen_reg_rtx (SFmode);
1877 emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
1878 emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
1879 scratch));
1880 DONE;
1881})
18e9d2f9
AO
1882
1883(define_insn "rsqrtsf2"
4af476d7
NC
1884 [(set (match_operand:SF 0 "register_operand" "=f,f")
1885 (div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
1886 (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))
0d9e23f4 1887 (clobber (reg:CC_FLOAT CC_REG))]
18e9d2f9
AO
1888 "TARGET_AM33_2"
1889 "@
1890 frsqrt %0
1891 frsqrt %1, %0"
f3f63737
NC
1892 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1893 (const_int 4753) (const_int 2327)))]
4af476d7
NC
1894)
1895
0d9e23f4 1896(define_insn "addsf3"
4af476d7 1897 [(set (match_operand:SF 0 "register_operand" "=f,f")
18e9d2f9 1898 (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
e7ab5593 1899 (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
0d9e23f4 1900 (clobber (reg:CC_FLOAT CC_REG))]
18e9d2f9
AO
1901 "TARGET_AM33_2"
1902 "@
1903 fadd %2, %0
1904 fadd %2, %1, %0"
f3f63737
NC
1905 [(set_attr_alternative "timings"
1906 [(if_then_else (eq_attr "cpu" "am34")
1907 (const_int 17) (const_int 14))
1908 (if_then_else (eq_attr "cpu" "am34")
1909 (const_int 17) (const_int 25))
0d9e23f4 1910 ])]
4af476d7
NC
1911)
1912
0d9e23f4 1913(define_insn "subsf3"
4af476d7 1914 [(set (match_operand:SF 0 "register_operand" "=f,f")
18e9d2f9 1915 (minus:SF (match_operand:SF 1 "register_operand" "0,f")
e7ab5593 1916 (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
0d9e23f4 1917 (clobber (reg:CC_FLOAT CC_REG))]
18e9d2f9
AO
1918 "TARGET_AM33_2"
1919 "@
1920 fsub %2, %0
1921 fsub %2, %1, %0"
f3f63737
NC
1922 [(set_attr_alternative "timings"
1923 [(if_then_else (eq_attr "cpu" "am34")
1924 (const_int 17) (const_int 14))
1925 (if_then_else (eq_attr "cpu" "am34")
1926 (const_int 17) (const_int 25))
0d9e23f4 1927 ])]
4af476d7
NC
1928)
1929
0d9e23f4 1930(define_insn "mulsf3"
4af476d7 1931 [(set (match_operand:SF 0 "register_operand" "=f,f")
18e9d2f9 1932 (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
e7ab5593 1933 (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
4af476d7
NC
1934 (clobber (reg:CC_FLOAT CC_REG))
1935 ]
18e9d2f9
AO
1936 "TARGET_AM33_2"
1937 "@
1938 fmul %2, %0
1939 fmul %2, %1, %0"
f3f63737
NC
1940 [(set_attr_alternative "timings"
1941 [(if_then_else (eq_attr "cpu" "am34")
1942 (const_int 17) (const_int 14))
1943 (if_then_else (eq_attr "cpu" "am34")
1944 (const_int 17) (const_int 25))
0d9e23f4 1945 ])]
4af476d7 1946)
18e9d2f9
AO
1947
1948(define_insn "divsf3"
4af476d7
NC
1949 [(set (match_operand:SF 0 "register_operand" "=f,f")
1950 (div:SF (match_operand:SF 1 "register_operand" "0,f")
1951 (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
0d9e23f4 1952 (clobber (reg:CC_FLOAT CC_REG))]
18e9d2f9
AO
1953 "TARGET_AM33_2"
1954 "@
1955 fdiv %2, %0
1956 fdiv %2, %1, %0"
f3f63737
NC
1957 [(set_attr_alternative "timings"
1958 [(if_then_else (eq_attr "cpu" "am34")
1959 (const_int 2531) (const_int 1216))
1960 (if_then_else (eq_attr "cpu" "am34")
1961 (const_int 2531) (const_int 1317))
0d9e23f4 1962 ])]
4af476d7 1963)
18e9d2f9 1964
93f9a911 1965(define_insn "fmasf4"
85a337b5 1966 [(set (match_operand:SF 0 "register_operand" "=c")
93f9a911
RH
1967 (fma:SF (match_operand:SF 1 "register_operand" "f")
1968 (match_operand:SF 2 "register_operand" "f")
1969 (match_operand:SF 3 "register_operand" "f")))
4af476d7
NC
1970 (clobber (reg:CC_FLOAT CC_REG))
1971 ]
18e9d2f9
AO
1972 "TARGET_AM33_2"
1973 "fmadd %1, %2, %3, %0"
f3f63737
NC
1974 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1975 (const_int 17) (const_int 24)))]
4af476d7 1976)
18e9d2f9 1977
93f9a911 1978(define_insn "fmssf4"
85a337b5 1979 [(set (match_operand:SF 0 "register_operand" "=c")
93f9a911
RH
1980 (fma:SF (match_operand:SF 1 "register_operand" "f")
1981 (match_operand:SF 2 "register_operand" "f")
1982 (neg:SF (match_operand:SF 3 "register_operand" "f"))))
4af476d7
NC
1983 (clobber (reg:CC_FLOAT CC_REG))
1984 ]
18e9d2f9
AO
1985 "TARGET_AM33_2"
1986 "fmsub %1, %2, %3, %0"
f3f63737
NC
1987 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1988 (const_int 17) (const_int 24)))]
4af476d7 1989)
18e9d2f9 1990
93f9a911 1991(define_insn "fnmasf4"
85a337b5 1992 [(set (match_operand:SF 0 "register_operand" "=c")
93f9a911
RH
1993 (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
1994 (match_operand:SF 2 "register_operand" "f")
1995 (match_operand:SF 3 "register_operand" "f")))
4af476d7
NC
1996 (clobber (reg:CC_FLOAT CC_REG))
1997 ]
18e9d2f9
AO
1998 "TARGET_AM33_2"
1999 "fnmadd %1, %2, %3, %0"
f3f63737
NC
2000 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2001 (const_int 17) (const_int 24)))]
4af476d7 2002)
18e9d2f9 2003
93f9a911 2004(define_insn "fnmssf4"
85a337b5 2005 [(set (match_operand:SF 0 "register_operand" "=c")
93f9a911
RH
2006 (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
2007 (match_operand:SF 2 "register_operand" "f")
2008 (neg:SF (match_operand:SF 3 "register_operand" "f"))))
4af476d7
NC
2009 (clobber (reg:CC_FLOAT CC_REG))
2010 ]
18e9d2f9
AO
2011 "TARGET_AM33_2"
2012 "fnmsub %1, %2, %3, %0"
f3f63737
NC
2013 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2014 (const_int 17) (const_int 24)))]
4af476d7 2015)
9c907d54 2016
11bb1f11
JL
2017;; ----------------------------------------------------------------------
2018;; PROLOGUE/EPILOGUE
2019;; ----------------------------------------------------------------------
2020(define_expand "prologue"
2021 [(const_int 0)]
2022 ""
040c5757
RH
2023 { mn10300_expand_prologue (); DONE; }
2024)
11bb1f11
JL
2025
2026(define_expand "epilogue"
2027 [(return)]
2028 ""
040c5757
RH
2029 { mn10300_expand_epilogue (); DONE; }
2030)
11bb1f11 2031
37a185d7
RH
2032(define_insn "return"
2033 [(return)]
2034 "mn10300_can_use_rets_insn ()"
2035{
2036 /* The RETF insn is 4 cycles faster than RETS, though 1 byte larger. */
2037 if (optimize_insn_for_speed_p () && mn10300_can_use_retf_insn ())
2038 return "retf [],0";
2039 else
2040 return "rets";
2041})
11bb1f11 2042
37a185d7
RH
2043(define_insn "return_ret"
2044 [(return)
2045 (use (match_operand:SI 0 "const_int_operand" ""))]
11bb1f11 2046 ""
040c5757 2047{
37a185d7
RH
2048 /* The RETF insn is up to 3 cycles faster than RET. */
2049 fputs ((mn10300_can_use_retf_insn () ? "\tretf " : "\tret "), asm_out_file);
e902c266 2050 mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs (NULL));
040c5757
RH
2051 fprintf (asm_out_file, ",%d\n", (int) INTVAL (operands[0]));
2052 return "";
37a185d7 2053})
11bb1f11 2054
f6cd7c62 2055;; This instruction matches one generated by mn10300_gen_multiple_store()
11bb1f11 2056(define_insn "store_movm"
e7ab5593 2057 [(match_parallel 0 "mn10300_store_multiple_operation"
4af476d7 2058 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand 1 "" "")))])]
11bb1f11 2059 ""
040c5757
RH
2060{
2061 fputs ("\tmovm ", asm_out_file);
2062 mn10300_print_reg_list (asm_out_file,
c345a0b1 2063 mn10300_store_multiple_regs (operands[0]));
040c5757
RH
2064 fprintf (asm_out_file, ",(sp)\n");
2065 return "";
2066}
f3f63737
NC
2067 ;; Assume that no more than 8 registers will be pushed.
2068 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2069 (const_int 99) (const_int 88)))]
4af476d7 2070)
5abc5de9 2071
040c5757
RH
2072(define_expand "load_pic"
2073 [(const_int 0)]
2074 "flag_pic"
d1776069 2075{
d1776069 2076 if (TARGET_AM33)
040c5757
RH
2077 emit_insn (gen_am33_load_pic (pic_offset_table_rtx));
2078 else if (mn10300_frame_size () == 0)
2079 emit_insn (gen_mn10300_load_pic0 (pic_offset_table_rtx));
d1776069 2080 else
040c5757 2081 emit_insn (gen_mn10300_load_pic1 (pic_offset_table_rtx));
d1776069 2082 DONE;
040c5757 2083})
d1776069 2084
040c5757
RH
2085(define_insn "am33_load_pic"
2086 [(set (match_operand:SI 0 "register_operand" "=a")
2087 (unspec:SI [(const_int 0)] UNSPEC_GOT))
2088 (clobber (reg:CC CC_REG))]
d1776069 2089 "TARGET_AM33"
040c5757
RH
2090{
2091 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2092 return ".LPIC%=:\;mov pc,%0\;add %1-(.LPIC%=-.),%0";
2093}
2094 [(set_attr "timings" "33")]
4af476d7 2095)
d1776069 2096
040c5757
RH
2097;; Load pic register with push/pop of stack.
2098(define_insn "mn10300_load_pic0"
2099 [(set (match_operand:SI 0 "register_operand" "=a")
2100 (unspec:SI [(const_int 0)] UNSPEC_GOT))
2101 (clobber (reg:SI MDR_REG))
2102 (clobber (reg:CC CC_REG))]
2103 ""
2104{
2105 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2106 return ("add -4,sp\;"
2107 "calls .LPIC%=\n"
2108 ".LPIC%=:\;"
2109 "movm (sp),[%0]\;"
2110 "add %1-(.LPIC%=-.),%0");
2111}
2112 [(set_attr "timings" "88")]
4af476d7 2113)
d1776069 2114
040c5757
RH
2115;; Load pic register re-using existing stack space.
2116(define_insn "mn10300_load_pic1"
2117 [(set (match_operand:SI 0 "register_operand" "=a")
2118 (unspec:SI [(const_int 0)] UNSPEC_GOT))
2119 (clobber (mem:SI (reg:SI SP_REG)))
2120 (clobber (reg:SI MDR_REG))
2121 (clobber (reg:CC CC_REG))]
4af476d7 2122 ""
040c5757
RH
2123{
2124 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2125 return ("calls .LPIC%=\n"
2126 ".LPIC%=:\;"
2127 "mov (sp),%0\;"
2128 "add %1-(.LPIC%=-.),%0");
2129}
2130 [(set_attr "timings" "66")]
4af476d7 2131)
298362c8
NC
2132
2133;; The mode on operand 3 has been deliberately omitted because it
2134;; can be either SI (for arithmetic operations) or QI (for shifts).
2135(define_insn "liw"
2136 [(set (match_operand:SI 0 "register_operand" "=r")
2137 (unspec:SI [(match_dup 0)
a45d420a 2138 (match_operand 2 "liw_operand" "rO")
298362c8
NC
2139 (match_operand:SI 4 "const_int_operand" "")]
2140 UNSPEC_LIW))
2141 (set (match_operand:SI 1 "register_operand" "=r")
2142 (unspec:SI [(match_dup 1)
a45d420a 2143 (match_operand 3 "liw_operand" "rO")
298362c8
NC
2144 (match_operand:SI 5 "const_int_operand" "")]
2145 UNSPEC_LIW))]
2146 "TARGET_ALLOW_LIW"
2147 "%W4_%W5 %2, %0, %3, %1"
2148 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2149 (const_int 13) (const_int 12)))]
2150)
2151
2152;; The mode on operand 1 has been deliberately omitted because it
2153;; can be either SI (for arithmetic operations) or QI (for shifts).
2154(define_insn "cmp_liw"
2155 [(set (reg:CC CC_REG)
2156 (compare:CC (match_operand:SI 2 "register_operand" "r")
a45d420a 2157 (match_operand 3 "liw_operand" "rO")))
298362c8
NC
2158 (set (match_operand:SI 0 "register_operand" "=r")
2159 (unspec:SI [(match_dup 0)
a45d420a 2160 (match_operand 1 "liw_operand" "rO")
298362c8
NC
2161 (match_operand:SI 4 "const_int_operand" "")]
2162 UNSPEC_LIW))]
2163 "TARGET_ALLOW_LIW"
a45d420a 2164 "cmp_%W4 %3, %2, %1, %0"
298362c8
NC
2165 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2166 (const_int 13) (const_int 12)))]
2167)
2168
2169(define_insn "liw_cmp"
2170 [(set (match_operand:SI 0 "register_operand" "=r")
2171 (unspec:SI [(match_dup 0)
a45d420a 2172 (match_operand 1 "liw_operand" "rO")
298362c8
NC
2173 (match_operand:SI 4 "const_int_operand" "")]
2174 UNSPEC_LIW))
2175 (set (reg:CC CC_REG)
2176 (compare:CC (match_operand:SI 2 "register_operand" "r")
a45d420a 2177 (match_operand 3 "liw_operand" "rO")))]
298362c8 2178 "TARGET_ALLOW_LIW"
a45d420a 2179 "%W4_cmp %1, %0, %3, %2"
298362c8
NC
2180 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2181 (const_int 13) (const_int 12)))]
2182)
662c03f4
NC
2183
2184;; Note - in theory the doloop patterns could be used here to express
2185;; the SETLB and Lcc instructions. In practice this does not work because
2186;; the acceptable forms of the doloop patterns do not include UNSPECs
2187;; and without them gcc's basic block reordering code can duplicate the
2188;; doloop_end pattern, leading to bogus multiple decrements of the loop
2189;; counter.
2190
2191(define_insn "setlb"
2192 [(unspec [(const_int 0)] UNSPEC_SETLB)]
2193 "TARGET_AM33 && TARGET_ALLOW_SETLB"
2194 "setlb"
2195)
2196
2197(define_insn "Lcc"
2198 [(set (pc)
2199 (if_then_else (match_operator 0 "comparison_operator"
2200 [(reg:CC CC_REG) (const_int 0)])
2201 (label_ref (match_operand 1 "" ""))
2202 (pc)))
2203 (unspec [(const_int 1)] UNSPEC_SETLB)]
2204 "TARGET_AM33 && TARGET_ALLOW_SETLB"
2205 "L%b0 # loop back to: %1"
2206)
2207
2208(define_insn "FLcc"
2209 [(set (pc)
2210 (if_then_else (match_operator 0 "comparison_operator"
2211 [(reg:CC_FLOAT CC_REG) (const_int 0)])
2212 (label_ref (match_operand 1 "" ""))
2213 (pc)))
2214 (unspec [(const_int 2)] UNSPEC_SETLB)]
2215 "TARGET_AM33_2 && TARGET_ALLOW_SETLB"
2216 "FL%b0 # loop back to: %1"
2217 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") (const_int 44) (const_int 11)))]
2218)
This page took 7.115092 seconds and 6 git commands to generate.