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