xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/moxie/moxie.md (revision 63aea4bd5b445e491ff0389fe27ec78b3099dba3)
1;; Machine description for Moxie
2;; Copyright (C) 2009-2013 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")
451