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 ;; -------------------------------------------------------------------------
33 ;; -------------------------------------------------------------------------
40 ;; -------------------------------------------------------------------------
41 ;; Arithmetic instructions
42 ;; -------------------------------------------------------------------------
45 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
47 (match_operand:SI 1 "register_operand" "0,0,0")
48 (match_operand:SI 2 "moxie_add_operand" "I,N,r")))]
56 [(set (match_operand:SI 0 "register_operand" "=r,r")
58 (match_operand:SI 1 "register_operand" "0,0")
59 (match_operand:SI 2 "moxie_sub_operand" "I,r")))]
66 [(set (match_operand:SI 0 "register_operand" "=r")
68 (match_operand:SI 1 "register_operand" "0")
69 (match_operand:SI 2 "register_operand" "r")))]
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")
80 (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" "0"))
81 (EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
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"))))]
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);
102 (define_insn "divsi3"
103 [(set (match_operand:SI 0 "register_operand" "=r")
105 (match_operand:SI 1 "register_operand" "0")
106 (match_operand:SI 2 "register_operand" "r")))]
110 (define_insn "udivsi3"
111 [(set (match_operand:SI 0 "register_operand" "=r")
113 (match_operand:SI 1 "register_operand" "0")
114 (match_operand:SI 2 "register_operand" "r")))]
118 (define_insn "modsi3"
119 [(set (match_operand:SI 0 "register_operand" "=r")
121 (match_operand:SI 1 "register_operand" "0")
122 (match_operand:SI 2 "register_operand" "r")))]
126 (define_insn "umodsi3"
127 [(set (match_operand:SI 0 "register_operand" "=r")
129 (match_operand:SI 1 "register_operand" "0")
130 (match_operand:SI 2 "register_operand" "r")))]
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")))]
144 (define_insn "one_cmplsi2"
145 [(set (match_operand:SI 0 "register_operand" "=r")
146 (not:SI (match_operand:SI 1 "register_operand" "r")))]
150 ;; -------------------------------------------------------------------------
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")))]
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")))]
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")))]
178 return "or\\t%0, %2";
181 ;; -------------------------------------------------------------------------
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")))]
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")))]
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")))]
209 return "lshr\\t%0, %2";
212 ;; -------------------------------------------------------------------------
214 ;; -------------------------------------------------------------------------
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"))]
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"))))]
232 (define_expand "movsi"
233 [(set (match_operand:SI 0 "general_operand" "")
234 (match_operand:SI 1 "general_operand" ""))]
238 /* If this is a store, force the value into a register. */
239 if (! (reload_in_progress || reload_completed))
241 if (MEM_P (operands[0]))
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)));
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)));
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)"
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")))]
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")))]
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")))]
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")))]
307 [(set_attr "length" "2")])
309 (define_expand "movqi"
310 [(set (match_operand:QI 0 "general_operand" "")
311 (match_operand:QI 1 "general_operand" ""))]
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)"
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" ""))]
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))"
363 [(set_attr "length" "2,2,6,2,6,2,6,4,4")])
365 ;; -------------------------------------------------------------------------
366 ;; Compare instructions
367 ;; -------------------------------------------------------------------------
372 (define_expand "cbranchsi4"
373 [(set (reg:CC CC_REG)
375 (match_operand:SI 1 "general_operand" "")
376 (match_operand:SI 2 "general_operand" "")))
378 (if_then_else (match_operator 0 "comparison_operator"
379 [(reg:CC CC_REG) (const_int 0)])
380 (label_ref (match_operand 3 "" ""))
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]);
391 (define_insn "*cmpsi"
392 [(set (reg:CC CC_REG)
394 (match_operand:SI 0 "register_operand" "r")
395 (match_operand:SI 1 "register_operand" "r")))]
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>"
414 (if_then_else (cond (reg:CC CC_REG)
416 (label_ref (match_operand 0 "" ""))
420 if (get_attr_length (insn) == 2)
421 return "b<CC>\\t%l0";
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" ""))]
438 gcc_assert (MEM_P (operands[0]));
442 [(call (mem:QI (match_operand:SI
443 0 "nonmemory_operand" "i,r"))
444 (match_operand 1 "" ""))]
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 "" "")))]
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 "" "")))]
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 "" "")))]
477 (define_insn "indirect_jump"
478 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
484 (label_ref (match_operand 0 "" "")))]
487 [(set_attr "length" "6")])
490 ;; -------------------------------------------------------------------------
491 ;; Prologue & Epilogue
492 ;; -------------------------------------------------------------------------
494 (define_expand "prologue"
495 [(clobber (const_int 0))]
499 moxie_expand_prologue ();
504 (define_expand "epilogue"
509 moxie_expand_epilogue ();
514 (define_insn "returner"