1 ;; Machine description for Moxie
2 ;; Copyright (C) 2009 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")))]
74 [(set (match_operand:SI 0 "register_operand" "=r")
76 (match_operand:SI 1 "register_operand" "0")
77 (match_operand:SI 2 "register_operand" "r")))]
81 (define_insn "udivsi3"
82 [(set (match_operand:SI 0 "register_operand" "=r")
84 (match_operand:SI 1 "register_operand" "0")
85 (match_operand:SI 2 "register_operand" "r")))]
90 [(set (match_operand:SI 0 "register_operand" "=r")
92 (match_operand:SI 1 "register_operand" "0")
93 (match_operand:SI 2 "register_operand" "r")))]
97 (define_insn "umodsi3"
98 [(set (match_operand:SI 0 "register_operand" "=r")
100 (match_operand:SI 1 "register_operand" "0")
101 (match_operand:SI 2 "register_operand" "r")))]
105 ;; -------------------------------------------------------------------------
106 ;; Unary arithmetic instructions
107 ;; -------------------------------------------------------------------------
109 (define_insn "negsi2"
110 [(set (match_operand:SI 0 "register_operand" "=r")
111 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
115 (define_insn "one_cmplsi2"
116 [(set (match_operand:SI 0 "register_operand" "=r")
117 (not:SI (match_operand:SI 1 "register_operand" "r")))]
121 ;; -------------------------------------------------------------------------
123 ;; -------------------------------------------------------------------------
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")))]
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")))]
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")))]
152 ;; -------------------------------------------------------------------------
154 ;; -------------------------------------------------------------------------
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")))]
162 return "ashl %0, %2";
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")))]
171 return "ashr %0, %2";
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")))]
180 return "lshr %0, %2";
183 ;; -------------------------------------------------------------------------
185 ;; -------------------------------------------------------------------------
189 ;; Push a register onto the stack
190 (define_insn "movsi_push"
191 [(set:SI (mem:SI (pre_dec:SI (reg:SI 1)))
192 (match_operand:SI 0 "register_operand" "r"))]
196 ;; Pop a register from the stack
197 (define_insn "movsi_pop"
198 [(set:SI (match_operand:SI 1 "register_operand" "=r")
199 (mem:SI (post_inc:SI (match_operand:SI 0 "register_operand" "r"))))]
203 (define_expand "movsi"
204 [(set (match_operand:SI 0 "general_operand" "")
205 (match_operand:SI 1 "general_operand" ""))]
209 /* If this is a store, force the value into a register. */
210 if (! (reload_in_progress || reload_completed))
212 if (MEM_P (operands[0]))
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)));
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)));
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)"
240 [(set_attr "length" "2,2,6,2,6,2,6,6,6")])
242 (define_expand "movqi"
243 [(set (match_operand:QI 0 "general_operand" "")
244 (match_operand:QI 1 "general_operand" ""))]
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]);
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)"
268 [(set_attr "length" "2,2,6,2,6,2,6,6,6")])
270 (define_expand "movhi"
271 [(set (match_operand:HI 0 "general_operand" "")
272 (match_operand:HI 1 "general_operand" ""))]
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]);
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))"
296 [(set_attr "length" "2,2,6,2,6,2,6,6,6")])
298 ;; -------------------------------------------------------------------------
299 ;; Compare instructions
300 ;; -------------------------------------------------------------------------
305 (define_expand "cbranchsi4"
306 [(set (reg:CC CC_REG)
308 (match_operand:SI 1 "general_operand" "")
309 (match_operand:SI 2 "general_operand" "")))
311 (if_then_else (match_operator:CC 0 "comparison_operator"
312 [(reg:CC CC_REG) (const_int 0)])
313 (label_ref (match_operand 3 "" ""))
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]);
324 (define_insn "*cmpsi"
325 [(set (reg:CC CC_REG)
327 (match_operand:SI 0 "register_operand" "r")
328 (match_operand:SI 1 "register_operand" "r")))]
333 ;; -------------------------------------------------------------------------
334 ;; Branch instructions
335 ;; -------------------------------------------------------------------------
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") ])
345 (define_insn "*b<cond:code>"
347 (if_then_else (cond (reg:CC CC_REG)
349 (label_ref (match_operand 0 "" ""))
353 if (get_attr_length (insn) == 2)
356 return "b<rCC> .+6\n\tjmpa %l0";
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)))])
362 ;; -------------------------------------------------------------------------
363 ;; Call and Jump instructions
364 ;; -------------------------------------------------------------------------
366 (define_expand "call"
367 [(call (match_operand:QI 0 "memory_operand" "")
368 (match_operand 1 "general_operand" ""))]
371 gcc_assert (MEM_P (operands[0]));
375 [(call (mem:QI (match_operand:SI
376 0 "nonmemory_operand" "i,r"))
377 (match_operand 1 "" ""))]
382 [(set_attr "length" "6,2")])
384 (define_expand "call_value"
385 [(set (match_operand 0 "" "")
386 (call (match_operand:QI 1 "memory_operand" "")
387 (match_operand 2 "" "")))]
390 gcc_assert (MEM_P (operands[1]));
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 "" "")))]
400 [(set_attr "length" "6")])
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 "" "")))]
410 (define_insn "indirect_jump"
411 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
417 (label_ref (match_operand 0 "" "")))]
420 [(set_attr "length" "6")])
423 ;; -------------------------------------------------------------------------
424 ;; Prologue & Epilogue
425 ;; -------------------------------------------------------------------------
427 (define_expand "prologue"
428 [(clobber (const_int 0))]
432 moxie_expand_prologue ();
437 (define_expand "epilogue"
442 moxie_expand_epilogue ();
447 (define_insn "returner"