]>
Commit | Line | Data |
---|---|---|
956d6950 | 1 | ;; GCC machine description for Matsushita MN10300 |
6e86170d | 2 | ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc. |
11bb1f11 JL |
3 | |
4 | ;; Contributed by Jeff Law (law@cygnus.com). | |
5 | ||
6 | ;; This file is part of GNU CC. | |
7 | ||
8 | ;; GNU CC is free software; you can redistribute it and/or modify | |
9 | ;; it under the terms of the GNU General Public License as published by | |
10 | ;; the Free Software Foundation; either version 2, or (at your option) | |
11 | ;; any later version. | |
12 | ||
13 | ;; GNU CC is distributed in the hope that it will be useful, | |
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 | |
19 | ;; along with GNU CC; see the file COPYING. If not, write to | |
20 | ;; the Free Software Foundation, 59 Temple Place - Suite 330, | |
21 | ;; Boston, MA 02111-1307, USA. | |
22 | ||
23 | ;; The original PO technology requires these to be ordered by speed, | |
24 | ;; so that assigner will pick the fastest. | |
25 | ||
26 | ;; See file "rtl.def" for documentation on define_insn, match_*, et. al. | |
27 | ||
28 | ;; Condition code settings. | |
29 | ;; none - insn does not affect cc | |
30 | ;; none_0hit - insn does not affect cc but it does modify operand 0 | |
31 | ;; This attribute is used to keep track of when operand 0 changes. | |
32 | ;; See the description of NOTICE_UPDATE_CC for more info. | |
956d6950 JL |
33 | ;; set_znv - insn sets z,n,v to usable values; c is unusable. |
34 | ;; set_zn - insn sets z,n to usable values; v,c are unusable. | |
11bb1f11 | 35 | ;; compare - compare instruction |
3b800f71 | 36 | ;; invert -- like compare, but flags are inverted. |
11bb1f11 | 37 | ;; clobber - value of cc is unknown |
d116300b | 38 | (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber,invert" |
11bb1f11 JL |
39 | (const_string "clobber")) |
40 | \f | |
41 | ;; ---------------------------------------------------------------------- | |
42 | ;; MOVE INSTRUCTIONS | |
43 | ;; ---------------------------------------------------------------------- | |
44 | ||
45 | ;; movqi | |
46 | ||
47 | (define_expand "movqi" | |
48 | [(set (match_operand:QI 0 "general_operand" "") | |
49 | (match_operand:QI 1 "general_operand" ""))] | |
50 | "" | |
51 | " | |
52 | { | |
53 | /* One of the ops has to be in a register */ | |
54 | if (!register_operand (operand0, QImode) | |
55 | && !register_operand (operand1, QImode)) | |
56 | operands[1] = copy_to_mode_reg (QImode, operand1); | |
57 | }") | |
58 | ||
59 | (define_insn "" | |
c6ee9150 | 60 | [(set (match_operand:QI 0 "general_operand" "=d,*a,d,*a,d,*a,d,*a,d,m") |
74452ac3 | 61 | (match_operand:QI 1 "general_operand" "0,0,I,I,a,d,di,ia,m,d"))] |
11bb1f11 JL |
62 | "register_operand (operands[0], QImode) |
63 | || register_operand (operands[1], QImode)" | |
74452ac3 JL |
64 | "* |
65 | { | |
66 | switch (which_alternative) | |
67 | { | |
68 | case 0: | |
69 | case 1: | |
70 | return \"nop\"; | |
71 | case 2: | |
72 | return \"clr %0\"; | |
73 | case 3: | |
74 | if (zero_areg) | |
75 | { | |
76 | rtx xoperands[2]; | |
77 | ||
78 | xoperands[0] = operands[0]; | |
79 | xoperands[1] = zero_areg; | |
80 | if (rtx_equal_p (xoperands[0], xoperands[1])) | |
81 | output_asm_insn (\"sub %1,%0\", xoperands); | |
82 | else | |
83 | output_asm_insn (\"mov %1,%0\", xoperands); | |
84 | return \"\"; | |
85 | } | |
86 | ||
87 | /* FALLTHROUGH */ | |
88 | case 4: | |
89 | case 5: | |
90 | case 6: | |
91 | case 7: | |
92 | return \"mov %1,%0\"; | |
93 | case 8: | |
94 | case 9: | |
95 | return \"movbu %1,%0\"; | |
96 | } | |
97 | }" | |
98 | [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) | |
11bb1f11 JL |
99 | |
100 | ;; movhi | |
101 | ||
102 | (define_expand "movhi" | |
103 | [(set (match_operand:HI 0 "general_operand" "") | |
104 | (match_operand:HI 1 "general_operand" ""))] | |
105 | "" | |
106 | " | |
107 | { | |
108 | /* One of the ops has to be in a register */ | |
109 | if (!register_operand (operand1, HImode) | |
110 | && !register_operand (operand0, HImode)) | |
111 | operands[1] = copy_to_mode_reg (HImode, operand1); | |
112 | }") | |
113 | ||
114 | (define_insn "" | |
c6ee9150 | 115 | [(set (match_operand:HI 0 "general_operand" "=d,*a,d,*a,d,*a,d,*a,d,m") |
74452ac3 | 116 | (match_operand:HI 1 "general_operand" "0,0,I,I,a,d,di,ia,m,d"))] |
11bb1f11 JL |
117 | "register_operand (operands[0], HImode) |
118 | || register_operand (operands[1], HImode)" | |
74452ac3 JL |
119 | "* |
120 | { | |
121 | switch (which_alternative) | |
122 | { | |
123 | case 0: | |
124 | case 1: | |
125 | return \"nop\"; | |
126 | case 2: | |
127 | return \"clr %0\"; | |
128 | case 3: | |
129 | if (zero_areg) | |
130 | { | |
131 | rtx xoperands[2]; | |
132 | ||
133 | xoperands[0] = operands[0]; | |
134 | xoperands[1] = zero_areg; | |
135 | if (rtx_equal_p (xoperands[0], xoperands[1])) | |
136 | output_asm_insn (\"sub %1,%0\", xoperands); | |
137 | else | |
138 | output_asm_insn (\"mov %1,%0\", xoperands); | |
139 | return \"\"; | |
140 | } | |
141 | ||
142 | /* FALLTHROUGH */ | |
143 | case 4: | |
144 | case 5: | |
145 | case 6: | |
146 | case 7: | |
147 | return \"mov %1,%0\"; | |
148 | case 8: | |
149 | case 9: | |
150 | return \"movhu %1,%0\"; | |
151 | } | |
152 | }" | |
153 | [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) | |
11bb1f11 JL |
154 | |
155 | ;; movsi and helpers | |
156 | ||
460f4b9d JL |
157 | ;; We use this to handle addition of two values when one operand is the |
158 | ;; stack pointer and the other is a memory reference of some kind. Reload | |
159 | ;; does not handle them correctly without this expander. | |
160 | (define_expand "reload_insi" | |
161 | [(set (match_operand:SI 0 "register_operand" "=a") | |
162 | (match_operand:SI 1 "impossible_plus_operand" "")) | |
4c742813 | 163 | (clobber (match_operand:SI 2 "register_operand" "=&r"))] |
460f4b9d JL |
164 | "" |
165 | " | |
166 | { | |
4c742813 JL |
167 | if (XEXP (operands[1], 0) == stack_pointer_rtx) |
168 | { | |
169 | emit_move_insn (operands[0], XEXP (operands[1], 0)); | |
bb75a000 JL |
170 | if (GET_CODE (XEXP (operands[1], 1)) == SUBREG |
171 | && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1))) | |
172 | > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1)))))) | |
173 | emit_move_insn (operands[2], | |
174 | gen_rtx (ZERO_EXTEND, GET_MODE (XEXP (operands[1], 1)), | |
175 | SUBREG_REG (XEXP (operands[1], 1)))); | |
176 | else | |
177 | emit_move_insn (operands[2], XEXP (operands[1], 1)); | |
4c742813 JL |
178 | } |
179 | else | |
180 | { | |
181 | emit_move_insn (operands[0], XEXP (operands[1], 1)); | |
bb75a000 JL |
182 | if (GET_CODE (XEXP (operands[1], 0)) == SUBREG |
183 | && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0))) | |
184 | > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0)))))) | |
185 | emit_move_insn (operands[2], | |
186 | gen_rtx (ZERO_EXTEND, GET_MODE (XEXP (operands[1], 0)), | |
187 | SUBREG_REG (XEXP (operands[1], 0)))); | |
188 | else | |
189 | emit_move_insn (operands[2], XEXP (operands[1], 0)); | |
4c742813 | 190 | } |
460f4b9d JL |
191 | emit_insn (gen_addsi3 (operands[0], operands[0], operands[2])); |
192 | DONE; | |
193 | }") | |
194 | ||
11bb1f11 JL |
195 | (define_expand "movsi" |
196 | [(set (match_operand:SI 0 "general_operand" "") | |
197 | (match_operand:SI 1 "general_operand" ""))] | |
198 | "" | |
199 | " | |
200 | { | |
201 | /* One of the ops has to be in a register */ | |
202 | if (!register_operand (operand1, SImode) | |
203 | && !register_operand (operand0, SImode)) | |
204 | operands[1] = copy_to_mode_reg (SImode, operand1); | |
205 | }") | |
206 | ||
11bb1f11 | 207 | (define_insn "" |
74452ac3 JL |
208 | [(set (match_operand:SI 0 "general_operand" |
209 | "=d,a,d,a,dm,dm,am,am,d,d,a,a,aR,x") | |
210 | (match_operand:SI 1 "general_operand" | |
211 | "0,0,I,I,d,a,d,a,dim,aim,dim,aim,x,aR"))] | |
11bb1f11 JL |
212 | "register_operand (operands[0], SImode) |
213 | || register_operand (operands[1], SImode)" | |
74452ac3 JL |
214 | "* |
215 | { | |
216 | switch (which_alternative) | |
217 | { | |
218 | case 0: | |
219 | case 1: | |
220 | return \"nop\"; | |
221 | case 2: | |
222 | return \"clr %0\"; | |
223 | case 3: | |
224 | if (zero_areg) | |
225 | { | |
226 | rtx xoperands[2]; | |
227 | ||
228 | xoperands[0] = operands[0]; | |
229 | xoperands[1] = zero_areg; | |
230 | if (rtx_equal_p (xoperands[0], xoperands[1])) | |
231 | output_asm_insn (\"sub %1,%0\", xoperands); | |
232 | else | |
233 | output_asm_insn (\"mov %1,%0\", xoperands); | |
234 | return \"\"; | |
235 | } | |
236 | ||
237 | /* FALLTHROUGH */ | |
238 | case 4: | |
239 | case 5: | |
240 | case 6: | |
241 | case 7: | |
242 | case 8: | |
243 | case 9: | |
244 | case 10: | |
245 | case 11: | |
246 | case 12: | |
247 | case 13: | |
248 | return \"mov %1,%0\"; | |
249 | } | |
250 | }" | |
251 | [(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")]) | |
11bb1f11 JL |
252 | |
253 | (define_expand "movsf" | |
254 | [(set (match_operand:SF 0 "general_operand" "") | |
255 | (match_operand:SF 1 "general_operand" ""))] | |
256 | "" | |
257 | " | |
258 | { | |
259 | /* One of the ops has to be in a register */ | |
260 | if (!register_operand (operand1, SFmode) | |
261 | && !register_operand (operand0, SFmode)) | |
262 | operands[1] = copy_to_mode_reg (SFmode, operand1); | |
263 | }") | |
264 | ||
11bb1f11 | 265 | (define_insn "" |
74452ac3 JL |
266 | [(set (match_operand:SF 0 "general_operand" "=d,a,d,a,dam,da") |
267 | (match_operand:SF 1 "general_operand" "0,0,G,G,da,daim"))] | |
11bb1f11 JL |
268 | "register_operand (operands[0], SFmode) |
269 | || register_operand (operands[1], SFmode)" | |
74452ac3 JL |
270 | "* |
271 | { | |
272 | switch (which_alternative) | |
273 | { | |
274 | case 0: | |
275 | case 1: | |
276 | return \"nop\"; | |
277 | case 2: | |
278 | return \"clr %0\"; | |
279 | case 3: | |
280 | if (zero_areg) | |
281 | { | |
282 | rtx xoperands[2]; | |
283 | ||
284 | xoperands[0] = operands[0]; | |
285 | xoperands[1] = zero_areg; | |
286 | if (rtx_equal_p (xoperands[0], xoperands[1])) | |
287 | output_asm_insn (\"sub %1,%0\", xoperands); | |
288 | else | |
289 | output_asm_insn (\"mov %1,%0\", xoperands); | |
290 | return \"\"; | |
291 | } | |
292 | ||
293 | /* FALLTHROUGH */ | |
294 | case 4: | |
295 | case 5: | |
296 | return \"mov %1,%0\"; | |
297 | } | |
298 | }" | |
299 | [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")]) | |
11bb1f11 | 300 | |
38c37a0e JL |
301 | (define_expand "movdi" |
302 | [(set (match_operand:DI 0 "general_operand" "") | |
303 | (match_operand:DI 1 "general_operand" ""))] | |
304 | "" | |
305 | " | |
306 | { | |
307 | /* One of the ops has to be in a register */ | |
308 | if (!register_operand (operand1, DImode) | |
309 | && !register_operand (operand0, DImode)) | |
310 | operands[1] = copy_to_mode_reg (DImode, operand1); | |
311 | }") | |
312 | ||
313 | (define_insn "" | |
74452ac3 JL |
314 | [(set (match_operand:DI 0 "general_operand" |
315 | "=d,a,d,a,dm,dm,am,am,d,d,a,a") | |
316 | (match_operand:DI 1 "general_operand" | |
317 | "0,0,I,I,d,a,d,a,dim,aim,dim,aim"))] | |
38c37a0e JL |
318 | "register_operand (operands[0], DImode) |
319 | || register_operand (operands[1], DImode)" | |
862bff88 JL |
320 | "* |
321 | { | |
22ef4e9b JL |
322 | long val[2]; |
323 | REAL_VALUE_TYPE rv; | |
324 | ||
862bff88 JL |
325 | switch (which_alternative) |
326 | { | |
327 | case 0: | |
328 | case 1: | |
329 | return \"nop\"; | |
330 | ||
331 | case 2: | |
332 | return \"clr %L0\;clr %H0\"; | |
333 | ||
334 | case 3: | |
74452ac3 JL |
335 | { |
336 | rtx xoperands[2]; | |
337 | ||
338 | xoperands[0] = operands[0]; | |
339 | xoperands[1] = zero_areg ? zero_areg : operands[1]; | |
340 | if (rtx_equal_p (xoperands[0], xoperands[1])) | |
341 | output_asm_insn (\"sub %L1,%L0\;mov %L0,%H0\", xoperands); | |
342 | else | |
343 | output_asm_insn (\"mov %1,%L0\;mov %L0,%H0\", xoperands); | |
344 | return \"\"; | |
345 | } | |
862bff88 JL |
346 | case 4: |
347 | case 5: | |
348 | case 6: | |
349 | case 7: | |
350 | case 8: | |
351 | case 9: | |
352 | case 10: | |
74452ac3 | 353 | case 11: |
22ef4e9b JL |
354 | if (GET_CODE (operands[1]) == CONST_INT) |
355 | { | |
356 | val[0] = INTVAL (operands[1]); | |
357 | val[1] = val[0] < 0 ? -1 : 0; | |
358 | } | |
359 | if (GET_CODE (operands[1]) == CONST_DOUBLE) | |
360 | { | |
361 | if (GET_MODE (operands[1]) == DFmode) | |
362 | { | |
363 | REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); | |
364 | REAL_VALUE_TO_TARGET_DOUBLE (rv, val); | |
365 | } | |
366 | else if (GET_MODE (operands[1]) == VOIDmode | |
367 | || GET_MODE (operands[1]) == DImode) | |
368 | { | |
369 | val[0] = CONST_DOUBLE_LOW (operands[1]); | |
370 | val[1] = CONST_DOUBLE_HIGH (operands[1]); | |
371 | } | |
372 | } | |
373 | ||
862bff88 JL |
374 | if (GET_CODE (operands[1]) == MEM |
375 | && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0))) | |
376 | { | |
377 | rtx temp = operands[0]; | |
378 | ||
379 | while (GET_CODE (temp) == SUBREG) | |
380 | temp = SUBREG_REG (temp); | |
381 | ||
382 | if (GET_CODE (temp) != REG) | |
383 | abort (); | |
384 | ||
385 | if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)), | |
386 | XEXP (operands[1], 0))) | |
387 | return \"mov %H1,%H0\;mov %L1,%L0\"; | |
388 | else | |
389 | return \"mov %L1,%L0\;mov %H1,%H0\"; | |
390 | ||
391 | } | |
74452ac3 JL |
392 | else if (GET_CODE (operands[1]) == MEM |
393 | && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)) | |
394 | && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS) | |
395 | { | |
396 | rtx xoperands[2]; | |
397 | ||
398 | xoperands[0] = operands[0]; | |
399 | xoperands[1] = XEXP (operands[1], 0); | |
400 | ||
401 | output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\", | |
402 | xoperands); | |
403 | return \"\"; | |
404 | } | |
862bff88 | 405 | else |
22ef4e9b JL |
406 | { |
407 | if ((GET_CODE (operands[1]) == CONST_INT | |
408 | || GET_CODE (operands[1]) == CONST_DOUBLE) | |
74452ac3 JL |
409 | && val[0] == 0) |
410 | { | |
411 | if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS) | |
412 | output_asm_insn (\"clr %L0\", operands); | |
413 | else if (zero_areg) | |
414 | { | |
415 | rtx xoperands[2]; | |
416 | ||
417 | xoperands[0] = operands[0]; | |
418 | xoperands[1] = zero_areg; | |
419 | if (rtx_equal_p (xoperands[0], xoperands[1])) | |
420 | output_asm_insn (\"sub %L0,%L0\", xoperands); | |
421 | else | |
422 | output_asm_insn (\"mov %1,%L0\", xoperands); | |
423 | } | |
424 | else | |
425 | output_asm_insn (\"mov %L1,%L0\", operands); | |
426 | } | |
22ef4e9b JL |
427 | else |
428 | output_asm_insn (\"mov %L1,%L0\", operands); | |
429 | ||
430 | if ((GET_CODE (operands[1]) == CONST_INT | |
431 | || GET_CODE (operands[1]) == CONST_DOUBLE) | |
74452ac3 JL |
432 | && val[1] == 0) |
433 | { | |
434 | if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS) | |
435 | output_asm_insn (\"clr %H0\", operands); | |
436 | else if (zero_areg) | |
437 | { | |
438 | rtx xoperands[2]; | |
439 | ||
440 | xoperands[0] = operands[0]; | |
441 | xoperands[1] = zero_areg; | |
442 | if (rtx_equal_p (xoperands[0], xoperands[1])) | |
443 | output_asm_insn (\"sub %H0,%H0\", xoperands); | |
444 | else | |
445 | output_asm_insn (\"mov %1,%H0\", xoperands); | |
446 | } | |
447 | else | |
448 | output_asm_insn (\"mov %H1,%H0\", operands); | |
449 | } | |
450 | else if ((GET_CODE (operands[1]) == CONST_INT | |
451 | || GET_CODE (operands[1]) == CONST_DOUBLE) | |
452 | && val[0] == val[1]) | |
453 | output_asm_insn (\"mov %L0,%H0\", operands); | |
22ef4e9b JL |
454 | else |
455 | output_asm_insn (\"mov %H1,%H0\", operands); | |
456 | return \"\"; | |
457 | } | |
862bff88 JL |
458 | } |
459 | }" | |
74452ac3 | 460 | [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) |
38c37a0e JL |
461 | |
462 | (define_expand "movdf" | |
463 | [(set (match_operand:DF 0 "general_operand" "") | |
464 | (match_operand:DF 1 "general_operand" ""))] | |
465 | "" | |
466 | " | |
467 | { | |
468 | /* One of the ops has to be in a register */ | |
469 | if (!register_operand (operand1, DFmode) | |
470 | && !register_operand (operand0, DFmode)) | |
471 | operands[1] = copy_to_mode_reg (DFmode, operand1); | |
472 | }") | |
473 | ||
474 | (define_insn "" | |
74452ac3 JL |
475 | [(set (match_operand:DF 0 "general_operand" |
476 | "=d,a,d,a,dm,dm,am,am,d,d,a,a") | |
477 | (match_operand:DF 1 "general_operand" | |
478 | "0,0,G,G,d,a,d,a,dim,aim,dim,aim"))] | |
38c37a0e JL |
479 | "register_operand (operands[0], DFmode) |
480 | || register_operand (operands[1], DFmode)" | |
862bff88 JL |
481 | "* |
482 | { | |
22ef4e9b JL |
483 | long val[2]; |
484 | REAL_VALUE_TYPE rv; | |
485 | ||
862bff88 JL |
486 | switch (which_alternative) |
487 | { | |
488 | case 0: | |
489 | case 1: | |
490 | return \"nop\"; | |
491 | ||
492 | case 2: | |
493 | return \"clr %L0\;clr %H0\"; | |
494 | ||
495 | case 3: | |
74452ac3 JL |
496 | { |
497 | rtx xoperands[2]; | |
498 | ||
499 | xoperands[0] = operands[0]; | |
500 | xoperands[1] = zero_areg ? zero_areg : operands[1]; | |
501 | if (rtx_equal_p (xoperands[0], xoperands[1])) | |
502 | output_asm_insn (\"sub %L1,%L0\;mov %L0,%H0\", xoperands); | |
503 | else | |
504 | output_asm_insn (\"mov %1,%L0\;mov %L0,%H0\", xoperands); | |
505 | return \"\"; | |
506 | } | |
862bff88 JL |
507 | case 4: |
508 | case 5: | |
509 | case 6: | |
510 | case 7: | |
511 | case 8: | |
512 | case 9: | |
513 | case 10: | |
74452ac3 | 514 | case 11: |
22ef4e9b JL |
515 | if (GET_CODE (operands[1]) == CONST_INT) |
516 | { | |
517 | val[0] = INTVAL (operands[1]); | |
518 | val[1] = val[0] < 0 ? -1 : 0; | |
519 | } | |
520 | if (GET_CODE (operands[1]) == CONST_DOUBLE) | |
521 | { | |
522 | if (GET_MODE (operands[1]) == DFmode) | |
523 | { | |
524 | REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); | |
525 | REAL_VALUE_TO_TARGET_DOUBLE (rv, val); | |
526 | } | |
527 | else if (GET_MODE (operands[1]) == VOIDmode | |
528 | || GET_MODE (operands[1]) == DImode) | |
529 | { | |
530 | val[0] = CONST_DOUBLE_LOW (operands[1]); | |
531 | val[1] = CONST_DOUBLE_HIGH (operands[1]); | |
532 | } | |
533 | } | |
534 | ||
862bff88 JL |
535 | if (GET_CODE (operands[1]) == MEM |
536 | && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0))) | |
537 | { | |
538 | rtx temp = operands[0]; | |
539 | ||
540 | while (GET_CODE (temp) == SUBREG) | |
541 | temp = SUBREG_REG (temp); | |
542 | ||
543 | if (GET_CODE (temp) != REG) | |
544 | abort (); | |
545 | ||
546 | if (reg_overlap_mentioned_p (gen_rtx (REG, SImode, REGNO (temp)), | |
547 | XEXP (operands[1], 0))) | |
548 | return \"mov %H1,%H0\;mov %L1,%L0\"; | |
549 | else | |
550 | return \"mov %L1,%L0\;mov %H1,%H0\"; | |
551 | ||
552 | } | |
74452ac3 JL |
553 | else if (GET_CODE (operands[1]) == MEM |
554 | && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)) | |
555 | && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS) | |
556 | { | |
557 | rtx xoperands[2]; | |
558 | ||
559 | xoperands[0] = operands[0]; | |
560 | xoperands[1] = XEXP (operands[1], 0); | |
561 | ||
562 | output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\", | |
563 | xoperands); | |
564 | return \"\"; | |
565 | } | |
862bff88 | 566 | else |
22ef4e9b JL |
567 | { |
568 | if ((GET_CODE (operands[1]) == CONST_INT | |
569 | || GET_CODE (operands[1]) == CONST_DOUBLE) | |
74452ac3 JL |
570 | && val[0] == 0) |
571 | { | |
572 | if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS) | |
573 | output_asm_insn (\"clr %L0\", operands); | |
574 | else if (zero_areg) | |
575 | { | |
576 | rtx xoperands[2]; | |
577 | ||
578 | xoperands[0] = operands[0]; | |
579 | xoperands[1] = zero_areg; | |
580 | if (rtx_equal_p (xoperands[0], xoperands[1])) | |
581 | output_asm_insn (\"sub %L0,%L0\", xoperands); | |
582 | else | |
583 | output_asm_insn (\"mov %1,%L0\", xoperands); | |
584 | } | |
585 | else | |
586 | output_asm_insn (\"mov %L1,%L0\", operands); | |
587 | } | |
22ef4e9b JL |
588 | else |
589 | output_asm_insn (\"mov %L1,%L0\", operands); | |
590 | ||
591 | if ((GET_CODE (operands[1]) == CONST_INT | |
592 | || GET_CODE (operands[1]) == CONST_DOUBLE) | |
74452ac3 JL |
593 | && val[1] == 0) |
594 | { | |
595 | if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS) | |
596 | output_asm_insn (\"clr %H0\", operands); | |
597 | else if (zero_areg) | |
598 | { | |
599 | rtx xoperands[2]; | |
600 | ||
601 | xoperands[0] = operands[0]; | |
602 | xoperands[1] = zero_areg; | |
603 | if (rtx_equal_p (xoperands[0], xoperands[1])) | |
604 | output_asm_insn (\"sub %H0,%H0\", xoperands); | |
605 | else | |
606 | output_asm_insn (\"mov %1,%H0\", xoperands); | |
607 | } | |
608 | else | |
609 | output_asm_insn (\"mov %H1,%H0\", operands); | |
610 | } | |
611 | else if ((GET_CODE (operands[1]) == CONST_INT | |
612 | || GET_CODE (operands[1]) == CONST_DOUBLE) | |
613 | && val[0] == val[1]) | |
614 | output_asm_insn (\"mov %L0,%H0\", operands); | |
22ef4e9b JL |
615 | else |
616 | output_asm_insn (\"mov %H1,%H0\", operands); | |
617 | return \"\"; | |
618 | } | |
862bff88 JL |
619 | } |
620 | }" | |
74452ac3 | 621 | [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) |
38c37a0e JL |
622 | |
623 | ||
11bb1f11 JL |
624 | \f |
625 | ;; ---------------------------------------------------------------------- | |
626 | ;; TEST INSTRUCTIONS | |
627 | ;; ---------------------------------------------------------------------- | |
628 | ||
629 | ;; Go ahead and define tstsi so we can eliminate redundant tst insns | |
630 | ;; when we start trying to optimize this port. | |
631 | (define_insn "tstsi" | |
632 | [(set (cc0) (match_operand:SI 0 "register_operand" "da"))] | |
633 | "" | |
22ef4e9b | 634 | "* return output_tst (operands[0], insn);" |
d116300b | 635 | [(set_attr "cc" "set_znv")]) |
22ef4e9b JL |
636 | |
637 | (define_insn "" | |
638 | [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "d")))] | |
639 | "" | |
640 | "* return output_tst (operands[0], insn);" | |
d116300b | 641 | [(set_attr "cc" "set_znv")]) |
22ef4e9b JL |
642 | |
643 | (define_insn "" | |
644 | [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "d")))] | |
645 | "" | |
646 | "* return output_tst (operands[0], insn);" | |
d116300b | 647 | [(set_attr "cc" "set_znv")]) |
11bb1f11 | 648 | |
22ef4e9b | 649 | |
11bb1f11 JL |
650 | (define_insn "cmpsi" |
651 | [(set (cc0) | |
3b800f71 JL |
652 | (compare (match_operand:SI 0 "register_operand" "!*d*a,da") |
653 | (match_operand:SI 1 "nonmemory_operand" "!*0,dai")))] | |
11bb1f11 | 654 | "" |
3b800f71 JL |
655 | "@ |
656 | add 0,%0 | |
657 | cmp %1,%0" | |
658 | [(set_attr "cc" "invert,compare")]) | |
11bb1f11 JL |
659 | \f |
660 | ;; ---------------------------------------------------------------------- | |
661 | ;; ADD INSTRUCTIONS | |
662 | ;; ---------------------------------------------------------------------- | |
663 | ||
664 | (define_expand "addsi3" | |
38c37a0e JL |
665 | [(set (match_operand:SI 0 "register_operand" "") |
666 | (plus:SI (match_operand:SI 1 "register_operand" "") | |
667 | (match_operand:SI 2 "nonmemory_operand" "")))] | |
11bb1f11 JL |
668 | "" |
669 | " | |
670 | { | |
671 | /* We can't add a variable amount directly to the stack pointer; | |
672 | so do so via a temporary register. */ | |
673 | if (operands[0] == stack_pointer_rtx | |
674 | && GET_CODE (operands[1]) != CONST_INT | |
675 | && GET_CODE (operands[2]) != CONST_INT) | |
676 | { | |
677 | rtx temp = gen_reg_rtx (SImode); | |
678 | emit_move_insn (temp, gen_rtx (PLUS, SImode, operands[1], operands[2])); | |
679 | emit_move_insn (operands[0], temp); | |
680 | DONE; | |
681 | } | |
682 | }") | |
683 | ||
684 | (define_insn "" | |
460f4b9d | 685 | [(set (match_operand:SI 0 "register_operand" "=d,a,a,da,x,&!da") |
74452ac3 JL |
686 | (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,da") |
687 | (match_operand:SI 2 "nonmemory_operand" "J,J,L,dai,i,da")))] | |
11bb1f11 JL |
688 | "" |
689 | "@ | |
690 | inc %0 | |
82c6faa8 | 691 | inc %0 |
11bb1f11 JL |
692 | inc4 %0 |
693 | add %2,%0 | |
74452ac3 JL |
694 | add %2,%0 |
695 | mov %2,%0\;add %1,%0" | |
d116300b | 696 | [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")]) |
11bb1f11 JL |
697 | |
698 | ;; ---------------------------------------------------------------------- | |
699 | ;; SUBTRACT INSTRUCTIONS | |
700 | ;; ---------------------------------------------------------------------- | |
701 | ||
702 | (define_insn "subsi3" | |
703 | [(set (match_operand:SI 0 "register_operand" "=da") | |
704 | (minus:SI (match_operand:SI 1 "register_operand" "0") | |
38c37a0e | 705 | (match_operand:SI 2 "nonmemory_operand" "dai")))] |
11bb1f11 JL |
706 | "" |
707 | "sub %2,%0" | |
d116300b | 708 | [(set_attr "cc" "set_zn")]) |
11bb1f11 JL |
709 | |
710 | (define_expand "negsi2" | |
711 | [(set (match_operand:SI 0 "register_operand" "") | |
712 | (neg:SI (match_operand:SI 1 "register_operand" "")))] | |
713 | "" | |
714 | " | |
715 | { | |
716 | rtx target = gen_reg_rtx (SImode); | |
717 | ||
718 | emit_move_insn (target, GEN_INT (0)); | |
719 | emit_insn (gen_subsi3 (target, target, operands[1])); | |
720 | emit_move_insn (operands[0], target); | |
721 | DONE; | |
722 | }") | |
723 | ||
11bb1f11 JL |
724 | ;; ---------------------------------------------------------------------- |
725 | ;; MULTIPLY INSTRUCTIONS | |
726 | ;; ---------------------------------------------------------------------- | |
727 | ||
728 | (define_insn "mulsi3" | |
729 | [(set (match_operand:SI 0 "register_operand" "=d") | |
730 | (mult:SI (match_operand:SI 1 "register_operand" "%0") | |
731 | (match_operand:SI 2 "register_operand" "d")))] | |
732 | "" | |
a6f7ba17 JL |
733 | "* |
734 | { | |
735 | if (TARGET_MULT_BUG) | |
736 | return \"nop\;nop\;mul %2,%0\"; | |
737 | else | |
738 | return \"mul %2,%0\"; | |
739 | }" | |
d116300b | 740 | [(set_attr "cc" "set_zn")]) |
11bb1f11 | 741 | |
6f54921d | 742 | (define_insn "udivmodsi4" |
22ef4e9b JL |
743 | [(set (match_operand:SI 0 "general_operand" "=d") |
744 | (udiv:SI (match_operand:SI 1 "general_operand" "0") | |
745 | (match_operand:SI 2 "general_operand" "d"))) | |
6f54921d | 746 | (set (match_operand:SI 3 "general_operand" "=&d") |
22ef4e9b | 747 | (umod:SI (match_dup 1) (match_dup 2)))] |
11bb1f11 | 748 | "" |
22ef4e9b JL |
749 | "* |
750 | { | |
6f54921d JL |
751 | if (zero_dreg) |
752 | output_asm_insn (\"mov %0,mdr\", &zero_dreg); | |
753 | else | |
754 | output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands); | |
755 | ||
22ef4e9b JL |
756 | if (find_reg_note (insn, REG_UNUSED, operands[3])) |
757 | return \"divu %2,%0\"; | |
758 | else | |
759 | return \"divu %2,%0\;mov mdr,%3\"; | |
760 | }" | |
d116300b | 761 | [(set_attr "cc" "set_zn")]) |
22ef4e9b | 762 | |
6f54921d | 763 | (define_insn "divmodsi4" |
22ef4e9b JL |
764 | [(set (match_operand:SI 0 "general_operand" "=d") |
765 | (div:SI (match_operand:SI 1 "general_operand" "0") | |
766 | (match_operand:SI 2 "general_operand" "d"))) | |
767 | (set (match_operand:SI 3 "general_operand" "=d") | |
768 | (mod:SI (match_dup 1) (match_dup 2)))] | |
769 | "" | |
770 | "* | |
771 | { | |
772 | if (find_reg_note (insn, REG_UNUSED, operands[3])) | |
773 | return \"ext %0\;div %2,%0\"; | |
774 | else | |
775 | return \"ext %0\;div %2,%0\;mov mdr,%3\"; | |
776 | }" | |
d116300b | 777 | [(set_attr "cc" "set_zn")]) |
11bb1f11 | 778 | |
11bb1f11 JL |
779 | \f |
780 | ;; ---------------------------------------------------------------------- | |
781 | ;; AND INSTRUCTIONS | |
782 | ;; ---------------------------------------------------------------------- | |
783 | ||
784 | (define_insn "andsi3" | |
38c37a0e JL |
785 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
786 | (and:SI (match_operand:SI 1 "register_operand" "%0,0") | |
787 | (match_operand:SI 2 "nonmemory_operand" "N,di")))] | |
11bb1f11 | 788 | "" |
38c37a0e JL |
789 | "* |
790 | { | |
791 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff) | |
792 | return \"extbu %0\"; | |
793 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff) | |
794 | return \"exthu %0\"; | |
22ef4e9b JL |
795 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff) |
796 | return \"add %0,%0\;lsr 1,%0\"; | |
797 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff) | |
798 | return \"asl2 %0\;lsr 2,%0\"; | |
799 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff) | |
800 | return \"add %0,%0\;asl2 %0\;lsr 3,%0\"; | |
801 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff) | |
802 | return \"asl2 %0,%0\;asl2 %0\;lsr 4,%0\"; | |
803 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe) | |
804 | return \"lsr 1,%0\;add %0,%0\"; | |
805 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc) | |
806 | return \"lsr 2,%0\;asl2 %0\"; | |
807 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8) | |
808 | return \"lsr 3,%0\;add %0,%0\;asl2 %0\"; | |
809 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0) | |
810 | return \"lsr 4,%0\;asl2 %0\;asl2 %0\"; | |
38c37a0e JL |
811 | return \"and %2,%0\"; |
812 | }" | |
d116300b | 813 | [(set_attr "cc" "none_0hit,set_znv")]) |
11bb1f11 JL |
814 | |
815 | ;; ---------------------------------------------------------------------- | |
816 | ;; OR INSTRUCTIONS | |
817 | ;; ---------------------------------------------------------------------- | |
818 | ||
819 | (define_insn "iorsi3" | |
820 | [(set (match_operand:SI 0 "register_operand" "=d") | |
821 | (ior:SI (match_operand:SI 1 "register_operand" "%0") | |
822 | (match_operand:SI 2 "nonmemory_operand" "di")))] | |
823 | "" | |
824 | "or %2,%0" | |
d116300b | 825 | [(set_attr "cc" "set_znv")]) |
11bb1f11 JL |
826 | |
827 | ;; ---------------------------------------------------------------------- | |
828 | ;; XOR INSTRUCTIONS | |
829 | ;; ---------------------------------------------------------------------- | |
830 | ||
831 | (define_insn "xorsi3" | |
832 | [(set (match_operand:SI 0 "register_operand" "=d") | |
833 | (xor:SI (match_operand:SI 1 "register_operand" "%0") | |
834 | (match_operand:SI 2 "nonmemory_operand" "di")))] | |
835 | "" | |
836 | "xor %2,%0" | |
d116300b | 837 | [(set_attr "cc" "set_znv")]) |
11bb1f11 JL |
838 | |
839 | ;; ---------------------------------------------------------------------- | |
840 | ;; NOT INSTRUCTIONS | |
841 | ;; ---------------------------------------------------------------------- | |
842 | ||
843 | (define_insn "one_cmplsi2" | |
844 | [(set (match_operand:SI 0 "register_operand" "=d") | |
845 | (not:SI (match_operand:SI 1 "register_operand" "0")))] | |
846 | "" | |
847 | "not %0" | |
d116300b | 848 | [(set_attr "cc" "set_znv")]) |
11bb1f11 JL |
849 | \f |
850 | ;; ----------------------------------------------------------------- | |
851 | ;; BIT FIELDS | |
852 | ;; ----------------------------------------------------------------- | |
11bb1f11 | 853 | |
38c37a0e JL |
854 | |
855 | ;; These set/clear memory in byte sized chunks. | |
856 | ;; | |
857 | ;; They are no smaller/faster than loading the value into a register | |
858 | ;; and storing the register, but they don't need a scratch register | |
859 | ;; which may allow for better code generation. | |
860 | (define_insn "" | |
861 | [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int 0))] | |
862 | "" | |
863 | "@ | |
864 | bclr 255,%A0 | |
865 | clr %0" | |
866 | [(set_attr "cc" "clobber")]) | |
867 | ||
868 | (define_insn "" | |
869 | [(set (match_operand:QI 0 "general_operand" "=R,d") (const_int -1))] | |
870 | "" | |
871 | "@ | |
872 | bset 255,%A0 | |
873 | mov -1,%0" | |
874 | [(set_attr "cc" "clobber,none_0hit")]) | |
875 | ||
876 | (define_insn "" | |
877 | [(set (match_operand:QI 0 "general_operand" "=R,d") | |
878 | (subreg:QI | |
879 | (and:SI (subreg:SI (match_dup 0) 0) | |
880 | (match_operand:SI 1 "const_int_operand" "i,i")) 0))] | |
881 | "" | |
882 | "@ | |
883 | bclr %N1,%A0 | |
884 | and %1,%0" | |
d116300b | 885 | [(set_attr "cc" "clobber,set_znv")]) |
38c37a0e JL |
886 | |
887 | (define_insn "" | |
888 | [(set (match_operand:QI 0 "general_operand" "=R,d") | |
889 | (subreg:QI | |
890 | (ior:SI (subreg:SI (match_dup 0) 0) | |
891 | (match_operand:SI 1 "const_int_operand" "i,i")) 0))] | |
892 | "" | |
893 | "@ | |
894 | bset %1,%A0 | |
895 | or %1,%0" | |
d116300b | 896 | [(set_attr "cc" "clobber,set_znv")]) |
38c37a0e JL |
897 | |
898 | (define_insn "" | |
899 | [(set (cc0) | |
900 | (zero_extract:SI (match_operand:SI 0 "register_operand" "d") | |
901 | (match_operand 1 "const_int_operand" "") | |
902 | (match_operand 2 "const_int_operand" "")))] | |
903 | "" | |
904 | "* | |
905 | { | |
906 | int len = INTVAL (operands[1]); | |
907 | int bit = INTVAL (operands[2]); | |
908 | int mask = 0; | |
909 | rtx xoperands[2]; | |
910 | ||
911 | while (len > 0) | |
912 | { | |
913 | mask |= (1 << bit); | |
914 | bit++; | |
915 | len--; | |
916 | } | |
917 | ||
918 | xoperands[0] = operands[0]; | |
919 | xoperands[1] = GEN_INT (mask); | |
920 | output_asm_insn (\"btst %1,%0\", xoperands); | |
921 | return \"\"; | |
922 | }" | |
d116300b | 923 | [(set_attr "cc" "set_znv")]) |
38c37a0e JL |
924 | |
925 | (define_insn "" | |
926 | [(set (cc0) | |
927 | (zero_extract:SI (match_operand:QI 0 "general_operand" "R,d") | |
928 | (match_operand 1 "const_int_operand" "") | |
929 | (match_operand 2 "const_int_operand" "")))] | |
f8912297 | 930 | "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))" |
38c37a0e JL |
931 | "* |
932 | { | |
933 | int len = INTVAL (operands[1]); | |
934 | int bit = INTVAL (operands[2]); | |
935 | int mask = 0; | |
936 | rtx xoperands[2]; | |
937 | ||
938 | while (len > 0) | |
939 | { | |
940 | mask |= (1 << bit); | |
941 | bit++; | |
942 | len--; | |
943 | } | |
944 | ||
f8912297 JL |
945 | /* If the source operand is not a reg (ie it is memory), then extract the |
946 | bits from mask that we actually want to test. Note that the mask will | |
947 | never cross a byte boundary. */ | |
948 | if (!REG_P (operands[0])) | |
949 | { | |
950 | if (mask & 0xff) | |
951 | mask = mask & 0xff; | |
952 | else if (mask & 0xff00) | |
953 | mask = (mask >> 8) & 0xff; | |
954 | else if (mask & 0xff0000) | |
955 | mask = (mask >> 16) & 0xff; | |
956 | else if (mask & 0xff000000) | |
957 | mask = (mask >> 24) & 0xff; | |
958 | } | |
959 | ||
38c37a0e JL |
960 | xoperands[0] = operands[0]; |
961 | xoperands[1] = GEN_INT (mask); | |
962 | if (GET_CODE (operands[0]) == REG) | |
963 | output_asm_insn (\"btst %1,%0\", xoperands); | |
964 | else | |
965 | output_asm_insn (\"btst %1,%A0\", xoperands); | |
966 | return \"\"; | |
967 | }" | |
d116300b | 968 | [(set_attr "cc" "set_znv")]) |
38c37a0e JL |
969 | |
970 | (define_insn "" | |
971 | [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "d") | |
972 | (match_operand:SI 1 "const_int_operand" "")))] | |
973 | "" | |
974 | "btst %1,%0" | |
d116300b | 975 | [(set_attr "cc" "set_znv")]) |
38c37a0e JL |
976 | |
977 | (define_insn "" | |
978 | [(set (cc0) | |
979 | (and:SI | |
980 | (subreg:SI (match_operand:QI 0 "general_operand" "R,d") 0) | |
f8912297 | 981 | (match_operand:SI 1 "const_8bit_operand" "")))] |
38c37a0e JL |
982 | "" |
983 | "@ | |
984 | btst %1,%A0 | |
985 | btst %1,%0" | |
d116300b | 986 | [(set_attr "cc" "set_znv")]) |
38c37a0e | 987 | |
11bb1f11 JL |
988 | \f |
989 | ;; ---------------------------------------------------------------------- | |
990 | ;; JUMP INSTRUCTIONS | |
991 | ;; ---------------------------------------------------------------------- | |
992 | ||
993 | ;; Conditional jump instructions | |
994 | ||
995 | (define_expand "ble" | |
996 | [(set (pc) | |
997 | (if_then_else (le (cc0) | |
998 | (const_int 0)) | |
999 | (label_ref (match_operand 0 "" "")) | |
1000 | (pc)))] | |
1001 | "" | |
1002 | "") | |
1003 | ||
1004 | (define_expand "bleu" | |
1005 | [(set (pc) | |
1006 | (if_then_else (leu (cc0) | |
1007 | (const_int 0)) | |
1008 | (label_ref (match_operand 0 "" "")) | |
1009 | (pc)))] | |
1010 | "" | |
1011 | "") | |
1012 | ||
1013 | (define_expand "bge" | |
1014 | [(set (pc) | |
1015 | (if_then_else (ge (cc0) | |
1016 | (const_int 0)) | |
1017 | (label_ref (match_operand 0 "" "")) | |
1018 | (pc)))] | |
1019 | "" | |
1020 | "") | |
1021 | ||
1022 | (define_expand "bgeu" | |
1023 | [(set (pc) | |
1024 | (if_then_else (geu (cc0) | |
1025 | (const_int 0)) | |
1026 | (label_ref (match_operand 0 "" "")) | |
1027 | (pc)))] | |
1028 | "" | |
1029 | "") | |
1030 | ||
1031 | (define_expand "blt" | |
1032 | [(set (pc) | |
1033 | (if_then_else (lt (cc0) | |
1034 | (const_int 0)) | |
1035 | (label_ref (match_operand 0 "" "")) | |
1036 | (pc)))] | |
1037 | "" | |
1038 | "") | |
1039 | ||
1040 | (define_expand "bltu" | |
1041 | [(set (pc) | |
1042 | (if_then_else (ltu (cc0) | |
1043 | (const_int 0)) | |
1044 | (label_ref (match_operand 0 "" "")) | |
1045 | (pc)))] | |
1046 | "" | |
1047 | "") | |
1048 | ||
1049 | (define_expand "bgt" | |
1050 | [(set (pc) | |
1051 | (if_then_else (gt (cc0) | |
1052 | (const_int 0)) | |
1053 | (label_ref (match_operand 0 "" "")) | |
1054 | (pc)))] | |
1055 | "" | |
1056 | "") | |
1057 | ||
1058 | (define_expand "bgtu" | |
1059 | [(set (pc) | |
1060 | (if_then_else (gtu (cc0) | |
1061 | (const_int 0)) | |
1062 | (label_ref (match_operand 0 "" "")) | |
1063 | (pc)))] | |
1064 | "" | |
1065 | "") | |
1066 | ||
1067 | (define_expand "beq" | |
1068 | [(set (pc) | |
1069 | (if_then_else (eq (cc0) | |
1070 | (const_int 0)) | |
1071 | (label_ref (match_operand 0 "" "")) | |
1072 | (pc)))] | |
1073 | "" | |
1074 | "") | |
1075 | ||
1076 | (define_expand "bne" | |
1077 | [(set (pc) | |
1078 | (if_then_else (ne (cc0) | |
1079 | (const_int 0)) | |
1080 | (label_ref (match_operand 0 "" "")) | |
1081 | (pc)))] | |
1082 | "" | |
1083 | "") | |
1084 | ||
1085 | (define_insn "" | |
1086 | [(set (pc) | |
1087 | (if_then_else (match_operator 1 "comparison_operator" | |
1088 | [(cc0) (const_int 0)]) | |
1089 | (label_ref (match_operand 0 "" "")) | |
1090 | (pc)))] | |
1091 | "" | |
82c6faa8 JL |
1092 | "* |
1093 | { | |
1094 | if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 | |
1095 | && (GET_CODE (operands[1]) == GT | |
1096 | || GET_CODE (operands[1]) == GE | |
1097 | || GET_CODE (operands[1]) == LE | |
1098 | || GET_CODE (operands[1]) == LT)) | |
1099 | return 0; | |
6e86170d | 1100 | return \"b%b1 %0\"; |
82c6faa8 | 1101 | }" |
11bb1f11 JL |
1102 | [(set_attr "cc" "none")]) |
1103 | ||
1104 | (define_insn "" | |
1105 | [(set (pc) | |
1106 | (if_then_else (match_operator 1 "comparison_operator" | |
1107 | [(cc0) (const_int 0)]) | |
1108 | (pc) | |
1109 | (label_ref (match_operand 0 "" ""))))] | |
1110 | "" | |
82c6faa8 JL |
1111 | "* |
1112 | { | |
1113 | if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 | |
1114 | && (GET_CODE (operands[1]) == GT | |
1115 | || GET_CODE (operands[1]) == GE | |
1116 | || GET_CODE (operands[1]) == LE | |
1117 | || GET_CODE (operands[1]) == LT)) | |
1118 | return 0; | |
6e86170d | 1119 | return \"b%B1 %0\"; |
82c6faa8 | 1120 | }" |
11bb1f11 JL |
1121 | [(set_attr "cc" "none")]) |
1122 | ||
1123 | ;; Unconditional and other jump instructions. | |
1124 | ||
1125 | (define_insn "jump" | |
1126 | [(set (pc) | |
1127 | (label_ref (match_operand 0 "" "")))] | |
1128 | "" | |
1129 | "jmp %l0" | |
1130 | [(set_attr "cc" "none")]) | |
1131 | ||
1132 | (define_insn "indirect_jump" | |
1133 | [(set (pc) (match_operand:SI 0 "register_operand" "a"))] | |
1134 | "" | |
1135 | "jmp (%0)" | |
1136 | [(set_attr "cc" "none")]) | |
1137 | ||
1138 | (define_insn "tablejump" | |
1139 | [(set (pc) (match_operand:SI 0 "register_operand" "a")) | |
1140 | (use (label_ref (match_operand 1 "" "")))] | |
1141 | "" | |
1142 | "jmp (%0)" | |
1143 | [(set_attr "cc" "none")]) | |
1144 | ||
1145 | ;; Call subroutine with no return value. | |
1146 | ||
1147 | (define_expand "call" | |
1148 | [(call (match_operand:QI 0 "general_operand" "") | |
1149 | (match_operand:SI 1 "general_operand" ""))] | |
1150 | "" | |
1151 | " | |
1152 | { | |
11bb1f11 JL |
1153 | if (! call_address_operand (XEXP (operands[0], 0))) |
1154 | XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0)); | |
1155 | emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1])); | |
11bb1f11 JL |
1156 | DONE; |
1157 | }") | |
1158 | ||
1159 | (define_insn "call_internal" | |
1160 | [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS")) | |
1161 | (match_operand:SI 1 "general_operand" "g"))] | |
1162 | "" | |
e5ffb50c JL |
1163 | "* |
1164 | { | |
1165 | if (REG_P (operands[0])) | |
1166 | return \"calls %C0\"; | |
1167 | else | |
1168 | return \"call %C0,[],0\"; | |
1169 | }" | |
11bb1f11 JL |
1170 | [(set_attr "cc" "clobber")]) |
1171 | ||
1172 | ;; Call subroutine, returning value in operand 0 | |
1173 | ;; (which must be a hard register). | |
1174 | ||
1175 | (define_expand "call_value" | |
1176 | [(set (match_operand 0 "" "") | |
1177 | (call (match_operand:QI 1 "general_operand" "") | |
1178 | (match_operand:SI 2 "general_operand" "")))] | |
1179 | "" | |
1180 | " | |
1181 | { | |
11bb1f11 JL |
1182 | if (! call_address_operand (XEXP (operands[1], 0))) |
1183 | XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0)); | |
1184 | emit_call_insn (gen_call_value_internal (operands[0], | |
1185 | XEXP (operands[1], 0), | |
1186 | operands[2])); | |
11bb1f11 JL |
1187 | DONE; |
1188 | }") | |
1189 | ||
1190 | (define_insn "call_value_internal" | |
460f4b9d | 1191 | [(set (match_operand 0 "" "=da") |
11bb1f11 JL |
1192 | (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS")) |
1193 | (match_operand:SI 2 "general_operand" "g")))] | |
1194 | "" | |
e5ffb50c JL |
1195 | "* |
1196 | { | |
1197 | if (REG_P (operands[1])) | |
1198 | return \"calls %C1\"; | |
1199 | else | |
1200 | return \"call %C1,[],0\"; | |
1201 | }" | |
11bb1f11 JL |
1202 | [(set_attr "cc" "clobber")]) |
1203 | ||
6c0870b8 JL |
1204 | (define_expand "untyped_call" |
1205 | [(parallel [(call (match_operand 0 "" "") | |
1206 | (const_int 0)) | |
1207 | (match_operand 1 "" "") | |
1208 | (match_operand 2 "" "")])] | |
1209 | "" | |
1210 | " | |
1211 | { | |
1212 | int i; | |
1213 | ||
1214 | emit_call_insn (gen_call (operands[0], const0_rtx)); | |
1215 | ||
1216 | for (i = 0; i < XVECLEN (operands[2], 0); i++) | |
1217 | { | |
1218 | rtx set = XVECEXP (operands[2], 0, i); | |
1219 | emit_move_insn (SET_DEST (set), SET_SRC (set)); | |
1220 | } | |
1221 | DONE; | |
1222 | }") | |
1223 | ||
11bb1f11 JL |
1224 | (define_insn "nop" |
1225 | [(const_int 0)] | |
1226 | "" | |
1227 | "nop" | |
1228 | [(set_attr "cc" "none")]) | |
1229 | \f | |
1230 | ;; ---------------------------------------------------------------------- | |
1231 | ;; EXTEND INSTRUCTIONS | |
1232 | ;; ---------------------------------------------------------------------- | |
1233 | ||
777fbf09 JL |
1234 | (define_insn "zero_extendqisi2" |
1235 | [(set (match_operand:SI 0 "general_operand" "=d,d,d") | |
11bb1f11 | 1236 | (zero_extend:SI |
777fbf09 | 1237 | (match_operand:QI 1 "general_operand" "0,d,m")))] |
11bb1f11 | 1238 | "" |
777fbf09 JL |
1239 | "@ |
1240 | extbu %0 | |
1241 | mov %1,%0\;extbu %0 | |
1242 | movbu %1,%0" | |
82c6faa8 | 1243 | [(set_attr "cc" "none_0hit")]) |
11bb1f11 | 1244 | |
777fbf09 JL |
1245 | (define_insn "zero_extendhisi2" |
1246 | [(set (match_operand:SI 0 "general_operand" "=d,d,d") | |
11bb1f11 | 1247 | (zero_extend:SI |
777fbf09 | 1248 | (match_operand:HI 1 "general_operand" "0,d,m")))] |
11bb1f11 | 1249 | "" |
777fbf09 JL |
1250 | "@ |
1251 | exthu %0 | |
1252 | mov %1,%0\;exthu %0 | |
1253 | movhu %1,%0" | |
82c6faa8 | 1254 | [(set_attr "cc" "none_0hit")]) |
11bb1f11 JL |
1255 | |
1256 | ;;- sign extension instructions | |
1257 | ||
777fbf09 JL |
1258 | (define_insn "extendqisi2" |
1259 | [(set (match_operand:SI 0 "general_operand" "=d,d") | |
11bb1f11 | 1260 | (sign_extend:SI |
777fbf09 | 1261 | (match_operand:QI 1 "general_operand" "0,d")))] |
11bb1f11 | 1262 | "" |
777fbf09 JL |
1263 | "@ |
1264 | extb %0 | |
38c37a0e | 1265 | mov %1,%0\;extb %0" |
82c6faa8 | 1266 | [(set_attr "cc" "none_0hit")]) |
11bb1f11 | 1267 | |
777fbf09 JL |
1268 | (define_insn "extendhisi2" |
1269 | [(set (match_operand:SI 0 "general_operand" "=d,d") | |
11bb1f11 | 1270 | (sign_extend:SI |
777fbf09 | 1271 | (match_operand:HI 1 "general_operand" "0,d")))] |
11bb1f11 | 1272 | "" |
777fbf09 JL |
1273 | "@ |
1274 | exth %0 | |
38c37a0e | 1275 | mov %1,%0\;exth %0" |
82c6faa8 | 1276 | [(set_attr "cc" "none_0hit")]) |
11bb1f11 JL |
1277 | \f |
1278 | ;; ---------------------------------------------------------------------- | |
1279 | ;; SHIFTS | |
1280 | ;; ---------------------------------------------------------------------- | |
1281 | ||
1282 | (define_insn "ashlsi3" | |
3dbc43d1 | 1283 | [(set (match_operand:SI 0 "register_operand" "=da,d,d,d,d") |
11bb1f11 | 1284 | (ashift:SI |
3dbc43d1 JL |
1285 | (match_operand:SI 1 "register_operand" "0,0,0,0,0") |
1286 | (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,di")))] | |
11bb1f11 JL |
1287 | "" |
1288 | "@ | |
777fbf09 | 1289 | add %0,%0 |
11bb1f11 | 1290 | asl2 %0 |
777fbf09 | 1291 | asl2 %0\;add %0,%0 |
777fbf09 | 1292 | asl2 %0\;asl2 %0 |
576e5acc | 1293 | asl %S2,%0" |
d116300b | 1294 | [(set_attr "cc" "set_zn")]) |
11bb1f11 JL |
1295 | |
1296 | (define_insn "lshrsi3" | |
1297 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1298 | (lshiftrt:SI | |
1299 | (match_operand:SI 1 "register_operand" "0") | |
1300 | (match_operand:QI 2 "nonmemory_operand" "di")))] | |
1301 | "" | |
576e5acc | 1302 | "lsr %S2,%0" |
d116300b | 1303 | [(set_attr "cc" "set_zn")]) |
11bb1f11 JL |
1304 | |
1305 | (define_insn "ashrsi3" | |
1306 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1307 | (ashiftrt:SI | |
1308 | (match_operand:SI 1 "register_operand" "0") | |
1309 | (match_operand:QI 2 "nonmemory_operand" "di")))] | |
1310 | "" | |
576e5acc | 1311 | "asr %S2,%0" |
d116300b | 1312 | [(set_attr "cc" "set_zn")]) |
11bb1f11 JL |
1313 | |
1314 | ;; ---------------------------------------------------------------------- | |
1315 | ;; PROLOGUE/EPILOGUE | |
1316 | ;; ---------------------------------------------------------------------- | |
1317 | (define_expand "prologue" | |
1318 | [(const_int 0)] | |
1319 | "" | |
1320 | "expand_prologue (); DONE;") | |
1321 | ||
1322 | (define_expand "epilogue" | |
1323 | [(return)] | |
1324 | "" | |
1325 | " | |
1326 | { | |
1327 | expand_epilogue (); | |
1328 | DONE; | |
1329 | }") | |
1330 | ||
777fbf09 JL |
1331 | (define_insn "return_internal" |
1332 | [(const_int 2)] | |
1333 | "" | |
11bb1f11 JL |
1334 | "rets" |
1335 | [(set_attr "cc" "clobber")]) | |
1336 | ||
4246e0c5 JL |
1337 | ;; This insn restores the callee saved registers and does a return, it |
1338 | ;; can also deallocate stack space. | |
777fbf09 | 1339 | (define_insn "return_internal_regs" |
11bb1f11 | 1340 | [(const_int 0) |
4246e0c5 | 1341 | (match_operand:SI 0 "const_int_operand" "i") |
11bb1f11 JL |
1342 | (return)] |
1343 | "" | |
4246e0c5 | 1344 | "ret [d2,d3,a2,a3],%0" |
11bb1f11 JL |
1345 | [(set_attr "cc" "clobber")]) |
1346 | ||
1347 | (define_insn "store_movm" | |
1348 | [(const_int 1)] | |
1349 | "" | |
1350 | "movm [d2,d3,a2,a3],(sp)" | |
82c6faa8 | 1351 | [(set_attr "cc" "clobber")]) |
777fbf09 | 1352 | |
38c37a0e JL |
1353 | (define_insn "return" |
1354 | [(return)] | |
1355 | "can_use_return_insn ()" | |
74452ac3 JL |
1356 | "* |
1357 | { | |
1358 | rtx next = next_active_insn (insn); | |
1359 | ||
1360 | if (next | |
1361 | && GET_CODE (next) == JUMP_INSN | |
1362 | && GET_CODE (PATTERN (next)) == RETURN) | |
1363 | return \"\"; | |
1364 | else | |
1365 | return \"rets\"; | |
1366 | }" | |
38c37a0e JL |
1367 | [(set_attr "cc" "clobber")]) |
1368 | ||
777fbf09 JL |
1369 | ;; Try to combine consecutive updates of the stack pointer (or any |
1370 | ;; other register for that matter). | |
1371 | (define_peephole | |
1372 | [(set (match_operand:SI 0 "register_operand" "=dax") | |
1373 | (plus:SI (match_dup 0) | |
1374 | (match_operand 1 "const_int_operand" ""))) | |
1375 | (set (match_dup 0) | |
1376 | (plus:SI (match_dup 0) | |
1377 | (match_operand 2 "const_int_operand" "")))] | |
1378 | "" | |
1379 | "* | |
1380 | { | |
1381 | operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1])); | |
1382 | return \"add %1,%0\"; | |
1383 | }" | |
1384 | [(set_attr "cc" "clobber")]) | |
38c37a0e JL |
1385 | |
1386 | ;; | |
1387 | ;; We had patterns to check eq/ne, but the they don't work because | |
1388 | ;; 0x80000000 + 0x80000000 = 0x0 with a carry out. | |
1389 | ;; | |
1390 | ;; The Z flag and C flag would be set, and we have no way to | |
1391 | ;; check for the Z flag set and C flag clear. | |
1392 | ;; | |
1393 | ;; This will work on the mn10200 because we can check the ZX flag | |
1394 | ;; if the comparison is in HImode. | |
1395 | (define_peephole | |
1396 | [(set (cc0) (match_operand:SI 0 "register_operand" "d")) | |
1397 | (set (pc) (if_then_else (ge (cc0) (const_int 0)) | |
1398 | (match_operand 1 "" "") | |
1399 | (pc)))] | |
1400 | "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" | |
1401 | "add %0,%0\;bcc %1" | |
1402 | [(set_attr "cc" "clobber")]) | |
1403 | ||
1404 | (define_peephole | |
1405 | [(set (cc0) (match_operand:SI 0 "register_operand" "d")) | |
1406 | (set (pc) (if_then_else (lt (cc0) (const_int 0)) | |
1407 | (match_operand 1 "" "") | |
1408 | (pc)))] | |
1409 | "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" | |
1410 | "add %0,%0\;bcs %1" | |
1411 | [(set_attr "cc" "clobber")]) | |
1412 | ||
1413 | (define_peephole | |
1414 | [(set (cc0) (match_operand:SI 0 "register_operand" "d")) | |
1415 | (set (pc) (if_then_else (ge (cc0) (const_int 0)) | |
1416 | (pc) | |
1417 | (match_operand 1 "" "")))] | |
1418 | "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" | |
1419 | "add %0,%0\;bcs %1" | |
1420 | [(set_attr "cc" "clobber")]) | |
1421 | ||
1422 | (define_peephole | |
1423 | [(set (cc0) (match_operand:SI 0 "register_operand" "d")) | |
1424 | (set (pc) (if_then_else (lt (cc0) (const_int 0)) | |
1425 | (pc) | |
1426 | (match_operand 1 "" "")))] | |
1427 | "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" | |
1428 | "add %0,%0\;bcc %1" | |
1429 | [(set_attr "cc" "clobber")]) | |
460f4b9d | 1430 |