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