Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/m32r/m32r.md @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 ;; Machine description of the Renesas M32R cpu for GNU C compiler |
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2001, 2003, 2004, 2005, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
3 ; 2007, 2008, 2009 Free Software Foundation, Inc. |
0 | 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 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al. | |
22 | |
23 ;; UNSPEC_VOLATILE usage | |
24 (define_constants | |
25 [(UNSPECV_BLOCKAGE 0) | |
26 (UNSPECV_FLUSH_ICACHE 1)]) | |
27 | |
28 ;; UNSPEC usage | |
29 (define_constants | |
30 [(UNSPEC_LOAD_SDA_BASE 2) | |
31 (UNSPEC_SET_CBIT 3) | |
32 (UNSPEC_PIC_LOAD_ADDR 4) | |
33 (UNSPEC_GET_PC 5) | |
34 (UNSPEC_GOTOFF 6) | |
35 ]) | |
36 | |
37 ;; Insn type. Used to default other attribute values. | |
38 (define_attr "type" | |
39 "int2,int4,load2,load4,load8,store2,store4,store8,shift2,shift4,mul2,div4,uncond_branch,branch,call,multi,misc" | |
40 (const_string "misc")) | |
41 | |
42 ;; Length in bytes. | |
43 (define_attr "length" "" | |
44 (cond [(eq_attr "type" "int2,load2,store2,shift2,mul2") | |
45 (const_int 2) | |
46 | |
47 (eq_attr "type" "int4,load4,store4,shift4,div4") | |
48 (const_int 4) | |
49 | |
50 (eq_attr "type" "multi") | |
51 (const_int 8) | |
52 | |
53 (eq_attr "type" "uncond_branch,branch,call") | |
54 (const_int 4)] | |
55 | |
56 (const_int 4))) | |
57 | |
58 ;; The length here is the length of a single asm. Unfortunately it might be | |
59 ;; 2 or 4 so we must allow for 4. That's ok though. | |
60 (define_asm_attributes | |
61 [(set_attr "length" "4") | |
62 (set_attr "type" "multi")]) | |
63 | |
64 ;; Whether an instruction is short (16-bit) or long (32-bit). | |
65 (define_attr "insn_size" "short,long" | |
66 (if_then_else (eq_attr "type" "int2,load2,store2,shift2,mul2") | |
67 (const_string "short") | |
68 (const_string "long"))) | |
69 | |
70 ;; The target CPU we're compiling for. | |
71 (define_attr "cpu" "m32r,m32r2,m32rx" | |
72 (cond [(ne (symbol_ref "TARGET_M32RX") (const_int 0)) | |
73 (const_string "m32rx") | |
74 (ne (symbol_ref "TARGET_M32R2") (const_int 0)) | |
75 (const_string "m32r2")] | |
76 (const_string "m32r"))) | |
77 | |
78 ;; Defines the pipeline where an instruction can be executed on. | |
79 ;; For the M32R, a short instruction can execute one of the two pipes. | |
80 ;; For the M32Rx, the restrictions are modelled in the second | |
81 ;; condition of this attribute definition. | |
82 (define_attr "m32r_pipeline" "either,s,o,long" | |
83 (cond [(and (eq_attr "cpu" "m32r") | |
84 (eq_attr "insn_size" "short")) | |
85 (const_string "either") | |
86 (eq_attr "insn_size" "!short") | |
87 (const_string "long")] | |
88 (cond [(eq_attr "type" "int2") | |
89 (const_string "either") | |
90 (eq_attr "type" "load2,store2,shift2,uncond_branch,branch,call") | |
91 (const_string "o") | |
92 (eq_attr "type" "mul2") | |
93 (const_string "s")] | |
94 (const_string "long")))) | |
95 | |
96 ;; :::::::::::::::::::: | |
97 ;; :: | |
98 ;; :: Pipeline description | |
99 ;; :: | |
100 ;; :::::::::::::::::::: | |
101 | |
102 ;; This model is based on Chapter 2, Appendix 3 and Appendix 4 of the | |
103 ;; "M32R-FPU Software Manual", Revision 1.01, plus additional information | |
104 ;; obtained by our best friend and mine, Google. | |
105 ;; | |
106 ;; The pipeline is modelled as a fetch unit, and a core with a memory unit, | |
107 ;; two execution units, where "fetch" models IF and D, "memory" for MEM1 | |
108 ;; and MEM2, and "EXEC" for E, E1, E2, EM, and EA. Writeback and | |
109 ;; bypasses are not modelled. | |
110 (define_automaton "m32r") | |
111 | |
112 ;; We pretend there are two short (16 bits) instruction fetchers. The | |
113 ;; "s" short fetcher cannot be reserved until the "o" short fetcher is | |
114 ;; reserved. Some instructions reserve both the left and right fetchers. | |
115 ;; These fetch units are a hack to get GCC to better pack the instructions | |
116 ;; for the M32Rx processor, which has two execution pipes. | |
117 ;; | |
118 ;; In reality there is only one decoder, which can decode either two 16-bit | |
119 ;; instructions, or a single 32-bit instruction. | |
120 ;; | |
121 ;; Note, "fetch" models both the IF and the D pipeline stages. | |
122 ;; | |
123 ;; The m32rx core has two execution pipes. We name them o_E and s_E. | |
124 ;; In addition, there's a memory unit. | |
125 | |
126 (define_cpu_unit "o_IF,s_IF,o_E,s_E,memory" "m32r") | |
127 | |
128 ;; Prevent the s pipe from being reserved before the o pipe. | |
129 (absence_set "s_IF" "o_IF") | |
130 (absence_set "s_E" "o_E") | |
131 | |
132 ;; On the M32Rx, long instructions execute on both pipes, so reserve | |
133 ;; both fetch slots and both pipes. | |
134 (define_reservation "long_IF" "o_IF+s_IF") | |
135 (define_reservation "long_E" "o_E+s_E") | |
136 | |
137 ;; :::::::::::::::::::: | |
138 | |
139 ;; Simple instructions do 4 stages: IF D E WB. WB is not modelled. | |
140 ;; Hence, ready latency is 1. | |
141 (define_insn_reservation "short_left" 1 | |
142 (and (eq_attr "m32r_pipeline" "o") | |
143 (and (eq_attr "insn_size" "short") | |
144 (eq_attr "type" "!load2"))) | |
145 "o_IF,o_E") | |
146 | |
147 (define_insn_reservation "short_right" 1 | |
148 (and (eq_attr "m32r_pipeline" "s") | |
149 (and (eq_attr "insn_size" "short") | |
150 (eq_attr "type" "!load2"))) | |
151 "s_IF,s_E") | |
152 | |
153 (define_insn_reservation "short_either" 1 | |
154 (and (eq_attr "m32r_pipeline" "either") | |
155 (and (eq_attr "insn_size" "short") | |
156 (eq_attr "type" "!load2"))) | |
157 "o_IF|s_IF,o_E|s_E") | |
158 | |
159 (define_insn_reservation "long_m32r" 1 | |
160 (and (eq_attr "cpu" "m32r") | |
161 (and (eq_attr "insn_size" "long") | |
162 (eq_attr "type" "!load4,load8"))) | |
163 "long_IF,long_E") | |
164 | |
165 (define_insn_reservation "long_m32rx" 2 | |
166 (and (eq_attr "m32r_pipeline" "long") | |
167 (and (eq_attr "insn_size" "long") | |
168 (eq_attr "type" "!load4,load8"))) | |
169 "long_IF,long_E") | |
170 | |
171 ;; Load/store instructions do 6 stages: IF D E MEM1 MEM2 WB. | |
172 ;; MEM1 may require more than one cycle depending on locality. We | |
173 ;; optimistically assume all memory is nearby, i.e. MEM1 takes only | |
174 ;; one cycle. Hence, ready latency is 3. | |
175 | |
176 ;; The M32Rx can do short load/store only on the left pipe. | |
177 (define_insn_reservation "short_load_left" 3 | |
178 (and (eq_attr "m32r_pipeline" "o") | |
179 (and (eq_attr "insn_size" "short") | |
180 (eq_attr "type" "load2"))) | |
181 "o_IF,o_E,memory*2") | |
182 | |
183 (define_insn_reservation "short_load" 3 | |
184 (and (eq_attr "m32r_pipeline" "either") | |
185 (and (eq_attr "insn_size" "short") | |
186 (eq_attr "type" "load2"))) | |
187 "s_IF|o_IF,s_E|o_E,memory*2") | |
188 | |
189 (define_insn_reservation "long_load" 3 | |
190 (and (eq_attr "cpu" "m32r") | |
191 (and (eq_attr "insn_size" "long") | |
192 (eq_attr "type" "load4,load8"))) | |
193 "long_IF,long_E,memory*2") | |
194 | |
195 (define_insn_reservation "long_load_m32rx" 3 | |
196 (and (eq_attr "m32r_pipeline" "long") | |
197 (eq_attr "type" "load4,load8")) | |
198 "long_IF,long_E,memory*2") | |
199 | |
200 | |
201 (include "predicates.md") | |
202 (include "constraints.md") | |
203 | |
204 ;; Expand prologue as RTL | |
205 (define_expand "prologue" | |
206 [(const_int 1)] | |
207 "" | |
208 " | |
209 { | |
210 m32r_expand_prologue (); | |
211 DONE; | |
212 }") | |
213 | |
214 ;; Expand epilogue as RTL | |
215 (define_expand "epilogue" | |
216 [(return)] | |
217 "" | |
218 " | |
219 { | |
220 m32r_expand_epilogue (); | |
221 emit_jump_insn (gen_return_normal ()); | |
222 DONE; | |
223 }") | |
224 | |
225 ;; Move instructions. | |
226 ;; | |
227 ;; For QI and HI moves, the register must contain the full properly | |
228 ;; sign-extended value. nonzero_bits assumes this [otherwise | |
229 ;; SHORT_IMMEDIATES_SIGN_EXTEND must be used, but the comment for it | |
230 ;; says it's a kludge and the .md files should be fixed instead]. | |
231 | |
232 (define_expand "movqi" | |
233 [(set (match_operand:QI 0 "general_operand" "") | |
234 (match_operand:QI 1 "general_operand" ""))] | |
235 "" | |
236 " | |
237 { | |
238 /* Fixup PIC cases. */ | |
239 if (flag_pic) | |
240 { | |
241 if (symbolic_operand (operands[1], QImode)) | |
242 { | |
243 if (reload_in_progress || reload_completed) | |
244 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); | |
245 else | |
246 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); | |
247 } | |
248 } | |
249 | |
250 /* Everything except mem = const or mem = mem can be done easily. | |
251 Objects in the small data area are handled too. */ | |
252 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
253 if (MEM_P (operands[0])) |
0 | 254 operands[1] = force_reg (QImode, operands[1]); |
255 }") | |
256 | |
257 (define_insn "*movqi_insn" | |
258 [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,r,r,T,m") | |
259 (match_operand:QI 1 "move_src_operand" "r,I,JQR,T,m,r,r"))] | |
260 "register_operand (operands[0], QImode) || register_operand (operands[1], QImode)" | |
261 "@ | |
262 mv %0,%1 | |
263 ldi %0,%#%1 | |
264 ldi %0,%#%1 | |
265 ldub %0,%1 | |
266 ldub %0,%1 | |
267 stb %1,%0 | |
268 stb %1,%0" | |
269 [(set_attr "type" "int2,int2,int4,load2,load4,store2,store4") | |
270 (set_attr "length" "2,2,4,2,4,2,4")]) | |
271 | |
272 (define_expand "movhi" | |
273 [(set (match_operand:HI 0 "general_operand" "") | |
274 (match_operand:HI 1 "general_operand" ""))] | |
275 "" | |
276 " | |
277 { | |
278 /* Fixup PIC cases. */ | |
279 if (flag_pic) | |
280 { | |
281 if (symbolic_operand (operands[1], HImode)) | |
282 { | |
283 if (reload_in_progress || reload_completed) | |
284 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); | |
285 else | |
286 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); | |
287 } | |
288 } | |
289 | |
290 /* Everything except mem = const or mem = mem can be done easily. */ | |
291 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
292 if (MEM_P (operands[0])) |
0 | 293 operands[1] = force_reg (HImode, operands[1]); |
294 }") | |
295 | |
296 (define_insn "*movhi_insn" | |
297 [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,r,r,r,T,m") | |
298 (match_operand:HI 1 "move_src_operand" "r,I,JQR,K,T,m,r,r"))] | |
299 "register_operand (operands[0], HImode) || register_operand (operands[1], HImode)" | |
300 "@ | |
301 mv %0,%1 | |
302 ldi %0,%#%1 | |
303 ldi %0,%#%1 | |
304 ld24 %0,%#%1 | |
305 lduh %0,%1 | |
306 lduh %0,%1 | |
307 sth %1,%0 | |
308 sth %1,%0" | |
309 [(set_attr "type" "int2,int2,int4,int4,load2,load4,store2,store4") | |
310 (set_attr "length" "2,2,4,4,2,4,2,4")]) | |
311 | |
312 (define_expand "movsi_push" | |
313 [(set (mem:SI (pre_dec:SI (match_operand:SI 0 "register_operand" ""))) | |
314 (match_operand:SI 1 "register_operand" ""))] | |
315 "" | |
316 "") | |
317 | |
318 (define_expand "movsi_pop" | |
319 [(set (match_operand:SI 0 "register_operand" "") | |
320 (mem:SI (post_inc:SI (match_operand:SI 1 "register_operand" ""))))] | |
321 "" | |
322 "") | |
323 | |
324 (define_expand "movsi" | |
325 [(set (match_operand:SI 0 "general_operand" "") | |
326 (match_operand:SI 1 "general_operand" ""))] | |
327 "" | |
328 " | |
329 { | |
330 /* Fixup PIC cases. */ | |
331 if (flag_pic) | |
332 { | |
333 if (symbolic_operand (operands[1], SImode)) | |
334 { | |
335 if (reload_in_progress || reload_completed) | |
336 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); | |
337 else | |
338 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); | |
339 } | |
340 } | |
341 | |
342 /* Everything except mem = const or mem = mem can be done easily. */ | |
343 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
344 if (MEM_P (operands[0])) |
0 | 345 operands[1] = force_reg (SImode, operands[1]); |
346 | |
347 /* Small Data Area reference? */ | |
348 if (small_data_operand (operands[1], SImode)) | |
349 { | |
350 emit_insn (gen_movsi_sda (operands[0], operands[1])); | |
351 DONE; | |
352 } | |
353 | |
354 /* If medium or large code model, symbols have to be loaded with | |
355 seth/add3. */ | |
356 if (addr32_operand (operands[1], SImode)) | |
357 { | |
358 emit_insn (gen_movsi_addr32 (operands[0], operands[1])); | |
359 DONE; | |
360 } | |
361 }") | |
362 | |
363 ;; ??? Do we need a const_double constraint here for large unsigned values? | |
364 (define_insn "*movsi_insn" | |
365 [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,r,r,r,r,r,r,T,S,m") | |
366 (match_operand:SI 1 "move_src_operand" "r,I,J,MQ,L,n,T,U,m,r,r,r"))] | |
367 "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)" | |
368 "* | |
369 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
370 if (REG_P (operands[0]) || GET_CODE (operands[1]) == SUBREG) |
0 | 371 { |
372 switch (GET_CODE (operands[1])) | |
373 { | |
374 default: | |
375 break; | |
376 | |
377 case REG: | |
378 case SUBREG: | |
379 return \"mv %0,%1\"; | |
380 | |
381 case MEM: | |
382 if (GET_CODE (XEXP (operands[1], 0)) == POST_INC | |
383 && XEXP (XEXP (operands[1], 0), 0) == stack_pointer_rtx) | |
384 return \"pop %0\"; | |
385 | |
386 return \"ld %0,%1\"; | |
387 | |
388 case CONST_INT: | |
389 if (satisfies_constraint_J (operands[1])) | |
390 return \"ldi %0,%#%1\\t; %X1\"; | |
391 | |
392 if (satisfies_constraint_M (operands[1])) | |
393 return \"ld24 %0,%#%1\\t; %X1\"; | |
394 | |
395 if (satisfies_constraint_L (operands[1])) | |
396 return \"seth %0,%#%T1\\t; %X1\"; | |
397 | |
398 return \"#\"; | |
399 | |
400 case CONST: | |
401 case SYMBOL_REF: | |
402 case LABEL_REF: | |
403 if (TARGET_ADDR24) | |
404 return \"ld24 %0,%#%1\"; | |
405 | |
406 return \"#\"; | |
407 } | |
408 } | |
409 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
410 else if (MEM_P (operands[0]) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
411 && (REG_P (operands[1]) || GET_CODE (operands[1]) == SUBREG)) |
0 | 412 { |
413 if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC | |
414 && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx) | |
415 return \"push %1\"; | |
416 | |
417 return \"st %1,%0\"; | |
418 } | |
419 | |
420 gcc_unreachable (); | |
421 }" | |
422 [(set_attr "type" "int2,int2,int4,int4,int4,multi,load2,load2,load4,store2,store2,store4") | |
423 (set_attr "length" "2,2,4,4,4,8,2,2,4,2,2,4")]) | |
424 | |
425 ; Try to use a four byte / two byte pair for constants not loadable with | |
426 ; ldi, ld24, seth. | |
427 | |
428 (define_split | |
429 [(set (match_operand:SI 0 "register_operand" "") | |
430 (match_operand:SI 1 "two_insn_const_operand" ""))] | |
431 "" | |
432 [(set (match_dup 0) (match_dup 2)) | |
433 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 3)))] | |
434 " | |
435 { | |
436 unsigned HOST_WIDE_INT val = INTVAL (operands[1]); | |
437 unsigned HOST_WIDE_INT tmp; | |
438 int shift; | |
439 | |
440 /* In all cases we will emit two instructions. However we try to | |
441 use 2 byte instructions wherever possible. We can assume the | |
442 constant isn't loadable with any of ldi, ld24, or seth. */ | |
443 | |
444 /* See if we can load a 24-bit unsigned value and invert it. */ | |
445 if (UINT24_P (~ val)) | |
446 { | |
447 emit_insn (gen_movsi (operands[0], GEN_INT (~ val))); | |
448 emit_insn (gen_one_cmplsi2 (operands[0], operands[0])); | |
449 DONE; | |
450 } | |
451 | |
452 /* See if we can load a 24-bit unsigned value and shift it into place. | |
453 0x01fffffe is just beyond ld24's range. */ | |
454 for (shift = 1, tmp = 0x01fffffe; | |
455 shift < 8; | |
456 ++shift, tmp <<= 1) | |
457 { | |
458 if ((val & ~tmp) == 0) | |
459 { | |
460 emit_insn (gen_movsi (operands[0], GEN_INT (val >> shift))); | |
461 emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (shift))); | |
462 DONE; | |
463 } | |
464 } | |
465 | |
466 /* Can't use any two byte insn, fall back to seth/or3. Use ~0xffff instead | |
467 of 0xffff0000, since the later fails on a 64-bit host. */ | |
468 operands[2] = GEN_INT ((val) & ~0xffff); | |
469 operands[3] = GEN_INT ((val) & 0xffff); | |
470 }") | |
471 | |
472 (define_split | |
473 [(set (match_operand:SI 0 "register_operand" "") | |
474 (match_operand:SI 1 "seth_add3_operand" ""))] | |
475 "TARGET_ADDR32" | |
476 [(set (match_dup 0) | |
477 (high:SI (match_dup 1))) | |
478 (set (match_dup 0) | |
479 (lo_sum:SI (match_dup 0) | |
480 (match_dup 1)))] | |
481 "") | |
482 | |
483 ;; Small data area support. | |
484 ;; The address of _SDA_BASE_ is loaded into a register and all objects in | |
485 ;; the small data area are indexed off that. This is done for each reference | |
486 ;; but cse will clean things up for us. We let the compiler choose the | |
487 ;; register to use so we needn't allocate (and maybe even fix) a special | |
488 ;; register to use. Since the load and store insns have a 16-bit offset the | |
489 ;; total size of the data area can be 64K. However, if the data area lives | |
490 ;; above 16M (24 bits), _SDA_BASE_ will have to be loaded with seth/add3 which | |
491 ;; would then yield 3 instructions to reference an object [though there would | |
492 ;; be no net loss if two or more objects were referenced]. The 3 insns can be | |
493 ;; reduced back to 2 if the size of the small data area were reduced to 32K | |
494 ;; [then seth + ld/st would work for any object in the area]. Doing this | |
495 ;; would require special handling of _SDA_BASE_ (its value would be | |
496 ;; (.sdata + 32K) & 0xffff0000) and reloc computations would be different | |
497 ;; [I think]. What to do about this is deferred until later and for now we | |
498 ;; require .sdata to be in the first 16M. | |
499 | |
500 (define_expand "movsi_sda" | |
501 [(set (match_dup 2) | |
502 (unspec:SI [(const_int 0)] UNSPEC_LOAD_SDA_BASE)) | |
503 (set (match_operand:SI 0 "register_operand" "") | |
504 (lo_sum:SI (match_dup 2) | |
505 (match_operand:SI 1 "small_data_operand" "")))] | |
506 "" | |
507 " | |
508 { | |
509 if (reload_in_progress || reload_completed) | |
510 operands[2] = operands[0]; | |
511 else | |
512 operands[2] = gen_reg_rtx (SImode); | |
513 }") | |
514 | |
515 (define_insn "*load_sda_base_32" | |
516 [(set (match_operand:SI 0 "register_operand" "=r") | |
517 (unspec:SI [(const_int 0)] UNSPEC_LOAD_SDA_BASE))] | |
518 "TARGET_ADDR32" | |
519 "seth %0,%#shigh(_SDA_BASE_)\;add3 %0,%0,%#low(_SDA_BASE_)" | |
520 [(set_attr "type" "multi") | |
521 (set_attr "length" "8")]) | |
522 | |
523 (define_insn "*load_sda_base" | |
524 [(set (match_operand:SI 0 "register_operand" "=r") | |
525 (unspec:SI [(const_int 0)] UNSPEC_LOAD_SDA_BASE))] | |
526 "" | |
527 "ld24 %0,#_SDA_BASE_" | |
528 [(set_attr "type" "int4") | |
529 (set_attr "length" "4")]) | |
530 | |
531 ;; 32-bit address support. | |
532 | |
533 (define_expand "movsi_addr32" | |
534 [(set (match_dup 2) | |
535 ; addr32_operand isn't used because it's too restrictive, | |
536 ; seth_add3_operand is more general and thus safer. | |
537 (high:SI (match_operand:SI 1 "seth_add3_operand" ""))) | |
538 (set (match_operand:SI 0 "register_operand" "") | |
539 (lo_sum:SI (match_dup 2) (match_dup 1)))] | |
540 "" | |
541 " | |
542 { | |
543 if (reload_in_progress || reload_completed) | |
544 operands[2] = operands[0]; | |
545 else | |
546 operands[2] = gen_reg_rtx (SImode); | |
547 }") | |
548 | |
549 (define_insn "set_hi_si" | |
550 [(set (match_operand:SI 0 "register_operand" "=r") | |
551 (high:SI (match_operand 1 "symbolic_operand" "")))] | |
552 "" | |
553 "seth %0,%#shigh(%1)" | |
554 [(set_attr "type" "int4") | |
555 (set_attr "length" "4")]) | |
556 | |
557 (define_insn "lo_sum_si" | |
558 [(set (match_operand:SI 0 "register_operand" "=r") | |
559 (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
560 (match_operand:SI 2 "immediate_operand" "in")))] | |
561 "" | |
562 "add3 %0,%1,%#%B2" | |
563 [(set_attr "type" "int4") | |
564 (set_attr "length" "4")]) | |
565 | |
566 (define_expand "movdi" | |
567 [(set (match_operand:DI 0 "general_operand" "") | |
568 (match_operand:DI 1 "general_operand" ""))] | |
569 "" | |
570 " | |
571 { | |
572 /* Fixup PIC cases. */ | |
573 if (flag_pic) | |
574 { | |
575 if (symbolic_operand (operands[1], DImode)) | |
576 { | |
577 if (reload_in_progress || reload_completed) | |
578 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); | |
579 else | |
580 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); | |
581 } | |
582 } | |
583 | |
584 /* Everything except mem = const or mem = mem can be done easily. */ | |
585 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
586 if (MEM_P (operands[0])) |
0 | 587 operands[1] = force_reg (DImode, operands[1]); |
588 }") | |
589 | |
590 (define_insn "*movdi_insn" | |
591 [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,r,m") | |
592 (match_operand:DI 1 "move_double_src_operand" "r,nG,F,m,r"))] | |
593 "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)" | |
594 "#" | |
595 [(set_attr "type" "multi,multi,multi,load8,store8") | |
596 (set_attr "length" "4,4,16,6,6")]) | |
597 | |
598 (define_split | |
599 [(set (match_operand:DI 0 "move_dest_operand" "") | |
600 (match_operand:DI 1 "move_double_src_operand" ""))] | |
601 "reload_completed" | |
602 [(match_dup 2)] | |
603 "operands[2] = gen_split_move_double (operands);") | |
604 | |
605 ;; Floating point move insns. | |
606 | |
607 (define_expand "movsf" | |
608 [(set (match_operand:SF 0 "general_operand" "") | |
609 (match_operand:SF 1 "general_operand" ""))] | |
610 "" | |
611 " | |
612 { | |
613 /* Fixup PIC cases. */ | |
614 if (flag_pic) | |
615 { | |
616 if (symbolic_operand (operands[1], SFmode)) | |
617 { | |
618 if (reload_in_progress || reload_completed) | |
619 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); | |
620 else | |
621 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); | |
622 } | |
623 } | |
624 | |
625 /* Everything except mem = const or mem = mem can be done easily. */ | |
626 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
627 if (MEM_P (operands[0])) |
0 | 628 operands[1] = force_reg (SFmode, operands[1]); |
629 }") | |
630 | |
631 (define_insn "*movsf_insn" | |
632 [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,r,r,T,S,m") | |
633 (match_operand:SF 1 "move_src_operand" "r,F,U,S,m,r,r,r"))] | |
634 "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)" | |
635 "@ | |
636 mv %0,%1 | |
637 # | |
638 ld %0,%1 | |
639 ld %0,%1 | |
640 ld %0,%1 | |
641 st %1,%0 | |
642 st %1,%0 | |
643 st %1,%0" | |
644 ;; ??? Length of alternative 1 is either 2, 4 or 8. | |
645 [(set_attr "type" "int2,multi,load2,load2,load4,store2,store2,store4") | |
646 (set_attr "length" "2,8,2,2,4,2,2,4")]) | |
647 | |
648 (define_split | |
649 [(set (match_operand:SF 0 "register_operand" "") | |
650 (match_operand:SF 1 "const_double_operand" ""))] | |
651 "reload_completed" | |
652 [(set (match_dup 2) (match_dup 3))] | |
653 " | |
654 { | |
655 operands[2] = operand_subword (operands[0], 0, 0, SFmode); | |
656 operands[3] = operand_subword (operands[1], 0, 0, SFmode); | |
657 }") | |
658 | |
659 (define_expand "movdf" | |
660 [(set (match_operand:DF 0 "general_operand" "") | |
661 (match_operand:DF 1 "general_operand" ""))] | |
662 "" | |
663 " | |
664 { | |
665 /* Fixup PIC cases. */ | |
666 if (flag_pic) | |
667 { | |
668 if (symbolic_operand (operands[1], DFmode)) | |
669 { | |
670 if (reload_in_progress || reload_completed) | |
671 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); | |
672 else | |
673 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); | |
674 } | |
675 } | |
676 | |
677 /* Everything except mem = const or mem = mem can be done easily. */ | |
678 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
679 if (MEM_P (operands[0])) |
0 | 680 operands[1] = force_reg (DFmode, operands[1]); |
681 }") | |
682 | |
683 (define_insn "*movdf_insn" | |
684 [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m") | |
685 (match_operand:DF 1 "move_double_src_operand" "r,F,m,r"))] | |
686 "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)" | |
687 "#" | |
688 [(set_attr "type" "multi,multi,load8,store8") | |
689 (set_attr "length" "4,16,6,6")]) | |
690 | |
691 (define_split | |
692 [(set (match_operand:DF 0 "move_dest_operand" "") | |
693 (match_operand:DF 1 "move_double_src_operand" ""))] | |
694 "reload_completed" | |
695 [(match_dup 2)] | |
696 "operands[2] = gen_split_move_double (operands);") | |
697 | |
698 ;; Zero extension instructions. | |
699 | |
700 (define_insn "zero_extendqihi2" | |
701 [(set (match_operand:HI 0 "register_operand" "=r,r,r") | |
702 (zero_extend:HI (match_operand:QI 1 "extend_operand" "r,T,m")))] | |
703 "" | |
704 "@ | |
705 and3 %0,%1,%#255 | |
706 ldub %0,%1 | |
707 ldub %0,%1" | |
708 [(set_attr "type" "int4,load2,load4") | |
709 (set_attr "length" "4,2,4")]) | |
710 | |
711 (define_insn "zero_extendqisi2" | |
712 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
713 (zero_extend:SI (match_operand:QI 1 "extend_operand" "r,T,m")))] | |
714 "" | |
715 "@ | |
716 and3 %0,%1,%#255 | |
717 ldub %0,%1 | |
718 ldub %0,%1" | |
719 [(set_attr "type" "int4,load2,load4") | |
720 (set_attr "length" "4,2,4")]) | |
721 | |
722 (define_insn "zero_extendhisi2" | |
723 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
724 (zero_extend:SI (match_operand:HI 1 "extend_operand" "r,T,m")))] | |
725 "" | |
726 "@ | |
727 and3 %0,%1,%#65535 | |
728 lduh %0,%1 | |
729 lduh %0,%1" | |
730 [(set_attr "type" "int4,load2,load4") | |
731 (set_attr "length" "4,2,4")]) | |
732 | |
733 ;; Signed conversions from a smaller integer to a larger integer | |
734 (define_insn "extendqihi2" | |
735 [(set (match_operand:HI 0 "register_operand" "=r,r,r") | |
736 (sign_extend:HI (match_operand:QI 1 "extend_operand" "0,T,m")))] | |
737 "" | |
738 "@ | |
739 # | |
740 ldb %0,%1 | |
741 ldb %0,%1" | |
742 [(set_attr "type" "multi,load2,load4") | |
743 (set_attr "length" "2,2,4")]) | |
744 | |
745 (define_split | |
746 [(set (match_operand:HI 0 "register_operand" "") | |
747 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))] | |
748 "reload_completed" | |
749 [(match_dup 2) | |
750 (match_dup 3)] | |
751 " | |
752 { | |
753 rtx op0 = gen_lowpart (SImode, operands[0]); | |
754 rtx shift = GEN_INT (24); | |
755 | |
756 operands[2] = gen_ashlsi3 (op0, op0, shift); | |
757 operands[3] = gen_ashrsi3 (op0, op0, shift); | |
758 }") | |
759 | |
760 (define_insn "extendqisi2" | |
761 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
762 (sign_extend:SI (match_operand:QI 1 "extend_operand" "0,T,m")))] | |
763 "" | |
764 "@ | |
765 # | |
766 ldb %0,%1 | |
767 ldb %0,%1" | |
768 [(set_attr "type" "multi,load2,load4") | |
769 (set_attr "length" "4,2,4")]) | |
770 | |
771 (define_split | |
772 [(set (match_operand:SI 0 "register_operand" "") | |
773 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] | |
774 "reload_completed" | |
775 [(match_dup 2) | |
776 (match_dup 3)] | |
777 " | |
778 { | |
779 rtx shift = GEN_INT (24); | |
780 | |
781 operands[2] = gen_ashlsi3 (operands[0], operands[0], shift); | |
782 operands[3] = gen_ashrsi3 (operands[0], operands[0], shift); | |
783 }") | |
784 | |
785 (define_insn "extendhisi2" | |
786 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
787 (sign_extend:SI (match_operand:HI 1 "extend_operand" "0,T,m")))] | |
788 "" | |
789 "@ | |
790 # | |
791 ldh %0,%1 | |
792 ldh %0,%1" | |
793 [(set_attr "type" "multi,load2,load4") | |
794 (set_attr "length" "4,2,4")]) | |
795 | |
796 (define_split | |
797 [(set (match_operand:SI 0 "register_operand" "") | |
798 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] | |
799 "reload_completed" | |
800 [(match_dup 2) | |
801 (match_dup 3)] | |
802 " | |
803 { | |
804 rtx shift = GEN_INT (16); | |
805 | |
806 operands[2] = gen_ashlsi3 (operands[0], operands[0], shift); | |
807 operands[3] = gen_ashrsi3 (operands[0], operands[0], shift); | |
808 }") | |
809 | |
810 ;; Arithmetic instructions. | |
811 | |
812 ; ??? Adding an alternative to split add3 of small constants into two | |
813 ; insns yields better instruction packing but slower code. Adds of small | |
814 ; values is done a lot. | |
815 | |
816 (define_insn "addsi3" | |
817 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
818 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,r") | |
819 (match_operand:SI 2 "nonmemory_operand" "r,I,J")))] | |
820 "" | |
821 "@ | |
822 add %0,%2 | |
823 addi %0,%#%2 | |
824 add3 %0,%1,%#%2" | |
825 [(set_attr "type" "int2,int2,int4") | |
826 (set_attr "length" "2,2,4")]) | |
827 | |
828 ;(define_split | |
829 ; [(set (match_operand:SI 0 "register_operand" "") | |
830 ; (plus:SI (match_operand:SI 1 "register_operand" "") | |
831 ; (match_operand:SI 2 "int8_operand" "")))] | |
832 ; "reload_completed | |
833 ; && REGNO (operands[0]) != REGNO (operands[1]) | |
834 ; && satisfies_constraint_I (operands[2]) | |
835 ; && INTVAL (operands[2]) != 0" | |
836 ; [(set (match_dup 0) (match_dup 1)) | |
837 ; (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))] | |
838 ; "") | |
839 | |
840 (define_insn "adddi3" | |
841 [(set (match_operand:DI 0 "register_operand" "=r") | |
842 (plus:DI (match_operand:DI 1 "register_operand" "%0") | |
843 (match_operand:DI 2 "register_operand" "r"))) | |
844 (clobber (reg:CC 17))] | |
845 "" | |
846 "#" | |
847 [(set_attr "type" "multi") | |
848 (set_attr "length" "6")]) | |
849 | |
850 ;; ??? The cmp clears the condition bit. Can we speed up somehow? | |
851 (define_split | |
852 [(set (match_operand:DI 0 "register_operand" "") | |
853 (plus:DI (match_operand:DI 1 "register_operand" "") | |
854 (match_operand:DI 2 "register_operand" ""))) | |
855 (clobber (reg:CC 17))] | |
856 "reload_completed" | |
857 [(parallel [(set (reg:CC 17) | |
858 (const_int 0)) | |
859 (use (match_dup 4))]) | |
860 (parallel [(set (match_dup 4) | |
861 (plus:SI (match_dup 4) | |
862 (plus:SI (match_dup 5) | |
863 (ne:SI (reg:CC 17) (const_int 0))))) | |
864 (set (reg:CC 17) | |
865 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))]) | |
866 (parallel [(set (match_dup 6) | |
867 (plus:SI (match_dup 6) | |
868 (plus:SI (match_dup 7) | |
869 (ne:SI (reg:CC 17) (const_int 0))))) | |
870 (set (reg:CC 17) | |
871 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])] | |
872 " | |
873 { | |
874 operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode); | |
875 operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode); | |
876 operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode); | |
877 operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode); | |
878 }") | |
879 | |
880 (define_insn "*clear_c" | |
881 [(set (reg:CC 17) | |
882 (const_int 0)) | |
883 (use (match_operand:SI 0 "register_operand" "r"))] | |
884 "" | |
885 "cmp %0,%0" | |
886 [(set_attr "type" "int2") | |
887 (set_attr "length" "2")]) | |
888 | |
889 (define_insn "*add_carry" | |
890 [(set (match_operand:SI 0 "register_operand" "=r") | |
891 (plus:SI (match_operand:SI 1 "register_operand" "%0") | |
892 (plus:SI (match_operand:SI 2 "register_operand" "r") | |
893 (ne:SI (reg:CC 17) (const_int 0))))) | |
894 (set (reg:CC 17) | |
895 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))] | |
896 "" | |
897 "addx %0,%2" | |
898 [(set_attr "type" "int2") | |
899 (set_attr "length" "2")]) | |
900 | |
901 (define_insn "subsi3" | |
902 [(set (match_operand:SI 0 "register_operand" "=r") | |
903 (minus:SI (match_operand:SI 1 "register_operand" "0") | |
904 (match_operand:SI 2 "register_operand" "r")))] | |
905 "" | |
906 "sub %0,%2" | |
907 [(set_attr "type" "int2") | |
908 (set_attr "length" "2")]) | |
909 | |
910 (define_insn "subdi3" | |
911 [(set (match_operand:DI 0 "register_operand" "=r") | |
912 (minus:DI (match_operand:DI 1 "register_operand" "0") | |
913 (match_operand:DI 2 "register_operand" "r"))) | |
914 (clobber (reg:CC 17))] | |
915 "" | |
916 "#" | |
917 [(set_attr "type" "multi") | |
918 (set_attr "length" "6")]) | |
919 | |
920 ;; ??? The cmp clears the condition bit. Can we speed up somehow? | |
921 (define_split | |
922 [(set (match_operand:DI 0 "register_operand" "") | |
923 (minus:DI (match_operand:DI 1 "register_operand" "") | |
924 (match_operand:DI 2 "register_operand" ""))) | |
925 (clobber (reg:CC 17))] | |
926 "reload_completed" | |
927 [(parallel [(set (reg:CC 17) | |
928 (const_int 0)) | |
929 (use (match_dup 4))]) | |
930 (parallel [(set (match_dup 4) | |
931 (minus:SI (match_dup 4) | |
932 (minus:SI (match_dup 5) | |
933 (ne:SI (reg:CC 17) (const_int 0))))) | |
934 (set (reg:CC 17) | |
935 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))]) | |
936 (parallel [(set (match_dup 6) | |
937 (minus:SI (match_dup 6) | |
938 (minus:SI (match_dup 7) | |
939 (ne:SI (reg:CC 17) (const_int 0))))) | |
940 (set (reg:CC 17) | |
941 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])] | |
942 " | |
943 { | |
944 operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode); | |
945 operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode); | |
946 operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode); | |
947 operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode); | |
948 }") | |
949 | |
950 (define_insn "*sub_carry" | |
951 [(set (match_operand:SI 0 "register_operand" "=r") | |
952 (minus:SI (match_operand:SI 1 "register_operand" "%0") | |
953 (minus:SI (match_operand:SI 2 "register_operand" "r") | |
954 (ne:SI (reg:CC 17) (const_int 0))))) | |
955 (set (reg:CC 17) | |
956 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))] | |
957 "" | |
958 "subx %0,%2" | |
959 [(set_attr "type" "int2") | |
960 (set_attr "length" "2")]) | |
961 | |
962 ; Multiply/Divide instructions. | |
963 | |
964 (define_insn "mulhisi3" | |
965 [(set (match_operand:SI 0 "register_operand" "=r") | |
966 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r")) | |
967 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] | |
968 "" | |
969 "mullo %1,%2\;mvfacmi %0" | |
970 [(set_attr "type" "multi") | |
971 (set_attr "length" "4")]) | |
972 | |
973 (define_insn "mulsi3" | |
974 [(set (match_operand:SI 0 "register_operand" "=r") | |
975 (mult:SI (match_operand:SI 1 "register_operand" "%0") | |
976 (match_operand:SI 2 "register_operand" "r")))] | |
977 "" | |
978 "mul %0,%2" | |
979 [(set_attr "type" "mul2") | |
980 (set_attr "length" "2")]) | |
981 | |
982 (define_insn "divsi3" | |
983 [(set (match_operand:SI 0 "register_operand" "=r") | |
984 (div:SI (match_operand:SI 1 "register_operand" "0") | |
985 (match_operand:SI 2 "register_operand" "r")))] | |
986 "" | |
987 "div %0,%2" | |
988 [(set_attr "type" "div4") | |
989 (set_attr "length" "4")]) | |
990 | |
991 (define_insn "udivsi3" | |
992 [(set (match_operand:SI 0 "register_operand" "=r") | |
993 (udiv:SI (match_operand:SI 1 "register_operand" "0") | |
994 (match_operand:SI 2 "register_operand" "r")))] | |
995 "" | |
996 "divu %0,%2" | |
997 [(set_attr "type" "div4") | |
998 (set_attr "length" "4")]) | |
999 | |
1000 (define_insn "modsi3" | |
1001 [(set (match_operand:SI 0 "register_operand" "=r") | |
1002 (mod:SI (match_operand:SI 1 "register_operand" "0") | |
1003 (match_operand:SI 2 "register_operand" "r")))] | |
1004 "" | |
1005 "rem %0,%2" | |
1006 [(set_attr "type" "div4") | |
1007 (set_attr "length" "4")]) | |
1008 | |
1009 (define_insn "umodsi3" | |
1010 [(set (match_operand:SI 0 "register_operand" "=r") | |
1011 (umod:SI (match_operand:SI 1 "register_operand" "0") | |
1012 (match_operand:SI 2 "register_operand" "r")))] | |
1013 "" | |
1014 "remu %0,%2" | |
1015 [(set_attr "type" "div4") | |
1016 (set_attr "length" "4")]) | |
1017 | |
1018 ;; Boolean instructions. | |
1019 ;; | |
1020 ;; We don't define the DImode versions as expand_binop does a good enough job. | |
1021 ;; And if it doesn't it should be fixed. | |
1022 | |
1023 (define_insn "andsi3" | |
1024 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1025 (and:SI (match_operand:SI 1 "register_operand" "%0,r") | |
1026 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))] | |
1027 "" | |
1028 "* | |
1029 { | |
1030 /* If we are worried about space, see if we can break this up into two | |
1031 short instructions, which might eliminate a NOP being inserted. */ | |
1032 if (optimize_size | |
1033 && m32r_not_same_reg (operands[0], operands[1]) | |
1034 && satisfies_constraint_I (operands[2])) | |
1035 return \"#\"; | |
1036 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1037 else if (CONST_INT_P (operands[2])) |
0 | 1038 return \"and3 %0,%1,%#%X2\"; |
1039 | |
1040 return \"and %0,%2\"; | |
1041 }" | |
1042 [(set_attr "type" "int2,int4") | |
1043 (set_attr "length" "2,4")]) | |
1044 | |
1045 (define_split | |
1046 [(set (match_operand:SI 0 "register_operand" "") | |
1047 (and:SI (match_operand:SI 1 "register_operand" "") | |
1048 (match_operand:SI 2 "int8_operand" "")))] | |
1049 "optimize_size && m32r_not_same_reg (operands[0], operands[1])" | |
1050 [(set (match_dup 0) (match_dup 2)) | |
1051 (set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))] | |
1052 "") | |
1053 | |
1054 (define_insn "iorsi3" | |
1055 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1056 (ior:SI (match_operand:SI 1 "register_operand" "%0,r") | |
1057 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))] | |
1058 "" | |
1059 "* | |
1060 { | |
1061 /* If we are worried about space, see if we can break this up into two | |
1062 short instructions, which might eliminate a NOP being inserted. */ | |
1063 if (optimize_size | |
1064 && m32r_not_same_reg (operands[0], operands[1]) | |
1065 && satisfies_constraint_I (operands[2])) | |
1066 return \"#\"; | |
1067 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1068 else if (CONST_INT_P (operands[2])) |
0 | 1069 return \"or3 %0,%1,%#%X2\"; |
1070 | |
1071 return \"or %0,%2\"; | |
1072 }" | |
1073 [(set_attr "type" "int2,int4") | |
1074 (set_attr "length" "2,4")]) | |
1075 | |
1076 (define_split | |
1077 [(set (match_operand:SI 0 "register_operand" "") | |
1078 (ior:SI (match_operand:SI 1 "register_operand" "") | |
1079 (match_operand:SI 2 "int8_operand" "")))] | |
1080 "optimize_size && m32r_not_same_reg (operands[0], operands[1])" | |
1081 [(set (match_dup 0) (match_dup 2)) | |
1082 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 1)))] | |
1083 "") | |
1084 | |
1085 (define_insn "xorsi3" | |
1086 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1087 (xor:SI (match_operand:SI 1 "register_operand" "%0,r") | |
1088 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))] | |
1089 "" | |
1090 "* | |
1091 { | |
1092 /* If we are worried about space, see if we can break this up into two | |
1093 short instructions, which might eliminate a NOP being inserted. */ | |
1094 if (optimize_size | |
1095 && m32r_not_same_reg (operands[0], operands[1]) | |
1096 && satisfies_constraint_I (operands[2])) | |
1097 return \"#\"; | |
1098 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1099 else if (CONST_INT_P (operands[2])) |
0 | 1100 return \"xor3 %0,%1,%#%X2\"; |
1101 | |
1102 return \"xor %0,%2\"; | |
1103 }" | |
1104 [(set_attr "type" "int2,int4") | |
1105 (set_attr "length" "2,4")]) | |
1106 | |
1107 (define_split | |
1108 [(set (match_operand:SI 0 "register_operand" "") | |
1109 (xor:SI (match_operand:SI 1 "register_operand" "") | |
1110 (match_operand:SI 2 "int8_operand" "")))] | |
1111 "optimize_size && m32r_not_same_reg (operands[0], operands[1])" | |
1112 [(set (match_dup 0) (match_dup 2)) | |
1113 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))] | |
1114 "") | |
1115 | |
1116 (define_insn "negsi2" | |
1117 [(set (match_operand:SI 0 "register_operand" "=r") | |
1118 (neg:SI (match_operand:SI 1 "register_operand" "r")))] | |
1119 "" | |
1120 "neg %0,%1" | |
1121 [(set_attr "type" "int2") | |
1122 (set_attr "length" "2")]) | |
1123 | |
1124 (define_insn "one_cmplsi2" | |
1125 [(set (match_operand:SI 0 "register_operand" "=r") | |
1126 (not:SI (match_operand:SI 1 "register_operand" "r")))] | |
1127 "" | |
1128 "not %0,%1" | |
1129 [(set_attr "type" "int2") | |
1130 (set_attr "length" "2")]) | |
1131 | |
1132 ;; Shift instructions. | |
1133 | |
1134 (define_insn "ashlsi3" | |
1135 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
1136 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r") | |
1137 (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))] | |
1138 "" | |
1139 "@ | |
1140 sll %0,%2 | |
1141 slli %0,%#%2 | |
1142 sll3 %0,%1,%#%2" | |
1143 [(set_attr "type" "shift2,shift2,shift4") | |
1144 (set_attr "length" "2,2,4")]) | |
1145 | |
1146 (define_insn "ashrsi3" | |
1147 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
1148 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r") | |
1149 (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))] | |
1150 "" | |
1151 "@ | |
1152 sra %0,%2 | |
1153 srai %0,%#%2 | |
1154 sra3 %0,%1,%#%2" | |
1155 [(set_attr "type" "shift2,shift2,shift4") | |
1156 (set_attr "length" "2,2,4")]) | |
1157 | |
1158 (define_insn "lshrsi3" | |
1159 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
1160 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r") | |
1161 (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))] | |
1162 "" | |
1163 "@ | |
1164 srl %0,%2 | |
1165 srli %0,%#%2 | |
1166 srl3 %0,%1,%#%2" | |
1167 [(set_attr "type" "shift2,shift2,shift4") | |
1168 (set_attr "length" "2,2,4")]) | |
1169 | |
1170 ;; Compare instructions. | |
1171 ;; This controls RTL generation and register allocation. | |
1172 | |
1173 ;; We generate RTL for comparisons and branches by having the cmpxx | |
1174 ;; patterns store away the operands. Then the bcc patterns | |
1175 ;; emit RTL for both the compare and the branch. | |
1176 ;; | |
1177 ;; On the m32r it is more efficient to use the bxxz instructions and | |
1178 ;; thus merge the compare and branch into one instruction, so they are | |
1179 ;; preferred. | |
1180 | |
1181 (define_insn "cmp_eqsi_zero_insn" | |
1182 [(set (reg:CC 17) | |
1183 (eq:CC (match_operand:SI 0 "register_operand" "r,r") | |
1184 (match_operand:SI 1 "reg_or_zero_operand" "r,P")))] | |
1185 "TARGET_M32RX || TARGET_M32R2" | |
1186 "@ | |
1187 cmpeq %0, %1 | |
1188 cmpz %0" | |
1189 [(set_attr "type" "int4") | |
1190 (set_attr "length" "4")]) | |
1191 | |
1192 ;; The cmp_xxx_insn patterns set the condition bit to the result of the | |
1193 ;; comparison. There isn't a "compare equal" instruction so cmp_eqsi_insn | |
1194 ;; is quite inefficient. However, it is rarely used. | |
1195 | |
1196 (define_insn "cmp_eqsi_insn" | |
1197 [(set (reg:CC 17) | |
1198 (eq:CC (match_operand:SI 0 "register_operand" "r,r") | |
1199 (match_operand:SI 1 "reg_or_cmp_int16_operand" "r,P"))) | |
1200 (clobber (match_scratch:SI 2 "=&r,&r"))] | |
1201 "" | |
1202 "* | |
1203 { | |
1204 if (which_alternative == 0) | |
1205 { | |
1206 return \"mv %2,%0\;sub %2,%1\;cmpui %2,#1\"; | |
1207 } | |
1208 else | |
1209 { | |
1210 if (INTVAL (operands [1]) == 0) | |
1211 return \"cmpui %0, #1\"; | |
1212 else if (REGNO (operands [2]) == REGNO (operands [0])) | |
1213 return \"addi %0,%#%N1\;cmpui %2,#1\"; | |
1214 else | |
1215 return \"add3 %2,%0,%#%N1\;cmpui %2,#1\"; | |
1216 } | |
1217 }" | |
1218 [(set_attr "type" "multi,multi") | |
1219 (set_attr "length" "8,8")]) | |
1220 | |
1221 (define_insn "cmp_ltsi_insn" | |
1222 [(set (reg:CC 17) | |
1223 (lt:CC (match_operand:SI 0 "register_operand" "r,r") | |
1224 (match_operand:SI 1 "reg_or_int16_operand" "r,J")))] | |
1225 "" | |
1226 "@ | |
1227 cmp %0,%1 | |
1228 cmpi %0,%#%1" | |
1229 [(set_attr "type" "int2,int4") | |
1230 (set_attr "length" "2,4")]) | |
1231 | |
1232 (define_insn "cmp_ltusi_insn" | |
1233 [(set (reg:CC 17) | |
1234 (ltu:CC (match_operand:SI 0 "register_operand" "r,r") | |
1235 (match_operand:SI 1 "reg_or_int16_operand" "r,J")))] | |
1236 "" | |
1237 "@ | |
1238 cmpu %0,%1 | |
1239 cmpui %0,%#%1" | |
1240 [(set_attr "type" "int2,int4") | |
1241 (set_attr "length" "2,4")]) | |
1242 | |
1243 ;; These control RTL generation for conditional jump insns. | |
1244 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1245 (define_expand "cbranchsi4" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1246 ; the comparison is emitted by gen_compare if needed. |
0 | 1247 [(set (pc) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1248 (if_then_else (match_operator 0 "ordered_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1249 [(match_operand:SI 1 "register_operand" "") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1250 (match_operand:SI 2 "reg_or_cmp_int16_operand" "")]) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1251 (label_ref (match_operand 3 "" "")) |
0 | 1252 (pc)))] |
1253 "" | |
1254 " | |
1255 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1256 operands[0] = gen_compare (GET_CODE (operands[0]), operands[1], operands[2], FALSE); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1257 operands[1] = XEXP (operands[0], 0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1258 operands[2] = XEXP (operands[0], 1); |
0 | 1259 }") |
1260 | |
1261 ;; Now match both normal and inverted jump. | |
1262 | |
1263 (define_insn "*branch_insn" | |
1264 [(set (pc) | |
1265 (if_then_else (match_operator 1 "eqne_comparison_operator" | |
1266 [(reg 17) (const_int 0)]) | |
1267 (label_ref (match_operand 0 "" "")) | |
1268 (pc)))] | |
1269 "" | |
1270 "* | |
1271 { | |
1272 static char instruction[40]; | |
1273 sprintf (instruction, \"%s%s %%l0\", | |
1274 (GET_CODE (operands[1]) == NE) ? \"bc\" : \"bnc\", | |
1275 (get_attr_length (insn) == 2) ? \".s\" : \"\"); | |
1276 return instruction; | |
1277 }" | |
1278 [(set_attr "type" "branch") | |
1279 ; cf PR gcc/28508 | |
1280 ; We use 300/600 instead of 512,1024 to account for inaccurate insn | |
1281 ; lengths and insn alignments that are complex to track. | |
1282 ; It's not important that we be hyper-precise here. It may be more | |
1283 ; important blah blah blah when the chip supports parallel execution | |
1284 ; blah blah blah but until then blah blah blah this is simple and | |
1285 ; suffices. | |
1286 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) | |
1287 (const_int 300)) | |
1288 (const_int 600)) | |
1289 (const_int 2) | |
1290 (const_int 4)))]) | |
1291 | |
1292 (define_insn "*rev_branch_insn" | |
1293 [(set (pc) | |
1294 (if_then_else (match_operator 1 "eqne_comparison_operator" | |
1295 [(reg 17) (const_int 0)]) | |
1296 (pc) | |
1297 (label_ref (match_operand 0 "" ""))))] | |
1298 ;"REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))" | |
1299 "" | |
1300 "* | |
1301 { | |
1302 static char instruction[40]; | |
1303 sprintf (instruction, \"%s%s %%l0\", | |
1304 (GET_CODE (operands[1]) == EQ) ? \"bc\" : \"bnc\", | |
1305 (get_attr_length (insn) == 2) ? \".s\" : \"\"); | |
1306 return instruction; | |
1307 }" | |
1308 [(set_attr "type" "branch") | |
1309 ; cf PR gcc/28508 | |
1310 ; We use 300/600 instead of 512,1024 to account for inaccurate insn | |
1311 ; lengths and insn alignments that are complex to track. | |
1312 ; It's not important that we be hyper-precise here. It may be more | |
1313 ; important blah blah blah when the chip supports parallel execution | |
1314 ; blah blah blah but until then blah blah blah this is simple and | |
1315 ; suffices. | |
1316 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) | |
1317 (const_int 300)) | |
1318 (const_int 600)) | |
1319 (const_int 2) | |
1320 (const_int 4)))]) | |
1321 | |
1322 ; reg/reg compare and branch insns | |
1323 | |
1324 (define_insn "*reg_branch_insn" | |
1325 [(set (pc) | |
1326 (if_then_else (match_operator 1 "eqne_comparison_operator" | |
1327 [(match_operand:SI 2 "register_operand" "r") | |
1328 (match_operand:SI 3 "register_operand" "r")]) | |
1329 (label_ref (match_operand 0 "" "")) | |
1330 (pc)))] | |
1331 "" | |
1332 "* | |
1333 { | |
1334 /* Is branch target reachable with beq/bne? */ | |
1335 if (get_attr_length (insn) == 4) | |
1336 { | |
1337 if (GET_CODE (operands[1]) == EQ) | |
1338 return \"beq %2,%3,%l0\"; | |
1339 else | |
1340 return \"bne %2,%3,%l0\"; | |
1341 } | |
1342 else | |
1343 { | |
1344 if (GET_CODE (operands[1]) == EQ) | |
1345 return \"bne %2,%3,1f\;bra %l0\;1:\"; | |
1346 else | |
1347 return \"beq %2,%3,1f\;bra %l0\;1:\"; | |
1348 } | |
1349 }" | |
1350 [(set_attr "type" "branch") | |
1351 ; We use 25000/50000 instead of 32768/65536 to account for slot filling | |
1352 ; which is complex to track and inaccurate length specs. | |
1353 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) | |
1354 (const_int 25000)) | |
1355 (const_int 50000)) | |
1356 (const_int 4) | |
1357 (const_int 8)))]) | |
1358 | |
1359 (define_insn "*rev_reg_branch_insn" | |
1360 [(set (pc) | |
1361 (if_then_else (match_operator 1 "eqne_comparison_operator" | |
1362 [(match_operand:SI 2 "register_operand" "r") | |
1363 (match_operand:SI 3 "register_operand" "r")]) | |
1364 (pc) | |
1365 (label_ref (match_operand 0 "" ""))))] | |
1366 "" | |
1367 "* | |
1368 { | |
1369 /* Is branch target reachable with beq/bne? */ | |
1370 if (get_attr_length (insn) == 4) | |
1371 { | |
1372 if (GET_CODE (operands[1]) == NE) | |
1373 return \"beq %2,%3,%l0\"; | |
1374 else | |
1375 return \"bne %2,%3,%l0\"; | |
1376 } | |
1377 else | |
1378 { | |
1379 if (GET_CODE (operands[1]) == NE) | |
1380 return \"bne %2,%3,1f\;bra %l0\;1:\"; | |
1381 else | |
1382 return \"beq %2,%3,1f\;bra %l0\;1:\"; | |
1383 } | |
1384 }" | |
1385 [(set_attr "type" "branch") | |
1386 ; We use 25000/50000 instead of 32768/65536 to account for slot filling | |
1387 ; which is complex to track and inaccurate length specs. | |
1388 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) | |
1389 (const_int 25000)) | |
1390 (const_int 50000)) | |
1391 (const_int 4) | |
1392 (const_int 8)))]) | |
1393 | |
1394 ; reg/zero compare and branch insns | |
1395 | |
1396 (define_insn "*zero_branch_insn" | |
1397 [(set (pc) | |
1398 (if_then_else (match_operator 1 "signed_comparison_operator" | |
1399 [(match_operand:SI 2 "register_operand" "r") | |
1400 (const_int 0)]) | |
1401 (label_ref (match_operand 0 "" "")) | |
1402 (pc)))] | |
1403 "" | |
1404 "* | |
1405 { | |
1406 const char *br,*invbr; | |
1407 char asmtext[40]; | |
1408 | |
1409 switch (GET_CODE (operands[1])) | |
1410 { | |
1411 case EQ : br = \"eq\"; invbr = \"ne\"; break; | |
1412 case NE : br = \"ne\"; invbr = \"eq\"; break; | |
1413 case LE : br = \"le\"; invbr = \"gt\"; break; | |
1414 case GT : br = \"gt\"; invbr = \"le\"; break; | |
1415 case LT : br = \"lt\"; invbr = \"ge\"; break; | |
1416 case GE : br = \"ge\"; invbr = \"lt\"; break; | |
1417 | |
1418 default: gcc_unreachable (); | |
1419 } | |
1420 | |
1421 /* Is branch target reachable with bxxz? */ | |
1422 if (get_attr_length (insn) == 4) | |
1423 { | |
1424 sprintf (asmtext, \"b%sz %%2,%%l0\", br); | |
1425 output_asm_insn (asmtext, operands); | |
1426 } | |
1427 else | |
1428 { | |
1429 sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", invbr); | |
1430 output_asm_insn (asmtext, operands); | |
1431 } | |
1432 return \"\"; | |
1433 }" | |
1434 [(set_attr "type" "branch") | |
1435 ; We use 25000/50000 instead of 32768/65536 to account for slot filling | |
1436 ; which is complex to track and inaccurate length specs. | |
1437 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) | |
1438 (const_int 25000)) | |
1439 (const_int 50000)) | |
1440 (const_int 4) | |
1441 (const_int 8)))]) | |
1442 | |
1443 (define_insn "*rev_zero_branch_insn" | |
1444 [(set (pc) | |
1445 (if_then_else (match_operator 1 "eqne_comparison_operator" | |
1446 [(match_operand:SI 2 "register_operand" "r") | |
1447 (const_int 0)]) | |
1448 (pc) | |
1449 (label_ref (match_operand 0 "" ""))))] | |
1450 "" | |
1451 "* | |
1452 { | |
1453 const char *br,*invbr; | |
1454 char asmtext[40]; | |
1455 | |
1456 switch (GET_CODE (operands[1])) | |
1457 { | |
1458 case EQ : br = \"eq\"; invbr = \"ne\"; break; | |
1459 case NE : br = \"ne\"; invbr = \"eq\"; break; | |
1460 case LE : br = \"le\"; invbr = \"gt\"; break; | |
1461 case GT : br = \"gt\"; invbr = \"le\"; break; | |
1462 case LT : br = \"lt\"; invbr = \"ge\"; break; | |
1463 case GE : br = \"ge\"; invbr = \"lt\"; break; | |
1464 | |
1465 default: gcc_unreachable (); | |
1466 } | |
1467 | |
1468 /* Is branch target reachable with bxxz? */ | |
1469 if (get_attr_length (insn) == 4) | |
1470 { | |
1471 sprintf (asmtext, \"b%sz %%2,%%l0\", invbr); | |
1472 output_asm_insn (asmtext, operands); | |
1473 } | |
1474 else | |
1475 { | |
1476 sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", br); | |
1477 output_asm_insn (asmtext, operands); | |
1478 } | |
1479 return \"\"; | |
1480 }" | |
1481 [(set_attr "type" "branch") | |
1482 ; We use 25000/50000 instead of 32768/65536 to account for slot filling | |
1483 ; which is complex to track and inaccurate length specs. | |
1484 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) | |
1485 (const_int 25000)) | |
1486 (const_int 50000)) | |
1487 (const_int 4) | |
1488 (const_int 8)))]) | |
1489 | |
1490 ;; S<cc> operations to set a register to 1/0 based on a comparison | |
1491 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1492 (define_expand "cstoresi4" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1493 [(match_operand:SI 0 "register_operand" "") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1494 (match_operator:SI 1 "ordered_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1495 [(match_operand:SI 2 "register_operand" "") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1496 (match_operand:SI 3 "reg_or_cmp_int16_operand" "")])] |
0 | 1497 "" |
1498 " | |
1499 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1500 if (GET_MODE (operands[0]) != SImode) |
0 | 1501 FAIL; |
1502 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1503 if (!gen_cond_store (GET_CODE (operands[1]), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1504 operands[0], operands[2], operands[3])) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1505 FAIL; |
0 | 1506 |
1507 DONE; | |
1508 }") | |
1509 | |
1510 (define_insn "seq_insn_m32rx" | |
1511 [(set (match_operand:SI 0 "register_operand" "=r") | |
1512 (eq:SI (match_operand:SI 1 "register_operand" "%r") | |
1513 (match_operand:SI 2 "reg_or_zero_operand" "rP"))) | |
1514 (clobber (reg:CC 17))] | |
1515 "TARGET_M32RX || TARGET_M32R2" | |
1516 "#" | |
1517 [(set_attr "type" "multi") | |
1518 (set_attr "length" "6")]) | |
1519 | |
1520 (define_split | |
1521 [(set (match_operand:SI 0 "register_operand" "") | |
1522 (eq:SI (match_operand:SI 1 "register_operand" "") | |
1523 (match_operand:SI 2 "reg_or_zero_operand" ""))) | |
1524 (clobber (reg:CC 17))] | |
1525 "TARGET_M32RX || TARGET_M32R2" | |
1526 [(set (reg:CC 17) | |
1527 (eq:CC (match_dup 1) | |
1528 (match_dup 2))) | |
1529 (set (match_dup 0) | |
1530 (ne:SI (reg:CC 17) (const_int 0)))] | |
1531 "") | |
1532 | |
1533 (define_insn "seq_zero_insn" | |
1534 [(set (match_operand:SI 0 "register_operand" "=r") | |
1535 (eq:SI (match_operand:SI 1 "register_operand" "r") | |
1536 (const_int 0))) | |
1537 (clobber (reg:CC 17))] | |
1538 "TARGET_M32R" | |
1539 "#" | |
1540 [(set_attr "type" "multi") | |
1541 (set_attr "length" "6")]) | |
1542 | |
1543 (define_split | |
1544 [(set (match_operand:SI 0 "register_operand" "") | |
1545 (eq:SI (match_operand:SI 1 "register_operand" "") | |
1546 (const_int 0))) | |
1547 (clobber (reg:CC 17))] | |
1548 "TARGET_M32R" | |
1549 [(match_dup 3)] | |
1550 " | |
1551 { | |
1552 rtx op0 = operands[0]; | |
1553 rtx op1 = operands[1]; | |
1554 | |
1555 start_sequence (); | |
1556 emit_insn (gen_cmp_ltusi_insn (op1, const1_rtx)); | |
1557 emit_insn (gen_movcc_insn (op0)); | |
1558 operands[3] = get_insns (); | |
1559 end_sequence (); | |
1560 }") | |
1561 | |
1562 (define_insn "seq_insn" | |
1563 [(set (match_operand:SI 0 "register_operand" "=r,r,??r,r") | |
1564 (eq:SI (match_operand:SI 1 "register_operand" "r,r,r,r") | |
1565 (match_operand:SI 2 "reg_or_eq_int16_operand" "r,r,r,PK"))) | |
1566 (clobber (reg:CC 17)) | |
1567 (clobber (match_scratch:SI 3 "=1,2,&r,r"))] | |
1568 "TARGET_M32R" | |
1569 "#" | |
1570 [(set_attr "type" "multi") | |
1571 (set_attr "length" "8,8,10,10")]) | |
1572 | |
1573 (define_split | |
1574 [(set (match_operand:SI 0 "register_operand" "") | |
1575 (eq:SI (match_operand:SI 1 "register_operand" "") | |
1576 (match_operand:SI 2 "reg_or_eq_int16_operand" ""))) | |
1577 (clobber (reg:CC 17)) | |
1578 (clobber (match_scratch:SI 3 ""))] | |
1579 "TARGET_M32R && reload_completed" | |
1580 [(match_dup 4)] | |
1581 " | |
1582 { | |
1583 rtx op0 = operands[0]; | |
1584 rtx op1 = operands[1]; | |
1585 rtx op2 = operands[2]; | |
1586 rtx op3 = operands[3]; | |
1587 HOST_WIDE_INT value; | |
1588 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1589 if (REG_P (op2) && REG_P (op3) |
0 | 1590 && REGNO (op2) == REGNO (op3)) |
1591 { | |
1592 op1 = operands[2]; | |
1593 op2 = operands[1]; | |
1594 } | |
1595 | |
1596 start_sequence (); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1597 if (REG_P (op1) && REG_P (op3) |
0 | 1598 && REGNO (op1) != REGNO (op3)) |
1599 { | |
1600 emit_move_insn (op3, op1); | |
1601 op1 = op3; | |
1602 } | |
1603 | |
1604 if (satisfies_constraint_P (op2) && (value = INTVAL (op2)) != 0) | |
1605 emit_insn (gen_addsi3 (op3, op1, GEN_INT (-value))); | |
1606 else | |
1607 emit_insn (gen_xorsi3 (op3, op1, op2)); | |
1608 | |
1609 emit_insn (gen_cmp_ltusi_insn (op3, const1_rtx)); | |
1610 emit_insn (gen_movcc_insn (op0)); | |
1611 operands[4] = get_insns (); | |
1612 end_sequence (); | |
1613 }") | |
1614 | |
1615 (define_insn "sne_zero_insn" | |
1616 [(set (match_operand:SI 0 "register_operand" "=r") | |
1617 (ne:SI (match_operand:SI 1 "register_operand" "r") | |
1618 (const_int 0))) | |
1619 (clobber (reg:CC 17)) | |
1620 (clobber (match_scratch:SI 2 "=&r"))] | |
1621 "" | |
1622 "#" | |
1623 [(set_attr "type" "multi") | |
1624 (set_attr "length" "6")]) | |
1625 | |
1626 (define_split | |
1627 [(set (match_operand:SI 0 "register_operand" "") | |
1628 (ne:SI (match_operand:SI 1 "register_operand" "") | |
1629 (const_int 0))) | |
1630 (clobber (reg:CC 17)) | |
1631 (clobber (match_scratch:SI 2 ""))] | |
1632 "reload_completed" | |
1633 [(set (match_dup 2) | |
1634 (const_int 0)) | |
1635 (set (reg:CC 17) | |
1636 (ltu:CC (match_dup 2) | |
1637 (match_dup 1))) | |
1638 (set (match_dup 0) | |
1639 (ne:SI (reg:CC 17) (const_int 0)))] | |
1640 "") | |
1641 | |
1642 (define_insn "slt_insn" | |
1643 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1644 (lt:SI (match_operand:SI 1 "register_operand" "r,r") | |
1645 (match_operand:SI 2 "reg_or_int16_operand" "r,J"))) | |
1646 (clobber (reg:CC 17))] | |
1647 "" | |
1648 "#" | |
1649 [(set_attr "type" "multi") | |
1650 (set_attr "length" "4,6")]) | |
1651 | |
1652 (define_split | |
1653 [(set (match_operand:SI 0 "register_operand" "") | |
1654 (lt:SI (match_operand:SI 1 "register_operand" "") | |
1655 (match_operand:SI 2 "reg_or_int16_operand" ""))) | |
1656 (clobber (reg:CC 17))] | |
1657 "" | |
1658 [(set (reg:CC 17) | |
1659 (lt:CC (match_dup 1) | |
1660 (match_dup 2))) | |
1661 (set (match_dup 0) | |
1662 (ne:SI (reg:CC 17) (const_int 0)))] | |
1663 "") | |
1664 | |
1665 (define_insn "sle_insn" | |
1666 [(set (match_operand:SI 0 "register_operand" "=r") | |
1667 (le:SI (match_operand:SI 1 "register_operand" "r") | |
1668 (match_operand:SI 2 "register_operand" "r"))) | |
1669 (clobber (reg:CC 17))] | |
1670 "" | |
1671 "#" | |
1672 [(set_attr "type" "multi") | |
1673 (set_attr "length" "8")]) | |
1674 | |
1675 (define_split | |
1676 [(set (match_operand:SI 0 "register_operand" "") | |
1677 (le:SI (match_operand:SI 1 "register_operand" "") | |
1678 (match_operand:SI 2 "register_operand" ""))) | |
1679 (clobber (reg:CC 17))] | |
1680 "!optimize_size" | |
1681 [(set (reg:CC 17) | |
1682 (lt:CC (match_dup 2) | |
1683 (match_dup 1))) | |
1684 (set (match_dup 0) | |
1685 (ne:SI (reg:CC 17) (const_int 0))) | |
1686 (set (match_dup 0) | |
1687 (xor:SI (match_dup 0) | |
1688 (const_int 1)))] | |
1689 "") | |
1690 | |
1691 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than | |
1692 ;; xor reg,reg,1 which might eliminate a NOP being inserted. | |
1693 (define_split | |
1694 [(set (match_operand:SI 0 "register_operand" "") | |
1695 (le:SI (match_operand:SI 1 "register_operand" "") | |
1696 (match_operand:SI 2 "register_operand" ""))) | |
1697 (clobber (reg:CC 17))] | |
1698 "optimize_size" | |
1699 [(set (reg:CC 17) | |
1700 (lt:CC (match_dup 2) | |
1701 (match_dup 1))) | |
1702 (set (match_dup 0) | |
1703 (ne:SI (reg:CC 17) (const_int 0))) | |
1704 (set (match_dup 0) | |
1705 (plus:SI (match_dup 0) | |
1706 (const_int -1))) | |
1707 (set (match_dup 0) | |
1708 (neg:SI (match_dup 0)))] | |
1709 "") | |
1710 | |
1711 (define_insn "sge_insn" | |
1712 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1713 (ge:SI (match_operand:SI 1 "register_operand" "r,r") | |
1714 (match_operand:SI 2 "reg_or_int16_operand" "r,J"))) | |
1715 (clobber (reg:CC 17))] | |
1716 "" | |
1717 "#" | |
1718 [(set_attr "type" "multi") | |
1719 (set_attr "length" "8,10")]) | |
1720 | |
1721 (define_split | |
1722 [(set (match_operand:SI 0 "register_operand" "") | |
1723 (ge:SI (match_operand:SI 1 "register_operand" "") | |
1724 (match_operand:SI 2 "reg_or_int16_operand" ""))) | |
1725 (clobber (reg:CC 17))] | |
1726 "!optimize_size" | |
1727 [(set (reg:CC 17) | |
1728 (lt:CC (match_dup 1) | |
1729 (match_dup 2))) | |
1730 (set (match_dup 0) | |
1731 (ne:SI (reg:CC 17) (const_int 0))) | |
1732 (set (match_dup 0) | |
1733 (xor:SI (match_dup 0) | |
1734 (const_int 1)))] | |
1735 "") | |
1736 | |
1737 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than | |
1738 ;; xor reg,reg,1 which might eliminate a NOP being inserted. | |
1739 (define_split | |
1740 [(set (match_operand:SI 0 "register_operand" "") | |
1741 (ge:SI (match_operand:SI 1 "register_operand" "") | |
1742 (match_operand:SI 2 "reg_or_int16_operand" ""))) | |
1743 (clobber (reg:CC 17))] | |
1744 "optimize_size" | |
1745 [(set (reg:CC 17) | |
1746 (lt:CC (match_dup 1) | |
1747 (match_dup 2))) | |
1748 (set (match_dup 0) | |
1749 (ne:SI (reg:CC 17) (const_int 0))) | |
1750 (set (match_dup 0) | |
1751 (plus:SI (match_dup 0) | |
1752 (const_int -1))) | |
1753 (set (match_dup 0) | |
1754 (neg:SI (match_dup 0)))] | |
1755 "") | |
1756 | |
1757 (define_insn "sltu_insn" | |
1758 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1759 (ltu:SI (match_operand:SI 1 "register_operand" "r,r") | |
1760 (match_operand:SI 2 "reg_or_int16_operand" "r,J"))) | |
1761 (clobber (reg:CC 17))] | |
1762 "" | |
1763 "#" | |
1764 [(set_attr "type" "multi") | |
1765 (set_attr "length" "6,8")]) | |
1766 | |
1767 (define_split | |
1768 [(set (match_operand:SI 0 "register_operand" "") | |
1769 (ltu:SI (match_operand:SI 1 "register_operand" "") | |
1770 (match_operand:SI 2 "reg_or_int16_operand" ""))) | |
1771 (clobber (reg:CC 17))] | |
1772 "" | |
1773 [(set (reg:CC 17) | |
1774 (ltu:CC (match_dup 1) | |
1775 (match_dup 2))) | |
1776 (set (match_dup 0) | |
1777 (ne:SI (reg:CC 17) (const_int 0)))] | |
1778 "") | |
1779 | |
1780 (define_insn "sleu_insn" | |
1781 [(set (match_operand:SI 0 "register_operand" "=r") | |
1782 (leu:SI (match_operand:SI 1 "register_operand" "r") | |
1783 (match_operand:SI 2 "register_operand" "r"))) | |
1784 (clobber (reg:CC 17))] | |
1785 "" | |
1786 "#" | |
1787 [(set_attr "type" "multi") | |
1788 (set_attr "length" "8")]) | |
1789 | |
1790 (define_split | |
1791 [(set (match_operand:SI 0 "register_operand" "") | |
1792 (leu:SI (match_operand:SI 1 "register_operand" "") | |
1793 (match_operand:SI 2 "register_operand" ""))) | |
1794 (clobber (reg:CC 17))] | |
1795 "!optimize_size" | |
1796 [(set (reg:CC 17) | |
1797 (ltu:CC (match_dup 2) | |
1798 (match_dup 1))) | |
1799 (set (match_dup 0) | |
1800 (ne:SI (reg:CC 17) (const_int 0))) | |
1801 (set (match_dup 0) | |
1802 (xor:SI (match_dup 0) | |
1803 (const_int 1)))] | |
1804 "") | |
1805 | |
1806 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than | |
1807 ;; xor reg,reg,1 which might eliminate a NOP being inserted. | |
1808 (define_split | |
1809 [(set (match_operand:SI 0 "register_operand" "") | |
1810 (leu:SI (match_operand:SI 1 "register_operand" "") | |
1811 (match_operand:SI 2 "register_operand" ""))) | |
1812 (clobber (reg:CC 17))] | |
1813 "optimize_size" | |
1814 [(set (reg:CC 17) | |
1815 (ltu:CC (match_dup 2) | |
1816 (match_dup 1))) | |
1817 (set (match_dup 0) | |
1818 (ne:SI (reg:CC 17) (const_int 0))) | |
1819 (set (match_dup 0) | |
1820 (plus:SI (match_dup 0) | |
1821 (const_int -1))) | |
1822 (set (match_dup 0) | |
1823 (neg:SI (match_dup 0)))] | |
1824 "") | |
1825 | |
1826 (define_insn "sgeu_insn" | |
1827 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
1828 (geu:SI (match_operand:SI 1 "register_operand" "r,r") | |
1829 (match_operand:SI 2 "reg_or_int16_operand" "r,J"))) | |
1830 (clobber (reg:CC 17))] | |
1831 "" | |
1832 "#" | |
1833 [(set_attr "type" "multi") | |
1834 (set_attr "length" "8,10")]) | |
1835 | |
1836 (define_split | |
1837 [(set (match_operand:SI 0 "register_operand" "") | |
1838 (geu:SI (match_operand:SI 1 "register_operand" "") | |
1839 (match_operand:SI 2 "reg_or_int16_operand" ""))) | |
1840 (clobber (reg:CC 17))] | |
1841 "!optimize_size" | |
1842 [(set (reg:CC 17) | |
1843 (ltu:CC (match_dup 1) | |
1844 (match_dup 2))) | |
1845 (set (match_dup 0) | |
1846 (ne:SI (reg:CC 17) (const_int 0))) | |
1847 (set (match_dup 0) | |
1848 (xor:SI (match_dup 0) | |
1849 (const_int 1)))] | |
1850 "") | |
1851 | |
1852 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than | |
1853 ;; xor reg,reg,1 which might eliminate a NOP being inserted. | |
1854 (define_split | |
1855 [(set (match_operand:SI 0 "register_operand" "") | |
1856 (geu:SI (match_operand:SI 1 "register_operand" "") | |
1857 (match_operand:SI 2 "reg_or_int16_operand" ""))) | |
1858 (clobber (reg:CC 17))] | |
1859 "optimize_size" | |
1860 [(set (reg:CC 17) | |
1861 (ltu:CC (match_dup 1) | |
1862 (match_dup 2))) | |
1863 (set (match_dup 0) | |
1864 (ne:SI (reg:CC 17) (const_int 0))) | |
1865 (set (match_dup 0) | |
1866 (plus:SI (match_dup 0) | |
1867 (const_int -1))) | |
1868 (set (match_dup 0) | |
1869 (neg:SI (match_dup 0)))] | |
1870 "") | |
1871 | |
1872 (define_insn "movcc_insn" | |
1873 [(set (match_operand:SI 0 "register_operand" "=r") | |
1874 (ne:SI (reg:CC 17) (const_int 0)))] | |
1875 "" | |
1876 "mvfc %0, cbr" | |
1877 [(set_attr "type" "misc") | |
1878 (set_attr "length" "2")]) | |
1879 | |
1880 | |
1881 ;; Unconditional and other jump instructions. | |
1882 | |
1883 (define_insn "jump" | |
1884 [(set (pc) (label_ref (match_operand 0 "" "")))] | |
1885 "" | |
1886 "bra %l0" | |
1887 [(set_attr "type" "uncond_branch") | |
1888 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) | |
1889 (const_int 400)) | |
1890 (const_int 800)) | |
1891 (const_int 2) | |
1892 (const_int 4)))]) | |
1893 | |
1894 (define_insn "indirect_jump" | |
1895 [(set (pc) (match_operand:SI 0 "address_operand" "p"))] | |
1896 "" | |
1897 "jmp %a0" | |
1898 [(set_attr "type" "uncond_branch") | |
1899 (set_attr "length" "2")]) | |
1900 | |
1901 (define_insn "return_lr" | |
1902 [(parallel [(return) (use (reg:SI 14))])] | |
1903 "" | |
1904 "jmp lr" | |
1905 [(set_attr "type" "uncond_branch") | |
1906 (set_attr "length" "2")]) | |
1907 | |
1908 (define_insn "return_rte" | |
1909 [(return)] | |
1910 "" | |
1911 "rte" | |
1912 [(set_attr "type" "uncond_branch") | |
1913 (set_attr "length" "2")]) | |
1914 | |
1915 (define_expand "return" | |
1916 [(return)] | |
1917 "direct_return ()" | |
1918 " | |
1919 { | |
1920 emit_jump_insn (gen_return_lr ()); | |
1921 DONE; | |
1922 }") | |
1923 | |
1924 (define_expand "return_normal" | |
1925 [(return)] | |
1926 "!direct_return ()" | |
1927 " | |
1928 { | |
1929 enum m32r_function_type fn_type; | |
1930 | |
1931 fn_type = m32r_compute_function_type (current_function_decl); | |
1932 if (M32R_INTERRUPT_P (fn_type)) | |
1933 { | |
1934 emit_jump_insn (gen_return_rte ()); | |
1935 DONE; | |
1936 } | |
1937 | |
1938 emit_jump_insn (gen_return_lr ()); | |
1939 DONE; | |
1940 }") | |
1941 | |
1942 (define_expand "tablejump" | |
1943 [(parallel [(set (pc) (match_operand 0 "register_operand" "r")) | |
1944 (use (label_ref (match_operand 1 "" "")))])] | |
1945 "" | |
1946 " | |
1947 { | |
1948 /* In pic mode, our address differences are against the base of the | |
1949 table. Add that base value back in; CSE ought to be able to combine | |
1950 the two address loads. */ | |
1951 if (flag_pic) | |
1952 { | |
1953 rtx tmp, tmp2; | |
1954 | |
1955 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]); | |
1956 tmp2 = operands[0]; | |
1957 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp); | |
1958 operands[0] = memory_address (Pmode, tmp); | |
1959 } | |
1960 }") | |
1961 | |
1962 (define_insn "*tablejump_insn" | |
1963 [(set (pc) (match_operand:SI 0 "address_operand" "p")) | |
1964 (use (label_ref (match_operand 1 "" "")))] | |
1965 "" | |
1966 "jmp %a0" | |
1967 [(set_attr "type" "uncond_branch") | |
1968 (set_attr "length" "2")]) | |
1969 | |
1970 (define_expand "call" | |
1971 ;; operands[1] is stack_size_rtx | |
1972 ;; operands[2] is next_arg_register | |
1973 [(parallel [(call (match_operand:SI 0 "call_operand" "") | |
1974 (match_operand 1 "" "")) | |
1975 (clobber (reg:SI 14))])] | |
1976 "" | |
1977 " | |
1978 { | |
1979 if (flag_pic) | |
1980 crtl->uses_pic_offset_table = 1; | |
1981 }") | |
1982 | |
1983 (define_insn "*call_via_reg" | |
1984 [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) | |
1985 (match_operand 1 "" "")) | |
1986 (clobber (reg:SI 14))] | |
1987 "" | |
1988 "jl %0" | |
1989 [(set_attr "type" "call") | |
1990 (set_attr "length" "2")]) | |
1991 | |
1992 (define_insn "*call_via_label" | |
1993 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "")) | |
1994 (match_operand 1 "" "")) | |
1995 (clobber (reg:SI 14))] | |
1996 "" | |
1997 "* | |
1998 { | |
1999 int call26_p = call26_operand (operands[0], FUNCTION_MODE); | |
2000 | |
2001 if (! call26_p) | |
2002 { | |
2003 /* We may not be able to reach with a `bl' insn so punt and leave it to | |
2004 the linker. | |
2005 We do this here, rather than doing a force_reg in the define_expand | |
2006 so these insns won't be separated, say by scheduling, thus simplifying | |
2007 the linker. */ | |
2008 return \"seth r14,%T0\;add3 r14,r14,%B0\;jl r14\"; | |
2009 } | |
2010 else | |
2011 return \"bl %0\"; | |
2012 }" | |
2013 [(set_attr "type" "call") | |
2014 (set (attr "length") | |
2015 (if_then_else (eq (symbol_ref "call26_operand (operands[0], FUNCTION_MODE)") | |
2016 (const_int 0)) | |
2017 (const_int 12) ; 10 + 2 for nop filler | |
2018 ; The return address must be on a 4 byte boundary so | |
2019 ; there's no point in using a value of 2 here. A 2 byte | |
2020 ; insn may go in the left slot but we currently can't | |
2021 ; use such knowledge. | |
2022 (const_int 4)))]) | |
2023 | |
2024 (define_expand "call_value" | |
2025 ;; operand 2 is stack_size_rtx | |
2026 ;; operand 3 is next_arg_register | |
2027 [(parallel [(set (match_operand 0 "register_operand" "=r") | |
2028 (call (match_operand:SI 1 "call_operand" "") | |
2029 (match_operand 2 "" ""))) | |
2030 (clobber (reg:SI 14))])] | |
2031 "" | |
2032 " | |
2033 { | |
2034 if (flag_pic) | |
2035 crtl->uses_pic_offset_table = 1; | |
2036 }") | |
2037 | |
2038 (define_insn "*call_value_via_reg" | |
2039 [(set (match_operand 0 "register_operand" "=r") | |
2040 (call (mem:SI (match_operand:SI 1 "register_operand" "r")) | |
2041 (match_operand 2 "" ""))) | |
2042 (clobber (reg:SI 14))] | |
2043 "" | |
2044 "jl %1" | |
2045 [(set_attr "type" "call") | |
2046 (set_attr "length" "2")]) | |
2047 | |
2048 (define_insn "*call_value_via_label" | |
2049 [(set (match_operand 0 "register_operand" "=r") | |
2050 (call (mem:SI (match_operand:SI 1 "call_address_operand" "")) | |
2051 (match_operand 2 "" ""))) | |
2052 (clobber (reg:SI 14))] | |
2053 "" | |
2054 "* | |
2055 { | |
2056 int call26_p = call26_operand (operands[1], FUNCTION_MODE); | |
2057 | |
2058 if (flag_pic) | |
2059 crtl->uses_pic_offset_table = 1; | |
2060 | |
2061 if (! call26_p) | |
2062 { | |
2063 /* We may not be able to reach with a `bl' insn so punt and leave it to | |
2064 the linker. | |
2065 We do this here, rather than doing a force_reg in the define_expand | |
2066 so these insns won't be separated, say by scheduling, thus simplifying | |
2067 the linker. */ | |
2068 return \"seth r14,%T1\;add3 r14,r14,%B1\;jl r14\"; | |
2069 } | |
2070 else | |
2071 return \"bl %1\"; | |
2072 }" | |
2073 [(set_attr "type" "call") | |
2074 (set (attr "length") | |
2075 (if_then_else (eq (symbol_ref "call26_operand (operands[1], FUNCTION_MODE)") | |
2076 (const_int 0)) | |
2077 (const_int 12) ; 10 + 2 for nop filler | |
2078 ; The return address must be on a 4 byte boundary so | |
2079 ; there's no point in using a value of 2 here. A 2 byte | |
2080 ; insn may go in the left slot but we currently can't | |
2081 ; use such knowledge. | |
2082 (const_int 4)))]) | |
2083 | |
2084 (define_insn "nop" | |
2085 [(const_int 0)] | |
2086 "" | |
2087 "nop" | |
2088 [(set_attr "type" "int2") | |
2089 (set_attr "length" "2")]) | |
2090 | |
2091 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and | |
2092 ;; all of memory. This blocks insns from being moved across this point. | |
2093 | |
2094 (define_insn "blockage" | |
2095 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] | |
2096 "" | |
2097 "") | |
2098 | |
2099 ;; Special pattern to flush the icache. | |
2100 | |
2101 (define_insn "flush_icache" | |
2102 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] | |
2103 UNSPECV_FLUSH_ICACHE) | |
2104 (match_operand 1 "" "") | |
2105 (clobber (reg:SI 17))] | |
2106 "" | |
2107 "* return \"trap %#%1 ; flush-icache\";" | |
2108 [(set_attr "type" "int4") | |
2109 (set_attr "length" "4")]) | |
2110 | |
2111 ;; Speed up fabs and provide correct sign handling for -0 | |
2112 | |
2113 (define_insn "absdf2" | |
2114 [(set (match_operand:DF 0 "register_operand" "=r") | |
2115 (abs:DF (match_operand:DF 1 "register_operand" "0")))] | |
2116 "" | |
2117 "#" | |
2118 [(set_attr "type" "multi") | |
2119 (set_attr "length" "4")]) | |
2120 | |
2121 (define_split | |
2122 [(set (match_operand:DF 0 "register_operand" "") | |
2123 (abs:DF (match_operand:DF 1 "register_operand" "")))] | |
2124 "reload_completed" | |
2125 [(set (match_dup 2) | |
2126 (ashift:SI (match_dup 2) | |
2127 (const_int 1))) | |
2128 (set (match_dup 2) | |
2129 (lshiftrt:SI (match_dup 2) | |
2130 (const_int 1)))] | |
2131 "operands[2] = gen_highpart (SImode, operands[0]);") | |
2132 | |
2133 (define_insn "abssf2" | |
2134 [(set (match_operand:SF 0 "register_operand" "=r") | |
2135 (abs:SF (match_operand:SF 1 "register_operand" "0")))] | |
2136 "" | |
2137 "#" | |
2138 [(set_attr "type" "multi") | |
2139 (set_attr "length" "4")]) | |
2140 | |
2141 (define_split | |
2142 [(set (match_operand:SF 0 "register_operand" "") | |
2143 (abs:SF (match_operand:SF 1 "register_operand" "")))] | |
2144 "reload_completed" | |
2145 [(set (match_dup 2) | |
2146 (ashift:SI (match_dup 2) | |
2147 (const_int 1))) | |
2148 (set (match_dup 2) | |
2149 (lshiftrt:SI (match_dup 2) | |
2150 (const_int 1)))] | |
2151 "operands[2] = gen_highpart (SImode, operands[0]);") | |
2152 | |
2153 ;; Conditional move instructions | |
2154 ;; Based on those done for the d10v | |
2155 | |
2156 (define_expand "movsicc" | |
2157 [ | |
2158 (set (match_operand:SI 0 "register_operand" "r") | |
2159 (if_then_else:SI (match_operand 1 "" "") | |
2160 (match_operand:SI 2 "conditional_move_operand" "O") | |
2161 (match_operand:SI 3 "conditional_move_operand" "O") | |
2162 ) | |
2163 ) | |
2164 ] | |
2165 "" | |
2166 " | |
2167 { | |
2168 if (! zero_and_one (operands [2], operands [3])) | |
2169 FAIL; | |
2170 | |
2171 /* Generate the comparison that will set the carry flag. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2172 operands[1] = gen_compare (GET_CODE (operands[1]), XEXP (operands[1], 0), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2173 XEXP (operands[1], 1), TRUE); |
0 | 2174 |
2175 /* See other movsicc pattern below for reason why. */ | |
2176 emit_insn (gen_blockage ()); | |
2177 }") | |
2178 | |
2179 ;; Generate the conditional instructions based on how the carry flag is examined. | |
2180 (define_insn "*movsicc_internal" | |
2181 [(set (match_operand:SI 0 "register_operand" "=r") | |
2182 (if_then_else:SI (match_operand 1 "carry_compare_operand" "") | |
2183 (match_operand:SI 2 "conditional_move_operand" "O") | |
2184 (match_operand:SI 3 "conditional_move_operand" "O") | |
2185 ) | |
2186 )] | |
2187 "zero_and_one (operands [2], operands[3])" | |
2188 "* return emit_cond_move (operands, insn);" | |
2189 [(set_attr "type" "multi") | |
2190 (set_attr "length" "8") | |
2191 ] | |
2192 ) | |
2193 | |
2194 | |
2195 ;; Block moves, see m32r.c for more details. | |
2196 ;; Argument 0 is the destination | |
2197 ;; Argument 1 is the source | |
2198 ;; Argument 2 is the length | |
2199 ;; Argument 3 is the alignment | |
2200 | |
2201 (define_expand "movmemsi" | |
2202 [(parallel [(set (match_operand:BLK 0 "general_operand" "") | |
2203 (match_operand:BLK 1 "general_operand" "")) | |
2204 (use (match_operand:SI 2 "immediate_operand" "")) | |
2205 (use (match_operand:SI 3 "immediate_operand" ""))])] | |
2206 "" | |
2207 " | |
2208 { | |
2209 if (operands[0]) /* Avoid unused code messages. */ | |
2210 { | |
2211 if (m32r_expand_block_move (operands)) | |
2212 DONE; | |
2213 else | |
2214 FAIL; | |
2215 } | |
2216 }") | |
2217 | |
2218 ;; Insn generated by block moves | |
2219 | |
2220 (define_insn "movmemsi_internal" | |
2221 [(set (mem:BLK (match_operand:SI 0 "register_operand" "r")) ;; destination | |
2222 (mem:BLK (match_operand:SI 1 "register_operand" "r"))) ;; source | |
2223 (use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to move | |
2224 (set (match_operand:SI 3 "register_operand" "=0") | |
2225 (plus:SI (minus (match_dup 2) (const_int 4)) | |
2226 (match_dup 0))) | |
2227 (set (match_operand:SI 4 "register_operand" "=1") | |
2228 (plus:SI (match_dup 1) | |
2229 (match_dup 2))) | |
2230 (clobber (match_scratch:SI 5 "=&r")) ;; temp1 | |
2231 (clobber (match_scratch:SI 6 "=&r"))] ;; temp2 | |
2232 "" | |
2233 "* m32r_output_block_move (insn, operands); return \"\"; " | |
2234 [(set_attr "type" "store8") | |
2235 (set_attr "length" "72")]) ;; Maximum | |
2236 | |
2237 ;; PIC | |
2238 | |
2239 /* When generating pic, we need to load the symbol offset into a register. | |
2240 So that the optimizer does not confuse this with a normal symbol load | |
2241 we use an unspec. The offset will be loaded from a constant pool entry, | |
2242 since that is the only type of relocation we can use. */ | |
2243 | |
2244 (define_insn "pic_load_addr" | |
2245 [(set (match_operand:SI 0 "register_operand" "=r") | |
2246 (unspec:SI [(match_operand 1 "" "")] UNSPEC_PIC_LOAD_ADDR))] | |
2247 "flag_pic" | |
2248 "ld24 %0,%#%1" | |
2249 [(set_attr "type" "int4")]) | |
2250 | |
2251 (define_insn "gotoff_load_addr" | |
2252 [(set (match_operand:SI 0 "register_operand" "=r") | |
2253 (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFF))] | |
2254 "flag_pic" | |
2255 "seth %0, %#shigh(%1@GOTOFF)\;add3 %0, %0, low(%1@GOTOFF)" | |
2256 [(set_attr "type" "int4") | |
2257 (set_attr "length" "8")]) | |
2258 | |
2259 ;; Load program counter insns. | |
2260 | |
2261 (define_insn "get_pc" | |
2262 [(clobber (reg:SI 14)) | |
2263 (set (match_operand 0 "register_operand" "=r,r") | |
2264 (unspec [(match_operand 1 "" "")] UNSPEC_GET_PC)) | |
2265 (use (match_operand:SI 2 "immediate_operand" "W,i"))] | |
2266 "flag_pic" | |
2267 "@ | |
2268 bl.s .+4\;seth %0,%#shigh(%1)\;add3 %0,%0,%#low(%1+4)\;add %0,lr | |
2269 bl.s .+4\;ld24 %0,%#%1\;add %0,lr" | |
2270 [(set_attr "length" "12,8")]) | |
2271 | |
2272 (define_expand "builtin_setjmp_receiver" | |
2273 [(label_ref (match_operand 0 "" ""))] | |
2274 "flag_pic" | |
2275 " | |
2276 { | |
2277 m32r_load_pic_register (); | |
2278 DONE; | |
2279 }") |