Sync usage with man page.
[netbsd-mini2440.git] / gnu / dist / gcc4 / gcc / config / m32c / mov.md
blobe146bb6cc20d1f921822bcf1ac2b8fe420b88cfe
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.
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.
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.
23 ;; move, push, extend, etc.
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.
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   )
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   )
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   )
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   )
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   )
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.
107 (define_mode_macro QHSI [QI HI SI])
108 (define_mode_macro HPSI [(HI "TARGET_A16") (PSI "TARGET_A24")])
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    && dead_or_set_p (peep2_next_insn (1), operands[4])
119    && ! reg_mentioned_p (operands[0], operands[3])"
120   [(set (match_dup 3)
121         (mem:QHSI (plus:HPSI (match_dup 1)
122                              (match_dup 2))))]
123   "")
125 (define_peephole2
126   [(set (match_operand:HPSI 0 "register_operand" "")
127         (plus:HPSI (match_operand:HPSI 1 "register_operand" "")
128                    (match_operand:HPSI 2 "immediate_operand" "")))
129    (set (mem:QHSI (match_operand:HPSI 4 "register_operand" ""))
130         (match_operand:QHSI 3 "general_operand" ""))]
131   "REGNO (operands[0]) == REGNO (operands[1])
132    && REGNO (operands[0]) == REGNO (operands[4])
133    && dead_or_set_p (peep2_next_insn (1), operands[4])
134    && ! reg_mentioned_p (operands[0], operands[3])"
135   [(set (mem:QHSI (plus:HPSI (match_dup 1)
136                              (match_dup 2)))
137         (match_dup 3))]
138   "")
141 ; Some PSI moves must be split.
142 (define_split
143   [(set (match_operand:PSI 0 "nonimmediate_operand" "")
144         (match_operand:PSI 1 "general_operand" ""))]
145   "reload_completed && m32c_split_psi_p (operands)"
146   [(set (match_dup 2)
147         (match_dup 3))
148    (set (match_dup 4)
149         (match_dup 5))]
150   "m32c_split_move (operands, PSImode, 3);"
151   )
153 (define_expand "movpsi"
154   [(set (match_operand:PSI 0 "mras_operand" "")
155         (match_operand:PSI 1 "mrasi_operand" ""))]
156   ""
157   "if (m32c_prepare_move (operands, PSImode)) DONE;"
158   )
162 (define_expand "movsi"
163   [(set (match_operand:SI 0 "mras_operand" "=RsiSd*Rmm")
164         (match_operand:SI 1 "mrasi_operand" "iRsiSd*Rmm"))]
165   ""
166   "if (m32c_split_move (operands, SImode, 0)) DONE;"
167   )
169 ; All SI moves are split if TARGET_A16
170 (define_insn_and_split "movsi_splittable"
171   [(set (match_operand:SI 0 "mras_operand" "=Rsi<*Rmm,RsiSd*Rmm,Ss")
172         (match_operand:SI 1 "mrasi_operand" "iRsiSd*Rmm,iRsi>*Rmm,Rsi*Rmm"))]
173   "TARGET_A16"
174   "#"
175   "TARGET_A16 && reload_completed"
176   [(pc)]
177   "m32c_split_move (operands, SImode, 1); DONE;"
178   )
180 ; The movsi pattern doesn't always match because sometimes the modes
181 ; don't match.
182 (define_insn "push_a01_l"
183   [(set (mem:SI (pre_dec:PSI (reg:PSI SP_REGNO)))
184         (match_operand 0 "a_operand" ""))]
185   ""
186   "push.l\t%0"
187   )
189 (define_insn "movsi_24"
190   [(set (match_operand:SI 0 "mras_operand"  "=Rsi*Rmm,   Sd,       RsiSd*Rmm,     <")
191         (match_operand:SI 1 "mrasi_operand" "iRsiSd*Rmm, iRsi*Rmm, >, iRsiRaaSd*Rmm"))]
192   "TARGET_A24"
193   "@
194    mov.l\t%1,%0
195    mov.l\t%1,%0
196    #
197    push.l\t%1"
198   )
200 (define_expand "movdi"
201   [(set (match_operand:DI 0 "mras_operand" "=RdiSd*Rmm")
202         (match_operand:DI 1 "mrasi_operand" "iRdiSd*Rmm"))]
203   ""
204   "if (m32c_split_move (operands, DImode, 0)) DONE;"
205   )
207 (define_insn_and_split "movdi_splittable"
208   [(set (match_operand:DI 0 "mras_operand" "=Rdi<*Rmm,RdiSd*Rmm")
209         (match_operand:DI 1 "mrasi_operand" "iRdiSd*Rmm,iRdi>*Rmm"))]
210   ""
211   "#"
212   "reload_completed"
213   [(pc)]
214   "m32c_split_move (operands, DImode, 1); DONE;"
215   )
220 (define_insn "pushqi"
221   [(set (mem:QI (pre_dec:PSI (reg:PSI SP_REGNO)))
222         (match_operand:QI 0 "mrai_operand" "iRqiSd*Rmm"))]
223   ""
224   "push.b\t%0"
225   )
227 (define_expand "pushhi"
228   [(set (mem:HI (pre_dec:PSI (reg:PSI SP_REGNO)))
229         (match_operand:HI 0 "" ""))]
230   ""
231   "if (TARGET_A16)
232      gen_pushhi_16 (operands[0]);
233    else
234      gen_pushhi_24 (operands[0]);
235    DONE;"
236   )
238 (define_insn "pushhi_16"
239   [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO)))
240         (match_operand:HI 0 "mrai_operand" "iRhiSd*Rmm,Rcr"))]
241   "TARGET_A16"
242   "@
243    push.w\t%0
244    pushc\t%0"
245   )
247 (define_insn "pushhi_24"
248   [(set (mem:HI (pre_dec:PSI (reg:PSI SP_REGNO)))
249         (match_operand:HI 0 "mrai_operand" "iRhiSd*Rmm"))]
250   "TARGET_A24"
251   "push.w\t%0"
252   )
254 ;(define_insn "pushpi"
255 ;  [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO)))
256 ;        (match_operand:PI 0 "mrai_operand" "iRaa,Rcr"))]
257 ;  "TARGET_A24"
258 ;  "@
259 ;   push.l\t%0
260 ;   pushc\t%0"
261 ;  )
263 (define_insn "pushsi"
264   [(set (mem:SI (pre_dec:PSI (reg:PSI SP_REGNO)))
265         (match_operand:SI 0 "mrai_operand" "iRsiSd*Rmm"))]
266   "TARGET_A24"
267   "push.l\t%0"
268   )
270 (define_expand "pophi"
271   [(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm,Rcr")
272         (mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
273   ""
274   "if (TARGET_A16)
275      gen_pophi_16 (operands[0]);
276    else
277      gen_pophi_24 (operands[0]);
278    DONE;"
279   )
281 (define_insn "pophi_16"
282   [(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm,Rcr")
283         (mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
284   "TARGET_A16"
285   "@
286    pop.w\t%0
287    popc\t%0"
288   )
290 (define_insn "pophi_24"
291   [(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm")
292         (mem:HI (post_inc:PSI (reg:PSI SP_REGNO))))]
293   "TARGET_A24"
294   "pop.w\t%0"
295   )
297 (define_insn "poppsi"
298   [(set (match_operand:PSI 0 "cr_operand" "=Rcl")
299         (mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))]
300   "TARGET_A24"
301   "popc\t%0"
302   )
305 ;; Rhl used here as an HI-mode Rxl
306 (define_insn "extendqihi2"
307 [(set (match_operand:HI 0 "mra_operand" "=RhlSd*Rmm")
308         (sign_extend:HI (match_operand:QI 1 "mra_operand" "0")))]
309   ""
310   "exts.b\t%1"
311   [(set_attr "flags" "sz")]
312   )
314 (define_insn "extendhisi2"
315   [(set (match_operand:SI 0 "r0123_operand" "=R03")
316         (sign_extend:SI (match_operand:HI 1 "r0123_operand" "0")))]
317   ""
318   "*
319    if (REGNO(operands[0]) == 0) return \"exts.w\t%1\";
320    else return \"mov.w r1,r3 | sha.w #-8,r3 | sha.w #-7,r3\";"
321   [(set_attr "flags" "sz")]
322   )
324 (define_insn "extendpsisi2"
325   [(set (match_operand:SI 0 "mr_operand" "=R03Sd*Rmm")
326         (sign_extend:SI (match_operand:PSI 1 "mr_operand" "0")))]
327   ""
328   "; expand psi %1 to si %0"
329   )
331 (define_insn "zero_extendpsisi2"
332   [(set (match_operand:SI 0 "mr_operand" "=R03Sd*Rmm")
333         (zero_extend:SI (match_operand:PSI 1 "mr_operand" "0")))]
334   ""
335   "; expand psi %1 to si %0"
336   )
338 (define_insn "zero_extendhipsi2"
339   [(set (match_operand:PSI 0 "nonimmediate_operand" "=Raa")
340         (truncate:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "Rhi"))))]
341   ""
342   "mov.w\t%1,%0"
343   )
345 (define_insn "zero_extendhisi2"
346   [(set (match_operand:SI 0 "nonimmediate_operand" "=RsiSd")
347         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
348   ""
349   "mov.w\t#0,%H0"
350   )
352 (define_insn "zero_extendqihi2"
353   [(set (match_operand:HI 0 "nonimmediate_operand" "=RsiRaaSd*Rmm")
354         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))]
355   ""
356   "and.w\t#255,%0"
357   )
359 (define_insn "truncsipsi2_16"
360   [(set (match_operand:PSI 0 "nonimmediate_operand" "=RsiRadSd*Rmm,Raa,Rcr,RsiSd*Rmm")
361         (truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,Rcr")))]
362   "TARGET_A16"
363   "@
364    ; no-op trunc si %1 to psi %0
365    #
366    ldc\t%1,%0
367    stc\t%1,%0"
368   )
370 (define_insn "trunchiqi2"
371   [(set (match_operand:QI 0 "mra_qi_operand" "=RqiRmmSd")
372         (truncate:QI (match_operand:HI 1 "mra_qi_operand" "0")))]
373   ""
374   "; no-op trunc hi %1 to qi %0"
375   )
377 (define_insn "truncsipsi2_24"
378   [(set (match_operand:PSI 0              "nonimmediate_operand" "=RsiSd*Rmm,Raa,!Rcl,RsiSd*Rmm")
379         (truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,!Rcl")))]
380   "TARGET_A24"
381   "@
382    ; no-op trunc si %1 to psi %0
383    mov.l\t%1,%0
384    ldc\t%1,%0
385    stc\t%1,%0"
386   )
388 (define_expand "truncsipsi2"
389   [(set (match_operand:PSI 0 "nonimmediate_operand" "=RsiRadSd*Rmm,Raa,Rcr,RsiSd*Rmm")
390         (truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,Rcr")))]
391   ""
392   ""
393   )
395 (define_expand "reload_inqi"
396   [(set (match_operand:QI 2 "" "=&Rqi")
397         (match_operand:QI 1 "" ""))
398    (set (match_operand:QI 0 "" "")
399         (match_dup 2))
400    ]
401   ""
402   "")
404 (define_expand "reload_outqi"
405   [(set (match_operand:QI 2 "" "=&Rqi")
406         (match_operand:QI 1 "" ""))
407    (set (match_operand:QI 0 "" "")
408         (match_dup 2))
409    ]
410   ""
411   "")
413 (define_expand "reload_inhi"
414   [(set (match_operand:HI 2 "" "=&Rhi")
415         (match_operand:HI 1 "" ""))
416    (set (match_operand:HI 0 "" "")
417         (match_dup 2))
418    ]
419   ""
420   "")
422 (define_expand "reload_outhi"
423   [(set (match_operand:HI 2 "" "=&Rhi")
424         (match_operand:HI 1 "" ""))
425    (set (match_operand:HI 0 "" "")
426         (match_dup 2))
427    ]
428   ""
429   "")