OSDN Git Service

* gcc-interface/trans.c (can_equal_min_or_max_val_p): Be prepared for
[pf3gnuchains/gcc-fork.git] / gcc / config / moxie / moxie.md
1 ;; Machine description for Moxie
2 ;; Copyright (C) 2009 Free Software Foundation, Inc.
3 ;; Contributed by Anthony Green <green@moxielogic.com>
4
5 ;; This file is part of GCC.
6
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
11
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 ;; -------------------------------------------------------------------------
22 ;; Moxie specific constraints, predicates and attributes
23 ;; -------------------------------------------------------------------------
24
25 (include "constraints.md")
26 (include "predicates.md")
27
28 ; Most instructions are two bytes long.
29 (define_attr "length" "" (const_int 2))
30
31 ;; -------------------------------------------------------------------------
32 ;; nop instruction
33 ;; -------------------------------------------------------------------------
34
35 (define_insn "nop"
36   [(const_int 0)]
37   ""
38   "nop")
39
40 ;; -------------------------------------------------------------------------
41 ;; Arithmetic instructions
42 ;; -------------------------------------------------------------------------
43
44 (define_insn "addsi3"
45   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
46           (plus:SI
47            (match_operand:SI 1 "register_operand" "0,0,0")
48            (match_operand:SI 2 "moxie_add_operand" "I,N,r")))]
49   ""
50   "@
51   inc    %0, %2
52   dec    %0, -%2
53   add.l  %0, %2")
54
55 (define_insn "subsi3"
56   [(set (match_operand:SI 0 "register_operand" "=r,r")
57           (minus:SI
58            (match_operand:SI 1 "register_operand" "0,0")
59            (match_operand:SI 2 "moxie_sub_operand" "I,r")))]
60   ""
61   "@
62   dec    %0, %2
63   sub.l  %0, %2")
64
65 (define_insn "mulsi3"
66   [(set (match_operand:SI 0 "register_operand" "=r")
67           (mult:SI
68            (match_operand:SI 1 "register_operand" "0")
69            (match_operand:SI 2 "register_operand" "r")))]
70   ""
71   "mul.l  %0, %2")
72
73 (define_insn "divsi3"
74   [(set (match_operand:SI 0 "register_operand" "=r")
75           (div:SI
76            (match_operand:SI 1 "register_operand" "0")
77            (match_operand:SI 2 "register_operand" "r")))]
78   ""
79   "div.l  %0, %2")
80
81 (define_insn "udivsi3"
82   [(set (match_operand:SI 0 "register_operand" "=r")
83           (udiv:SI
84            (match_operand:SI 1 "register_operand" "0")
85            (match_operand:SI 2 "register_operand" "r")))]
86   ""
87   "udiv.l %0, %2")
88
89 (define_insn "modsi3"
90   [(set (match_operand:SI 0 "register_operand" "=r")
91           (mod:SI
92            (match_operand:SI 1 "register_operand" "0")
93            (match_operand:SI 2 "register_operand" "r")))]
94   ""
95   "mod.l  %0, %2")
96
97 (define_insn "umodsi3"
98   [(set (match_operand:SI 0 "register_operand" "=r")
99           (umod:SI
100            (match_operand:SI 1 "register_operand" "0")
101            (match_operand:SI 2 "register_operand" "r")))]
102   ""
103   "umod.l %0, %2")
104
105 ;; -------------------------------------------------------------------------
106 ;; Unary arithmetic instructions
107 ;; -------------------------------------------------------------------------
108
109 (define_insn "negsi2"
110   [(set (match_operand:SI 0 "register_operand" "=r")
111           (neg:SI (match_operand:SI 1 "register_operand" "r")))]
112   ""
113   "neg    %0, %1")
114
115 (define_insn "one_cmplsi2"
116   [(set (match_operand:SI 0 "register_operand" "=r")
117         (not:SI (match_operand:SI 1 "register_operand" "r")))]
118   ""
119   "not    %0, %1")
120
121 ;; -------------------------------------------------------------------------
122 ;; Logical operators
123 ;; -------------------------------------------------------------------------
124
125 (define_insn "andsi3"
126   [(set (match_operand:SI 0 "register_operand" "=r")
127         (and:SI (match_operand:SI 1 "register_operand" "0")
128                 (match_operand:SI 2 "register_operand" "r")))]
129   ""
130 {
131   return "and    %0, %2";
132 })
133
134 (define_insn "xorsi3"
135   [(set (match_operand:SI 0 "register_operand" "=r")
136         (xor:SI (match_operand:SI 1 "register_operand" "0")
137                 (match_operand:SI 2 "register_operand" "r")))]
138   ""
139 {
140   return "xor    %0, %2";
141 })
142
143 (define_insn "iorsi3"
144   [(set (match_operand:SI 0 "register_operand" "=r")
145         (ior:SI (match_operand:SI 1 "register_operand" "0")
146                 (match_operand:SI 2 "register_operand" "r")))]
147   ""
148 {
149   return "or     %0, %2";
150 })
151
152 ;; -------------------------------------------------------------------------
153 ;; Shifters
154 ;; -------------------------------------------------------------------------
155
156 (define_insn "ashlsi3"
157   [(set (match_operand:SI 0 "register_operand" "=r")
158         (ashift:SI (match_operand:SI 1 "register_operand" "0")
159                    (match_operand:SI 2 "register_operand" "r")))]
160   ""
161 {
162   return "ashl   %0, %2";
163 })
164
165 (define_insn "ashrsi3"
166   [(set (match_operand:SI 0 "register_operand" "=r")
167         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
168                      (match_operand:SI 2 "register_operand" "r")))]
169   ""
170 {
171   return "ashr   %0, %2";
172 })
173
174 (define_insn "lshrsi3"
175   [(set (match_operand:SI 0 "register_operand" "=r")
176         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
177                      (match_operand:SI 2 "register_operand" "r")))]
178   ""
179 {
180   return "lshr   %0, %2";
181 })
182
183 ;; -------------------------------------------------------------------------
184 ;; Move instructions
185 ;; -------------------------------------------------------------------------
186
187 ;; SImode
188
189 ;; Push a register onto the stack
190 (define_insn "movsi_push"
191   [(set (mem:SI (pre_dec:SI (reg:SI 1)))
192         (match_operand:SI 0 "register_operand" "r"))]
193   ""
194   "push   $sp, %0")
195
196 ;; Pop a register from the stack
197 (define_insn "movsi_pop"
198   [(set (match_operand:SI 1 "register_operand" "=r")
199         (mem:SI (post_inc:SI (match_operand:SI 0 "register_operand" "r"))))]
200   ""
201   "pop    %0, %1")
202
203 (define_expand "movsi"
204    [(set (match_operand:SI 0 "general_operand" "")
205         (match_operand:SI 1 "general_operand" ""))]
206    ""
207   "
208 {
209   /* If this is a store, force the value into a register.  */
210   if (! (reload_in_progress || reload_completed))
211   {
212     if (MEM_P (operands[0]))
213     {
214       operands[1] = force_reg (SImode, operands[1]);
215       if (MEM_P (XEXP (operands[0], 0)))
216         operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0)));
217     }
218     else 
219       if (MEM_P (operands[1])
220           && MEM_P (XEXP (operands[1], 0)))
221         operands[1] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[1], 0)));
222   }
223 }")
224
225 (define_insn "*movsi"
226   [(set (match_operand:SI 0 "general_operand" "=r,r,r,W,A,r,r,B,r")
227         (match_operand:SI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
228   "register_operand (operands[0], SImode)
229    || register_operand (operands[1], SImode)"
230   "@
231    xor    %0, %0
232    mov    %0, %1
233    ldi.l  %0, %1
234    st.l   %0, %1
235    sta.l  %0, %1
236    ld.l   %0, %1
237    lda.l  %0, %1
238    sto.l  %0, %1
239    ldo.l  %0, %1"
240   [(set_attr "length"   "2,2,6,2,6,2,6,6,6")])
241
242 (define_expand "movqi"
243   [(set (match_operand:QI 0 "general_operand" "")
244         (match_operand:QI 1 "general_operand" ""))]
245   ""
246   "
247 {
248   /* If this is a store, force the value into a register.  */
249   if (MEM_P (operands[0]))
250     operands[1] = force_reg (QImode, operands[1]);
251 }")
252
253 (define_insn "*movqi"
254   [(set (match_operand:QI 0 "general_operand" "=r,r,r,W,A,r,r,B,r")
255         (match_operand:QI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
256   "register_operand (operands[0], QImode)
257    || register_operand (operands[1], QImode)"
258   "@
259    xor    %0, %0
260    mov    %0, %1
261    ldi.b  %0, %1
262    st.b   %0, %1
263    sta.b  %0, %1
264    ld.b   %0, %1
265    lda.b  %0, %1
266    sto.b  %0, %1
267    ldo.b  %0, %1"
268   [(set_attr "length"   "2,2,6,2,6,2,6,6,6")])
269
270 (define_expand "movhi"
271   [(set (match_operand:HI 0 "general_operand" "")
272         (match_operand:HI 1 "general_operand" ""))]
273   ""
274   "
275 {
276   /* If this is a store, force the value into a register.  */
277   if (MEM_P (operands[0]))
278     operands[1] = force_reg (HImode, operands[1]);
279 }")
280
281 (define_insn "*movhi"
282   [(set (match_operand:HI 0 "general_operand" "=r,r,r,W,A,r,r,B,r")
283         (match_operand:HI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
284   "(register_operand (operands[0], HImode)
285     || register_operand (operands[1], HImode))"
286   "@
287    xor    %0, %0
288    mov    %0, %1
289    ldi.s  %0, %1
290    st.s   %0, %1
291    sta.s  %0, %1
292    ld.s   %0, %1
293    lda.s  %0, %1
294    sto.s  %0, %1
295    ldo.s  %0, %1"
296   [(set_attr "length"   "2,2,6,2,6,2,6,6,6")])
297
298 ;; -------------------------------------------------------------------------
299 ;; Compare instructions
300 ;; -------------------------------------------------------------------------
301
302 (define_constants
303   [(CC_REG 11)])
304
305 (define_expand "cbranchsi4"
306   [(set (reg:CC CC_REG)
307         (compare:CC
308          (match_operand:SI 1 "general_operand" "")
309          (match_operand:SI 2 "general_operand" "")))
310    (set (pc)
311         (if_then_else (match_operator 0 "comparison_operator"
312                        [(reg:CC CC_REG) (const_int 0)])
313                       (label_ref (match_operand 3 "" ""))
314                       (pc)))]
315   ""
316   "
317   /* Force the compare operands into registers.  */
318   if (GET_CODE (operands[1]) != REG)
319         operands[1] = force_reg (SImode, operands[1]);
320   if (GET_CODE (operands[2]) != REG)
321         operands[2] = force_reg (SImode, operands[2]);
322   ")
323
324 (define_insn "*cmpsi"
325   [(set (reg:CC CC_REG)
326         (compare
327          (match_operand:SI 0 "register_operand" "r")
328          (match_operand:SI 1 "register_operand" "r")))]
329   ""
330   "cmp    %0, %1")
331
332
333 ;; -------------------------------------------------------------------------
334 ;; Branch instructions
335 ;; -------------------------------------------------------------------------
336
337 (define_code_iterator cond [ne eq lt ltu gt gtu ge le geu leu])
338 (define_code_attr CC [(ne "ne") (eq "eq") (lt "lt") (ltu "ltu") 
339                       (gt "gt") (gtu "gtu") (ge "ge") (le "le") 
340                       (geu "geu") (leu "leu") ])
341 (define_code_attr rCC [(ne "eq") (eq "ne") (lt "ge") (ltu "geu") 
342                        (gt "le") (gtu "leu") (ge "lt") (le "gt") 
343                        (geu "ltu") (leu "gtu") ])
344
345 (define_insn "*b<cond:code>"
346   [(set (pc)
347         (if_then_else (cond (reg:CC CC_REG)
348                             (const_int 0))
349                       (label_ref (match_operand 0 "" ""))
350                       (pc)))]
351   ""
352 {
353   if (get_attr_length (insn) == 2)
354     return "b<CC>   %l0";
355   else
356     return "b<rCC>   .+6\n\tjmpa   %l0";
357 }
358   [(set (attr "length")
359         (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 1022))
360                       (const_int 2) (const_int 8)))])
361
362 ;; -------------------------------------------------------------------------
363 ;; Call and Jump instructions
364 ;; -------------------------------------------------------------------------
365
366 (define_expand "call"
367   [(call (match_operand:QI 0 "memory_operand" "")
368                 (match_operand 1 "general_operand" ""))]
369   ""
370 {
371   gcc_assert (MEM_P (operands[0]));
372 })
373
374 (define_insn "*call"
375   [(call (mem:QI (match_operand:SI
376                   0 "nonmemory_operand" "i,r"))
377          (match_operand 1 "" ""))]
378   ""
379   "@
380    jsra   %0
381    jsr    %0"
382   [(set_attr "length"   "6,2")])
383
384 (define_expand "call_value"
385   [(set (match_operand 0 "" "")
386                 (call (match_operand:QI 1 "memory_operand" "")
387                  (match_operand 2 "" "")))]
388   ""
389 {
390   gcc_assert (MEM_P (operands[1]));
391 })
392
393 (define_insn "*call_value"
394   [(set (match_operand 0 "register_operand" "=r")
395         (call (mem:QI (match_operand:SI
396                        1 "immediate_operand" "i"))
397               (match_operand 2 "" "")))]
398   ""
399   "jsra   %1"
400   [(set_attr "length"   "6")])
401
402 (define_insn "*call_value_indirect"
403   [(set (match_operand 0 "register_operand" "=r")
404         (call (mem:QI (match_operand:SI
405                        1 "register_operand" "r"))
406               (match_operand 2 "" "")))]
407   ""
408   "jsr    %1")
409
410 (define_insn "indirect_jump"
411   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
412   ""
413   "jmp    %0")
414
415 (define_insn "jump"
416   [(set (pc)
417         (label_ref (match_operand 0 "" "")))]
418   ""
419   "jmpa   %l0"
420   [(set_attr "length"   "6")])
421
422
423 ;; -------------------------------------------------------------------------
424 ;; Prologue & Epilogue
425 ;; -------------------------------------------------------------------------
426
427 (define_expand "prologue"
428   [(clobber (const_int 0))]
429   ""
430   "
431 {
432   moxie_expand_prologue ();
433   DONE;
434 }
435 ")
436
437 (define_expand "epilogue"
438   [(return)]
439   ""
440   "
441 {
442   moxie_expand_epilogue ();
443   DONE;
444 }
445 ")
446
447 (define_insn "returner"
448   [(return)]
449   "reload_completed"
450   "ret")