xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/rl78/rl78-expand.md (revision 1580a27b92f58fcdcb23fdfbc04a7c2b54a0b7c8)
1;;  Machine Description for Renesas RL78 processors
2;;  Copyright (C) 2011-2015 Free Software Foundation, Inc.
3;;  Contributed by Red Hat.
4
5;; This file is part of GCC.
6
7;; GCC is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 3, or (at your option)
10;; any later version.
11
12;; GCC is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15;; GNU General Public 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;;---------- Moving ------------------------
22
23(define_expand "movqi"
24  [(set (match_operand:QI 0 "nonimmediate_operand")
25	(match_operand:QI 1 "general_operand"))]
26  ""
27  {
28    if (MEM_P (operands[0]) && MEM_P (operands[1]))
29      operands[1] = copy_to_mode_reg (QImode, operands[1]);
30    if (rl78_far_p (operands[0]) && rl78_far_p (operands[1]))
31      operands[1] = copy_to_mode_reg (QImode, operands[1]);
32
33    /* GCC can generate (SUBREG (SYMBOL_REF)) when it has to store a symbol
34       into a bitfield, or a packed ordinary field.  We can handle this
35       provided that the destination is a register.  If not, then load the
36       source into a register first.  */
37    if (GET_CODE (operands[1]) == SUBREG
38        && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
39	&& ! REG_P (operands[0]))
40	operands[1] = copy_to_mode_reg (QImode, operands[1]);
41
42    /* Similarly for (SUBREG (CONST (PLUS (SYMBOL_REF)))).
43       cf. g++.dg/abi/packed.C.  */
44    if (GET_CODE (operands[1]) == SUBREG
45	&& GET_CODE (XEXP (operands[1], 0)) == CONST
46        && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == PLUS
47        && GET_CODE (XEXP (XEXP (XEXP (operands[1], 0), 0), 0)) == SYMBOL_REF
48	&& ! REG_P (operands[0]))
49	operands[1] = copy_to_mode_reg (QImode, operands[1]);
50
51    if (CONST_INT_P (operands[1]) && ! IN_RANGE (INTVAL (operands[1]), (-1 << 8) + 1, (1 << 8) - 1))
52      FAIL;
53  }
54)
55
56(define_expand "movhi"
57  [(set (match_operand:HI 0 "nonimmediate_operand")
58	(match_operand:HI 1 "general_operand"))]
59  ""
60  {
61    if (MEM_P (operands[0]) && MEM_P (operands[1]))
62      operands[1] = copy_to_mode_reg (HImode, operands[1]);
63    if (rl78_far_p (operands[0]) && rl78_far_p (operands[1]))
64      operands[1] = copy_to_mode_reg (HImode, operands[1]);
65
66    /* FIXME: Not sure how GCC can generate (SUBREG (SYMBOL_REF)),
67       but it does.  Since this makes no sense, reject it here.  */
68    if (GET_CODE (operands[1]) == SUBREG
69        && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
70      FAIL;
71    /* Similarly for (SUBREG (CONST (PLUS (SYMBOL_REF)))).  */
72    if (GET_CODE (operands[1]) == SUBREG
73	&& GET_CODE (XEXP (operands[1], 0)) == CONST
74        && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == PLUS
75        && GET_CODE (XEXP (XEXP (XEXP (operands[1], 0), 0), 0)) == SYMBOL_REF)
76      FAIL;
77  }
78)
79
80(define_insn_and_split "movsi"
81  [(set (match_operand:SI 0 "nonimmediate_operand" "=vYS,v,Wfr")
82	(match_operand:SI 1 "general_operand" "viYS,Wfr,v"))]
83  ""
84  "#"
85  ""
86  [(set (match_operand:HI 2 "nonimmediate_operand")
87	(match_operand:HI 4 "general_operand"))
88   (set (match_operand:HI 3 "nonimmediate_operand")
89	(match_operand:HI 5 "general_operand"))]
90  "rl78_split_movsi (operands, SImode);"
91  [(set_attr "valloc" "op1")]
92)
93
94(define_insn_and_split "movsf"
95  [(set (match_operand:SF 0 "nonimmediate_operand" "=vYS,v,Wfr")
96	(match_operand:SF 1 "general_operand" "viYS,Wfr,v"))]
97  ""
98  "#"
99  ""
100  [(set (match_operand:HI 2 "nonimmediate_operand")
101	(match_operand:HI 4 "general_operand"))
102   (set (match_operand:HI 3 "nonimmediate_operand")
103	(match_operand:HI 5 "general_operand"))]
104  "rl78_split_movsi (operands, SFmode);"
105  [(set_attr "valloc" "op1")]
106)
107
108;;---------- Conversions ------------------------
109
110(define_expand "zero_extendqihi2"
111  [(set (match_operand:HI                 0 "nonimmediate_operand")
112	(zero_extend:HI (match_operand:QI 1 "general_operand")))]
113  ""
114  "if (rl78_force_nonfar_2 (operands, gen_zero_extendqihi2))
115     DONE;"
116  )
117
118(define_expand "extendqihi2"
119  [(set (match_operand:HI                 0 "nonimmediate_operand")
120	(sign_extend:HI (match_operand:QI 1 "general_operand")))]
121  ""
122  "if (rl78_force_nonfar_2 (operands, gen_extendqihi2))
123     DONE;"
124  )
125
126;;---------- Arithmetic ------------------------
127
128(define_expand "add<mode>3"
129  [(set (match_operand:QHI           0 "nonimmediate_operand")
130	(plus:QHI (match_operand:QHI 1 "general_operand")
131		  (match_operand:QHI 2 "general_operand")))
132   ]
133  ""
134  "if (rl78_force_nonfar_3 (operands, gen_add<mode>3))
135     DONE;"
136)
137
138(define_expand "sub<mode>3"
139  [(set (match_operand:QHI            0 "nonimmediate_operand")
140	(minus:QHI (match_operand:QHI 1 "general_operand")
141		   (match_operand:QHI 2 "general_operand")))
142   ]
143  ""
144  "if (rl78_force_nonfar_3 (operands, gen_sub<mode>3))
145     DONE;"
146)
147
148(define_expand "neg<mode>2"
149  [(set (match_operand:QHI            0 "nonimmediate_operand")
150	(minus:QHI (const_int 0)
151		   (match_operand:QHI 1 "general_operand")))
152   ]
153  ""
154  "if (rl78_force_nonfar_2 (operands, gen_neg<mode>2))
155     DONE;"
156)
157
158(define_expand "umulqihi3"
159  [(set (match_operand:HI 0 "register_operand")
160        (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand"))
161                 (zero_extend:HI (match_operand:QI 2 "register_operand"))))]
162  ""
163  ""
164)
165
166(define_expand "andqi3"
167  [(set (match_operand:QI         0 "rl78_nonimmediate_operand")
168	(and:QI (match_operand:QI 1 "rl78_general_operand")
169		(match_operand:QI 2 "rl78_general_operand")))
170   ]
171  ""
172  "if (rl78_force_nonfar_3 (operands, gen_andqi3))
173     DONE;"
174)
175
176(define_expand "iorqi3"
177  [(set (match_operand:QI         0 "rl78_nonimmediate_operand")
178	(ior:QI (match_operand:QI 1 "rl78_general_operand")
179		(match_operand:QI 2 "rl78_general_operand")))
180   ]
181  ""
182  "if (rl78_force_nonfar_3 (operands, gen_iorqi3))
183     DONE;"
184)
185
186(define_expand "xorqi3"
187  [(set (match_operand:QI         0 "rl78_nonimmediate_operand")
188	(xor:QI (match_operand:QI 1 "rl78_general_operand")
189		(match_operand:QI 2 "rl78_general_operand")))
190   ]
191  ""
192  "if (rl78_force_nonfar_3 (operands, gen_xorqi3))
193     DONE;"
194)
195
196(define_expand "one_cmplqi2"
197  [(set (match_operand:QI         0 "nonimmediate_operand")
198	(xor:QI (match_operand:QI 1 "general_operand")
199		(const_int -1)))
200   ]
201  ""
202  "if (rl78_force_nonfar_2 (operands, gen_one_cmplqi2))
203     DONE;"
204)
205
206;;---------- Shifts ------------------------
207
208(define_expand "ashl<mode>3"
209  [(set (match_operand:QHI             0 "nonimmediate_operand")
210	(ashift:QHI (match_operand:QHI 1 "general_operand")
211		    (match_operand:QI  2 "general_operand")))
212   ]
213  ""
214  "if (rl78_force_nonfar_3 (operands, gen_ashl<mode>3))
215     DONE;"
216)
217
218(define_expand "ashr<mode>3"
219  [(set (match_operand:QHI               0 "nonimmediate_operand")
220	(ashiftrt:QHI (match_operand:QHI 1 "general_operand")
221		      (match_operand:QI  2 "general_operand")))
222   ]
223  ""
224  "if (rl78_force_nonfar_3 (operands, gen_ashr<mode>3))
225     DONE;"
226)
227
228(define_expand "lshr<mode>3"
229  [(set (match_operand:QHI               0 "nonimmediate_operand")
230	(lshiftrt:QHI (match_operand:QHI 1 "general_operand")
231		      (match_operand:QI  2 "general_operand")))
232   ]
233  ""
234  "if (rl78_force_nonfar_3 (operands, gen_lshr<mode>3))
235     DONE;"
236)
237
238(define_expand "ashrsi3"
239  [(parallel [(set (match_operand:SI               0 "nonimmediate_operand")
240		   (ashiftrt:SI (match_operand:SI  1 "nonimmediate_operand")
241				(match_operand:SI  2 "nonmemory_operand")))
242	      (clobber (reg:HI X_REG))])
243   ]
244  ""
245  ""
246)
247
248(define_expand "lshrsi3"
249  [(parallel [(set (match_operand:SI               0 "nonimmediate_operand")
250		   (lshiftrt:SI (match_operand:SI  1 "nonimmediate_operand")
251				(match_operand:SI  2 "nonmemory_operand")))
252	      (clobber (reg:HI X_REG))])
253   ]
254  ""
255  ""
256)
257
258(define_expand "ashlsi3"
259  [(parallel [(set (match_operand:SI            0 "nonimmediate_operand")
260		   (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
261			      (match_operand:SI 2 "nonmemory_operand")))
262	      (clobber (reg:HI X_REG))])
263   ]
264  ""
265  ""
266)
267
268;;---------- Branching ------------------------
269
270(define_expand "indirect_jump"
271  [(set (pc)
272	(match_operand:HI 0 "nonimmediate_operand"))]
273  ""
274  ""
275)
276
277(define_expand "call"
278  [(call (match_operand:HI 0 "memory_operand")
279	 (match_operand 1 ""))]
280  ""
281  ""
282)
283
284(define_expand "call_value"
285  [(set (match_operand          0 "register_operand")
286	(call (match_operand:HI 1 "memory_operand")
287	      (match_operand    2 "")))]
288  ""
289  ""
290)
291
292(define_expand "cbranchqi4"
293  [(set (pc) (if_then_else
294	      (match_operator                    0 "rl78_cmp_operator"
295			      [(match_operand:QI 1 "general_operand")
296			       (match_operand:QI 2 "general_operand")])
297              (label_ref (match_operand 3 "" ""))
298	      (pc)))]
299  ""
300  "rl78_expand_compare (operands);"
301)
302
303(define_expand "cbranchhi4"
304  [(set (pc) (if_then_else
305	      (match_operator                    0 "rl78_cmp_operator"
306			      [(match_operand:HI 1 "general_operand")
307			       (match_operand:HI 2 "general_operand")])
308              (label_ref (match_operand 3 "" ""))
309	      (pc)))]
310  ""
311  "rl78_expand_compare (operands);"
312)
313
314(define_expand "cbranchsi4"
315  [(parallel [(set (pc) (if_then_else
316			 (match_operator 0 "rl78_cmp_operator"
317					 [(match_operand:SI 1 "general_operand")
318					  (match_operand:SI 2 "nonmemory_operand")])
319			 (label_ref (match_operand 3 "" ""))
320			 (pc)))
321	      (clobber (reg:HI AX_REG))
322	      ])]
323  "1"
324  "rl78_expand_compare (operands);"
325)
326