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