2015-09-24 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / config / moxie / moxie.md
blobd09f3b19e69729fb50061bae28444f75a64daf05
1 ;; Machine description for Moxie
2 ;; Copyright (C) 2009-2015 Free Software Foundation, Inc.
3 ;; Contributed by Anthony Green <green@moxielogic.com>
5 ;; This file is part of GCC.
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.
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.
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/>.
21 ;; -------------------------------------------------------------------------
22 ;; Moxie specific constraints, predicates and attributes
23 ;; -------------------------------------------------------------------------
25 (include "constraints.md")
26 (include "predicates.md")
28 ; Most instructions are two bytes long.
29 (define_attr "length" "" (const_int 2))
31 ;; -------------------------------------------------------------------------
32 ;; nop instruction
33 ;; -------------------------------------------------------------------------
35 (define_insn "nop"
36   [(const_int 0)]
37   ""
38   "nop")
40 ;; -------------------------------------------------------------------------
41 ;; Arithmetic instructions
42 ;; -------------------------------------------------------------------------
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\\t%0, %2
52   dec\\t%0, -%2
53   add\\t%0, %2")
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\\t%0, %2
63   sub\\t%0, %2")
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\\t%0, %2")
73 (define_code_iterator EXTEND [sign_extend zero_extend])
74 (define_code_attr mul [(sign_extend "mul") (zero_extend "umul")])
76 (define_insn "<mul>si3_highpart"
77   [(set (match_operand:SI 0 "register_operand"                       "=r")
78         (truncate:SI
79          (lshiftrt:DI
80           (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand"  "0"))
81                    (EXTEND:DI (match_operand:SI 2 "register_operand"  "r")))
82           (const_int 32))))]
83   "TARGET_HAS_MULX"
84   "<mul>.x\\t%0, %2")
86 (define_expand "<mul>sidi3"
87   [(set (match_operand:DI 0 "register_operand" "")
88         (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" "0"))
89                  (EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
90   "TARGET_HAS_MULX"
92   rtx hi = gen_reg_rtx (SImode);
93   rtx lo = gen_reg_rtx (SImode);
95   emit_insn (gen_<mul>si3_highpart (hi, operands[1], operands[2]));
96   emit_insn (gen_mulsi3 (lo, operands[1], operands[2]));
97   emit_move_insn (gen_lowpart (SImode, operands[0]), lo);
98   emit_move_insn (gen_highpart (SImode, operands[0]), hi);
99   DONE;
102 (define_insn "divsi3"
103   [(set (match_operand:SI 0 "register_operand" "=r")
104           (div:SI
105            (match_operand:SI 1 "register_operand" "0")
106            (match_operand:SI 2 "register_operand" "r")))]
107   ""
108   "div\\t%0, %2")
110 (define_insn "udivsi3"
111   [(set (match_operand:SI 0 "register_operand" "=r")
112           (udiv:SI
113            (match_operand:SI 1 "register_operand" "0")
114            (match_operand:SI 2 "register_operand" "r")))]
115   ""
116   "udiv\\t%0, %2")
118 (define_insn "modsi3"
119   [(set (match_operand:SI 0 "register_operand" "=r")
120           (mod:SI
121            (match_operand:SI 1 "register_operand" "0")
122            (match_operand:SI 2 "register_operand" "r")))]
123   ""
124   "mod\\t%0, %2")
126 (define_insn "umodsi3"
127   [(set (match_operand:SI 0 "register_operand" "=r")
128           (umod:SI
129            (match_operand:SI 1 "register_operand" "0")
130            (match_operand:SI 2 "register_operand" "r")))]
131   ""
132   "umod\\t%0, %2")
134 ;; -------------------------------------------------------------------------
135 ;; Unary arithmetic instructions
136 ;; -------------------------------------------------------------------------
138 (define_insn "negsi2"
139   [(set (match_operand:SI 0 "register_operand" "=r")
140           (neg:SI (match_operand:SI 1 "register_operand" "r")))]
141   ""
142   "neg\\t%0, %1")
144 (define_insn "one_cmplsi2"
145   [(set (match_operand:SI 0 "register_operand" "=r")
146         (not:SI (match_operand:SI 1 "register_operand" "r")))]
147   ""
148   "not\\t%0, %1")
150 ;; -------------------------------------------------------------------------
151 ;; Logical operators
152 ;; -------------------------------------------------------------------------
154 (define_insn "andsi3"
155   [(set (match_operand:SI 0 "register_operand" "=r")
156         (and:SI (match_operand:SI 1 "register_operand" "0")
157                 (match_operand:SI 2 "register_operand" "r")))]
158   ""
160   return "and\\t%0, %2";
163 (define_insn "xorsi3"
164   [(set (match_operand:SI 0 "register_operand" "=r")
165         (xor:SI (match_operand:SI 1 "register_operand" "0")
166                 (match_operand:SI 2 "register_operand" "r")))]
167   ""
169   return "xor\\t%0, %2";
172 (define_insn "iorsi3"
173   [(set (match_operand:SI 0 "register_operand" "=r")
174         (ior:SI (match_operand:SI 1 "register_operand" "0")
175                 (match_operand:SI 2 "register_operand" "r")))]
176   ""
178   return "or\\t%0, %2";
181 ;; -------------------------------------------------------------------------
182 ;; Shifters
183 ;; -------------------------------------------------------------------------
185 (define_insn "ashlsi3"
186   [(set (match_operand:SI 0 "register_operand" "=r")
187         (ashift:SI (match_operand:SI 1 "register_operand" "0")
188                    (match_operand:SI 2 "register_operand" "r")))]
189   ""
191   return "ashl\\t%0, %2";
194 (define_insn "ashrsi3"
195   [(set (match_operand:SI 0 "register_operand" "=r")
196         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
197                      (match_operand:SI 2 "register_operand" "r")))]
198   ""
200   return "ashr\\t%0, %2";
203 (define_insn "lshrsi3"
204   [(set (match_operand:SI 0 "register_operand" "=r")
205         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
206                      (match_operand:SI 2 "register_operand" "r")))]
207   ""
209   return "lshr\\t%0, %2";
212 ;; -------------------------------------------------------------------------
213 ;; Move instructions
214 ;; -------------------------------------------------------------------------
216 ;; SImode
218 ;; Push a register onto the stack
219 (define_insn "movsi_push"
220   [(set (mem:SI (pre_dec:SI (reg:SI 1)))
221         (match_operand:SI 0 "register_operand" "r"))]
222   ""
223   "push\\t$sp, %0")
225 ;; Pop a register from the stack
226 (define_insn "movsi_pop"
227   [(set (match_operand:SI 1 "register_operand" "=r")
228         (mem:SI (post_inc:SI (match_operand:SI 0 "register_operand" "r"))))]
229   ""
230   "pop\\t%0, %1")
232 (define_expand "movsi"
233    [(set (match_operand:SI 0 "general_operand" "")
234         (match_operand:SI 1 "general_operand" ""))]
235    ""
236   "
238   /* If this is a store, force the value into a register.  */
239   if (! (reload_in_progress || reload_completed))
240   {
241     if (MEM_P (operands[0]))
242     {
243       operands[1] = force_reg (SImode, operands[1]);
244       if (MEM_P (XEXP (operands[0], 0)))
245         operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0)));
246     }
247     else 
248       if (MEM_P (operands[1])
249           && MEM_P (XEXP (operands[1], 0)))
250         operands[1] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[1], 0)));
251   }
254 (define_insn "*movsi"
255   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,W,A,r,r,B,r")
256         (match_operand:SI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
257   "register_operand (operands[0], SImode)
258    || register_operand (operands[1], SImode)"
259   "@
260    xor\\t%0, %0
261    mov\\t%0, %1
262    ldi.l\\t%0, %1
263    st.l\\t%0, %1
264    sta.l\\t%0, %1
265    ld.l\\t%0, %1
266    lda.l\\t%0, %1
267    sto.l\\t%0, %1
268    ldo.l\\t%0, %1"
269   [(set_attr "length"   "2,2,6,2,6,2,6,4,4")])
271 (define_insn "zero_extendqisi2"
272   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
273         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,W,A,B")))]
274   ""
275   "@
276    zex.b\\t%0, %1
277    ld.b\\t%0, %1
278    lda.b\\t%0, %1
279    ldo.b\\t%0, %1"
280   [(set_attr "length" "2,2,6,4")])
282 (define_insn "zero_extendhisi2"
283   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
284         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,W,A,B")))]
285   ""
286   "@
287    zex.s\\t%0, %1
288    ld.s\\t%0, %1
289    lda.s\\t%0, %1
290    ldo.s\\t%0, %1"
291   [(set_attr "length" "2,2,6,4")])
293 (define_insn "extendqisi2"
294   [(set (match_operand:SI 0 "register_operand" "=r")
295         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r")))]
296   ""
297   "@
298    sex.b\\t%0, %1"
299   [(set_attr "length" "2")])
301 (define_insn "extendhisi2"
302   [(set (match_operand:SI 0 "register_operand" "=r")
303         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
304   ""
305   "@
306    sex.s\\t%0, %1"
307   [(set_attr "length" "2")])
309 (define_expand "movqi"
310   [(set (match_operand:QI 0 "general_operand" "")
311         (match_operand:QI 1 "general_operand" ""))]
312   ""
313   "
315   /* If this is a store, force the value into a register.  */
316   if (MEM_P (operands[0]))
317     operands[1] = force_reg (QImode, operands[1]);
320 (define_insn "*movqi"
321   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,W,A,r,r,B,r")
322         (match_operand:QI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
323   "register_operand (operands[0], QImode)
324    || register_operand (operands[1], QImode)"
325   "@
326    xor\\t%0, %0
327    mov\\t%0, %1
328    ldi.b\\t%0, %1
329    st.b\\t%0, %1
330    sta.b\\t%0, %1
331    ld.b\\t%0, %1
332    lda.b\\t%0, %1
333    sto.b\\t%0, %1
334    ldo.b\\t%0, %1"
335   [(set_attr "length"   "2,2,6,2,6,2,6,4,4")])
337 (define_expand "movhi"
338   [(set (match_operand:HI 0 "general_operand" "")
339         (match_operand:HI 1 "general_operand" ""))]
340   ""
341   "
343   /* If this is a store, force the value into a register.  */
344   if (MEM_P (operands[0]))
345     operands[1] = force_reg (HImode, operands[1]);
348 (define_insn "*movhi"
349   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,W,A,r,r,B,r")
350         (match_operand:HI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
351   "(register_operand (operands[0], HImode)
352     || register_operand (operands[1], HImode))"
353   "@
354    xor\\t%0, %0
355    mov\\t%0, %1
356    ldi.s\\t%0, %1
357    st.s\\t%0, %1
358    sta.s\\t%0, %1
359    ld.s\\t%0, %1
360    lda.s\\t%0, %1
361    sto.s\\t%0, %1
362    ldo.s\\t%0, %1"
363   [(set_attr "length"   "2,2,6,2,6,2,6,4,4")])
365 ;; -------------------------------------------------------------------------
366 ;; Compare instructions
367 ;; -------------------------------------------------------------------------
369 (define_constants
370   [(CC_REG 19)])
372 (define_expand "cbranchsi4"
373   [(set (reg:CC CC_REG)
374         (compare:CC
375          (match_operand:SI 1 "general_operand" "")
376          (match_operand:SI 2 "general_operand" "")))
377    (set (pc)
378         (if_then_else (match_operator 0 "comparison_operator"
379                        [(reg:CC CC_REG) (const_int 0)])
380                       (label_ref (match_operand 3 "" ""))
381                       (pc)))]
382   ""
383   "
384   /* Force the compare operands into registers.  */
385   if (GET_CODE (operands[1]) != REG)
386         operands[1] = force_reg (SImode, operands[1]);
387   if (GET_CODE (operands[2]) != REG)
388         operands[2] = force_reg (SImode, operands[2]);
389   ")
391 (define_insn "*cmpsi"
392   [(set (reg:CC CC_REG)
393         (compare
394          (match_operand:SI 0 "register_operand" "r")
395          (match_operand:SI 1 "register_operand" "r")))]
396   ""
397   "cmp\\t%0, %1")
400 ;; -------------------------------------------------------------------------
401 ;; Branch instructions
402 ;; -------------------------------------------------------------------------
404 (define_code_iterator cond [ne eq lt ltu gt gtu ge le geu leu])
405 (define_code_attr CC [(ne "ne") (eq "eq") (lt "lt") (ltu "ltu") 
406                       (gt "gt") (gtu "gtu") (ge "ge") (le "le") 
407                       (geu "geu") (leu "leu") ])
408 (define_code_attr rCC [(ne "eq") (eq "ne") (lt "ge") (ltu "geu") 
409                        (gt "le") (gtu "leu") (ge "lt") (le "gt") 
410                        (geu "ltu") (leu "gtu") ])
412 (define_insn "*b<cond:code>"
413   [(set (pc)
414         (if_then_else (cond (reg:CC CC_REG)
415                             (const_int 0))
416                       (label_ref (match_operand 0 "" ""))
417                       (pc)))]
418   ""
420   if (get_attr_length (insn) == 2)
421     return "b<CC>\\t%l0";
422   else
423     return "b<rCC>\\t.+6\n\tjmpa   %l0";
425   [(set (attr "length")
426         (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 1022))
427                       (const_int 2) (const_int 8)))])
429 ;; -------------------------------------------------------------------------
430 ;; Call and Jump instructions
431 ;; -------------------------------------------------------------------------
433 (define_expand "call"
434   [(call (match_operand:QI 0 "memory_operand" "")
435                 (match_operand 1 "general_operand" ""))]
436   ""
438   gcc_assert (MEM_P (operands[0]));
441 (define_insn "*call"
442   [(call (mem:QI (match_operand:SI
443                   0 "nonmemory_operand" "i,r"))
444          (match_operand 1 "" ""))]
445   ""
446   "@
447    jsra\\t%0
448    jsr\\t%0"
449   [(set_attr "length"   "6,2")])
451 (define_expand "call_value"
452   [(set (match_operand 0 "" "")
453                 (call (match_operand:QI 1 "memory_operand" "")
454                  (match_operand 2 "" "")))]
455   ""
457   gcc_assert (MEM_P (operands[1]));
460 (define_insn "*call_value"
461   [(set (match_operand 0 "register_operand" "=r")
462         (call (mem:QI (match_operand:SI
463                        1 "immediate_operand" "i"))
464               (match_operand 2 "" "")))]
465   ""
466   "jsra\\t%1"
467   [(set_attr "length"   "6")])
469 (define_insn "*call_value_indirect"
470   [(set (match_operand 0 "register_operand" "=r")
471         (call (mem:QI (match_operand:SI
472                        1 "register_operand" "r"))
473               (match_operand 2 "" "")))]
474   ""
475   "jsr\\t%1")
477 (define_insn "indirect_jump"
478   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
479   ""
480   "jmp\\t%0")
482 (define_insn "jump"
483   [(set (pc)
484         (label_ref (match_operand 0 "" "")))]
485   ""
486   "jmpa\\t%l0"
487   [(set_attr "length"   "6")])
490 ;; -------------------------------------------------------------------------
491 ;; Prologue & Epilogue
492 ;; -------------------------------------------------------------------------
494 (define_expand "prologue"
495   [(clobber (const_int 0))]
496   ""
497   "
499   moxie_expand_prologue ();
500   DONE;
504 (define_expand "epilogue"
505   [(return)]
506   ""
507   "
509   moxie_expand_epilogue ();
510   DONE;
514 (define_insn "returner"
515   [(return)]
516   "reload_completed"
517   "ret")