0
|
1 ;; GCC machine description for CRX.
|
|
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
|
3 ;; 2001, 2002, 2003, 2004, 2007
|
|
4 ;; Free Software Foundation, Inc.
|
|
5 ;;
|
|
6 ;; This file is part of GCC.
|
|
7 ;;
|
|
8 ;; GCC is free software; you can redistribute it and/or modify
|
|
9 ;; it under the terms of the GNU General Public License as published by
|
|
10 ;; the Free Software Foundation; either version 3, or (at your option)
|
|
11 ;; any later version.
|
|
12 ;;
|
|
13 ;; GCC is distributed in the hope that it will be useful,
|
|
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16 ;; GNU General Public License for more details.
|
|
17 ;;
|
|
18 ;; You should have received a copy of the GNU General Public License
|
|
19 ;; along with GCC; see the file COPYING3. If not see
|
|
20 ;; <http://www.gnu.org/licenses/>. */
|
|
21
|
|
22 ;; Register numbers
|
|
23
|
|
24 (define_constants
|
|
25 [(SP_REGNUM 15) ; Stack pointer
|
|
26 (RA_REGNUM 14) ; Return address
|
|
27 (LO_REGNUM 16) ; LO register
|
|
28 (HI_REGNUM 17) ; HI register
|
|
29 (CC_REGNUM 18) ; Condition code register
|
|
30 ]
|
|
31 )
|
|
32
|
|
33 (define_attr "length" "" ( const_int 6 ))
|
|
34
|
|
35 (define_asm_attributes
|
|
36 [(set_attr "length" "6")]
|
|
37 )
|
|
38
|
|
39 ;; Predicates
|
|
40
|
|
41 (define_predicate "u4bits_operand"
|
|
42 (match_code "const_int,const_double")
|
|
43 {
|
|
44 if (GET_CODE (op) == CONST_DOUBLE)
|
|
45 return crx_const_double_ok (op);
|
|
46 return (UNSIGNED_INT_FITS_N_BITS(INTVAL(op), 4)) ? 1 : 0;
|
|
47 }
|
|
48 )
|
|
49
|
|
50 (define_predicate "cst4_operand"
|
|
51 (and (match_code "const_int")
|
|
52 (match_test "INT_CST4(INTVAL(op))")))
|
|
53
|
|
54 (define_predicate "reg_or_u4bits_operand"
|
|
55 (ior (match_operand 0 "u4bits_operand")
|
|
56 (match_operand 0 "register_operand")))
|
|
57
|
|
58 (define_predicate "reg_or_cst4_operand"
|
|
59 (ior (match_operand 0 "cst4_operand")
|
|
60 (match_operand 0 "register_operand")))
|
|
61
|
|
62 (define_predicate "reg_or_sym_operand"
|
|
63 (ior (match_code "symbol_ref")
|
|
64 (match_operand 0 "register_operand")))
|
|
65
|
|
66 (define_predicate "nosp_reg_operand"
|
|
67 (and (match_operand 0 "register_operand")
|
|
68 (match_test "REGNO (op) != SP_REGNUM")))
|
|
69
|
|
70 (define_predicate "store_operand"
|
|
71 (and (match_operand 0 "memory_operand")
|
|
72 (not (match_operand 0 "push_operand"))))
|
|
73
|
|
74 ;; Mode Macro Definitions
|
|
75
|
|
76 (define_mode_iterator ALLMT [QI HI SI SF DI DF])
|
|
77 (define_mode_iterator CRXMM [QI HI SI SF])
|
|
78 (define_mode_iterator CRXIM [QI HI SI])
|
|
79 (define_mode_iterator DIDFM [DI DF])
|
|
80 (define_mode_iterator SISFM [SI SF])
|
|
81 (define_mode_iterator SHORT [QI HI])
|
|
82
|
|
83 (define_mode_attr tIsa [(QI "b") (HI "w") (SI "d") (SF "d")])
|
|
84 (define_mode_attr lImmArith [(QI "4") (HI "4") (SI "6")])
|
|
85 (define_mode_attr lImmRotl [(QI "2") (HI "2") (SI "4")])
|
|
86 (define_mode_attr IJK [(QI "I") (HI "J") (SI "K")])
|
|
87 (define_mode_attr iF [(QI "i") (HI "i") (SI "i") (DI "i") (SF "F") (DF "F")])
|
|
88 (define_mode_attr JG [(QI "J") (HI "J") (SI "J") (DI "J") (SF "G") (DF "G")])
|
|
89 ; In HI or QI mode we push 4 bytes.
|
|
90 (define_mode_attr pushCnstr [(QI "X") (HI "X") (SI "<") (SF "<") (DI "<") (DF "<")])
|
|
91 (define_mode_attr tpush [(QI "") (HI "") (SI "") (SF "") (DI "sp, ") (DF "sp, ")])
|
|
92 (define_mode_attr lpush [(QI "2") (HI "2") (SI "2") (SF "2") (DI "4") (DF "4")])
|
|
93
|
|
94
|
|
95 ;; Code Macro Definitions
|
|
96
|
|
97 (define_code_iterator sz_xtnd [sign_extend zero_extend])
|
|
98 (define_code_attr sIsa [(sign_extend "") (zero_extend "u")])
|
|
99 (define_code_attr sPat [(sign_extend "s") (zero_extend "u")])
|
|
100 (define_code_attr szPat [(sign_extend "") (zero_extend "zero_")])
|
|
101 (define_code_attr szIsa [(sign_extend "s") (zero_extend "z")])
|
|
102
|
|
103 (define_code_iterator sh_oprnd [ashift ashiftrt lshiftrt])
|
|
104 (define_code_attr shIsa [(ashift "ll") (ashiftrt "ra") (lshiftrt "rl")])
|
|
105 (define_code_attr shPat [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr")])
|
|
106
|
|
107 (define_code_iterator mima_oprnd [smax umax smin umin])
|
|
108 (define_code_attr mimaIsa [(smax "maxs") (umax "maxu") (smin "mins") (umin "minu")])
|
|
109
|
|
110 (define_code_iterator any_cond [eq ne gt gtu lt ltu ge geu le leu])
|
|
111
|
|
112 ;; Addition Instructions
|
|
113
|
|
114 (define_insn "adddi3"
|
|
115 [(set (match_operand:DI 0 "register_operand" "=r,r")
|
|
116 (plus:DI (match_operand:DI 1 "register_operand" "%0,0")
|
|
117 (match_operand:DI 2 "nonmemory_operand" "r,i")))
|
|
118 (clobber (reg:CC CC_REGNUM))]
|
|
119 ""
|
|
120 "addd\t%L2, %L1\;addcd\t%H2, %H1"
|
|
121 [(set_attr "length" "4,12")]
|
|
122 )
|
|
123
|
|
124 (define_insn "add<mode>3"
|
|
125 [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
|
|
126 (plus:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0")
|
|
127 (match_operand:CRXIM 2 "nonmemory_operand" "r,i")))
|
|
128 (clobber (reg:CC CC_REGNUM))]
|
|
129 ""
|
|
130 "add<tIsa>\t%2, %0"
|
|
131 [(set_attr "length" "2,<lImmArith>")]
|
|
132 )
|
|
133
|
|
134 ;; Subtract Instructions
|
|
135
|
|
136 (define_insn "subdi3"
|
|
137 [(set (match_operand:DI 0 "register_operand" "=r,r")
|
|
138 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
|
|
139 (match_operand:DI 2 "nonmemory_operand" "r,i")))
|
|
140 (clobber (reg:CC CC_REGNUM))]
|
|
141 ""
|
|
142 "subd\t%L2, %L1\;subcd\t%H2, %H1"
|
|
143 [(set_attr "length" "4,12")]
|
|
144 )
|
|
145
|
|
146 (define_insn "sub<mode>3"
|
|
147 [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
|
|
148 (minus:CRXIM (match_operand:CRXIM 1 "register_operand" "0,0")
|
|
149 (match_operand:CRXIM 2 "nonmemory_operand" "r,i")))
|
|
150 (clobber (reg:CC CC_REGNUM))]
|
|
151 ""
|
|
152 "sub<tIsa>\t%2, %0"
|
|
153 [(set_attr "length" "2,<lImmArith>")]
|
|
154 )
|
|
155
|
|
156 ;; Multiply Instructions
|
|
157
|
|
158 (define_insn "mul<mode>3"
|
|
159 [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
|
|
160 (mult:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0")
|
|
161 (match_operand:CRXIM 2 "nonmemory_operand" "r,i")))
|
|
162 (clobber (reg:CC CC_REGNUM))]
|
|
163 ""
|
|
164 "mul<tIsa>\t%2, %0"
|
|
165 [(set_attr "length" "2,<lImmArith>")]
|
|
166 )
|
|
167
|
|
168 ;; Widening-multiplication Instructions
|
|
169
|
|
170 (define_insn "<sIsa>mulsidi3"
|
|
171 [(set (match_operand:DI 0 "register_operand" "=k")
|
|
172 (mult:DI (sz_xtnd:DI (match_operand:SI 1 "register_operand" "%r"))
|
|
173 (sz_xtnd:DI (match_operand:SI 2 "register_operand" "r"))))
|
|
174 (clobber (reg:CC CC_REGNUM))]
|
|
175 ""
|
|
176 "mull<sPat>d\t%2, %1"
|
|
177 [(set_attr "length" "4")]
|
|
178 )
|
|
179
|
|
180 (define_insn "<sIsa>mulhisi3"
|
|
181 [(set (match_operand:SI 0 "register_operand" "=r")
|
|
182 (mult:SI (sz_xtnd:SI (match_operand:HI 1 "register_operand" "%0"))
|
|
183 (sz_xtnd:SI (match_operand:HI 2 "register_operand" "r"))))
|
|
184 (clobber (reg:CC CC_REGNUM))]
|
|
185 ""
|
|
186 "mul<sPat>wd\t%2, %0"
|
|
187 [(set_attr "length" "4")]
|
|
188 )
|
|
189
|
|
190 (define_insn "<sIsa>mulqihi3"
|
|
191 [(set (match_operand:HI 0 "register_operand" "=r")
|
|
192 (mult:HI (sz_xtnd:HI (match_operand:QI 1 "register_operand" "%0"))
|
|
193 (sz_xtnd:HI (match_operand:QI 2 "register_operand" "r"))))
|
|
194 (clobber (reg:CC CC_REGNUM))]
|
|
195 ""
|
|
196 "mul<sPat>bw\t%2, %0"
|
|
197 [(set_attr "length" "4")]
|
|
198 )
|
|
199
|
|
200 ;; Logical Instructions - and
|
|
201
|
|
202 (define_insn "and<mode>3"
|
|
203 [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
|
|
204 (and:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0")
|
|
205 (match_operand:CRXIM 2 "nonmemory_operand" "r,i")))
|
|
206 (clobber (reg:CC CC_REGNUM))]
|
|
207 ""
|
|
208 "and<tIsa>\t%2, %0"
|
|
209 [(set_attr "length" "2,<lImmArith>")]
|
|
210 )
|
|
211
|
|
212 ;; Logical Instructions - or
|
|
213
|
|
214 (define_insn "ior<mode>3"
|
|
215 [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
|
|
216 (ior:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0")
|
|
217 (match_operand:CRXIM 2 "nonmemory_operand" "r,i")))
|
|
218 (clobber (reg:CC CC_REGNUM))]
|
|
219 ""
|
|
220 "or<tIsa>\t%2, %0"
|
|
221 [(set_attr "length" "2,<lImmArith>")]
|
|
222 )
|
|
223
|
|
224 ;; Logical Instructions - xor
|
|
225
|
|
226 (define_insn "xor<mode>3"
|
|
227 [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
|
|
228 (xor:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0")
|
|
229 (match_operand:CRXIM 2 "nonmemory_operand" "r,i")))
|
|
230 (clobber (reg:CC CC_REGNUM))]
|
|
231 ""
|
|
232 "xor<tIsa>\t%2, %0"
|
|
233 [(set_attr "length" "2,<lImmArith>")]
|
|
234 )
|
|
235
|
|
236 ;; Sign and Zero Extend Instructions
|
|
237
|
|
238 (define_insn "<szPat>extendhisi2"
|
|
239 [(set (match_operand:SI 0 "register_operand" "=r")
|
|
240 (sz_xtnd:SI (match_operand:HI 1 "register_operand" "r")))
|
|
241 (clobber (reg:CC CC_REGNUM))]
|
|
242 ""
|
|
243 "<szIsa>extwd\t%1, %0"
|
|
244 [(set_attr "length" "4")]
|
|
245 )
|
|
246
|
|
247 (define_insn "<szPat>extendqisi2"
|
|
248 [(set (match_operand:SI 0 "register_operand" "=r")
|
|
249 (sz_xtnd:SI (match_operand:QI 1 "register_operand" "r")))
|
|
250 (clobber (reg:CC CC_REGNUM))]
|
|
251 ""
|
|
252 "<szIsa>extbd\t%1, %0"
|
|
253 [(set_attr "length" "4")]
|
|
254 )
|
|
255
|
|
256 (define_insn "<szPat>extendqihi2"
|
|
257 [(set (match_operand:HI 0 "register_operand" "=r")
|
|
258 (sz_xtnd:HI (match_operand:QI 1 "register_operand" "r")))
|
|
259 (clobber (reg:CC CC_REGNUM))]
|
|
260 ""
|
|
261 "<szIsa>extbw\t%1, %0"
|
|
262 [(set_attr "length" "4")]
|
|
263 )
|
|
264
|
|
265 ;; Negation Instructions
|
|
266
|
|
267 (define_insn "neg<mode>2"
|
|
268 [(set (match_operand:CRXIM 0 "register_operand" "=r")
|
|
269 (neg:CRXIM (match_operand:CRXIM 1 "register_operand" "r")))
|
|
270 (clobber (reg:CC CC_REGNUM))]
|
|
271 ""
|
|
272 "neg<tIsa>\t%1, %0"
|
|
273 [(set_attr "length" "4")]
|
|
274 )
|
|
275
|
|
276 ;; Absolute Instructions
|
|
277
|
|
278 (define_insn "abs<mode>2"
|
|
279 [(set (match_operand:CRXIM 0 "register_operand" "=r")
|
|
280 (abs:CRXIM (match_operand:CRXIM 1 "register_operand" "r")))
|
|
281 (clobber (reg:CC CC_REGNUM))]
|
|
282 ""
|
|
283 "abs<tIsa>\t%1, %0"
|
|
284 [(set_attr "length" "4")]
|
|
285 )
|
|
286
|
|
287 ;; Max and Min Instructions
|
|
288
|
|
289 (define_insn "<code><mode>3"
|
|
290 [(set (match_operand:CRXIM 0 "register_operand" "=r")
|
|
291 (mima_oprnd:CRXIM (match_operand:CRXIM 1 "register_operand" "%0")
|
|
292 (match_operand:CRXIM 2 "register_operand" "r")))]
|
|
293 ""
|
|
294 "<mimaIsa><tIsa>\t%2, %0"
|
|
295 [(set_attr "length" "4")]
|
|
296 )
|
|
297
|
|
298 ;; One's Complement
|
|
299
|
|
300 (define_insn "one_cmpl<mode>2"
|
|
301 [(set (match_operand:CRXIM 0 "register_operand" "=r")
|
|
302 (not:CRXIM (match_operand:CRXIM 1 "register_operand" "0")))
|
|
303 (clobber (reg:CC CC_REGNUM))]
|
|
304 ""
|
|
305 "xor<tIsa>\t$-1, %0"
|
|
306 [(set_attr "length" "2")]
|
|
307 )
|
|
308
|
|
309 ;; Rotate Instructions
|
|
310
|
|
311 (define_insn "rotl<mode>3"
|
|
312 [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
|
|
313 (rotate:CRXIM (match_operand:CRXIM 1 "register_operand" "0,0")
|
|
314 (match_operand:CRXIM 2 "nonmemory_operand" "r,<IJK>")))
|
|
315 (clobber (reg:CC CC_REGNUM))]
|
|
316 ""
|
|
317 "@
|
|
318 rotl<tIsa>\t%2, %0
|
|
319 rot<tIsa>\t%2, %0"
|
|
320 [(set_attr "length" "4,<lImmRotl>")]
|
|
321 )
|
|
322
|
|
323 (define_insn "rotr<mode>3"
|
|
324 [(set (match_operand:CRXIM 0 "register_operand" "=r")
|
|
325 (rotatert:CRXIM (match_operand:CRXIM 1 "register_operand" "0")
|
|
326 (match_operand:CRXIM 2 "register_operand" "r")))
|
|
327 (clobber (reg:CC CC_REGNUM))]
|
|
328 ""
|
|
329 "rotr<tIsa>\t%2, %0"
|
|
330 [(set_attr "length" "4")]
|
|
331 )
|
|
332
|
|
333 ;; Arithmetic Left and Right Shift Instructions
|
|
334
|
|
335 (define_insn "<shPat><mode>3"
|
|
336 [(set (match_operand:CRXIM 0 "register_operand" "=r,r")
|
|
337 (sh_oprnd:CRXIM (match_operand:CRXIM 1 "register_operand" "0,0")
|
|
338 (match_operand:QI 2 "nonmemory_operand" "r,<IJK>")))
|
|
339 (clobber (reg:CC CC_REGNUM))]
|
|
340 ""
|
|
341 "s<shIsa><tIsa>\t%2, %0"
|
|
342 [(set_attr "length" "2,2")]
|
|
343 )
|
|
344
|
|
345 ;; Bit Set Instructions
|
|
346
|
|
347 (define_insn "extv"
|
|
348 [(set (match_operand:SI 0 "register_operand" "=r")
|
|
349 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
|
|
350 (match_operand:SI 2 "const_int_operand" "n")
|
|
351 (match_operand:SI 3 "const_int_operand" "n")))]
|
|
352 ""
|
|
353 {
|
|
354 static char buf[100];
|
|
355 int strpntr;
|
|
356 int size = INTVAL (operands[2]);
|
|
357 int pos = INTVAL (operands[3]);
|
|
358 strpntr = sprintf (buf, "ram\t$%d, $31, $%d, %%1, %%0\;",
|
|
359 BITS_PER_WORD - (size + pos), BITS_PER_WORD - size);
|
|
360 sprintf (buf + strpntr, "srad\t$%d, %%0", BITS_PER_WORD - size);
|
|
361 return buf;
|
|
362 }
|
|
363 [(set_attr "length" "6")]
|
|
364 )
|
|
365
|
|
366 (define_insn "extzv"
|
|
367 [(set (match_operand:SI 0 "register_operand" "=r")
|
|
368 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
|
|
369 (match_operand:SI 2 "const_int_operand" "n")
|
|
370 (match_operand:SI 3 "const_int_operand" "n")))]
|
|
371 ""
|
|
372 {
|
|
373 static char buf[40];
|
|
374 int size = INTVAL (operands[2]);
|
|
375 int pos = INTVAL (operands[3]);
|
|
376 sprintf (buf, "ram\t$%d, $%d, $0, %%1, %%0",
|
|
377 (BITS_PER_WORD - pos) % BITS_PER_WORD, size - 1);
|
|
378 return buf;
|
|
379 }
|
|
380 [(set_attr "length" "4")]
|
|
381 )
|
|
382
|
|
383 (define_insn "insv"
|
|
384 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
|
|
385 (match_operand:SI 1 "const_int_operand" "n")
|
|
386 (match_operand:SI 2 "const_int_operand" "n"))
|
|
387 (match_operand:SI 3 "register_operand" "r"))]
|
|
388 ""
|
|
389 {
|
|
390 static char buf[40];
|
|
391 int size = INTVAL (operands[1]);
|
|
392 int pos = INTVAL (operands[2]);
|
|
393 sprintf (buf, "rim\t$%d, $%d, $%d, %%3, %%0",
|
|
394 pos, size + pos - 1, pos);
|
|
395 return buf;
|
|
396 }
|
|
397 [(set_attr "length" "4")]
|
|
398 )
|
|
399
|
|
400 ;; Move Instructions
|
|
401
|
|
402 (define_expand "mov<mode>"
|
|
403 [(set (match_operand:ALLMT 0 "nonimmediate_operand" "")
|
|
404 (match_operand:ALLMT 1 "general_operand" ""))]
|
|
405 ""
|
|
406 {
|
|
407 if (!(reload_in_progress || reload_completed))
|
|
408 {
|
|
409 if (!register_operand (operands[0], <MODE>mode))
|
|
410 {
|
|
411 if (push_operand (operands[0], <MODE>mode) ?
|
|
412 !nosp_reg_operand (operands[1], <MODE>mode) :
|
|
413 !reg_or_u4bits_operand (operands[1], <MODE>mode))
|
|
414 {
|
|
415 operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]);
|
|
416 }
|
|
417 }
|
|
418 }
|
|
419 }
|
|
420 )
|
|
421
|
|
422 (define_insn "push<mode>_internal"
|
|
423 [(set (match_operand:ALLMT 0 "push_operand" "=<pushCnstr>")
|
|
424 (match_operand:ALLMT 1 "nosp_reg_operand" "b"))]
|
|
425 ""
|
|
426 "push\t<tpush>%p1"
|
|
427 [(set_attr "length" "<lpush>")]
|
|
428 )
|
|
429
|
|
430 (define_insn "mov<mode>_regs"
|
|
431 [(set (match_operand:SISFM 0 "register_operand" "=r, r, r, k")
|
|
432 (match_operand:SISFM 1 "nonmemory_operand" "r, <iF>, k, r"))]
|
|
433 ""
|
|
434 "@
|
|
435 movd\t%1, %0
|
|
436 movd\t%1, %0
|
|
437 mfpr\t%1, %0
|
|
438 mtpr\t%1, %0"
|
|
439 [(set_attr "length" "2,6,4,4")]
|
|
440 )
|
|
441
|
|
442 (define_insn "mov<mode>_regs"
|
|
443 [(set (match_operand:DIDFM 0 "register_operand" "=r, r, r, k")
|
|
444 (match_operand:DIDFM 1 "nonmemory_operand" "r, <iF>, k, r"))]
|
|
445 ""
|
|
446 {
|
|
447 switch (which_alternative)
|
|
448 {
|
|
449 case 0: if (REGNO (operands[0]) > REGNO (operands[1]))
|
|
450 return "movd\t%H1, %H0\;movd\t%L1, %L0";
|
|
451 else
|
|
452 return "movd\t%L1, %L0\;movd\t%H1, %H0";
|
|
453 case 1: return "movd\t%H1, %H0\;movd\t%L1, %L0";
|
|
454 case 2: return "mfpr\t%H1, %H0\;mfpr\t%L1, %L0";
|
|
455 case 3: return "mtpr\t%H1, %H0\;mtpr\t%L1, %L0";
|
|
456 default: gcc_unreachable ();
|
|
457 }
|
|
458 }
|
|
459 [(set_attr "length" "4,12,8,8")]
|
|
460 )
|
|
461
|
|
462 (define_insn "mov<mode>_regs" ; no HI/QI mode in HILO regs
|
|
463 [(set (match_operand:SHORT 0 "register_operand" "=r, r")
|
|
464 (match_operand:SHORT 1 "nonmemory_operand" "r, i"))]
|
|
465 ""
|
|
466 "mov<tIsa>\t%1, %0"
|
|
467 [(set_attr "length" "2,<lImmArith>")]
|
|
468 )
|
|
469
|
|
470 (define_insn "mov<mode>_load"
|
|
471 [(set (match_operand:CRXMM 0 "register_operand" "=r")
|
|
472 (match_operand:CRXMM 1 "memory_operand" "m"))]
|
|
473 ""
|
|
474 "load<tIsa>\t%1, %0"
|
|
475 [(set_attr "length" "6")]
|
|
476 )
|
|
477
|
|
478 (define_insn "mov<mode>_load"
|
|
479 [(set (match_operand:DIDFM 0 "register_operand" "=r")
|
|
480 (match_operand:DIDFM 1 "memory_operand" "m"))]
|
|
481 ""
|
|
482 {
|
|
483 rtx first_dest_reg = gen_rtx_REG (SImode, REGNO (operands[0]));
|
|
484 if (reg_overlap_mentioned_p (first_dest_reg, operands[1]))
|
|
485 return "loadd\t%H1, %H0\;loadd\t%L1, %L0";
|
|
486 return "loadd\t%L1, %L0\;loadd\t%H1, %H0";
|
|
487 }
|
|
488 [(set_attr "length" "12")]
|
|
489 )
|
|
490
|
|
491 (define_insn "mov<mode>_store"
|
|
492 [(set (match_operand:CRXMM 0 "store_operand" "=m, m")
|
|
493 (match_operand:CRXMM 1 "reg_or_u4bits_operand" "r, <JG>"))]
|
|
494 ""
|
|
495 "stor<tIsa>\t%1, %0"
|
|
496 [(set_attr "length" "6")]
|
|
497 )
|
|
498
|
|
499 (define_insn "mov<mode>_store"
|
|
500 [(set (match_operand:DIDFM 0 "store_operand" "=m, m")
|
|
501 (match_operand:DIDFM 1 "reg_or_u4bits_operand" "r, <JG>"))]
|
|
502 ""
|
|
503 "stord\t%H1, %H0\;stord\t%L1, %L0"
|
|
504 [(set_attr "length" "12")]
|
|
505 )
|
|
506
|
|
507 ;; Movmem Instruction
|
|
508
|
|
509 (define_expand "movmemsi"
|
|
510 [(use (match_operand:BLK 0 "memory_operand" ""))
|
|
511 (use (match_operand:BLK 1 "memory_operand" ""))
|
|
512 (use (match_operand:SI 2 "nonmemory_operand" ""))
|
|
513 (use (match_operand:SI 3 "const_int_operand" ""))]
|
|
514 ""
|
|
515 {
|
|
516 if (crx_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
|
|
517 DONE;
|
|
518 else
|
|
519 FAIL;
|
|
520 }
|
|
521 )
|
|
522
|
|
523 ;; Compare and Branch Instructions
|
|
524
|
|
525 (define_insn "cbranch<mode>4"
|
|
526 [(set (pc)
|
|
527 (if_then_else (match_operator 0 "comparison_operator"
|
|
528 [(match_operand:CRXIM 1 "register_operand" "r")
|
|
529 (match_operand:CRXIM 2 "reg_or_cst4_operand" "rL")])
|
|
530 (label_ref (match_operand 3 "" ""))
|
|
531 (pc)))
|
|
532 (clobber (reg:CC CC_REGNUM))]
|
|
533 ""
|
|
534 "cmpb%d0<tIsa>\t%2, %1, %l3"
|
|
535 [(set_attr "length" "6")]
|
|
536 )
|
|
537
|
|
538 ;; Compare Instructions
|
|
539
|
|
540 (define_expand "cmp<mode>"
|
|
541 [(set (reg:CC CC_REGNUM)
|
|
542 (compare:CC (match_operand:CRXIM 0 "register_operand" "")
|
|
543 (match_operand:CRXIM 1 "nonmemory_operand" "")))]
|
|
544 ""
|
|
545 {
|
|
546 crx_compare_op0 = operands[0];
|
|
547 crx_compare_op1 = operands[1];
|
|
548 DONE;
|
|
549 }
|
|
550 )
|
|
551
|
|
552 (define_insn "cmp<mode>_internal"
|
|
553 [(set (reg:CC CC_REGNUM)
|
|
554 (compare:CC (match_operand:CRXIM 0 "register_operand" "r,r")
|
|
555 (match_operand:CRXIM 1 "nonmemory_operand" "r,i")))]
|
|
556 ""
|
|
557 "cmp<tIsa>\t%1, %0"
|
|
558 [(set_attr "length" "2,<lImmArith>")]
|
|
559 )
|
|
560
|
|
561 ;; Conditional Branch Instructions
|
|
562
|
|
563 (define_expand "b<code>"
|
|
564 [(set (pc)
|
|
565 (if_then_else (any_cond (reg:CC CC_REGNUM)
|
|
566 (const_int 0))
|
|
567 (label_ref (match_operand 0 ""))
|
|
568 (pc)))]
|
|
569 ""
|
|
570 {
|
|
571 crx_expand_branch (<CODE>, operands[0]);
|
|
572 DONE;
|
|
573 }
|
|
574 )
|
|
575
|
|
576 (define_insn "bCOND_internal"
|
|
577 [(set (pc)
|
|
578 (if_then_else (match_operator 0 "comparison_operator"
|
|
579 [(reg:CC CC_REGNUM)
|
|
580 (const_int 0)])
|
|
581 (label_ref (match_operand 1 ""))
|
|
582 (pc)))]
|
|
583 ""
|
|
584 "b%d0\t%l1"
|
|
585 [(set_attr "length" "6")]
|
|
586 )
|
|
587
|
|
588 ;; Scond Instructions
|
|
589
|
|
590 (define_expand "s<code>"
|
|
591 [(set (match_operand:SI 0 "register_operand")
|
|
592 (any_cond:SI (reg:CC CC_REGNUM) (const_int 0)))]
|
|
593 ""
|
|
594 {
|
|
595 crx_expand_scond (<CODE>, operands[0]);
|
|
596 DONE;
|
|
597 }
|
|
598 )
|
|
599
|
|
600 (define_insn "sCOND_internal"
|
|
601 [(set (match_operand:SI 0 "register_operand" "=r")
|
|
602 (match_operator:SI 1 "comparison_operator"
|
|
603 [(reg:CC CC_REGNUM) (const_int 0)]))]
|
|
604 ""
|
|
605 "s%d1\t%0"
|
|
606 [(set_attr "length" "2")]
|
|
607 )
|
|
608
|
|
609 ;; Jumps and Branches
|
|
610
|
|
611 (define_insn "indirect_jump_return"
|
|
612 [(parallel
|
|
613 [(set (pc)
|
|
614 (reg:SI RA_REGNUM))
|
|
615 (return)])
|
|
616 ]
|
|
617 "reload_completed"
|
|
618 "jump\tra"
|
|
619 [(set_attr "length" "2")]
|
|
620 )
|
|
621
|
|
622 (define_insn "indirect_jump"
|
|
623 [(set (pc)
|
|
624 (match_operand:SI 0 "reg_or_sym_operand" "r,i"))]
|
|
625 ""
|
|
626 "@
|
|
627 jump\t%0
|
|
628 br\t%a0"
|
|
629 [(set_attr "length" "2,6")]
|
|
630 )
|
|
631
|
|
632 (define_insn "interrupt_return"
|
|
633 [(parallel
|
|
634 [(unspec_volatile [(const_int 0)] 0)
|
|
635 (return)])]
|
|
636 ""
|
|
637 {
|
|
638 return crx_prepare_push_pop_string (1);
|
|
639 }
|
|
640 [(set_attr "length" "14")]
|
|
641 )
|
|
642
|
|
643 (define_insn "jump_to_imm"
|
|
644 [(set (pc)
|
|
645 (match_operand 0 "immediate_operand" "i"))]
|
|
646 ""
|
|
647 "br\t%c0"
|
|
648 [(set_attr "length" "6")]
|
|
649 )
|
|
650
|
|
651 (define_insn "jump"
|
|
652 [(set (pc)
|
|
653 (label_ref (match_operand 0 "" "")))]
|
|
654 ""
|
|
655 "br\t%l0"
|
|
656 [(set_attr "length" "6")]
|
|
657 )
|
|
658
|
|
659 ;; Function Prologue and Epilogue
|
|
660
|
|
661 (define_expand "prologue"
|
|
662 [(const_int 0)]
|
|
663 ""
|
|
664 {
|
|
665 crx_expand_prologue ();
|
|
666 DONE;
|
|
667 }
|
|
668 )
|
|
669
|
|
670 (define_insn "push_for_prologue"
|
|
671 [(parallel
|
|
672 [(set (reg:SI SP_REGNUM)
|
|
673 (minus:SI (reg:SI SP_REGNUM)
|
|
674 (match_operand:SI 0 "immediate_operand" "i")))])]
|
|
675 "reload_completed"
|
|
676 {
|
|
677 return crx_prepare_push_pop_string (0);
|
|
678 }
|
|
679 [(set_attr "length" "4")]
|
|
680 )
|
|
681
|
|
682 (define_expand "epilogue"
|
|
683 [(return)]
|
|
684 ""
|
|
685 {
|
|
686 crx_expand_epilogue ();
|
|
687 DONE;
|
|
688 }
|
|
689 )
|
|
690
|
|
691 (define_insn "pop_and_popret_return"
|
|
692 [(parallel
|
|
693 [(set (reg:SI SP_REGNUM)
|
|
694 (plus:SI (reg:SI SP_REGNUM)
|
|
695 (match_operand:SI 0 "immediate_operand" "i")))
|
|
696 (use (reg:SI RA_REGNUM))
|
|
697 (return)])
|
|
698 ]
|
|
699 "reload_completed"
|
|
700 {
|
|
701 return crx_prepare_push_pop_string (1);
|
|
702 }
|
|
703 [(set_attr "length" "4")]
|
|
704 )
|
|
705
|
|
706 (define_insn "popret_RA_return"
|
|
707 [(parallel
|
|
708 [(use (reg:SI RA_REGNUM))
|
|
709 (return)])
|
|
710 ]
|
|
711 "reload_completed"
|
|
712 "popret\tra"
|
|
713 [(set_attr "length" "2")]
|
|
714 )
|
|
715
|
|
716 ;; Table Jump
|
|
717
|
|
718 (define_insn "tablejump"
|
|
719 [(set (pc)
|
|
720 (match_operand:SI 0 "register_operand" "r"))
|
|
721 (use (label_ref:SI (match_operand 1 "" "" )))]
|
|
722 ""
|
|
723 "jump\t%0"
|
|
724 [(set_attr "length" "2")]
|
|
725 )
|
|
726
|
|
727 ;; Call Instructions
|
|
728
|
|
729 (define_expand "call"
|
|
730 [(call (match_operand:QI 0 "memory_operand" "")
|
|
731 (match_operand 1 "" ""))]
|
|
732 ""
|
|
733 {
|
|
734 emit_call_insn (gen_crx_call (operands[0], operands[1]));
|
|
735 DONE;
|
|
736 }
|
|
737 )
|
|
738
|
|
739 (define_expand "crx_call"
|
|
740 [(parallel
|
|
741 [(call (match_operand:QI 0 "memory_operand" "")
|
|
742 (match_operand 1 "" ""))
|
|
743 (clobber (reg:SI RA_REGNUM))])]
|
|
744 ""
|
|
745 ""
|
|
746 )
|
|
747
|
|
748 (define_insn "crx_call_insn_branch"
|
|
749 [(call (mem:QI (match_operand:SI 0 "immediate_operand" "i"))
|
|
750 (match_operand 1 "" ""))
|
|
751 (clobber (match_operand:SI 2 "register_operand" "+r"))]
|
|
752 ""
|
|
753 "bal\tra, %a0"
|
|
754 [(set_attr "length" "6")]
|
|
755 )
|
|
756
|
|
757 (define_insn "crx_call_insn_jump"
|
|
758 [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
|
|
759 (match_operand 1 "" ""))
|
|
760 (clobber (match_operand:SI 2 "register_operand" "+r"))]
|
|
761 ""
|
|
762 "jal\t%0"
|
|
763 [(set_attr "length" "2")]
|
|
764 )
|
|
765
|
|
766 (define_insn "crx_call_insn_jalid"
|
|
767 [(call (mem:QI (mem:SI (plus:SI
|
|
768 (match_operand:SI 0 "register_operand" "r")
|
|
769 (match_operand:SI 1 "register_operand" "r"))))
|
|
770 (match_operand 2 "" ""))
|
|
771 (clobber (match_operand:SI 3 "register_operand" "+r"))]
|
|
772 ""
|
|
773 "jalid\t%0, %1"
|
|
774 [(set_attr "length" "4")]
|
|
775 )
|
|
776
|
|
777 ;; Call Value Instructions
|
|
778
|
|
779 (define_expand "call_value"
|
|
780 [(set (match_operand 0 "general_operand" "")
|
|
781 (call (match_operand:QI 1 "memory_operand" "")
|
|
782 (match_operand 2 "" "")))]
|
|
783 ""
|
|
784 {
|
|
785 emit_call_insn (gen_crx_call_value (operands[0], operands[1], operands[2]));
|
|
786 DONE;
|
|
787 }
|
|
788 )
|
|
789
|
|
790 (define_expand "crx_call_value"
|
|
791 [(parallel
|
|
792 [(set (match_operand 0 "general_operand" "")
|
|
793 (call (match_operand 1 "memory_operand" "")
|
|
794 (match_operand 2 "" "")))
|
|
795 (clobber (reg:SI RA_REGNUM))])]
|
|
796 ""
|
|
797 ""
|
|
798 )
|
|
799
|
|
800 (define_insn "crx_call_value_insn_branch"
|
|
801 [(set (match_operand 0 "" "=g")
|
|
802 (call (mem:QI (match_operand:SI 1 "immediate_operand" "i"))
|
|
803 (match_operand 2 "" "")))
|
|
804 (clobber (match_operand:SI 3 "register_operand" "+r"))]
|
|
805 ""
|
|
806 "bal\tra, %a1"
|
|
807 [(set_attr "length" "6")]
|
|
808 )
|
|
809
|
|
810 (define_insn "crx_call_value_insn_jump"
|
|
811 [(set (match_operand 0 "" "=g")
|
|
812 (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
|
|
813 (match_operand 2 "" "")))
|
|
814 (clobber (match_operand:SI 3 "register_operand" "+r"))]
|
|
815 ""
|
|
816 "jal\t%1"
|
|
817 [(set_attr "length" "2")]
|
|
818 )
|
|
819
|
|
820 (define_insn "crx_call_value_insn_jalid"
|
|
821 [(set (match_operand 0 "" "=g")
|
|
822 (call (mem:QI (mem:SI (plus:SI
|
|
823 (match_operand:SI 1 "register_operand" "r")
|
|
824 (match_operand:SI 2 "register_operand" "r"))))
|
|
825 (match_operand 3 "" "")))
|
|
826 (clobber (match_operand:SI 4 "register_operand" "+r"))]
|
|
827 ""
|
|
828 "jalid\t%0, %1"
|
|
829 [(set_attr "length" "4")]
|
|
830 )
|
|
831
|
|
832 ;; Nop
|
|
833
|
|
834 (define_insn "nop"
|
|
835 [(const_int 0)]
|
|
836 ""
|
|
837 ""
|
|
838 )
|
|
839
|
|
840 ;; Multiply and Accumulate Instructions
|
|
841
|
|
842 (define_insn "<sPat>madsidi3"
|
|
843 [(set (match_operand:DI 0 "register_operand" "+k")
|
|
844 (plus:DI
|
|
845 (mult:DI (sz_xtnd:DI (match_operand:SI 1 "register_operand" "%r"))
|
|
846 (sz_xtnd:DI (match_operand:SI 2 "register_operand" "r")))
|
|
847 (match_dup 0)))
|
|
848 (clobber (reg:CC CC_REGNUM))]
|
|
849 "TARGET_MAC"
|
|
850 "mac<sPat>d\t%2, %1"
|
|
851 [(set_attr "length" "4")]
|
|
852 )
|
|
853
|
|
854 (define_insn "<sPat>madhisi3"
|
|
855 [(set (match_operand:SI 0 "register_operand" "+l")
|
|
856 (plus:SI
|
|
857 (mult:SI (sz_xtnd:SI (match_operand:HI 1 "register_operand" "%r"))
|
|
858 (sz_xtnd:SI (match_operand:HI 2 "register_operand" "r")))
|
|
859 (match_dup 0)))
|
|
860 (clobber (reg:CC CC_REGNUM))]
|
|
861 "TARGET_MAC"
|
|
862 "mac<sPat>w\t%2, %1"
|
|
863 [(set_attr "length" "4")]
|
|
864 )
|
|
865
|
|
866 (define_insn "<sPat>madqihi3"
|
|
867 [(set (match_operand:HI 0 "register_operand" "+l")
|
|
868 (plus:HI
|
|
869 (mult:HI (sz_xtnd:HI (match_operand:QI 1 "register_operand" "%r"))
|
|
870 (sz_xtnd:HI (match_operand:QI 2 "register_operand" "r")))
|
|
871 (match_dup 0)))
|
|
872 (clobber (reg:CC CC_REGNUM))]
|
|
873 "TARGET_MAC"
|
|
874 "mac<sPat>b\t%2, %1"
|
|
875 [(set_attr "length" "4")]
|
|
876 )
|
|
877
|
|
878 ;; Loop Instructions
|
|
879
|
|
880 (define_expand "doloop_end"
|
|
881 [(use (match_operand 0 "" "")) ; loop pseudo
|
|
882 (use (match_operand 1 "" "")) ; iterations; zero if unknown
|
|
883 (use (match_operand 2 "" "")) ; max iterations
|
|
884 (use (match_operand 3 "" "")) ; loop level
|
|
885 (use (match_operand 4 "" ""))] ; label
|
|
886 ""
|
|
887 {
|
|
888 if (INTVAL (operands[3]) > crx_loop_nesting)
|
|
889 FAIL;
|
|
890 switch (GET_MODE (operands[0]))
|
|
891 {
|
|
892 case SImode:
|
|
893 emit_jump_insn (gen_doloop_end_si (operands[4], operands[0]));
|
|
894 break;
|
|
895 case HImode:
|
|
896 emit_jump_insn (gen_doloop_end_hi (operands[4], operands[0]));
|
|
897 break;
|
|
898 case QImode:
|
|
899 emit_jump_insn (gen_doloop_end_qi (operands[4], operands[0]));
|
|
900 break;
|
|
901 default:
|
|
902 FAIL;
|
|
903 }
|
|
904 DONE;
|
|
905 }
|
|
906 )
|
|
907
|
|
908 ; CRX dbnz[bwd] used explicitly (see above) but also by the combiner.
|
|
909
|
|
910 (define_insn "doloop_end_<mode>"
|
|
911 [(set (pc)
|
|
912 (if_then_else (ne (match_operand:CRXIM 1 "register_operand" "+r,!m")
|
|
913 (const_int 1))
|
|
914 (label_ref (match_operand 0 "" ""))
|
|
915 (pc)))
|
|
916 (set (match_dup 1) (plus:CRXIM (match_dup 1) (const_int -1)))
|
|
917 (clobber (match_scratch:CRXIM 2 "=X,r"))
|
|
918 (clobber (reg:CC CC_REGNUM))]
|
|
919 ""
|
|
920 "@
|
|
921 dbnz<tIsa>\t%1, %l0
|
|
922 load<tIsa>\t%1, %2\;add<tIsa>\t$-1, %2\;stor<tIsa>\t%2, %1\;bne\t%l0"
|
|
923 [(set_attr "length" "6, 12")]
|
|
924 )
|