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