OSDN Git Service

* config/m32c/m32c.h (REG_ALLOC_ORDER): Define.
[pf3gnuchains/gcc-fork.git] / gcc / config / m32c / mov.md
1 ;; Machine Descriptions for R8C/M16C/M32C
2 ;; Copyright (C) 2005
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Red Hat.
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify it
9 ;; under the terms of the GNU General Public License as published
10 ;; by the Free Software Foundation; either version 2, or (at your
11 ;; option) any later version.
12 ;;
13 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
14 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16 ;; License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING.  If not, write to the Free
20 ;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 ;; 02110-1301, USA.
22
23 ;; move, push, extend, etc.
24
25 ;; Be careful to never create an alternative that has memory as both
26 ;; src and dest, as that makes gcc think that mem-mem moves in general
27 ;; are supported.  While the chip does support this, it only has two
28 ;; address registers and sometimes gcc requires more than that.  One
29 ;; example is code like this: a = *b where both a and b are spilled to
30 ;; the stack.
31
32 ;; Match push/pop before mov.b for passing char as arg,
33 ;; e.g. stdlib/efgcvt.c.
34 (define_insn "movqi_op"
35   [(set (match_operand:QI 0 "mra_qi_operand"
36                           "=Rqi*Rmm, <,          RqiSd*Rmm, SdSs,    Rqi*Rmm, Sd")
37         (match_operand:QI 1 "mrai_qi_operand"
38                           "iRqi*Rmm, iRqiSd*Rmm, >,         Rqi*Rmm, SdSs,    i"))]
39   "m32c_mov_ok (operands, QImode)"
40   "@
41     mov.b\t%1,%0
42     push.b\t%1
43     pop.b\t%0
44     mov.b\t%1,%0
45     mov.b\t%1,%0
46     mov.b\t%1,%0"
47   [(set_attr "flags" "sz,*,*,sz,sz,sz")]
48   )
49
50 (define_expand "movqi"
51   [(set (match_operand:QI 0 "mra_qi_operand" "=RqiSd*Rmm")
52         (match_operand:QI 1 "mrai_qi_operand" "iRqiSd*Rmm"))]
53   ""
54   "if (m32c_prepare_move (operands, QImode)) DONE;"
55   )
56
57
58 (define_insn "movhi_op"
59   [(set (match_operand:HI 0 "nonimmediate_operand"
60                           "=Rhi*Rmm,     Sd, SdSs,   *Rcr, RhiSd*Rmm, <, RhiSd*Rmm, <, *Rcr")
61         (match_operand:HI 1 "general_operand"
62                           "iRhi*RmmSdSs, i, Rhi*Rmm, RhiSd*Rmm, *Rcr, iRhiSd*Rmm, >, *Rcr, >"))]
63   "m32c_mov_ok (operands, HImode)"
64   "@
65    mov.w\t%1,%0
66    mov.w\t%1,%0
67    mov.w\t%1,%0
68    ldc\t%1,%0
69    stc\t%1,%0
70    push.w\t%1
71    pop.w\t%0
72    pushc\t%1
73    popc\t%0"
74   [(set_attr "flags" "sz,sz,sz,*,*,*,*,*,*")]
75   )
76
77 (define_expand "movhi"
78   [(set (match_operand:HI 0 "nonimmediate_operand" "=RhiSd*Rmm")
79         (match_operand:HI 1 "general_operand" "iRhiSd*Rmm"))]
80   ""
81   "if (m32c_prepare_move (operands, HImode)) DONE;"
82   )
83
84
85 (define_insn "movpsi_op"
86   [(set (match_operand:PSI 0 "nonimmediate_operand"
87                            "=Raa, SdRmmRpi,  Rcl,  RpiSd*Rmm, <,       <, Rcl, Rsi*Rmm")
88         (match_operand:PSI 1 "general_operand"
89                            "sIU3, iSdRmmRpi, iRpiSd*Rmm, Rcl, Rsi*Rmm, Rcl, >, >"))]
90   "TARGET_A24 && m32c_mov_ok (operands, PSImode)"
91   "@
92    mov.l:s\t%1,%0
93    mov.l\t%1,%0
94    ldc\t%1,%0
95    stc\t%1,%0
96    push.l\t%1
97    pushc\t%1
98    popc\t%0
99    #"
100   [(set_attr "flags" "sz,sz,*,*,*,*,*,*")]
101   )
102
103
104 ;; The intention here is to combine the add with the move to create an
105 ;; indexed move.  GCC doesn't always figure this out itself.
106
107 (define_mode_macro QHSI [QI HI SI])
108 (define_mode_macro HPSI [(HI "TARGET_A16") (PSI "TARGET_A24")])
109
110 (define_peephole2
111   [(set (match_operand:HPSI 0 "register_operand" "")
112         (plus:HPSI (match_operand:HPSI 1 "register_operand" "")
113                    (match_operand:HPSI 2 "immediate_operand" "")))
114    (set (match_operand:QHSI 3 "nonimmediate_operand" "")
115         (mem:QHSI (match_operand:HPSI 4 "register_operand" "")))]
116   "REGNO (operands[0]) == REGNO (operands[1])
117    && REGNO (operands[0]) == REGNO (operands[4])
118    && (rtx_equal_p (operands[0], operands[3])
119        || (dead_or_set_p (peep2_next_insn (1), operands[4])
120           && ! reg_mentioned_p (operands[0], operands[3])))"
121   [(set (match_dup 3)
122         (mem:QHSI (plus:HPSI (match_dup 1)
123                              (match_dup 2))))]
124   "")
125
126 (define_peephole2
127   [(set (match_operand:HPSI 0 "register_operand" "")
128         (plus:HPSI (match_operand:HPSI 1 "register_operand" "")
129                    (match_operand:HPSI 2 "immediate_operand" "")))
130    (set (mem:QHSI (match_operand:HPSI 4 "register_operand" ""))
131         (match_operand:QHSI 3 "general_operand" ""))]
132   "REGNO (operands[0]) == REGNO (operands[1])
133    && REGNO (operands[0]) == REGNO (operands[4])
134    && dead_or_set_p (peep2_next_insn (1), operands[4])
135    && ! reg_mentioned_p (operands[0], operands[3])"
136   [(set (mem:QHSI (plus:HPSI (match_dup 1)
137                              (match_dup 2)))
138         (match_dup 3))]
139   "")
140
141
142 ; Some PSI moves must be split.
143 (define_split
144   [(set (match_operand:PSI 0 "nonimmediate_operand" "")
145         (match_operand:PSI 1 "general_operand" ""))]
146   "reload_completed && m32c_split_psi_p (operands)"
147   [(set (match_dup 2)
148         (match_dup 3))
149    (set (match_dup 4)
150         (match_dup 5))]
151   "m32c_split_move (operands, PSImode, 3);"
152   )
153
154 (define_expand "movpsi"
155   [(set (match_operand:PSI 0 "mras_operand" "")
156         (match_operand:PSI 1 "mrasi_operand" ""))]
157   ""
158   "if (m32c_prepare_move (operands, PSImode)) DONE;"
159   )
160
161
162
163 (define_expand "movsi"
164   [(set (match_operand:SI 0 "mras_operand" "=RsiSd*Rmm")
165         (match_operand:SI 1 "mrasi_operand" "iRsiSd*Rmm"))]
166   ""
167   "if (m32c_split_move (operands, SImode, 0)) DONE;"
168   )
169
170 ; All SI moves are split if TARGET_A16
171 (define_insn_and_split "movsi_splittable"
172   [(set (match_operand:SI 0 "mras_operand" "=Rsi<*Rmm,RsiSd*Rmm,Ss")
173         (match_operand:SI 1 "mrasi_operand" "iRsiSd*Rmm,iRsi>*Rmm,Rsi*Rmm"))]
174   "TARGET_A16"
175   "#"
176   "TARGET_A16 && reload_completed"
177   [(pc)]
178   "m32c_split_move (operands, SImode, 1); DONE;"
179   )
180
181 ; The movsi pattern doesn't always match because sometimes the modes
182 ; don't match.
183 (define_insn "push_a01_l"
184   [(set (mem:SI (pre_dec:PSI (reg:PSI SP_REGNO)))
185         (match_operand 0 "a_operand" ""))]
186   ""
187   "push.l\t%0"
188   )
189
190 (define_insn "movsi_24"
191   [(set (match_operand:SI 0 "mras_operand"  "=Rsi*Rmm,   Sd,       RsiSd*Rmm,     <")
192         (match_operand:SI 1 "mrasi_operand" "iRsiSd*Rmm, iRsi*Rmm, >, iRsiRaaSd*Rmm"))]
193   "TARGET_A24"
194   "@
195    mov.l\t%1,%0
196    mov.l\t%1,%0
197    #
198    push.l\t%1"
199   )
200
201 (define_expand "movdi"
202   [(set (match_operand:DI 0 "mras_operand" "=RdiSd*Rmm")
203         (match_operand:DI 1 "mrasi_operand" "iRdiSd*Rmm"))]
204   ""
205   "if (m32c_split_move (operands, DImode, 0)) DONE;"
206   )
207
208 (define_insn_and_split "movdi_splittable"
209   [(set (match_operand:DI 0 "mras_operand" "=Rdi<*Rmm,RdiSd*Rmm")
210         (match_operand:DI 1 "mrasi_operand" "iRdiSd*Rmm,iRdi>*Rmm"))]
211   ""
212   "#"
213   "reload_completed"
214   [(pc)]
215   "m32c_split_move (operands, DImode, 1); DONE;"
216   )
217
218
219
220
221 (define_insn "pushqi"
222   [(set (mem:QI (pre_dec:PSI (reg:PSI SP_REGNO)))
223         (match_operand:QI 0 "mrai_operand" "iRqiSd*Rmm"))]
224   ""
225   "push.b\t%0"
226   )
227
228 (define_expand "pushhi"
229   [(set (mem:HI (pre_dec:PSI (reg:PSI SP_REGNO)))
230         (match_operand:HI 0 "" ""))]
231   ""
232   "if (TARGET_A16)
233      gen_pushhi_16 (operands[0]);
234    else
235      gen_pushhi_24 (operands[0]);
236    DONE;"
237   )
238
239 (define_insn "pushhi_16"
240   [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO)))
241         (match_operand:HI 0 "mrai_operand" "iRhiSd*Rmm,Rcr"))]
242   "TARGET_A16"
243   "@
244    push.w\t%0
245    pushc\t%0"
246   )
247
248 (define_insn "pushhi_24"
249   [(set (mem:HI (pre_dec:PSI (reg:PSI SP_REGNO)))
250         (match_operand:HI 0 "mrai_operand" "iRhiSd*Rmm"))]
251   "TARGET_A24"
252   "push.w\t%0"
253   )
254
255 ;(define_insn "pushpi"
256 ;  [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO)))
257 ;        (match_operand:PI 0 "mrai_operand" "iRaa,Rcr"))]
258 ;  "TARGET_A24"
259 ;  "@
260 ;   push.l\t%0
261 ;   pushc\t%0"
262 ;  )
263
264 (define_insn "pushsi"
265   [(set (mem:SI (pre_dec:PSI (reg:PSI SP_REGNO)))
266         (match_operand:SI 0 "mrai_operand" "iRsiSd*Rmm"))]
267   "TARGET_A24"
268   "push.l\t%0"
269   )
270
271 (define_expand "pophi"
272   [(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm,Rcr")
273         (mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
274   ""
275   "if (TARGET_A16)
276      gen_pophi_16 (operands[0]);
277    else
278      gen_pophi_24 (operands[0]);
279    DONE;"
280   )
281
282 (define_insn "pophi_16"
283   [(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm,Rcr")
284         (mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
285   "TARGET_A16"
286   "@
287    pop.w\t%0
288    popc\t%0"
289   )
290
291 (define_insn "pophi_24"
292   [(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm")
293         (mem:HI (post_inc:PSI (reg:PSI SP_REGNO))))]
294   "TARGET_A24"
295   "pop.w\t%0"
296   )
297
298 (define_insn "poppsi"
299   [(set (match_operand:PSI 0 "cr_operand" "=Rcl")
300         (mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))]
301   "TARGET_A24"
302   "popc\t%0"
303   )
304
305
306 ;; Rhl used here as an HI-mode Rxl
307 (define_insn "extendqihi2"
308 [(set (match_operand:HI 0 "mra_operand" "=RhlSd*Rmm")
309         (sign_extend:HI (match_operand:QI 1 "mra_operand" "0")))]
310   ""
311   "exts.b\t%1"
312   [(set_attr "flags" "sz")]
313   )
314
315 (define_insn "extendhisi2"
316   [(set (match_operand:SI 0 "r0123_operand" "=R03")
317         (sign_extend:SI (match_operand:HI 1 "r0123_operand" "0")))]
318   ""
319   "*
320    if (REGNO(operands[0]) == 0) return \"exts.w\t%1\";
321    else return \"mov.w r1,r3 | sha.w #-8,r3 | sha.w #-7,r3\";"
322   [(set_attr "flags" "sz")]
323   )
324
325 (define_insn "extendpsisi2"
326   [(set (match_operand:SI 0 "mr_operand" "=R03Sd*Rmm")
327         (sign_extend:SI (match_operand:PSI 1 "mr_operand" "0")))]
328   ""
329   "; expand psi %1 to si %0"
330   )
331
332 (define_insn "zero_extendpsisi2"
333   [(set (match_operand:SI 0 "mr_operand" "=R03Sd*Rmm")
334         (zero_extend:SI (match_operand:PSI 1 "mr_operand" "0")))]
335   ""
336   "; expand psi %1 to si %0"
337   )
338
339 (define_insn "zero_extendhipsi2"
340   [(set (match_operand:PSI 0 "nonimmediate_operand" "=Raa")
341         (truncate:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "Rhi"))))]
342   ""
343   "mov.w\t%1,%0"
344   )
345
346 (define_insn "zero_extendhisi2"
347   [(set (match_operand:SI 0 "nonimmediate_operand" "=RsiSd")
348         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
349   ""
350   "mov.w\t#0,%H0"
351   )
352
353 (define_insn "zero_extendqihi2"
354   [(set (match_operand:HI 0 "nonimmediate_operand" "=RsiRaaSd*Rmm")
355         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))]
356   ""
357   "and.w\t#255,%0"
358   )
359
360 (define_insn "truncsipsi2_16"
361   [(set (match_operand:PSI 0 "nonimmediate_operand" "=RsiRadSd*Rmm,Raa,Rcr,RsiSd*Rmm")
362         (truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,Rcr")))]
363   "TARGET_A16"
364   "@
365    ; no-op trunc si %1 to psi %0
366    #
367    ldc\t%1,%0
368    stc\t%1,%0"
369   )
370
371 (define_insn "trunchiqi2"
372   [(set (match_operand:QI 0 "mra_qi_operand" "=RqiRmmSd")
373         (truncate:QI (match_operand:HI 1 "mra_qi_operand" "0")))]
374   ""
375   "; no-op trunc hi %1 to qi %0"
376   )
377
378 (define_insn "truncsipsi2_24"
379   [(set (match_operand:PSI 0              "nonimmediate_operand" "=RsiSd*Rmm,Raa,!Rcl,RsiSd*Rmm")
380         (truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,!Rcl")))]
381   "TARGET_A24"
382   "@
383    ; no-op trunc si %1 to psi %0
384    mov.l\t%1,%0
385    ldc\t%1,%0
386    stc\t%1,%0"
387   )
388
389 (define_expand "truncsipsi2"
390   [(set (match_operand:PSI 0 "nonimmediate_operand" "=RsiRadSd*Rmm,Raa,Rcr,RsiSd*Rmm")
391         (truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,Rcr")))]
392   ""
393   ""
394   )
395
396 (define_expand "reload_inqi"
397   [(set (match_operand:QI 2 "" "=&Rqi")
398         (match_operand:QI 1 "" ""))
399    (set (match_operand:QI 0 "" "")
400         (match_dup 2))
401    ]
402   ""
403   "")
404
405 (define_expand "reload_outqi"
406   [(set (match_operand:QI 2 "" "=&Rqi")
407         (match_operand:QI 1 "" ""))
408    (set (match_operand:QI 0 "" "")
409         (match_dup 2))
410    ]
411   ""
412   "")
413
414 (define_expand "reload_inhi"
415   [(set (match_operand:HI 2 "" "=&Rhi")
416         (match_operand:HI 1 "" ""))
417    (set (match_operand:HI 0 "" "")
418         (match_dup 2))
419    ]
420   ""
421   "")
422
423 (define_expand "reload_outhi"
424   [(set (match_operand:HI 2 "" "=&Rhi")
425         (match_operand:HI 1 "" ""))
426    (set (match_operand:HI 0 "" "")
427         (match_dup 2))
428    ]
429   ""
430   "")