]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/m32r/m32r.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / m32r / m32r.md
CommitLineData
1f92da87 1;; Machine description of the Renesas M32R cpu for GNU C compiler
7adcbafe 2;; Copyright (C) 1996-2022 Free Software Foundation, Inc.
8c5ca3b9 3
7ec022b2 4;; This file is part of GCC.
8c5ca3b9 5
1f92da87
NC
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
2f83c7d6 8;; by the Free Software Foundation; either version 3, or (at your
1f92da87 9;; option) any later version.
8c5ca3b9 10
1f92da87
NC
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.
8c5ca3b9
DE
15
16;; You should have received a copy of the GNU General Public License
2f83c7d6
NC
17;; along with GCC; see the file COPYING3. If not see
18;; <http://www.gnu.org/licenses/>.
8c5ca3b9
DE
19
20;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
8c5ca3b9 21\f
a2ab189d
KH
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)
c331bf08
KI
32 (UNSPEC_GET_PC 5)
33 (UNSPEC_GOTOFF 6)
34 ])
a2ab189d 35
8c5ca3b9 36;; Insn type. Used to default other attribute values.
8c5ca3b9 37(define_attr "type"
5b8ae21f 38 "int2,int4,load2,load4,load8,store2,store4,store8,shift2,shift4,mul2,div4,uncond_branch,branch,call,multi,misc"
8c5ca3b9
DE
39 (const_string "misc"))
40
41;; Length in bytes.
42(define_attr "length" ""
5b8ae21f 43 (cond [(eq_attr "type" "int2,load2,store2,shift2,mul2")
8c5ca3b9
DE
44 (const_int 2)
45
5b8ae21f
MM
46 (eq_attr "type" "int4,load4,store4,shift4,div4")
47 (const_int 4)
8c5ca3b9
DE
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")])
2b7972b0 62
5ad6fca5 63;; Whether an instruction is short (16-bit) or long (32-bit).
2b7972b0 64(define_attr "insn_size" "short,long"
5b8ae21f 65 (if_then_else (eq_attr "type" "int2,load2,store2,shift2,mul2")
2b7972b0
MM
66 (const_string "short")
67 (const_string "long")))
68
5ad6fca5
SB
69;; The target CPU we're compiling for.
70(define_attr "cpu" "m32r,m32r2,m32rx"
f18d1d16 71 (cond [(match_test "TARGET_M32RX")
5ad6fca5 72 (const_string "m32rx")
f18d1d16 73 (match_test "TARGET_M32R2")
5ad6fca5
SB
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
18d7916e
NC
80;; condition of this attribute definition.
81(define_attr "m32r_pipeline" "either,s,o,long"
5ad6fca5
SB
82 (cond [(and (eq_attr "cpu" "m32r")
83 (eq_attr "insn_size" "short"))
84 (const_string "either")
de41e41c 85 (eq_attr "insn_size" "!short")
5ad6fca5 86 (const_string "long")]
18d7916e 87 (cond [(eq_attr "type" "int2")
5ad6fca5 88 (const_string "either")
18d7916e 89 (eq_attr "type" "load2,store2,shift2,uncond_branch,branch,call")
5ad6fca5 90 (const_string "o")
18d7916e 91 (eq_attr "type" "mul2")
5ad6fca5 92 (const_string "s")]
18d7916e 93 (const_string "long"))))
8c5ca3b9 94\f
2b7972b0
MM
95;; ::::::::::::::::::::
96;; ::
5ad6fca5 97;; :: Pipeline description
2b7972b0
MM
98;; ::
99;; ::::::::::::::::::::
100
5ad6fca5
SB
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;;
85f65093
KH
117;; In reality there is only one decoder, which can decode either two 16-bit
118;; instructions, or a single 32-bit instruction.
2b7972b0 119;;
5ad6fca5 120;; Note, "fetch" models both the IF and the D pipeline stages.
2b7972b0 121;;
5ad6fca5
SB
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.
18d7916e
NC
128(absence_set "s_IF" "o_IF")
129(absence_set "s_E" "o_E")
5ad6fca5
SB
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")
5b8ae21f
MM
148 (and (eq_attr "insn_size" "short")
149 (eq_attr "type" "!load2")))
5ad6fca5 150 "s_IF,s_E")
8c5ca3b9 151
5ad6fca5
SB
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")
8c5ca3b9 157
5ad6fca5
SB
158(define_insn_reservation "long_m32r" 1
159 (and (eq_attr "cpu" "m32r")
5b8ae21f
MM
160 (and (eq_attr "insn_size" "long")
161 (eq_attr "type" "!load4,load8")))
5ad6fca5 162 "long_IF,long_E")
5b8ae21f 163
5ad6fca5
SB
164(define_insn_reservation "long_m32rx" 2
165 (and (eq_attr "m32r_pipeline" "long")
de41e41c
BE
166 (and (eq_attr "insn_size" "long")
167 (eq_attr "type" "!load4,load8")))
5ad6fca5
SB
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
19525b57 172;; optimistically assume all memory is nearby, i.e. MEM1 takes only
5ad6fca5
SB
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")
de41e41c 181
5ad6fca5
SB
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")
de41e41c
BE
190 (and (eq_attr "insn_size" "long")
191 (eq_attr "type" "load4,load8")))
5ad6fca5
SB
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
8c5ca3b9 199\f
22a14e0d 200(include "predicates.md")
fbaeb717 201(include "constraints.md")
e2265be0 202
8c5ca3b9 203;; Expand prologue as RTL
5b8ae21f
MM
204(define_expand "prologue"
205 [(const_int 1)]
206 ""
207 "
208{
209 m32r_expand_prologue ();
210 DONE;
211}")
212
e2265be0
KK
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}")
8c5ca3b9
DE
223\f
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{
ad126521
KI
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
8c5ca3b9
DE
249 /* Everything except mem = const or mem = mem can be done easily.
250 Objects in the small data area are handled too. */
251
d000f0d9 252 if (MEM_P (operands[0]))
8c5ca3b9
DE
253 operands[1] = force_reg (QImode, operands[1]);
254}")
255
256(define_insn "*movqi_insn"
5b8ae21f
MM
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"))]
8c5ca3b9
DE
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
5b8ae21f
MM
265 ldub %0,%1
266 stb %1,%0
8c5ca3b9 267 stb %1,%0"
5b8ae21f
MM
268 [(set_attr "type" "int2,int2,int4,load2,load4,store2,store4")
269 (set_attr "length" "2,2,4,2,4,2,4")])
8c5ca3b9
DE
270
271(define_expand "movhi"
272 [(set (match_operand:HI 0 "general_operand" "")
273 (match_operand:HI 1 "general_operand" ""))]
274 ""
275 "
276{
ad126521
KI
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
8c5ca3b9
DE
289 /* Everything except mem = const or mem = mem can be done easily. */
290
d000f0d9 291 if (MEM_P (operands[0]))
8c5ca3b9
DE
292 operands[1] = force_reg (HImode, operands[1]);
293}")
294
295(define_insn "*movhi_insn"
5b8ae21f
MM
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"))]
8c5ca3b9
DE
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
5b8ae21f
MM
305 lduh %0,%1
306 sth %1,%0
8c5ca3b9 307 sth %1,%0"
5b8ae21f
MM
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 "")
8c5ca3b9
DE
322
323(define_expand "movsi"
324 [(set (match_operand:SI 0 "general_operand" "")
325 (match_operand:SI 1 "general_operand" ""))]
326 ""
327 "
328{
ad126521
KI
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
4d6c607f 341 /* Everything except mem = const or mem = mem can be done easily. */
8c5ca3b9 342
d000f0d9 343 if (MEM_P (operands[0]))
8c5ca3b9
DE
344 operands[1] = force_reg (SImode, operands[1]);
345
4d6c607f 346 /* Small Data Area reference? */
8c5ca3b9
DE
347 if (small_data_operand (operands[1], SImode))
348 {
349 emit_insn (gen_movsi_sda (operands[0], operands[1]));
350 DONE;
351 }
4d6c607f
DE
352
353 /* If medium or large code model, symbols have to be loaded with
354 seth/add3. */
355 if (addr32_operand (operands[1], SImode))
8c5ca3b9
DE
356 {
357 emit_insn (gen_movsi_addr32 (operands[0], operands[1]));
358 DONE;
359 }
360}")
361
4b6bb562 362;; ??? Do we need a const_double constraint here for large unsigned values?
5b8ae21f 363(define_insn "*movsi_insn"
56e2e762 364 [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,r,r,r,r,r,r,T,S,m")
5b8ae21f 365 (match_operand:SI 1 "move_src_operand" "r,I,J,MQ,L,n,T,U,m,r,r,r"))]
8c5ca3b9 366 "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)"
5b8ae21f
MM
367 "*
368{
d000f0d9 369 if (REG_P (operands[0]) || GET_CODE (operands[1]) == SUBREG)
5b8ae21f
MM
370 {
371 switch (GET_CODE (operands[1]))
372 {
5b8ae21f
MM
373 default:
374 break;
375
376 case REG:
377 case SUBREG:
378 return \"mv %0,%1\";
379
380 case MEM:
56e2e762
NC
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
5b8ae21f
MM
385 return \"ld %0,%1\";
386
387 case CONST_INT:
fbaeb717 388 if (satisfies_constraint_J (operands[1]))
5b8ae21f
MM
389 return \"ldi %0,%#%1\\t; %X1\";
390
fbaeb717 391 if (satisfies_constraint_M (operands[1]))
5b8ae21f
MM
392 return \"ld24 %0,%#%1\\t; %X1\";
393
fbaeb717 394 if (satisfies_constraint_L (operands[1]))
5b8ae21f
MM
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
d000f0d9
SZ
409 else if (MEM_P (operands[0])
410 && (REG_P (operands[1]) || GET_CODE (operands[1]) == SUBREG))
56e2e762
NC
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 }
5b8ae21f 418
75c3cfba 419 gcc_unreachable ();
5b8ae21f
MM
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")])
8c5ca3b9 423
4d6c607f
DE
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
4b6bb562 440 use 2 byte instructions wherever possible. We can assume the
4d6c607f
DE
441 constant isn't loadable with any of ldi, ld24, or seth. */
442
85f65093 443 /* See if we can load a 24-bit unsigned value and invert it. */
4d6c607f
DE
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
85f65093 451 /* See if we can load a 24-bit unsigned value and shift it into place.
4d6c607f
DE
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
737e7965
JW
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);
4d6c607f
DE
468 operands[3] = GEN_INT ((val) & 0xffff);
469}")
470
5b8ae21f
MM
471(define_split
472 [(set (match_operand:SI 0 "register_operand" "")
a98dd5bb 473 (match_operand:SI 1 "seth_add3_operand" ""))]
5b8ae21f
MM
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
8c5ca3b9
DE
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
85f65093 487;; register to use. Since the load and store insns have a 16-bit offset the
8c5ca3b9
DE
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
4b6bb562 496;; [I think]. What to do about this is deferred until later and for now we
8c5ca3b9
DE
497;; require .sdata to be in the first 16M.
498
499(define_expand "movsi_sda"
500 [(set (match_dup 2)
bd5ca07e 501 (unspec:SI [(const_int 0)] UNSPEC_LOAD_SDA_BASE))
8c5ca3b9
DE
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
91c18512
KI
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
8c5ca3b9
DE
522(define_insn "*load_sda_base"
523 [(set (match_operand:SI 0 "register_operand" "=r")
a2ab189d 524 (unspec:SI [(const_int 0)] UNSPEC_LOAD_SDA_BASE))]
8c5ca3b9
DE
525 ""
526 "ld24 %0,#_SDA_BASE_"
5b8ae21f
MM
527 [(set_attr "type" "int4")
528 (set_attr "length" "4")])
8c5ca3b9 529
85f65093 530;; 32-bit address support.
8c5ca3b9
DE
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)"
5b8ae21f
MM
553 [(set_attr "type" "int4")
554 (set_attr "length" "4")])
8c5ca3b9
DE
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"
5b8ae21f
MM
562 [(set_attr "type" "int4")
563 (set_attr "length" "4")])
8c5ca3b9
DE
564
565(define_expand "movdi"
566 [(set (match_operand:DI 0 "general_operand" "")
567 (match_operand:DI 1 "general_operand" ""))]
568 ""
569 "
570{
ad126521
KI
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
8c5ca3b9
DE
583 /* Everything except mem = const or mem = mem can be done easily. */
584
d000f0d9 585 if (MEM_P (operands[0]))
8c5ca3b9 586 operands[1] = force_reg (DImode, operands[1]);
8c5ca3b9
DE
587}")
588
589(define_insn "*movdi_insn"
5b8ae21f
MM
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"))]
8c5ca3b9 592 "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
5b8ae21f
MM
593 "#"
594 [(set_attr "type" "multi,multi,multi,load8,store8")
595 (set_attr "length" "4,4,16,6,6")])
8c5ca3b9
DE
596
597(define_split
5b8ae21f
MM
598 [(set (match_operand:DI 0 "move_dest_operand" "")
599 (match_operand:DI 1 "move_double_src_operand" ""))]
8c5ca3b9 600 "reload_completed"
5b8ae21f
MM
601 [(match_dup 2)]
602 "operands[2] = gen_split_move_double (operands);")
8c5ca3b9
DE
603\f
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{
ad126521
KI
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
8c5ca3b9
DE
624 /* Everything except mem = const or mem = mem can be done easily. */
625
d000f0d9 626 if (MEM_P (operands[0]))
8c5ca3b9
DE
627 operands[1] = force_reg (SFmode, operands[1]);
628}")
629
630(define_insn "*movsf_insn"
56e2e762
NC
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"))]
8c5ca3b9 633 "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)"
5b8ae21f
MM
634 "@
635 mv %0,%1
636 #
637 ld %0,%1
638 ld %0,%1
56e2e762
NC
639 ld %0,%1
640 st %1,%0
5b8ae21f
MM
641 st %1,%0
642 st %1,%0"
8c5ca3b9 643 ;; ??? Length of alternative 1 is either 2, 4 or 8.
56e2e762
NC
644 [(set_attr "type" "int2,multi,load2,load2,load4,store2,store2,store4")
645 (set_attr "length" "2,8,2,2,4,2,2,4")])
5b8ae21f
MM
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{
5b8ae21f 654 operands[2] = operand_subword (operands[0], 0, 0, SFmode);
b5a3eb84 655 operands[3] = operand_subword (operands[1], 0, 0, SFmode);
5b8ae21f 656}")
8c5ca3b9
DE
657
658(define_expand "movdf"
659 [(set (match_operand:DF 0 "general_operand" "")
660 (match_operand:DF 1 "general_operand" ""))]
661 ""
662 "
663{
ad126521
KI
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
8c5ca3b9
DE
676 /* Everything except mem = const or mem = mem can be done easily. */
677
d000f0d9 678 if (MEM_P (operands[0]))
8c5ca3b9 679 operands[1] = force_reg (DFmode, operands[1]);
8c5ca3b9
DE
680}")
681
682(define_insn "*movdf_insn"
683 [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
5b8ae21f 684 (match_operand:DF 1 "move_double_src_operand" "r,F,m,r"))]
8c5ca3b9 685 "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
5b8ae21f
MM
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);")
8c5ca3b9
DE
696\f
697;; Zero extension instructions.
698
699(define_insn "zero_extendqihi2"
5b8ae21f 700 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
56e2e762 701 (zero_extend:HI (match_operand:QI 1 "extend_operand" "r,T,m")))]
8c5ca3b9
DE
702 ""
703 "@
704 and3 %0,%1,%#255
5b8ae21f 705 ldub %0,%1
8c5ca3b9 706 ldub %0,%1"
5b8ae21f
MM
707 [(set_attr "type" "int4,load2,load4")
708 (set_attr "length" "4,2,4")])
8c5ca3b9
DE
709
710(define_insn "zero_extendqisi2"
5b8ae21f 711 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
56e2e762 712 (zero_extend:SI (match_operand:QI 1 "extend_operand" "r,T,m")))]
8c5ca3b9
DE
713 ""
714 "@
715 and3 %0,%1,%#255
5b8ae21f 716 ldub %0,%1
8c5ca3b9 717 ldub %0,%1"
5b8ae21f
MM
718 [(set_attr "type" "int4,load2,load4")
719 (set_attr "length" "4,2,4")])
8c5ca3b9
DE
720
721(define_insn "zero_extendhisi2"
5b8ae21f 722 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
56e2e762 723 (zero_extend:SI (match_operand:HI 1 "extend_operand" "r,T,m")))]
8c5ca3b9
DE
724 ""
725 "@
726 and3 %0,%1,%#65535
5b8ae21f 727 lduh %0,%1
8c5ca3b9 728 lduh %0,%1"
5b8ae21f
MM
729 [(set_attr "type" "int4,load2,load4")
730 (set_attr "length" "4,2,4")])
8c5ca3b9 731\f
56e2e762
NC
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")])
8c5ca3b9 743
56e2e762 744(define_split
8c5ca3b9
DE
745 [(set (match_operand:HI 0 "register_operand" "")
746 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
56e2e762
NC
747 "reload_completed"
748 [(match_dup 2)
749 (match_dup 3)]
8c5ca3b9
DE
750 "
751{
56e2e762 752 rtx op0 = gen_lowpart (SImode, operands[0]);
e512ab39 753 rtx shift = GEN_INT (24);
8c5ca3b9 754
56e2e762
NC
755 operands[2] = gen_ashlsi3 (op0, op0, shift);
756 operands[3] = gen_ashrsi3 (op0, op0, shift);
8c5ca3b9
DE
757}")
758
56e2e762
NC
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")))]
8c5ca3b9 762 ""
56e2e762
NC
763 "@
764 #
765 ldb %0,%1
766 ldb %0,%1"
767 [(set_attr "type" "multi,load2,load4")
768 (set_attr "length" "4,2,4")])
8c5ca3b9 769
56e2e762 770(define_split
8c5ca3b9
DE
771 [(set (match_operand:SI 0 "register_operand" "")
772 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
56e2e762
NC
773 "reload_completed"
774 [(match_dup 2)
775 (match_dup 3)]
8c5ca3b9
DE
776 "
777{
e512ab39 778 rtx shift = GEN_INT (24);
8c5ca3b9 779
5a67e41f
KH
780 operands[2] = gen_ashlsi3 (operands[0], operands[0], shift);
781 operands[3] = gen_ashrsi3 (operands[0], operands[0], shift);
8c5ca3b9
DE
782}")
783
56e2e762
NC
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")))]
8c5ca3b9 787 ""
56e2e762
NC
788 "@
789 #
790 ldh %0,%1
791 ldh %0,%1"
792 [(set_attr "type" "multi,load2,load4")
793 (set_attr "length" "4,2,4")])
8c5ca3b9 794
56e2e762 795(define_split
8c5ca3b9
DE
796 [(set (match_operand:SI 0 "register_operand" "")
797 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
56e2e762
NC
798 "reload_completed"
799 [(match_dup 2)
800 (match_dup 3)]
8c5ca3b9
DE
801 "
802{
e512ab39 803 rtx shift = GEN_INT (16);
8c5ca3b9 804
5a67e41f
KH
805 operands[2] = gen_ashlsi3 (operands[0], operands[0], shift);
806 operands[3] = gen_ashrsi3 (operands[0], operands[0], shift);
8c5ca3b9 807}")
8c5ca3b9
DE
808\f
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"
5b8ae21f 824 [(set_attr "type" "int2,int2,int4")
8c5ca3b9
DE
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])
fbaeb717 833; && satisfies_constraint_I (operands[2])
8c5ca3b9
DE
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")))
58ebda9c 843 (clobber (reg:CC 17))]
8c5ca3b9 844 ""
5b8ae21f
MM
845 "#"
846 [(set_attr "type" "multi")
8c5ca3b9
DE
847 (set_attr "length" "6")])
848
5b8ae21f
MM
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" "")))
58ebda9c 854 (clobber (reg:CC 17))]
5b8ae21f 855 "reload_completed"
58ebda9c 856 [(parallel [(set (reg:CC 17)
5b8ae21f
MM
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)
58ebda9c
KH
862 (ne:SI (reg:CC 17) (const_int 0)))))
863 (set (reg:CC 17)
a2ab189d 864 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])
5b8ae21f
MM
865 (parallel [(set (match_dup 6)
866 (plus:SI (match_dup 6)
867 (plus:SI (match_dup 7)
58ebda9c
KH
868 (ne:SI (reg:CC 17) (const_int 0)))))
869 (set (reg:CC 17)
a2ab189d 870 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])]
5b8ae21f
MM
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"
58ebda9c 880 [(set (reg:CC 17)
5b8ae21f
MM
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")
58ebda9c
KH
892 (ne:SI (reg:CC 17) (const_int 0)))))
893 (set (reg:CC 17)
a2ab189d 894 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))]
5b8ae21f
MM
895 ""
896 "addx %0,%2"
897 [(set_attr "type" "int2")
898 (set_attr "length" "2")])
899
8c5ca3b9
DE
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"
5b8ae21f
MM
906 [(set_attr "type" "int2")
907 (set_attr "length" "2")])
8c5ca3b9
DE
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")))
58ebda9c 913 (clobber (reg:CC 17))]
8c5ca3b9 914 ""
5b8ae21f
MM
915 "#"
916 [(set_attr "type" "multi")
8c5ca3b9 917 (set_attr "length" "6")])
5b8ae21f
MM
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" "")))
58ebda9c 924 (clobber (reg:CC 17))]
5b8ae21f 925 "reload_completed"
58ebda9c 926 [(parallel [(set (reg:CC 17)
5b8ae21f
MM
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)
58ebda9c
KH
932 (ne:SI (reg:CC 17) (const_int 0)))))
933 (set (reg:CC 17)
a2ab189d 934 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])
5b8ae21f
MM
935 (parallel [(set (match_dup 6)
936 (minus:SI (match_dup 6)
937 (minus:SI (match_dup 7)
58ebda9c
KH
938 (ne:SI (reg:CC 17) (const_int 0)))))
939 (set (reg:CC 17)
a2ab189d 940 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])]
5b8ae21f
MM
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")
58ebda9c
KH
953 (ne:SI (reg:CC 17) (const_int 0)))))
954 (set (reg:CC 17)
a2ab189d 955 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))]
5b8ae21f
MM
956 ""
957 "subx %0,%2"
958 [(set_attr "type" "int2")
959 (set_attr "length" "2")])
8c5ca3b9
DE
960\f
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"
5b8ae21f 969 [(set_attr "type" "multi")
8c5ca3b9
DE
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"
5b8ae21f
MM
978 [(set_attr "type" "mul2")
979 (set_attr "length" "2")])
8c5ca3b9
DE
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"
5b8ae21f
MM
987 [(set_attr "type" "div4")
988 (set_attr "length" "4")])
8c5ca3b9
DE
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"
5b8ae21f
MM
996 [(set_attr "type" "div4")
997 (set_attr "length" "4")])
8c5ca3b9
DE
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"
5b8ae21f
MM
1005 [(set_attr "type" "div4")
1006 (set_attr "length" "4")])
8c5ca3b9
DE
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"
5b8ae21f
MM
1014 [(set_attr "type" "div4")
1015 (set_attr "length" "4")])
8c5ca3b9
DE
1016\f
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")
56e2e762 1025 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
8c5ca3b9 1026 ""
56e2e762
NC
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])
fbaeb717 1033 && satisfies_constraint_I (operands[2]))
56e2e762
NC
1034 return \"#\";
1035
d000f0d9 1036 else if (CONST_INT_P (operands[2]))
56e2e762
NC
1037 return \"and3 %0,%1,%#%X2\";
1038
1039 return \"and %0,%2\";
1040}"
5b8ae21f
MM
1041 [(set_attr "type" "int2,int4")
1042 (set_attr "length" "2,4")])
8c5ca3b9 1043
56e2e762
NC
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))
c73a5e94 1050 (set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))]
56e2e762
NC
1051 "")
1052
8c5ca3b9
DE
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")
56e2e762 1056 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
8c5ca3b9 1057 ""
56e2e762
NC
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])
fbaeb717 1064 && satisfies_constraint_I (operands[2]))
56e2e762
NC
1065 return \"#\";
1066
d000f0d9 1067 else if (CONST_INT_P (operands[2]))
56e2e762
NC
1068 return \"or3 %0,%1,%#%X2\";
1069
1070 return \"or %0,%2\";
1071}"
5b8ae21f
MM
1072 [(set_attr "type" "int2,int4")
1073 (set_attr "length" "2,4")])
8c5ca3b9 1074
56e2e762
NC
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))
c73a5e94 1081 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 1)))]
56e2e762
NC
1082 "")
1083
8c5ca3b9
DE
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")
56e2e762 1087 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
8c5ca3b9 1088 ""
56e2e762
NC
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])
fbaeb717 1095 && satisfies_constraint_I (operands[2]))
56e2e762
NC
1096 return \"#\";
1097
d000f0d9 1098 else if (CONST_INT_P (operands[2]))
56e2e762
NC
1099 return \"xor3 %0,%1,%#%X2\";
1100
1101 return \"xor %0,%2\";
1102}"
5b8ae21f
MM
1103 [(set_attr "type" "int2,int4")
1104 (set_attr "length" "2,4")])
8c5ca3b9 1105
56e2e762
NC
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))
c73a5e94 1112 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))]
56e2e762
NC
1113 "")
1114
8c5ca3b9
DE
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"
5b8ae21f
MM
1120 [(set_attr "type" "int2")
1121 (set_attr "length" "2")])
8c5ca3b9
DE
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"
5b8ae21f
MM
1128 [(set_attr "type" "int2")
1129 (set_attr "length" "2")])
8c5ca3b9
DE
1130\f
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"
5b8ae21f 1142 [(set_attr "type" "shift2,shift2,shift4")
8c5ca3b9
DE
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"
5b8ae21f 1154 [(set_attr "type" "shift2,shift2,shift4")
8c5ca3b9
DE
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"
5b8ae21f 1166 [(set_attr "type" "shift2,shift2,shift4")
8c5ca3b9
DE
1167 (set_attr "length" "2,2,4")])
1168\f
1169;; Compare instructions.
1170;; This controls RTL generation and register allocation.
1171
e2265be0 1172;; We generate RTL for comparisons and branches by having the cmpxx
8c5ca3b9
DE
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
4b6bb562 1178;; preferred.
8c5ca3b9 1179
de41e41c 1180(define_insn "cmp_eqsi_zero_insn"
58ebda9c
KH
1181 [(set (reg:CC 17)
1182 (eq:CC (match_operand:SI 0 "register_operand" "r,r")
de41e41c 1183 (match_operand:SI 1 "reg_or_zero_operand" "r,P")))]
6975bd2c 1184 "TARGET_M32RX || TARGET_M32R2"
de41e41c
BE
1185 "@
1186 cmpeq %0, %1
1187 cmpz %0"
1188 [(set_attr "type" "int4")
1189 (set_attr "length" "4")])
1190
8c5ca3b9
DE
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"
58ebda9c
KH
1196 [(set (reg:CC 17)
1197 (eq:CC (match_operand:SI 0 "register_operand" "r,r")
de41e41c 1198 (match_operand:SI 1 "reg_or_cmp_int16_operand" "r,P")))
8c5ca3b9 1199 (clobber (match_scratch:SI 2 "=&r,&r"))]
2b7972b0
MM
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}"
5b8ae21f 1217 [(set_attr "type" "multi,multi")
8c5ca3b9
DE
1218 (set_attr "length" "8,8")])
1219
1220(define_insn "cmp_ltsi_insn"
58ebda9c
KH
1221 [(set (reg:CC 17)
1222 (lt:CC (match_operand:SI 0 "register_operand" "r,r")
de41e41c 1223 (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
8c5ca3b9
DE
1224 ""
1225 "@
1226 cmp %0,%1
1227 cmpi %0,%#%1"
5b8ae21f
MM
1228 [(set_attr "type" "int2,int4")
1229 (set_attr "length" "2,4")])
8c5ca3b9
DE
1230
1231(define_insn "cmp_ltusi_insn"
58ebda9c
KH
1232 [(set (reg:CC 17)
1233 (ltu:CC (match_operand:SI 0 "register_operand" "r,r")
de41e41c 1234 (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
8c5ca3b9 1235 ""
5b8ae21f
MM
1236 "@
1237 cmpu %0,%1
1238 cmpui %0,%#%1"
1239 [(set_attr "type" "int2,int4")
1240 (set_attr "length" "2,4")])
8c5ca3b9
DE
1241\f
1242;; These control RTL generation for conditional jump insns.
1243
f90b7a5a
PB
1244(define_expand "cbranchsi4"
1245 ; the comparison is emitted by gen_compare if needed.
8c5ca3b9 1246 [(set (pc)
f90b7a5a
PB
1247 (if_then_else (match_operator 0 "ordered_comparison_operator"
1248 [(match_operand:SI 1 "register_operand" "")
1249 (match_operand:SI 2 "reg_or_cmp_int16_operand" "")])
1250 (label_ref (match_operand 3 "" ""))
8c5ca3b9
DE
1251 (pc)))]
1252 ""
1253 "
1254{
f90b7a5a
PB
1255 operands[0] = gen_compare (GET_CODE (operands[0]), operands[1], operands[2], FALSE);
1256 operands[1] = XEXP (operands[0], 0);
1257 operands[2] = XEXP (operands[0], 1);
8c5ca3b9
DE
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{
2b7972b0
MM
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;
8c5ca3b9
DE
1276}"
1277 [(set_attr "type" "branch")
721cedf2
KI
1278 ; cf PR gcc/28508
1279 ; We use 300/600 instead of 512,1024 to account for inaccurate insn
8c5ca3b9
DE
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))
721cedf2
KI
1286 (const_int 300))
1287 (const_int 600))
8c5ca3b9
DE
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{
2b7972b0
MM
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;
8c5ca3b9
DE
1306}"
1307 [(set_attr "type" "branch")
721cedf2
KI
1308 ; cf PR gcc/28508
1309 ; We use 300/600 instead of 512,1024 to account for inaccurate insn
8c5ca3b9
DE
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))
721cedf2
KI
1316 (const_int 300))
1317 (const_int 600))
8c5ca3b9
DE
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{
a5a9cb26 1405 const char *br,*invbr;
8c5ca3b9
DE
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;
61f3b78f 1416
75c3cfba 1417 default: gcc_unreachable ();
8c5ca3b9
DE
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{
a5a9cb26 1452 const char *br,*invbr;
8c5ca3b9
DE
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;
61f3b78f 1463
75c3cfba 1464 default: gcc_unreachable ();
8c5ca3b9
DE
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\f
56e2e762
NC
1489;; S<cc> operations to set a register to 1/0 based on a comparison
1490
f90b7a5a
PB
1491(define_expand "cstoresi4"
1492 [(match_operand:SI 0 "register_operand" "")
1493 (match_operator:SI 1 "ordered_comparison_operator"
1494 [(match_operand:SI 2 "register_operand" "")
1495 (match_operand:SI 3 "reg_or_cmp_int16_operand" "")])]
56e2e762
NC
1496 ""
1497 "
1498{
f90b7a5a 1499 if (GET_MODE (operands[0]) != SImode)
56e2e762
NC
1500 FAIL;
1501
f90b7a5a
PB
1502 if (!gen_cond_store (GET_CODE (operands[1]),
1503 operands[0], operands[2], operands[3]))
1504 FAIL;
56e2e762 1505
56e2e762
NC
1506 DONE;
1507}")
1508
de41e41c
BE
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")))
58ebda9c 1513 (clobber (reg:CC 17))]
6975bd2c 1514 "TARGET_M32RX || TARGET_M32R2"
de41e41c
BE
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" "")))
58ebda9c 1523 (clobber (reg:CC 17))]
6975bd2c 1524 "TARGET_M32RX || TARGET_M32R2"
58ebda9c
KH
1525 [(set (reg:CC 17)
1526 (eq:CC (match_dup 1)
de41e41c
BE
1527 (match_dup 2)))
1528 (set (match_dup 0)
58ebda9c 1529 (ne:SI (reg:CC 17) (const_int 0)))]
de41e41c
BE
1530 "")
1531
56e2e762
NC
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)))
58ebda9c 1536 (clobber (reg:CC 17))]
56e2e762
NC
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)))
58ebda9c 1546 (clobber (reg:CC 17))]
56e2e762
NC
1547 "TARGET_M32R"
1548 [(match_dup 3)]
1549 "
1550{
1551 rtx op0 = operands[0];
1552 rtx op1 = operands[1];
1553
1554 start_sequence ();
a556fd39 1555 emit_insn (gen_cmp_ltusi_insn (op1, const1_rtx));
56e2e762 1556 emit_insn (gen_movcc_insn (op0));
9d0fa9d6 1557 operands[3] = get_insns ();
56e2e762
NC
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")))
58ebda9c 1565 (clobber (reg:CC 17))
56e2e762
NC
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" "")))
58ebda9c 1576 (clobber (reg:CC 17))
56e2e762
NC
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
d000f0d9 1588 if (REG_P (op2) && REG_P (op3)
56e2e762
NC
1589 && REGNO (op2) == REGNO (op3))
1590 {
1591 op1 = operands[2];
1592 op2 = operands[1];
1593 }
1594
1595 start_sequence ();
d000f0d9 1596 if (REG_P (op1) && REG_P (op3)
56e2e762
NC
1597 && REGNO (op1) != REGNO (op3))
1598 {
1599 emit_move_insn (op3, op1);
1600 op1 = op3;
1601 }
1602
fbaeb717 1603 if (satisfies_constraint_P (op2) && (value = INTVAL (op2)) != 0)
56e2e762
NC
1604 emit_insn (gen_addsi3 (op3, op1, GEN_INT (-value)));
1605 else
1606 emit_insn (gen_xorsi3 (op3, op1, op2));
1607
a556fd39 1608 emit_insn (gen_cmp_ltusi_insn (op3, const1_rtx));
56e2e762 1609 emit_insn (gen_movcc_insn (op0));
9d0fa9d6 1610 operands[4] = get_insns ();
56e2e762
NC
1611 end_sequence ();
1612}")
1613
56e2e762
NC
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)))
58ebda9c 1618 (clobber (reg:CC 17))
56e2e762
NC
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)))
58ebda9c 1629 (clobber (reg:CC 17))
56e2e762
NC
1630 (clobber (match_scratch:SI 2 ""))]
1631 "reload_completed"
1632 [(set (match_dup 2)
1633 (const_int 0))
58ebda9c
KH
1634 (set (reg:CC 17)
1635 (ltu:CC (match_dup 2)
56e2e762
NC
1636 (match_dup 1)))
1637 (set (match_dup 0)
58ebda9c 1638 (ne:SI (reg:CC 17) (const_int 0)))]
56e2e762 1639 "")
e2265be0 1640
56e2e762
NC
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")))
58ebda9c 1645 (clobber (reg:CC 17))]
56e2e762
NC
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" "")))
58ebda9c 1655 (clobber (reg:CC 17))]
56e2e762 1656 ""
58ebda9c
KH
1657 [(set (reg:CC 17)
1658 (lt:CC (match_dup 1)
56e2e762
NC
1659 (match_dup 2)))
1660 (set (match_dup 0)
58ebda9c 1661 (ne:SI (reg:CC 17) (const_int 0)))]
56e2e762
NC
1662 "")
1663
56e2e762
NC
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")))
58ebda9c 1668 (clobber (reg:CC 17))]
56e2e762
NC
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" "")))
58ebda9c 1678 (clobber (reg:CC 17))]
56e2e762 1679 "!optimize_size"
58ebda9c
KH
1680 [(set (reg:CC 17)
1681 (lt:CC (match_dup 2)
56e2e762
NC
1682 (match_dup 1)))
1683 (set (match_dup 0)
58ebda9c 1684 (ne:SI (reg:CC 17) (const_int 0)))
56e2e762
NC
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" "")))
58ebda9c 1696 (clobber (reg:CC 17))]
56e2e762 1697 "optimize_size"
58ebda9c
KH
1698 [(set (reg:CC 17)
1699 (lt:CC (match_dup 2)
56e2e762
NC
1700 (match_dup 1)))
1701 (set (match_dup 0)
58ebda9c 1702 (ne:SI (reg:CC 17) (const_int 0)))
56e2e762
NC
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
56e2e762
NC
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")))
58ebda9c 1714 (clobber (reg:CC 17))]
56e2e762
NC
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" "")))
58ebda9c 1724 (clobber (reg:CC 17))]
56e2e762 1725 "!optimize_size"
58ebda9c
KH
1726 [(set (reg:CC 17)
1727 (lt:CC (match_dup 1)
56e2e762
NC
1728 (match_dup 2)))
1729 (set (match_dup 0)
58ebda9c 1730 (ne:SI (reg:CC 17) (const_int 0)))
56e2e762
NC
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" "")))
58ebda9c 1742 (clobber (reg:CC 17))]
56e2e762 1743 "optimize_size"
58ebda9c
KH
1744 [(set (reg:CC 17)
1745 (lt:CC (match_dup 1)
56e2e762
NC
1746 (match_dup 2)))
1747 (set (match_dup 0)
58ebda9c 1748 (ne:SI (reg:CC 17) (const_int 0)))
56e2e762
NC
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
56e2e762
NC
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")))
58ebda9c 1760 (clobber (reg:CC 17))]
56e2e762
NC
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" "")))
58ebda9c 1770 (clobber (reg:CC 17))]
56e2e762 1771 ""
58ebda9c
KH
1772 [(set (reg:CC 17)
1773 (ltu:CC (match_dup 1)
56e2e762
NC
1774 (match_dup 2)))
1775 (set (match_dup 0)
58ebda9c 1776 (ne:SI (reg:CC 17) (const_int 0)))]
56e2e762
NC
1777 "")
1778
56e2e762
NC
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")))
58ebda9c 1783 (clobber (reg:CC 17))]
56e2e762
NC
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" "")))
58ebda9c 1793 (clobber (reg:CC 17))]
56e2e762 1794 "!optimize_size"
58ebda9c
KH
1795 [(set (reg:CC 17)
1796 (ltu:CC (match_dup 2)
56e2e762
NC
1797 (match_dup 1)))
1798 (set (match_dup 0)
58ebda9c 1799 (ne:SI (reg:CC 17) (const_int 0)))
56e2e762
NC
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" "")))
58ebda9c 1811 (clobber (reg:CC 17))]
56e2e762 1812 "optimize_size"
58ebda9c
KH
1813 [(set (reg:CC 17)
1814 (ltu:CC (match_dup 2)
56e2e762
NC
1815 (match_dup 1)))
1816 (set (match_dup 0)
58ebda9c 1817 (ne:SI (reg:CC 17) (const_int 0)))
56e2e762
NC
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
56e2e762
NC
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")))
58ebda9c 1829 (clobber (reg:CC 17))]
56e2e762
NC
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" "")))
58ebda9c 1839 (clobber (reg:CC 17))]
56e2e762 1840 "!optimize_size"
58ebda9c
KH
1841 [(set (reg:CC 17)
1842 (ltu:CC (match_dup 1)
56e2e762
NC
1843 (match_dup 2)))
1844 (set (match_dup 0)
58ebda9c 1845 (ne:SI (reg:CC 17) (const_int 0)))
56e2e762
NC
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" "")))
58ebda9c 1857 (clobber (reg:CC 17))]
56e2e762 1858 "optimize_size"
58ebda9c
KH
1859 [(set (reg:CC 17)
1860 (ltu:CC (match_dup 1)
56e2e762
NC
1861 (match_dup 2)))
1862 (set (match_dup 0)
58ebda9c 1863 (ne:SI (reg:CC 17) (const_int 0)))
56e2e762
NC
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")
58ebda9c 1873 (ne:SI (reg:CC 17) (const_int 0)))]
56e2e762
NC
1874 ""
1875 "mvfc %0, cbr"
1876 [(set_attr "type" "misc")
1877 (set_attr "length" "2")])
1878
1879\f
8c5ca3b9
DE
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")])
56e2e762 1899
e2265be0
KK
1900(define_insn "return_lr"
1901 [(parallel [(return) (use (reg:SI 14))])]
1902 ""
56e2e762
NC
1903 "jmp lr"
1904 [(set_attr "type" "uncond_branch")
1905 (set_attr "length" "2")])
e2265be0
KK
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
ad126521
KI
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"
8c5ca3b9
DE
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 ""
ad126521
KI
1976 "
1977{
1978 if (flag_pic)
e3b5732b 1979 crtl->uses_pic_offset_table = 1;
ad126521 1980}")
8c5ca3b9
DE
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")
f18d1d16 2014 (if_then_else (not (match_test "call26_operand (operands[0], FUNCTION_MODE)"))
8c5ca3b9
DE
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 ""
e2265be0 2030 "
ad126521
KI
2031{
2032 if (flag_pic)
e3b5732b 2033 crtl->uses_pic_offset_table = 1;
ad126521 2034}")
8c5ca3b9
DE
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
ad126521 2056 if (flag_pic)
e3b5732b 2057 crtl->uses_pic_offset_table = 1;
ad126521 2058
8c5ca3b9
DE
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")
f18d1d16 2073 (if_then_else (not (match_test "call26_operand (operands[1], FUNCTION_MODE)"))
8c5ca3b9
DE
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\f
2081(define_insn "nop"
2082 [(const_int 0)]
2083 ""
2084 "nop"
5b8ae21f 2085 [(set_attr "type" "int2")
8c5ca3b9
DE
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"
a2ab189d 2092 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
8c5ca3b9
DE
2093 ""
2094 "")
2095
2096;; Special pattern to flush the icache.
2097
2098(define_insn "flush_icache"
a2ab189d
KH
2099 [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
2100 UNSPECV_FLUSH_ICACHE)
ad126521
KI
2101 (match_operand 1 "" "")
2102 (clobber (reg:SI 17))]
8c5ca3b9 2103 ""
ad126521
KI
2104 "* return \"trap %#%1 ; flush-icache\";"
2105 [(set_attr "type" "int4")
2106 (set_attr "length" "4")])
2b7972b0 2107\f
56e2e762
NC
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\f
2b7972b0
MM
2150;; Conditional move instructions
2151;; Based on those done for the d10v
2152
2b7972b0
MM
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{
20f46632
NC
2165 /* FIXME: This expansion is hold over from a failed conversion of this
2166 port away from using cc0. It still relies upon the last comparison
2167 being the one that is now tested. Disabled for now in order to
2168 improve the generation of working code. */
2169 FAIL;
2170
2b7972b0
MM
2171 if (! zero_and_one (operands [2], operands [3]))
2172 FAIL;
2173
67f63f32 2174 /* Generate the comparison that will set the carry flag. */
f90b7a5a
PB
2175 operands[1] = gen_compare (GET_CODE (operands[1]), XEXP (operands[1], 0),
2176 XEXP (operands[1], 1), TRUE);
2b7972b0
MM
2177
2178 /* See other movsicc pattern below for reason why. */
56e2e762 2179 emit_insn (gen_blockage ());
2b7972b0
MM
2180}")
2181
2182;; Generate the conditional instructions based on how the carry flag is examined.
2183(define_insn "*movsicc_internal"
997718c7 2184 [(set (match_operand:SI 0 "register_operand" "=r")
2b7972b0
MM
2185 (if_then_else:SI (match_operand 1 "carry_compare_operand" "")
2186 (match_operand:SI 2 "conditional_move_operand" "O")
2187 (match_operand:SI 3 "conditional_move_operand" "O")
2188 )
2189 )]
2190 "zero_and_one (operands [2], operands[3])"
2191 "* return emit_cond_move (operands, insn);"
5b8ae21f 2192 [(set_attr "type" "multi")
2b7972b0
MM
2193 (set_attr "length" "8")
2194 ]
2195)
2196
8c5ca3b9 2197\f
d2a73f8e
NC
2198;; Block moves, see m32r.c for more details.
2199;; Argument 0 is the destination
2200;; Argument 1 is the source
2201;; Argument 2 is the length
2202;; Argument 3 is the alignment
2203
76715c32 2204(define_expand "cpymemsi"
d2a73f8e
NC
2205 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
2206 (match_operand:BLK 1 "general_operand" ""))
2207 (use (match_operand:SI 2 "immediate_operand" ""))
2208 (use (match_operand:SI 3 "immediate_operand" ""))])]
2209 ""
2210 "
2211{
0be4693a 2212 if (operands[0]) /* Avoid unused code messages. */
d2a73f8e 2213 {
0be4693a
KI
2214 if (m32r_expand_block_move (operands))
2215 DONE;
2216 else
2217 FAIL;
d2a73f8e
NC
2218 }
2219}")
2220
2221;; Insn generated by block moves
2222
76715c32 2223(define_insn "cpymemsi_internal"
81ad38a6
KH
2224 [(set (mem:BLK (match_operand:SI 0 "register_operand" "r")) ;; destination
2225 (mem:BLK (match_operand:SI 1 "register_operand" "r"))) ;; source
d2a73f8e 2226 (use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to move
81ad38a6 2227 (set (match_operand:SI 3 "register_operand" "=0")
085fd657
KI
2228 (plus:SI (minus (match_dup 2) (const_int 4))
2229 (match_dup 0)))
81ad38a6
KH
2230 (set (match_operand:SI 4 "register_operand" "=1")
2231 (plus:SI (match_dup 1)
2232 (match_dup 2)))
2233 (clobber (match_scratch:SI 5 "=&r")) ;; temp1
2234 (clobber (match_scratch:SI 6 "=&r"))] ;; temp2
d2a73f8e 2235 ""
16f104b3 2236 "* m32r_output_block_move (insn, operands); return \"\"; "
d2a73f8e
NC
2237 [(set_attr "type" "store8")
2238 (set_attr "length" "72")]) ;; Maximum
ad126521
KI
2239
2240;; PIC
2241
2242/* When generating pic, we need to load the symbol offset into a register.
2243 So that the optimizer does not confuse this with a normal symbol load
2244 we use an unspec. The offset will be loaded from a constant pool entry,
2245 since that is the only type of relocation we can use. */
2246
2247(define_insn "pic_load_addr"
2248 [(set (match_operand:SI 0 "register_operand" "=r")
a2ab189d 2249 (unspec:SI [(match_operand 1 "" "")] UNSPEC_PIC_LOAD_ADDR))]
ad126521
KI
2250 "flag_pic"
2251 "ld24 %0,%#%1"
2252 [(set_attr "type" "int4")])
2253
c331bf08
KI
2254(define_insn "gotoff_load_addr"
2255 [(set (match_operand:SI 0 "register_operand" "=r")
2256 (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFF))]
2257 "flag_pic"
2258 "seth %0, %#shigh(%1@GOTOFF)\;add3 %0, %0, low(%1@GOTOFF)"
2259 [(set_attr "type" "int4")
2260 (set_attr "length" "8")])
2261
ad126521
KI
2262;; Load program counter insns.
2263
2264(define_insn "get_pc"
2265 [(clobber (reg:SI 14))
3681df8f 2266 (set (match_operand 0 "register_operand" "=r,r")
a2ab189d 2267 (unspec [(match_operand 1 "" "")] UNSPEC_GET_PC))
3681df8f 2268 (use (match_operand:SI 2 "immediate_operand" "W,i"))]
ad126521 2269 "flag_pic"
3681df8f
NC
2270 "@
2271 bl.s .+4\;seth %0,%#shigh(%1)\;add3 %0,%0,%#low(%1+4)\;add %0,lr
2272 bl.s .+4\;ld24 %0,%#%1\;add %0,lr"
2273 [(set_attr "length" "12,8")])
ad126521
KI
2274
2275(define_expand "builtin_setjmp_receiver"
2276 [(label_ref (match_operand 0 "" ""))]
2277 "flag_pic"
2278 "
2279{
2280 m32r_load_pic_register ();
2281 DONE;
2282}")