Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/crx/crx.md @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 77e2b8dfacca |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
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 ) |