]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/visium/visium.md
Turn HARD_REGNO_MODE_OK into a target hook
[thirdparty/gcc.git] / gcc / config / visium / visium.md
CommitLineData
8992df51 1;; Machine description for Visium.
aad93da1 2;; Copyright (C) 2002-2017 Free Software Foundation, Inc.
8992df51 3;; Contributed by C.Nettleton, J.P.Parkes and P.Garbett.
4
5;; This file is part of GCC.
6
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published
9;; by the Free Software Foundation; either version 3, or (at your
10;; option) any later version.
11
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15;; License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3. If not see
19;; <http://www.gnu.org/licenses/>.
20
21;;
22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
23;;
24;; Extra register constraints are:
25;; 'b' EAM register mdb
26;; 'c' EAM register mdc
27;; 'f' Floating-point register
28;; 'k' Register that can be used as the target of a sibcall, i.e. call-used
29;; general register not clobbered in the epilogue: r1-r8 and r10
30;; 'l' Low general register, i.e. general register accessible in user mode
31;; on the GR6 and, consequently, that can be used as the target of a
32;; branch with prediction: r1-r28
33;; 't' Register r1
34;; 'u' Register r2
35;; 'v' Register r3
36;;
37;; Immediate integer operand constraints are:
38;; 'J' 0 .. 65535 (16-bit immediate)
39;; 'K' 1 .. 31 (5-bit immediate)
40;; 'L' -1 .. -65535 (16-bit negative immediate)
41;; 'M' -1 (minus one)
42;; 'O' 0 (integer zero)
43;; 'P' 32 (thirty two)
44;;
45;; Immediate FP operand constraints are:
46;; 'G' 0.0 (floating-point zero)
47;;
48;; Operand substitution characters are:
49;; %# delay slot follows, if empty, fill with NOP
50;; %b LS 8 bits of immediate operand
51;; %w LS 16 bits of immediate operand
52;; %u MS 16 bits of immediate operand
53;; %r register or zero (r0)
54;; %f FP register or zero (f0)
55;; %d second register in a pair
56;;
57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
58;;
59
60;; Registers by name.
61(define_constants [
62 (R_R1 1)
63 (R_R2 2)
64 (R_R3 3)
65 (R_R4 4)
66 (R_R5 5)
67 (R_R6 6)
68 (R_LINK 21)
69 (R_FP 22)
70 (R_SP 23)
71 (R_MDB 32)
72 (R_MDC 33)
73 (R_FLAGS 50)
74])
75
76;; UNSPEC usage.
77(define_c_enum "unspec" [
78 UNSPEC_MDBHI
79 UNSPEC_FLOAD
80 UNSPEC_FSTORE
81 UNSPEC_ITOF
82 UNSPEC_FTOI
83 UNSPEC_NOP
06904722 84 UNSPEC_ADDV
85 UNSPEC_SUBV
86 UNSPEC_NEGV
8992df51 87])
88
89;; UNSPEC_VOLATILE usage.
90(define_c_enum "unspecv" [
91 UNSPECV_BLOCKAGE
92 UNSPECV_DSI
93])
94
95(include "predicates.md")
96(include "constraints.md")
97
98;;
99;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
100;;
101;; Attributes.
102;;
103;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
104;;
105
106; Instruction type.
107;
108;imm_reg Move of immediate value to register.
109;mem_reg Move from memory to register.
110;eam_reg Move from EAM to register.
111;fp_reg Move from FPU to register.
112;reg_mem Move from register to memory.
113;reg_eam Move from register to EAM.
114;reg_fp Move from register to FPU.
115;arith Arithmetic operation, result in register, sets overflow.
116;arith2 Two successive arithmetic operations.
117;logic Logical operation, result in register, does not set overflow.
118;abs_branch Absolute branch.
119;branch Branch.
120;bmi Block move.
121;call Call to subprogram.
122;ret Return from subprogram.
123;rfi Return from interrupt.
124;dsi Disable interrupts.
125;cmp Compare or test.
126;div EAM 32/32 division.
127;divd EAM 64/32 division.
128;mul EAM 32 * 32 -> 64 multiplication.
129;shiftdi EAM 64 bit shift.
130;fdiv Floating point divide.
131;fsqrt Floating point square root.
132;ftoi Fix float to integer.
133;itof Float integer.
134;fmove Floating point move w/ or w/o change of sign: fmove, fabs, fneg.
135;fcmp Floating point compare or test.
136;fp Other floating point operations.
137;nop No operation.
138;multi Multiple instructions which split.
139;asm User asm instructions.
d049f24a 140;trap Trap instructions.
8992df51 141
142(define_attr "type"
d049f24a 143"imm_reg,mem_reg,eam_reg,fp_reg,reg_mem,reg_eam,reg_fp,arith,arith2,logic,abs_branch,branch,bmi,call,ret,rfi,dsi,cmp,div,divd,mul,shiftdi,fdiv,fsqrt,ftoi,itof,fmove,fcmp,fp,nop,multi,asm,trap" (const_string "logic"))
8992df51 144
145; Those insns that occupy 4 bytes.
146(define_attr "single_insn" "no,yes"
147 (if_then_else (eq_attr "type" "arith2,rfi,multi")
148 (const_string "no")
149 (const_string "yes")))
150
151; True if branch or call will be emitting a nop into its delay slot.
152(define_attr "empty_delay_slot" "false,true"
153 (symbol_ref "(empty_delay_slot (insn)
154 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
155
156; Length in bytes.
157; The allowed range for the offset of short branches is [-131072;131068]
158; and it is counted from the address of the insn so we need to subtract
159; 8 for forward branches because (pc) points to the next insn for them.
160(define_attr "length" ""
161 (cond [(eq_attr "type" "abs_branch,call,ret")
162 (if_then_else (eq_attr "empty_delay_slot" "true")
163 (const_int 8)
164 (const_int 4))
165 (eq_attr "type" "branch")
166 (if_then_else (leu (plus (minus (match_dup 0) (pc))
167 (const_int 131060))
168 (const_int 262120))
169 (if_then_else (eq_attr "empty_delay_slot" "true")
170 (const_int 8)
171 (const_int 4))
172 (const_int 20))
173 (eq_attr "single_insn" "no")
174 (const_int 8)] (const_int 4)))
175
176(define_asm_attributes [(set_attr "type" "asm")])
177
178; Delay slots.
179(define_delay (eq_attr "type" "abs_branch,branch,call,ret")
180 [(and (eq_attr "type" "!abs_branch,branch,call,ret,rfi,bmi,mul,div,divd,fdiv,fsqrt,asm")
181 (eq_attr "single_insn" "yes"))
182 (nil) (nil)])
183
184;;
185;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
186;;
187;; Processor pipeline description.
188;;
189;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
190;;
191
192; Attribute for cpu type.
193; These must match the values for enum processor_type in visium-opts.h.
194(define_attr "cpu" "gr5,gr6" (const (symbol_ref "visium_cpu_attr")))
195
196(include "gr5.md")
197(include "gr6.md")
198
199;;
200;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
201;;
202;; Iterators.
203;;
204;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
205;;
206
207(define_mode_iterator QHI [QI HI])
208(define_mode_iterator I [QI HI SI])
d049f24a 209(define_mode_attr b [(QI "8") (HI "16") (SI "32")])
8992df51 210(define_mode_attr s [(QI ".b") (HI ".w") (SI ".l")])
211
212; This code iterator allows signed and unsigned widening multiplications
213; to use the same template.
214(define_code_iterator any_extend [sign_extend zero_extend])
215
216; <u> expands to an empty string when doing a signed operation and
217; "u" when doing an unsigned operation.
218(define_code_attr u [(sign_extend "") (zero_extend "u")])
219
220; <su> is like <u>, but the signed form expands to "s" rather than "".
221(define_code_attr su [(sign_extend "s") (zero_extend "u")])
222
223; This code iterator allows returns and simple returns to use the same template.
224(define_code_iterator any_return [return simple_return])
225(define_code_attr return_pred [(return "visium_can_use_return_insn_p ()")
226 (simple_return "!visium_interrupt_function_p ()")])
227(define_code_attr return_str [(return "") (simple_return "simple_")])
228
229; This code iterator allows integer and FP cstores to use the same template.
230(define_code_iterator any_scc [ltu lt])
231(define_code_attr scc_str [(ltu "sltu") (lt "slt")])
232
233;This code iterator allows cstore splitters to use the same template.
234(define_code_iterator any_add [plus minus])
235(define_code_attr add_op [(plus "PLUS") (minus "MINUS")])
236(define_code_attr add_str [(plus "plus") (minus "minus")])
237
238;;
239;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
240;;
241;; Substitutions.
242;;
573c1e6a 243;; They are used to define the first instruction of the pairs required by
8992df51 244;; the postreload compare elimination pass, with a first variant for the
245;; logical insns and a second variant for the arithmetic insns.
246;;
247;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
248;;
249
250(define_subst "flags_subst_logic"
251 [(set (match_operand 0 "") (match_operand 1 ""))
252 (clobber (reg:CC R_FLAGS))]
253 ""
e3b93558 254 [(set (reg:CC R_FLAGS)
255 (compare:CC (match_dup 1) (const_int 0)))
256 (set (match_dup 0) (match_dup 1))])
8992df51 257
258(define_subst_attr "subst_logic" "flags_subst_logic" "_flags" "_set_flags")
259
260(define_subst "flags_subst_arith"
261 [(set (match_operand 0 "") (match_operand 1 ""))
262 (clobber (reg:CC R_FLAGS))]
263 ""
e3b93558 264 [(set (reg:CCNZ R_FLAGS)
265 (compare:CCNZ (match_dup 1) (const_int 0)))
266 (set (match_dup 0) (match_dup 1))])
8992df51 267
268(define_subst_attr "subst_arith" "flags_subst_arith" "_flags" "_set_flags")
269
270;;
271;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
272;;
273;; QImode moves
274;;
275;; For moving among registers we use the move.b instruction. This is
276;; actually an OR instruction using an alias. For moving between register
277;; and memory we need the address of the memory location in a register.
278;; However, we can accept an expression (reg + offset) where offset is in
279;; the range 0 .. 31.
280;;
281;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
282;;
283
284(define_expand "movqi"
285 [(set (match_operand:QI 0 "nonimmediate_operand" "")
286 (match_operand:QI 1 "general_operand" ""))]
287 ""
288{
289 prepare_move_operands (operands, QImode);
290})
291
292(define_insn "*movqi_insn"
293 [(set (match_operand:QI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r")
294 (match_operand:QI 1 "general_operand" " r,rO, r, r,?b,?c,i,m"))]
295 "ok_for_simple_move_operands (operands, QImode)"
296 "@
297 #
298 write.b %0,%r1
299 writemd %1,r0 ;movqi ?b r
300 writemdc %1 ;movqi ?c r
301 readmda %0 ;movqi r ?b
302 readmdc %0 ;movqi r ?c
303 moviq %0,%b1 ;movqi r i
304 read.b %0,%1"
305 [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,mem_reg")])
306
307(define_insn "*movqi_insn<subst_logic>"
308 [(set (match_operand:QI 0 "gpc_reg_operand" "=r")
309 (match_operand:QI 1 "gpc_reg_operand" "r"))
310 (clobber (reg:CC R_FLAGS))]
311 "reload_completed"
312 "move.b %0,%1"
313 [(set_attr "type" "logic")])
314
315(define_split
316 [(set (match_operand:QI 0 "gpc_reg_operand" "")
317 (match_operand:QI 1 "gpc_reg_operand" ""))]
318 "reload_completed"
319 [(parallel [(set (match_dup 0) (match_dup 1))
320 (clobber (reg:CC R_FLAGS))])]
321 "")
322
323(define_expand "movstrictqi"
324 [(set (strict_low_part (match_operand:QI 0 "register_operand" ""))
325 (match_operand:QI 1 "general_operand" ""))]
326 "")
327
328(define_insn "*movstrictqi_insn"
329 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r,r"))
330 (match_operand:QI 1 "general_operand" "rO,m"))]
331 "ok_for_simple_move_strict_operands (operands, QImode)"
332 "@
333 #
334 read.b %0,%1"
335 [(set_attr "type" "logic,mem_reg")])
336
337(define_insn "*movstrictqi_insn<subst_logic>"
338 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
339 (match_operand:QI 1 "reg_or_0_operand" "rO"))
340 (clobber (reg:CC R_FLAGS))]
341 "reload_completed"
342 "move.b %0,%r1"
343 [(set_attr "type" "logic")])
344
345(define_split
346 [(set (strict_low_part (match_operand:QI 0 "register_operand" ""))
347 (match_operand:QI 1 "reg_or_0_operand" ""))]
348 "reload_completed"
349 [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
350 (clobber (reg:CC R_FLAGS))])]
351 "")
352
353;;
354;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
355;;
356;; HImode moves
357;;
358;; For moving among registers we use the move.w instruction. This is
359;; actually an OR instruction using an alias. For moving between register
360;; and memory we need the address of the memory location in a register.
361;; However, we can accept an expression (reg + offset) where offset is in
362;; the range 0 .. 62 and is shifted right one place in the assembled
363;; instruction.
364;;
365;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
366;;
367
368(define_expand "movhi"
369 [(set (match_operand:HI 0 "nonimmediate_operand" "")
370 (match_operand:HI 1 "general_operand" ""))]
371 ""
372{
373 prepare_move_operands (operands, HImode);
374})
375
376(define_insn "*movhi_insn"
377 [(set (match_operand:HI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r")
378 (match_operand:HI 1 "general_operand" " r,rO, r, r,?b,?c,i,m"))]
379 "ok_for_simple_move_operands (operands, HImode)"
380 "@
381 #
382 write.w %0,%r1
383 writemd %1,r0 ;movhi ?b r
384 writemdc %1 ;movhi ?c r
385 readmda %0 ;movhi r ?b
386 readmdc %0 ;movhi r ?c
387 moviq %0,%w1 ;movhi r i
388 read.w %0,%1"
389 [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,mem_reg")])
390
391(define_insn "*movhi_insn<subst_logic>"
392 [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
393 (match_operand:HI 1 "gpc_reg_operand" "r"))
394 (clobber (reg:CC R_FLAGS))]
395 "reload_completed"
396 "move.w %0,%1"
397 [(set_attr "type" "logic")])
398
399(define_split
400 [(set (match_operand:HI 0 "gpc_reg_operand" "")
401 (match_operand:HI 1 "gpc_reg_operand" ""))]
402 "reload_completed"
403 [(parallel [(set (match_dup 0) (match_dup 1))
404 (clobber (reg:CC R_FLAGS))])]
405 "")
406
407(define_expand "movstricthi"
408 [(set (strict_low_part (match_operand:HI 0 "register_operand" ""))
409 (match_operand:HI 1 "general_operand" ""))]
410 "")
411
412(define_insn "*movstricthi_insn"
413 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r,r,r"))
414 (match_operand:HI 1 "general_operand" " r,i,m"))]
415 "ok_for_simple_move_strict_operands (operands, HImode)"
416 "@
417 #
418 movil %0,%w1
419 read.w %0,%1"
420 [(set_attr "type" "logic,imm_reg,mem_reg")])
421
422(define_insn "*movstricthi_insn<subst_logic>"
423 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
424 (match_operand:HI 1 "register_operand" "r"))
425 (clobber (reg:CC R_FLAGS))]
426 "reload_completed"
427 "move.w %0,%1"
428 [(set_attr "type" "logic")])
429
430(define_split
431 [(set (strict_low_part (match_operand:HI 0 "register_operand" ""))
432 (match_operand:HI 1 "register_operand" ""))]
433 "reload_completed"
434 [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
435 (clobber (reg:CC R_FLAGS))])]
436 "")
437
438;;
439;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
440;;
441;; SImode moves
442;;
443;; For moving among registers we use the move.l instruction. This is
444;; actually an OR instruction using an alias. For moving between register
445;; and memory we need the address of the memory location in a register.
446;; However, we can accept an expression (reg + offset) where offset is in
447;; the range 0 .. 124 and is shifted right two places in the assembled
448;; instruction.
449;;
450;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
451;;
452
453(define_expand "movsi"
454 [(set (match_operand:SI 0 "nonimmediate_operand" "")
455 (match_operand:SI 1 "general_operand" ""))]
456 ""
457{
458 prepare_move_operands (operands, SImode);
459})
460
461(define_insn "*movsi_high"
462 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
463 (high:SI (match_operand:SI 1 "immediate_operand" "n,i")) )]
464 ""
465 "@
466 moviu %0,%u1
467 moviu %0,%%u %a1"
468 [(set_attr "type" "imm_reg")])
469
470; We only care about the lower 16 bits of the constant
471; being inserted into the upper 16 bits of the register.
472(define_insn "*moviu"
473 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
474 (const_int 16)
475 (const_int 0))
476 (match_operand:SI 1 "const_int_operand" "n"))]
477 ""
478 "moviu %0,%w1"
479 [(set_attr "type" "imm_reg")])
480
481(define_insn "*movsi_losum"
482 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
483 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
484 (match_operand:SI 2 "immediate_operand" "n,i")))]
485 ""
486 "@
487 movil %0,%w2
488 movil %0,%%l %a2"
489 [(set_attr "type" "imm_reg")])
490
491(define_insn "*movil"
492 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
493 (const_int 16)
494 (const_int 16))
495 (match_operand:SI 1 "const_int_operand" "n"))]
496 ""
497 "movil %0,%w1"
498 [(set_attr "type" "imm_reg")])
499
500(define_insn "*movsi_insn_no_ieee"
501 [(set (match_operand:SI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r,r,r, r,!f")
502 (match_operand:SI 1 "general_operand" " r,rO, r, r,?b,?c,J,M,i,m,!f, r"))]
503 "!TARGET_FPU_IEEE && ok_for_simple_move_operands (operands, SImode)"
504 "@
505 #
506 write.l %0,%r1
507 writemd %1,r0 ;movsi ?b r
508 writemdc %1 ;movsi ?c r
509 readmda %0 ;movsi r ?b
510 readmdc %0 ;movsi r ?c
511 moviq %0,%1 ;movsi r J
512 #
513 # ;movsi r i
514 read.l %0,%1
515 fstore %0,%1
516 fload %0,%1"
517 [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,logic,multi,mem_reg,fp_reg,reg_fp")])
518
519(define_insn "*movsi_insn"
520 [(set (match_operand:SI 0 "nonimmediate_operand" "=r, m,?b,?c, r, r,r,r,r,r, r,?f,f")
521 (match_operand:SI 1 "general_operand" " r,rO, r, r,?b,?c,J,M,i,m,?f, r,f"))]
522 "TARGET_FPU_IEEE && ok_for_simple_move_operands (operands, SImode)"
523 "@
524 #
525 write.l %0,%r1
526 writemd %1,r0 ;movsi ?b r
527 writemdc %1 ;movsi ?c r
528 readmda %0 ;movsi r ?b
529 readmdc %0 ;movsi r ?c
530 moviq %0,%1 ;movsi r J
531 #
532 # ;movsi r i
533 read.l %0,%1
534 fstore %0,%1
535 fload %0,%1
536 fmove %0,%1"
537 [(set_attr "type" "logic,reg_mem,reg_eam,reg_eam,eam_reg,eam_reg,imm_reg,logic,multi,mem_reg,fp_reg,reg_fp,fmove")])
538
539(define_insn "*movsi_insn<subst_logic>"
540 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
541 (match_operand:SI 1 "gpc_reg_operand" "r"))
542 (clobber (reg:CC R_FLAGS))]
543 "reload_completed"
544 "move.l %0,%1"
545 [(set_attr "type" "logic")])
546
547(define_insn "*movsi_insn_m1<subst_logic>"
548 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
549 (const_int -1))
550 (clobber (reg:CC R_FLAGS))]
551 "reload_completed"
552 "not.l %0,r0"
553 [(set_attr "type" "logic")])
554
555(define_split
556 [(set (match_operand:SI 0 "gpc_reg_operand" "")
557 (match_operand:SI 1 "gpc_reg_operand" ""))]
558 "reload_completed"
559 [(parallel [(set (match_dup 0) (match_dup 1))
560 (clobber (reg:CC R_FLAGS))])]
561 "")
562
563(define_split
564 [(set (match_operand:SI 0 "gpc_reg_operand" "")
565 (const_int -1))]
566 "reload_completed"
567 [(parallel [(set (match_dup 0) (const_int -1))
568 (clobber (reg:CC R_FLAGS))])]
569 "")
570
571(define_insn "*movsi_mdbhi"
572 [(set (match_operand:SI 0 "register_operand" "=r")
573 (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))]
574 ""
575 "readmdb %0"
576 [(set_attr "type" "eam_reg")])
577
578(define_split
579 [(set (match_operand:SI 0 "gpc_reg_operand" "")
580 (match_operand:SI 1 "large_immediate_operand" ""))]
581 "reload_completed"
582 [(set (match_dup 0)
583 (high:SI (match_dup 1)) )
584 (set (match_dup 0)
585 (lo_sum:SI (match_dup 0) (match_dup 1)))]
586 "")
587
588;;
589;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
590;;
591;; DImode moves
592;;
593;; When the destination is the EAM register MDB, then we use the writemd
594;; instruction. In all other cases we split the move into two 32-bit moves.
595;;
596;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
597;;
598
599(define_expand "movdi"
600 [(set (match_operand:DI 0 "nonimmediate_operand" "")
601 (match_operand:DI 1 "general_operand" ""))]
602 ""
603{
604 prepare_move_operands (operands, DImode);
605})
606
607(define_insn "*movdi_insn"
608 [(set (match_operand:DI 0 "nonimmediate_operand" "= r, m, r,??b")
609 (match_operand:DI 1 "general_operand" "rim,rO,?b, r"))]
610 "ok_for_simple_move_operands (operands, DImode)"
611 "@
612 #
613 #
614 #
615 writemd %d1,%1 ;movdi ?b r"
616 [(set_attr "type" "multi,multi,multi,reg_eam")])
617
618(define_split
619 [(set (match_operand:DI 0 "gpc_reg_operand" "") (reg:DI R_MDB))]
620 "reload_completed"
621 [(set (match_dup 1) (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))
622 (set (match_dup 2) (reg:SI R_MDB))]
623{
624 operands[1] = operand_subword (operands[0], 0, 1, DImode);
625 operands[2] = operand_subword (operands[0], 1, 1, DImode);
626})
627
628(define_split
629 [(set (match_operand:DI 0 "non_eam_dst_operand" "")
630 (match_operand:DI 1 "non_eam_src_operand" ""))]
631 "reload_completed"
632 [(set (match_dup 2) (match_dup 3))
633 (set (match_dup 4) (match_dup 5))]
634{
c7235a4a 635 visium_split_double_move (operands, DImode);
8992df51 636})
637
638;;
639;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
640;;
641;; SFmode moves
642;;
643;; Constants are constructed in a GP register and moved to the FP register.
644;;
645;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
646;;
647
648(define_expand "movsf"
649 [(set (match_operand:SF 0 "nonimmediate_operand" "")
650 (match_operand:SF 1 "general_operand" ""))]
651 ""
652{
653 prepare_move_operands (operands, SFmode);
654})
655
656(define_insn "*movsf_insn"
657 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,r,r, m,r,r,r")
658 (match_operand:SF 1 "general_operand" " f,G,r,f,r,rG,G,F,m"))]
659 "ok_for_simple_move_operands (operands, SFmode)"
660 "@
661 fmove %0,%1
662 fmove %0,f0
663 fload %0,%1
664 fstore %0,%1
665 #
666 write.l %0,%r1
667 moviq %0,0
668 #
669 read.l %0,%1"
670 [(set_attr "type" "fmove,fmove,reg_fp,fp_reg,logic,reg_mem,imm_reg,multi,mem_reg")])
671
672(define_insn "*movsf_insn"
673 [(set (match_operand:SF 0 "gpc_reg_operand" "=r")
674 (match_operand:SF 1 "gpc_reg_operand" "r"))
675 (clobber (reg:CC R_FLAGS))]
676 "reload_completed"
677 "move.l %0,%1"
678 [(set_attr "type" "logic")])
679
680(define_split
681 [(set (match_operand:SF 0 "gpc_reg_operand" "")
682 (match_operand:SF 1 "gpc_reg_operand" ""))]
683 "reload_completed"
684 [(parallel [(set (match_dup 0) (match_dup 1))
685 (clobber (reg:CC R_FLAGS))])]
686 "")
687
688(define_split
689 [(set (match_operand:SF 0 "gpc_reg_operand" "")
690 (match_operand:SF 1 "const_double_operand" ""))]
691 "reload_completed"
692 [(set (match_dup 2) (match_dup 3))]
693{
694 long l;
8992df51 695
945f7b03 696 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
8992df51 697
698 operands[2] = operand_subword (operands[0], 0, 0, SFmode);
699 operands[3] = GEN_INT (trunc_int_for_mode (l, SImode));
700})
701
702;;
703;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
704;;
705;; DFmode moves
706;;
707;; We always split a DFmode move into two SImode moves.
708;;
709;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
710;;
711
712(define_expand "movdf"
713 [(set (match_operand:DF 0 "nonimmediate_operand" "")
714 (match_operand:DF 1 "general_operand" ""))]
715 ""
716{
717 prepare_move_operands (operands, DFmode);
718})
719
720(define_insn "*movdf_insn"
721 [(set (match_operand:DF 0 "nonimmediate_operand" "= r, m")
722 (match_operand:DF 1 "general_operand" "rFm,rG"))]
723 "ok_for_simple_move_operands (operands, DFmode)"
724 "#"
725 [(set_attr "type" "multi")])
726
727(define_split
728 [(set (match_operand:DF 0 "nonimmediate_operand" "")
729 (match_operand:DF 1 "general_operand" ""))]
730 "reload_completed"
731 [(set (match_dup 2) (match_dup 3))
732 (set (match_dup 4) (match_dup 5))]
733{
c7235a4a 734 visium_split_double_move (operands, DFmode);
8992df51 735})
736
737;;
738;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
739;;
740;; Integer Add
741;;
742;; Modes QI, HI, SI and DI are supported directly.
743;;
744;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
745;;
746
747(define_expand "add<mode>3"
748 [(set (match_operand:QHI 0 "register_operand" "")
749 (plus:QHI (match_operand:QHI 1 "register_operand" "")
750 (match_operand:QHI 2 "register_operand" "")))]
751 "")
752
06904722 753(define_expand "uaddv<mode>4"
754 [(set (match_operand:I 0 "register_operand" "")
755 (plus:I (match_operand:I 1 "register_operand" "")
756 (match_operand:I 2 "register_operand" "")))
757 (set (pc)
758 (if_then_else (ltu (match_dup 0) (match_dup 1))
759 (label_ref (match_operand 3 ""))
760 (pc)))]
761 "")
762
763(define_expand "addv<mode>4"
764 [(set (match_operand:I 0 "register_operand" "")
765 (plus:I (match_operand:I 1 "register_operand" "")
766 (match_operand:I 2 "register_operand" "")))
767 (set (pc)
768 (if_then_else (ne (match_dup 0)
769 (unspec:I [(match_dup 1) (match_dup 2)] UNSPEC_ADDV))
770 (label_ref (match_operand 3 ""))
771 (pc)))]
772 "")
773
8992df51 774(define_insn_and_split "*add<mode>3_insn"
775 [(set (match_operand:QHI 0 "register_operand" "=r")
776 (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
777 (match_operand:QHI 2 "register_operand" "r")))]
778 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
779 "#"
780 "reload_completed"
781 [(parallel [(set (match_dup 0)
782 (plus:QHI (match_dup 1) (match_dup 2)))
783 (clobber (reg:CC R_FLAGS))])]
784 ""
785 [(set_attr "type" "arith")])
786
787(define_insn "*add<mode>3_insn<subst_arith>"
788 [(set (match_operand:QHI 0 "register_operand" "=r")
789 (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
790 (match_operand:QHI 2 "register_operand" "r")))
791 (clobber (reg:CC R_FLAGS))]
792 "reload_completed"
793 "add<s> %0,%1,%2"
794 [(set_attr "type" "arith")])
795
06904722 796(define_insn "*add<mode>3_insn_set_carry"
e3b93558 797 [(set (reg:CCC R_FLAGS)
798 (compare:CCC (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
799 (match_operand:QHI 2 "register_operand" "r"))
800 (match_dup 1)))
801 (set (match_operand:QHI 0 "register_operand" "=r")
802 (plus:QHI (match_dup 1) (match_dup 2)))]
06904722 803 "reload_completed"
804 "add<s> %0,%1,%2"
805 [(set_attr "type" "arith")])
806
807(define_insn "*add<mode>3_insn_set_overflow"
e3b93558 808 [(set (reg:CCV R_FLAGS)
809 (compare:CCV (plus:QHI (match_operand:QHI 1 "register_operand" "%r")
810 (match_operand:QHI 2 "register_operand" "r"))
811 (unspec:QHI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
812 (set (match_operand:QHI 0 "register_operand" "=r")
813 (plus:QHI (match_dup 1) (match_dup 2)))]
06904722 814 "reload_completed"
815 "add<s> %0,%1,%2"
816 [(set_attr "type" "arith")])
817
8992df51 818(define_expand "addsi3"
819 [(set (match_operand:SI 0 "register_operand" "")
820 (plus:SI (match_operand:SI 1 "register_operand" "")
821 (match_operand:SI 2 "add_operand" "")))]
822 "")
823
824(define_expand "addsi3_flags"
825 [(parallel [(set (match_operand:SI 0 "register_operand" "")
826 (plus:SI (match_operand:SI 1 "register_operand" "")
827 (match_operand:SI 2 "add_operand" "")))
828 (clobber (reg:CC R_FLAGS))])]
829 "reload_completed"
830 "")
831
832(define_insn_and_split "*addsi3_insn"
833 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
834 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,0")
835 (match_operand:SI 2 "add_operand" " L,r,J")))]
836 "ok_for_simple_arith_logic_operands (operands, SImode)"
837 "#"
838 "reload_completed"
839 [(parallel [(set (match_dup 0)
840 (plus:SI (match_dup 1) (match_dup 2)))
841 (clobber (reg:CC R_FLAGS))])]
842 ""
843 [(set_attr "type" "arith")])
844
845; Favour the addition of small negative constants, since they are
846; expensive to load into a register.
847
848(define_insn "*addsi3_insn<subst_arith>"
849 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
850 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,0")
851 (match_operand:SI 2 "add_operand" " L,r,J")))
852 (clobber (reg:CC R_FLAGS))]
853 "reload_completed"
854 "@
855 subi %0,%n2
856 add.l %0,%1,%2
857 addi %0,%2"
858 [(set_attr "type" "arith")])
859
f9f22fee 860(define_insn "addsi3_insn_set_carry"
e3b93558 861 [(set (reg:CCC R_FLAGS)
862 (compare:CCC (plus:SI (match_operand:SI 1 "register_operand" "%r,0")
863 (match_operand:SI 2 "real_add_operand" " r,J"))
864 (match_dup 1)))
865 (set (match_operand:SI 0 "register_operand" "=r,r")
866 (plus:SI (match_dup 1) (match_dup 2)))]
f9f22fee 867 "reload_completed"
868 "@
869 add.l %0,%1,%2
870 addi %0,%2"
871 [(set_attr "type" "arith")])
872
06904722 873(define_insn "*addsi3_insn_set_overflow"
e3b93558 874 [(set (reg:CCV R_FLAGS)
875 (compare:CCV (plus:SI (match_operand:SI 1 "register_operand" "%r,0")
876 (match_operand:SI 2 "real_add_operand" " r,J"))
877 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
878 (set (match_operand:SI 0 "register_operand" "=r,r")
879 (plus:SI (match_dup 1) (match_dup 2)))]
06904722 880 "reload_completed"
881 "@
882 add.l %0,%1,%2
883 addi %0,%2"
884 [(set_attr "type" "arith")])
885
8992df51 886(define_expand "adddi3"
887 [(set (match_operand:DI 0 "register_operand" "")
888 (plus:DI (match_operand:DI 1 "register_operand" "")
889 (match_operand:DI 2 "add_operand" "")))]
890 "")
891
c7235a4a 892; Disfavour the use of add.l because of the early clobber.
893
8992df51 894(define_insn_and_split "*addi3_insn"
895 [(set (match_operand:DI 0 "register_operand" "=r,r,&r")
896 (plus:DI (match_operand:DI 1 "register_operand" "%0,0, r")
c7235a4a 897 (match_operand:DI 2 "add_operand" " L,J, r")))]
8992df51 898 "ok_for_simple_arith_logic_operands (operands, DImode)"
899 "#"
900 "reload_completed"
c7235a4a 901 [(const_int 0)]
902{
903 visium_split_double_add (PLUS, operands[0], operands[1], operands[2]);
904 DONE;
905}
8992df51 906 [(set_attr "type" "arith2")])
907
908;;
909;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
910;;
911;; Integer Add with Carry
912;;
c7235a4a 913;; Only SI mode is supported.
8992df51 914;;
915;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
916;;
917
918(define_insn "*<scc_str><subst_arith>"
919 [(set (match_operand:SI 0 "register_operand" "=r")
920 (any_scc:SI (reg R_FLAGS) (const_int 0)))
921 (clobber (reg:CC R_FLAGS))]
922 "reload_completed"
923 "adc.l %0,r0,r0"
924 [(set_attr "type" "arith")])
925
926(define_insn "*plus_<scc_str><subst_arith>"
927 [(set (match_operand:SI 0 "register_operand" "=r")
928 (plus:SI (match_operand:SI 1 "register_operand" "r")
929 (any_scc:SI (reg R_FLAGS) (const_int 0))))
930 (clobber (reg:CC R_FLAGS))]
931 "reload_completed"
932 "adc.l %0,%1,r0"
933 [(set_attr "type" "arith")])
934
c7235a4a 935(define_insn "*plus_plus_sltu<subst_arith>"
936 [(set (match_operand:SI 0 "register_operand" "=r")
937 (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
938 (match_operand:SI 2 "register_operand" "r"))
939 (ltu:SI (reg R_FLAGS) (const_int 0))))
940 (clobber (reg:CC R_FLAGS))]
941 "reload_completed"
942 "adc.l %0,%1,%2"
943 [(set_attr "type" "arith")])
944
8992df51 945;;
946;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
947;;
948;; Integer Subtract
949;;
950;; Modes QI, HI, SI and DI are supported directly.
951;;
952;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
953;;
954
955(define_expand "sub<mode>3"
956 [(set (match_operand:QHI 0 "register_operand" "")
957 (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "")
958 (match_operand:QHI 2 "register_operand" "")))]
959 "")
960
06904722 961(define_expand "usubv<mode>4"
962 [(set (match_operand:I 0 "register_operand" "")
963 (minus:I (match_operand:I 1 "reg_or_0_operand" "")
964 (match_operand:I 2 "register_operand" "")))
965 (set (pc)
966 (if_then_else (ltu (match_dup 1) (match_dup 2))
967 (label_ref (match_operand 3 ""))
968 (pc)))]
969 ""
970{
971 if (operands[1] == const0_rtx)
972 {
973 emit_insn (gen_unegv<mode>3 (operands[0], operands[2], operands[3]));
974 DONE;
975 }
976})
977
978(define_expand "subv<mode>4"
979 [(set (match_operand:I 0 "register_operand" "")
980 (minus:I (match_operand:I 1 "register_operand" "")
981 (match_operand:I 2 "register_operand" "")))
982 (set (pc)
983 (if_then_else (ne (match_dup 0)
984 (unspec:I [(match_dup 1) (match_dup 2)] UNSPEC_SUBV))
985 (label_ref (match_operand 3 ""))
986 (pc)))]
987 "")
988
8992df51 989(define_insn_and_split "*sub<mode>3_insn"
990 [(set (match_operand:QHI 0 "register_operand" "=r")
991 (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "rO")
992 (match_operand:QHI 2 "register_operand" "r")))]
993 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
994 "#"
995 "reload_completed"
996 [(parallel [(set (match_dup 0)
997 (minus:QHI (match_dup 1) (match_dup 2)))
998 (clobber (reg:CC R_FLAGS))])]
999 ""
1000 [(set_attr "type" "arith")])
1001
1002(define_insn "*sub<mode>3_insn<subst_arith>"
1003 [(set (match_operand:QHI 0 "register_operand" "=r")
1004 (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "rO")
1005 (match_operand:QHI 2 "register_operand" "r")))
1006 (clobber (reg:CC R_FLAGS))]
1007 "reload_completed"
1008 "sub<s> %0,%r1,%2"
1009 [(set_attr "type" "arith")])
1010
06904722 1011(define_insn "*sub<mode>3_insn_set_carry"
e3b93558 1012 [(set (reg:CC R_FLAGS)
1013 (compare:CC (match_operand:QHI 1 "reg_or_0_operand" "r0")
1014 (match_operand:QHI 2 "register_operand" "r")))
1015 (set (match_operand:QHI 0 "register_operand" "=r")
1016 (minus:QHI (match_dup 1) (match_dup 2)))]
06904722 1017 "reload_completed"
1018 "sub<s> %0,%r1,%2"
1019 [(set_attr "type" "arith")])
1020
1021(define_insn "*sub<mode>3_insn_set_overflow"
e3b93558 1022 [(set (reg:CCV R_FLAGS)
1023 (compare:CCV (minus:QHI (match_operand:QHI 1 "reg_or_0_operand" "r0")
1024 (match_operand:QHI 2 "register_operand" "r"))
1025 (unspec:QHI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
1026 (set (match_operand:QHI 0 "register_operand" "=r")
1027 (minus:QHI (match_dup 1) (match_dup 2)))]
06904722 1028 "reload_completed"
1029 "sub<s> %0,%r1,%2"
1030 [(set_attr "type" "arith")])
1031
8992df51 1032(define_expand "subsi3"
1033 [(set (match_operand:SI 0 "register_operand" "")
1034 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
1035 (match_operand:SI 2 "add_operand" "")))]
1036 "")
1037
1038(define_expand "subsi3_flags"
1039 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1040 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
1041 (match_operand:SI 2 "add_operand" "")))
1042 (clobber (reg:CC R_FLAGS))])]
1043 "reload_completed"
1044 "")
1045
1046(define_insn_and_split "*subsi3_insn"
1047 [(set (match_operand:SI 0 "register_operand" "=r,r, r")
1048 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " 0,rO,0")
1049 (match_operand:SI 2 "add_operand" " L,r, J")))]
1050 "ok_for_simple_arith_logic_operands (operands, SImode)"
1051 "#"
1052 "reload_completed"
1053 [(parallel [(set (match_dup 0)
1054 (minus:SI (match_dup 1) (match_dup 2)))
1055 (clobber (reg:CC R_FLAGS))])]
1056 ""
1057 [(set_attr "type" "arith")])
1058
1059; Favour the subtraction of small negative constants, since they are
1060; expensive to load into a register.
1061
1062(define_insn "*subsi3_insn<subst_arith>"
1063 [(set (match_operand:SI 0 "register_operand" "=r,r, r")
1064 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " 0,rO,0")
1065 (match_operand:SI 2 "add_operand" " L,r, J")))
1066 (clobber (reg:CC R_FLAGS))]
1067 "reload_completed"
1068 "@
1069 addi %0,%n2
1070 sub.l %0,%r1,%2
1071 subi %0,%2"
1072 [(set_attr "type" "arith")])
1073
f9f22fee 1074(define_insn "subsi3_insn_set_carry"
e3b93558 1075 [(set (reg:CC R_FLAGS)
1076 (compare:CC (match_operand:SI 1 "register_operand" "r,0")
1077 (match_operand:SI 2 "real_add_operand" "r,J")))
1078 (set (match_operand:SI 0 "register_operand" "=r,r")
1079 (minus:SI (match_dup 1) (match_dup 2)))]
f9f22fee 1080 "reload_completed"
1081 "@
1082 sub.l %0,%r1,%2
1083 subi %0,%2"
1084 [(set_attr "type" "arith")])
1085
06904722 1086(define_insn "*subsi3_insn_set_overflow"
e3b93558 1087 [(set (reg:CCV R_FLAGS)
1088 (compare:CCV (minus:SI (match_operand:SI 1 "register_operand" "r,0")
1089 (match_operand:SI 2 "real_add_operand" "r,J"))
1090 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
1091 (set (match_operand:SI 0 "register_operand" "=r,r")
1092 (minus:SI (match_dup 1) (match_dup 2)))]
06904722 1093 "reload_completed"
1094 "@
1095 sub.l %0,%1,%2
1096 subi %0,%2"
1097 [(set_attr "type" "arith")])
1098
8992df51 1099(define_expand "subdi3"
1100 [(set (match_operand:DI 0 "register_operand" "")
1101 (minus:DI (match_operand:DI 1 "register_operand" "")
1102 (match_operand:DI 2 "add_operand" "")))]
1103 "")
1104
c7235a4a 1105; Disfavour the use of the sub.l because of the early clobber.
1106
8992df51 1107(define_insn_and_split "*subdi3_insn"
1108 [(set (match_operand:DI 0 "register_operand" "=r,r,&r")
1109 (minus:DI (match_operand:DI 1 "register_operand" " 0,0, r")
c7235a4a 1110 (match_operand:DI 2 "add_operand" " L,J, r")))]
8992df51 1111 "ok_for_simple_arith_logic_operands (operands, DImode)"
1112 "#"
1113 "reload_completed"
c7235a4a 1114 [(const_int 0)]
1115{
1116 visium_split_double_add (MINUS, operands[0], operands[1], operands[2]);
1117 DONE;
1118}
8992df51 1119 [(set_attr "type" "arith2")])
1120
1121;;
1122;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1123;;
1124;; Integer Subtract with Carry
1125;;
c7235a4a 1126;; Only SI mode is supported.
8992df51 1127;;
1128;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1129;;
1130
1131(define_insn "*neg_<scc_str><subst_arith>"
1132 [(set (match_operand:SI 0 "register_operand" "=r")
1133 (neg:SI (any_scc:SI (reg R_FLAGS) (const_int 0))))
1134 (clobber (reg:CC R_FLAGS))]
1135 "reload_completed"
1136 "subc.l %0,r0,r0"
1137 [(set_attr "type" "arith")])
1138
1139(define_insn "*minus_<scc_str><subst_arith>"
1140 [(set (match_operand:SI 0 "register_operand" "=r")
1141 (minus:SI (match_operand:SI 1 "register_operand" "r")
1142 (any_scc:SI (reg R_FLAGS) (const_int 0))))
1143 (clobber (reg:CC R_FLAGS))]
1144 "reload_completed"
1145 "subc.l %0,%1,r0"
1146 [(set_attr "type" "arith")])
1147
c7235a4a 1148(define_insn "*minus_minus_sltu<subst_arith>"
1149 [(set (match_operand:SI 0 "register_operand" "=r")
1150 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
1151 (match_operand:SI 2 "register_operand" "r"))
1152 (ltu:SI (reg R_FLAGS) (const_int 0))))
1153 (clobber (reg:CC R_FLAGS))]
1154 "reload_completed"
1155 "subc.l %0,%r1,%2"
1156 [(set_attr "type" "arith")])
1157
8992df51 1158;;
1159;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1160;;
1161;; Integer Negate
1162;;
1163;; Modes QI, HI, SI and DI are supported directly.
1164;;
1165;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1166;;
1167
1168(define_expand "neg<mode>2"
1169 [(set (match_operand:I 0 "register_operand" "")
1170 (neg:I (match_operand:I 1 "register_operand" "")))]
1171 "")
1172
06904722 1173(define_expand "unegv<mode>3"
1174 [(set (match_operand:I 0 "register_operand" "")
1175 (neg:I (match_operand:I 1 "register_operand" "")))
1176 (set (pc)
1177 (if_then_else (ne (match_dup 0) (const_int 0))
1178 (label_ref (match_operand 2 ""))
1179 (pc)))]
1180 "")
1181
1182(define_expand "negv<mode>3"
1183 [(set (match_operand:I 0 "register_operand" "")
1184 (neg:I (match_operand:I 1 "register_operand" "")))
1185 (set (pc)
1186 (if_then_else (ne (match_dup 0)
1187 (unspec:I [(match_dup 1)] UNSPEC_NEGV))
1188 (label_ref (match_operand 2 ""))
1189 (pc)))]
1190 "")
1191
8992df51 1192(define_insn_and_split "*neg<mode>2_insn"
1193 [(set (match_operand:I 0 "register_operand" "=r")
1194 (neg:I (match_operand:I 1 "register_operand" "r")))]
1195 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1196 "#"
1197 "reload_completed"
1198 [(parallel [(set (match_dup 0) (neg:I (match_dup 1)))
1199 (clobber (reg:CC R_FLAGS))])]
1200 ""
1201 [(set_attr "type" "arith")])
1202
1203(define_insn "*neg<mode>2_insn<subst_arith>"
1204 [(set (match_operand:I 0 "register_operand" "=r")
1205 (neg:I (match_operand:I 1 "register_operand" "r")))
1206 (clobber (reg:CC R_FLAGS))]
1207 "reload_completed"
1208 "sub<s> %0,r0,%1"
1209 [(set_attr "type" "arith")])
1210
f9f22fee 1211(define_insn "negsi2_insn_set_carry"
e3b93558 1212 [(set (reg:CCC R_FLAGS)
1213 (compare:CCC (not:SI (match_operand:SI 1 "register_operand" "r"))
1214 (const_int -1)))
1215 (set (match_operand:SI 0 "register_operand" "=r")
1216 (neg:SI (match_dup 1)))]
f9f22fee 1217 "reload_completed"
1218 "sub.l %0,r0,%1"
1219 [(set_attr "type" "arith")])
1220
06904722 1221(define_insn "*neg<mode>2_insn_set_overflow"
e3b93558 1222 [(set (reg:CCV R_FLAGS)
1223 (compare:CCV (neg:I (match_operand:I 1 "register_operand" "r"))
1224 (unspec:I [(match_dup 1)] UNSPEC_NEGV)))
1225 (set (match_operand:I 0 "register_operand" "=r")
1226 (neg:I (match_dup 1)))]
06904722 1227 "reload_completed"
1228 "sub<s> %0,r0,%1"
1229 [(set_attr "type" "arith")])
1230
8992df51 1231(define_expand "negdi2"
1232 [(set (match_operand:DI 0 "register_operand" "")
1233 (neg:DI (match_operand:DI 1 "register_operand" "")))]
1234 "")
1235
1236(define_insn_and_split "*negdi2_insn"
1237 [(set (match_operand:DI 0 "register_operand" "=&r")
1238 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
1239 "ok_for_simple_arith_logic_operands (operands, DImode)"
1240 "#"
1241 "reload_completed"
c7235a4a 1242 [(const_int 0)]
1243{
1244 visium_split_double_add (MINUS, operands[0], const0_rtx, operands[1]);
1245 DONE;
1246}
8992df51 1247 [(set_attr "type" "arith2")])
1248
1249;;
1250;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1251;;
1252;; Integer Multiply (non-widening and widening, signed and unsigned)
1253;;
1254;; Only SI mode is supported.
1255;;
1256;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1257;;
1258
1259; The mults and multu instructions clear MDC but we only pretend that they
1260; clobber it to keep things relatively simple.
1261
1262(define_insn "mulsi3"
1263 [(set (match_operand:SI 0 "register_operand" "=b")
1264 (mult:SI (match_operand:SI 1 "register_operand" "%r")
1265 (match_operand:SI 2 "register_operand" "r")))
1266 (clobber (reg:SI R_MDC))]
1267 ""
1268 "mults %1,%2"
1269 [(set_attr "type" "mul")])
1270
1271; The names are mulsidi3 and umulsidi3 here.
1272
1273(define_insn "<u>mulsidi3"
1274 [(set (match_operand:DI 0 "register_operand" "=b")
1275 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
1276 (any_extend:DI (match_operand:SI 2 "register_operand" "r"))))
1277 (clobber (reg:SI R_MDC))]
1278 ""
1279 "mult<su> %1,%2"
1280 [(set_attr "type" "mul")])
1281
1282; But they are smulsi3_highpart and umulsi3_highpart here.
1283
1284(define_insn_and_split "<su>mulsi3_highpart"
1285 [(set (match_operand:SI 0 "register_operand" "=r")
1286 (truncate:SI
1287 (ashiftrt:DI
1288 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
1289 (any_extend:DI (match_operand:SI 2 "register_operand" "r")))
1290 (const_int 32))))
1291 (clobber (reg:DI R_MDB))
1292 (clobber (reg:SI R_MDC))]
1293 ""
1294 "#"
1295 "reload_completed"
1296 [(parallel [(set (reg:DI R_MDB)
1297 (mult:DI (any_extend:DI (match_dup 1))
1298 (any_extend:DI (match_dup 2))))
1299 (clobber (reg:SI R_MDC))])
1300 (set (match_dup 0) (unspec:SI [(reg:DI R_MDB)] UNSPEC_MDBHI))]
1301 ""
1302 [(set_attr "type" "multi")])
1303
1304;;
1305;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1306;;
1307;; Integer divide and modulus (signed and unsigned)
1308;;
1309;; Only SI mode is supported.
1310;;
1311;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1312;;
1313
1314(define_insn "*divmodsi4_insn"
1315 [(set (match_operand:SI 0 "register_operand" "=b")
1316 (div:SI (match_operand:SI 1 "register_operand" "0")
1317 (match_operand:SI 2 "register_operand" "r")))
1318 (set (reg:SI R_MDC) (mod:SI (match_dup 1) (match_dup 2)))]
1319 ""
1320 "divs %2"
1321 [(set_attr "type" "div")])
1322
1323(define_insn_and_split "divmodsi4"
1324 [(set (match_operand:SI 0 "register_operand" "=b")
1325 (div:SI (match_operand:SI 1 "register_operand" "0")
1326 (match_operand:SI 2 "register_operand" "r")))
1327 (set (match_operand:SI 3 "register_operand" "=r")
1328 (mod:SI (match_dup 1) (match_dup 2)))
1329 (clobber (reg:SI R_MDC))]
1330 ""
1331 "#"
1332 "reload_completed"
1333 [(parallel [(set (match_dup 0) (div:SI (match_dup 1) (match_dup 2)))
1334 (set (reg:SI R_MDC) (mod:SI (match_dup 1) (match_dup 2)))])
1335 (set (match_dup 3) (reg:SI R_MDC))]
1336 ""
1337 [(set_attr "type" "multi")])
1338
1339(define_insn "*udivmodsi4_insn"
1340 [(set (match_operand:SI 0 "register_operand" "=b")
1341 (udiv:SI (match_operand:SI 1 "register_operand" "0")
1342 (match_operand:SI 2 "register_operand" "r")))
1343 (set (reg:SI R_MDC) (umod:SI (match_dup 1) (match_dup 2)))]
1344 ""
1345 "divu %2"
1346 [(set_attr "type" "div")])
1347
1348(define_insn_and_split "udivmodsi4"
1349 [(set (match_operand:SI 0 "register_operand" "=b")
1350 (udiv:SI (match_operand:SI 1 "register_operand" "0")
1351 (match_operand:SI 2 "register_operand" "r")))
1352 (set (match_operand:SI 3 "register_operand" "=r")
1353 (umod:SI (match_dup 1) (match_dup 2)))
1354 (clobber (reg:SI R_MDC))]
1355 ""
1356 "#"
1357 "reload_completed"
1358 [(parallel [(set (match_dup 0) (udiv:SI (match_dup 1) (match_dup 2)))
1359 (set (reg:SI R_MDC) (umod:SI (match_dup 1) (match_dup 2)))])
1360 (set (match_dup 3) (reg:SI R_MDC))]
1361 ""
1362 [(set_attr "type" "multi")])
1363
1364; FIXME. How do we persuade the compiler to use 64/32 bit divides directly ?
1365
1366(define_insn "*divds"
1367 [(set (reg:DI R_MDB)
1368 (div:DI (reg:DI R_MDB) (sign_extend:DI (match_operand:SI 0 "register_operand" "r"))))
1369 (set (reg:SI R_MDC) (truncate:SI (mod:DI (reg:DI R_MDB) (sign_extend:DI (match_dup 0)))))]
1370 ""
1371 "divds %0"
1372 [(set_attr "type" "divd")])
1373
1374(define_insn "*divdu"
1375 [(set (reg:DI R_MDB)
1376 (udiv:DI (reg:DI R_MDB) (zero_extend:DI (match_operand:SI 0 "register_operand" "r"))))
1377 (set (reg:SI R_MDC) (truncate:SI (umod:DI (reg:DI R_MDB) (zero_extend:DI (match_dup 0)))))]
1378 ""
1379 "divdu %0"
1380 [(set_attr "type" "divd")])
1381
1382;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1383;;
1384;; Bitwise Logical AND
1385;;
1386;; Modes QI, HI and SI are supported directly.
1387;;
1388;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1389;;
1390
1391(define_expand "and<mode>3"
1392 [(set (match_operand:I 0 "register_operand" "")
1393 (and:I (match_operand:I 1 "register_operand" "")
1394 (match_operand:I 2 "register_operand" "")))]
1395 "")
1396
1397(define_insn_and_split "*and<mode>3_insn"
1398 [(set (match_operand:I 0 "register_operand" "=r")
1399 (and:I (match_operand:I 1 "register_operand" "%r")
1400 (match_operand:I 2 "register_operand" "r")))]
1401 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1402 "#"
1403 "reload_completed"
1404 [(parallel [(set (match_dup 0)
1405 (and:I (match_dup 1) (match_dup 2)))
1406 (clobber (reg:CC R_FLAGS))])]
1407 ""
1408 [(set_attr "type" "logic")])
1409
1410(define_insn "*and<mode>3_insn<subst_logic>"
1411 [(set (match_operand:I 0 "register_operand" "=r")
1412 (and:I (match_operand:I 1 "register_operand" "%r")
1413 (match_operand:I 2 "register_operand" "r")))
1414 (clobber (reg:CC R_FLAGS))]
1415 "reload_completed"
1416 "and<s> %0,%1,%2"
1417 [(set_attr "type" "logic")])
1418
1419;;
1420;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1421;;
1422;; Bitwise Inclusive Logical OR
1423;;
1424;; Modes QI, HI and SI are supported directly.
1425;;
1426;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1427;;
1428
1429(define_expand "ior<mode>3"
1430 [(set (match_operand:I 0 "register_operand" "")
1431 (ior:I (match_operand:I 1 "register_operand" "")
1432 (match_operand:I 2 "register_operand" "")))]
1433 "")
1434
1435(define_insn_and_split "*ior<mode>3_insn"
1436 [(set (match_operand:I 0 "register_operand" "=r")
1437 (ior:I (match_operand:I 1 "register_operand" "%r")
1438 (match_operand:I 2 "register_operand" "r")))]
1439 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1440 "#"
1441 "reload_completed"
1442 [(parallel [(set (match_dup 0)
1443 (ior:I (match_dup 1) (match_dup 2)))
1444 (clobber (reg:CC R_FLAGS))])]
1445 ""
1446 [(set_attr "type" "logic")])
1447
1448(define_insn "*ior<mode>3_insn<subst_logic>"
1449 [(set (match_operand:I 0 "register_operand" "=r")
1450 (ior:I (match_operand:I 1 "register_operand" "%r")
1451 (match_operand:I 2 "register_operand" "r")))
1452 (clobber (reg:CC R_FLAGS))]
1453 "reload_completed"
1454 "or<s> %0,%1,%2"
1455 [(set_attr "type" "logic")])
1456
1457;;
1458;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1459;;
1460;; Bitwise Exclusive Logical OR
1461;;
1462;; Modes QI, HI and SI are supported directly.
1463;;
1464;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1465;;
1466
1467(define_expand "xor<mode>3"
1468 [(set (match_operand:I 0 "register_operand" "")
1469 (xor:I (match_operand:I 1 "register_operand" "")
1470 (match_operand:I 2 "register_operand" "")))]
1471 "")
1472
1473(define_insn_and_split "*xor<mode>3_insn"
1474 [(set (match_operand:I 0 "register_operand" "=r")
1475 (xor:I (match_operand:I 1 "register_operand" "%r")
1476 (match_operand:I 2 "register_operand" "r")))]
1477 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1478 "#"
1479 "reload_completed"
1480 [(parallel [(set (match_dup 0)
1481 (xor:I (match_dup 1) (match_dup 2)))
1482 (clobber (reg:CC R_FLAGS))])]
1483 ""
1484 [(set_attr "type" "logic")])
1485
1486(define_insn "*xor<mode>3_insn<subst_logic>"
1487 [(set (match_operand:I 0 "register_operand" "=r")
1488 (xor:I (match_operand:I 1 "register_operand" "%r")
1489 (match_operand:I 2 "register_operand" "r")))
1490 (clobber (reg:CC R_FLAGS))]
1491 "reload_completed"
1492 "xor<s> %0,%1,%2"
1493 [(set_attr "type" "logic")])
1494
1495;;
1496;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1497;;
1498;; Bitwise Logical NOT
1499;;
1500;; Modes QI, HI and SI are supported directly.
1501;;
1502;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1503;;
1504
1505(define_expand "one_cmpl<mode>2"
1506 [(set (match_operand:I 0 "register_operand" "")
1507 (not:I (match_operand:I 1 "reg_or_0_operand" "")))]
1508 "")
1509
1510(define_insn_and_split "*one_cmpl<mode>2_insn"
1511 [(set (match_operand:I 0 "register_operand" "=r")
1512 (not:I (match_operand:I 1 "reg_or_0_operand" "rO")))]
1513 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1514 "#"
1515 "reload_completed"
1516 [(parallel [(set (match_dup 0) (not:I (match_dup 1)))
1517 (clobber (reg:CC R_FLAGS))])]
1518 ""
1519 [(set_attr "type" "logic")])
1520
1521(define_insn "*one_cmpl<mode>2_insn<subst_logic>"
1522 [(set (match_operand:I 0 "register_operand" "=r")
1523 (not:I (match_operand:I 1 "reg_or_0_operand" "rO")))
1524 (clobber (reg:CC R_FLAGS))]
1525 "reload_completed"
1526 "not<s> %0,%r1"
1527 [(set_attr "type" "logic")])
1528
1529;;
1530;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1531;;
1532;; Arithmetic Shift Left
1533;;
1534;; Modes QI, HI, SI and DI are supported directly.
1535;;
1536;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1537;;
1538
1539(define_expand "ashl<mode>3"
1540 [(set (match_operand:I 0 "register_operand" "")
1541 (ashift:I (match_operand:I 1 "register_operand" "")
1542 (match_operand:QI 2 "reg_or_shift_operand" "")))]
1543 "")
1544
1545(define_insn_and_split "*ashl<mode>3_insn"
1546 [(set (match_operand:I 0 "register_operand" "=r,r")
1547 (ashift:I (match_operand:I 1 "register_operand" "r,r")
1548 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1549 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1550 "#"
1551 "reload_completed"
1552 [(parallel [(set (match_dup 0)
1553 (ashift:I (match_dup 1) (match_dup 2)))
1554 (clobber (reg:CC R_FLAGS))])]
1555 ""
1556 [(set_attr "type" "arith")])
1557
1558(define_insn "*ashl<mode>3_insn<subst_arith>"
1559 [(set (match_operand:I 0 "register_operand" "=r,r")
1560 (ashift:I (match_operand:I 1 "register_operand" "r,r")
1561 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1562 (clobber (reg:CC R_FLAGS))]
1563 "reload_completed"
1564 "asl<s> %0,%1,%2"
1565 [(set_attr "type" "arith")])
1566
1567(define_insn "ashldi3"
1568 [(set (match_operand:DI 0 "register_operand" "=b,r")
1569 (ashift:DI (match_operand:DI 1 "register_operand" "0,r")
1570 (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1571 (clobber (reg:SI R_MDC))]
1572 ""
1573 "@
1574 asld %2
1575 #"
1576 [(set_attr "type" "shiftdi,multi")])
1577
1578(define_split
1579 [(set (match_operand:DI 0 "gpc_reg_operand" "")
1580 (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
1581 (const_int 32)))
1582 (clobber (reg:SI R_MDC))]
1583 "reload_completed"
1584 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 4))
1585 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
1586 "")
1587
1588;;
1589;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1590;;
1591;; Arithmetic Shift Right
1592;;
1593;; Modes QI, HI, SI and DI are supported directly.
1594;;
1595;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1596;;
1597
1598(define_expand "ashr<mode>3"
1599 [(set (match_operand:I 0 "register_operand" "")
1600 (ashiftrt:I (match_operand:I 1 "register_operand" "")
1601 (match_operand:QI 2 "reg_or_shift_operand" "")))]
1602 "")
1603
1604(define_insn_and_split "*ashr<mode>3_insn"
1605 [(set (match_operand:I 0 "register_operand" "=r,r")
1606 (ashiftrt:I (match_operand:I 1 "register_operand" "r,r")
1607 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1608 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1609 "#"
1610 "reload_completed"
1611 [(parallel [(set (match_dup 0)
1612 (ashiftrt:I (match_dup 1) (match_dup 2)))
1613 (clobber (reg:CC R_FLAGS))])]
1614 ""
1615 [(set_attr "type" "logic")])
1616
1617(define_insn "*ashr<mode>3_insn<subst_logic>"
1618 [(set (match_operand:I 0 "register_operand" "=r,r")
1619 (ashiftrt:I (match_operand:I 1 "register_operand" "r,r")
1620 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1621 (clobber (reg:CC R_FLAGS))]
1622 "reload_completed"
1623 "asr<s> %0,%1,%2"
1624 [(set_attr "type" "logic")])
1625
1626(define_insn "ashrdi3"
1627 [(set (match_operand:DI 0 "register_operand" "=b,r")
1628 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,r")
1629 (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1630 (clobber (reg:SI R_MDC))]
1631 ""
1632 "@
1633 asrd %2
1634 #"
1635 [(set_attr "type" "shiftdi,multi")])
1636
1637(define_split
1638 [(set (match_operand:DI 0 "gpc_reg_operand" "")
1639 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1640 (const_int 32)))
1641 (clobber (reg:SI R_MDC))]
1642 "reload_completed"
1643 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 0))
1644 (parallel [(set (subreg:SI (match_dup 0) 0)
1645 (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))
1646 (clobber (reg:CC R_FLAGS))])]
1647 "")
1648
1649;;
1650;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1651;;
1652;; Logical Shift Right
1653;;
1654;; Modes QI, HI, SI and DI are supported directly.
1655;;
1656;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1657;;
1658
1659(define_expand "lshr<mode>3"
1660 [(set (match_operand:I 0 "register_operand" "")
1661 (lshiftrt:I (match_operand:I 1 "register_operand" "")
1662 (match_operand:QI 2 "reg_or_shift_operand" "")))]
1663 "")
1664
1665(define_insn_and_split "*lshr<mode>3_insn"
1666 [(set (match_operand:I 0 "register_operand" "=r,r")
1667 (lshiftrt:I (match_operand:I 1 "register_operand" "r,r")
1668 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))]
1669 "ok_for_simple_arith_logic_operands (operands, <MODE>mode)"
1670 "#"
1671 "reload_completed"
1672 [(parallel [(set (match_dup 0)
1673 (lshiftrt:I (match_dup 1) (match_dup 2)))
1674 (clobber (reg:CC R_FLAGS))])]
1675 ""
1676 [(set_attr "type" "logic")])
1677
1678(define_insn "*lshr<mode>3_insn<subst_logic>"
1679 [(set (match_operand:I 0 "register_operand" "=r,r")
1680 (lshiftrt:I (match_operand:I 1 "register_operand" "r,r")
1681 (match_operand:QI 2 "reg_or_shift_operand" "r,K")))
1682 (clobber (reg:CC R_FLAGS))]
1683 "reload_completed"
1684 "lsr<s> %0,%1,%2"
1685 [(set_attr "type" "logic")])
1686
1687(define_insn "lshrdi3"
1688 [(set (match_operand:DI 0 "register_operand" "=b,r")
1689 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,r")
1690 (match_operand:QI 2 "reg_or_32_operand" "r,P")))
1691 (clobber (reg:SI R_MDC))]
1692 ""
1693 "@
1694 lsrd %2
1695 #"
1696 [(set_attr "type" "shiftdi,multi")])
1697
1698(define_split
1699 [(set (match_operand:DI 0 "gpc_reg_operand" "")
1700 (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1701 (const_int 32)))
1702 (clobber (reg:SI R_MDC))]
1703 "reload_completed"
1704 [(set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 0))
1705 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
1706 "")
1707
1708;;
1709;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1710;;
1711;; Truncate
1712;;
1713;; Truncations among modes QI, HI, SI and DI are supported directly.
1714;;
1715;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1716;;
1717
1718(define_expand "trunchiqi2"
1719 [(set (match_operand:QI 0 "register_operand" "")
1720 (truncate:QI (match_operand:HI 1 "register_operand" "")))]
1721 "")
1722
1723(define_insn_and_split "*trunchiqi2_insn"
1724 [(set (match_operand:QI 0 "register_operand" "=r")
1725 (truncate:QI (match_operand:HI 1 "register_operand" "r")))]
1726 "ok_for_simple_arith_logic_operands (operands, QImode)"
1727 "#"
1728 "reload_completed"
1729 [(parallel [(set (match_dup 0) (truncate:QI (match_dup 1)))
1730 (clobber (reg:CC R_FLAGS))])]
1731 ""
1732 [(set_attr "type" "logic")])
1733
1734(define_insn "*trunchiqi2_insn<subst_logic>"
1735 [(set (match_operand:QI 0 "register_operand" "=r")
1736 (truncate:QI (match_operand:HI 1 "register_operand" "r")))
1737 (clobber (reg:CC R_FLAGS))]
1738 "reload_completed"
1739 "move.b %0,%1"
1740 [(set_attr "type" "logic")])
1741
1742(define_expand "truncsihi2"
1743 [(set (match_operand:HI 0 "register_operand" "")
1744 (truncate:HI (match_operand:SI 1 "register_operand" "")))]
1745 "")
1746
1747(define_insn_and_split "*truncsihi2_insn"
1748 [(set (match_operand:HI 0 "register_operand" "=r")
1749 (truncate:HI (match_operand:SI 1 "register_operand" "r")))]
1750 "ok_for_simple_arith_logic_operands (operands, HImode)"
1751 "#"
1752 "reload_completed"
1753 [(parallel [(set (match_dup 0) (truncate:HI (match_dup 1)))
1754 (clobber (reg:CC R_FLAGS))])]
1755 ""
1756 [(set_attr "type" "logic")])
1757
1758(define_insn "*truncsihi2_insn<subst_logic>"
1759 [(set (match_operand:HI 0 "register_operand" "=r")
1760 (truncate:HI (match_operand:SI 1 "register_operand" "r")))
1761 (clobber (reg:CC R_FLAGS))]
1762 "reload_completed"
1763 "move.w %0,%1"
1764 [(set_attr "type" "logic")])
1765
1766(define_expand "truncdisi2"
1767 [(set (match_operand:SI 0 "register_operand" "")
1768 (truncate:SI (match_operand:DI 1 "register_operand" "")))]
1769 "")
1770
1771(define_insn_and_split "*truncdisi2_insn"
1772 [(set (match_operand:SI 0 "register_operand" "=r")
1773 (truncate:SI (match_operand:DI 1 "register_operand" "r")))]
1774 "ok_for_simple_arith_logic_operands (operands, SImode)"
1775 "#"
1776 "reload_completed"
1777 [(parallel [(set (match_dup 0) (truncate:SI (match_dup 1)))
1778 (clobber (reg:CC R_FLAGS))])]
1779 ""
1780 [(set_attr "type" "logic")])
1781
1782(define_insn "*truncdisi2_insn<subst_logic>"
1783 [(set (match_operand:SI 0 "register_operand" "=r")
1784 (truncate:SI (match_operand:DI 1 "register_operand" "r")))
1785 (clobber (reg:CC R_FLAGS))]
1786 "reload_completed"
1787 "move.l %0,%d1"
1788 [(set_attr "type" "logic")])
1789
1790;;
1791;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1792;;
1793;; Sign-extend
1794;;
1795;; Sign-extensions among modes QI, HI, SI and DI are supported directly.
1796;;
1797;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1798;;
1799
1800(define_expand "extendqihi2"
1801 [(set (match_operand:HI 0 "register_operand" "")
1802 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1803 "")
1804
1805(define_insn_and_split "*extendqihi2_insn"
1806 [(set (match_operand:HI 0 "register_operand" "=r")
1807 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1808 "ok_for_simple_arith_logic_operands (operands, HImode)"
1809 "#"
1810 "reload_completed"
1811 [(parallel [(set (match_dup 0) (sign_extend:HI (match_dup 1)))
1812 (clobber (reg:CC R_FLAGS))])]
1813 ""
1814 [(set_attr "type" "logic")])
1815
1816(define_insn "*extendqihi2_insn<subst_logic>"
1817 [(set (match_operand:HI 0 "register_operand" "=r")
1818 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))
1819 (clobber (reg:CC R_FLAGS))]
1820 "reload_completed"
1821 "extb.w %0,%1"
1822 [(set_attr "type" "logic")])
1823
1824(define_expand "extendqisi2"
1825 [(set (match_operand:SI 0 "register_operand" "")
1826 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1827 "")
1828
1829(define_insn_and_split "*extendqisi2_insn"
1830 [(set (match_operand:SI 0 "register_operand" "=r")
1831 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1832 "ok_for_simple_arith_logic_operands (operands, SImode)"
1833 "#"
1834 "reload_completed"
1835 [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
1836 (clobber (reg:CC R_FLAGS))])]
1837 ""
1838 [(set_attr "type" "logic")])
1839
1840(define_insn "*extendqisi2_insn<subst_logic>"
1841 [(set (match_operand:SI 0 "register_operand" "=r")
1842 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))
1843 (clobber (reg:CC R_FLAGS))]
1844 "reload_completed"
1845 "extb.l %0,%1"
1846 [(set_attr "type" "logic")])
1847
1848(define_expand "extendhisi2"
1849 [(set (match_operand:SI 0 "register_operand" "")
1850 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1851 "")
1852
1853(define_insn_and_split "*extendhisi2_insn"
1854 [(set (match_operand:SI 0 "register_operand" "=r")
1855 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1856 "ok_for_simple_arith_logic_operands (operands, SImode)"
1857 "#"
1858 "reload_completed"
1859 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1860 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
1861 (clobber (reg:CC R_FLAGS))])]
1862 ""
1863 [(set_attr "type" "logic")])
1864
1865(define_insn "*extendhisi2_insn<subst_logic>"
1866 [(set (match_operand:SI 0 "register_operand" "=r")
1867 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))
1868 (clobber (reg:CC R_FLAGS))]
1869 "reload_completed"
1870 "extw.l %0,%1"
1871 [(set_attr "type" "logic")])
1872
1873(define_expand "extendsidi2"
1874 [(set (match_operand:DI 0 "register_operand" "")
1875 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
1876 "")
1877
1878(define_insn_and_split "*extendsidi2_insn"
1879 [(set (match_operand:DI 0 "register_operand" "=r")
1880 (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1881 "ok_for_simple_arith_logic_operands (operands, DImode)"
1882 "#"
1883 "reload_completed"
1884 [(parallel [(set (match_dup 3) (match_dup 1))
1885 (clobber (reg:CC R_FLAGS))])
1886 (parallel [(set (match_dup 2)
1887 (ashiftrt:SI (match_dup 1) (const_int 31)))
1888 (clobber (reg:CC R_FLAGS))])]
1889{
1890 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1891 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1892}
1893 [(set_attr "type" "multi")])
1894
1895;;
1896;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1897;;
1898;; Zero-extend
1899;;
1900;; Zero-extensions among modes QI, HI, SI and DI are supported directly.
1901;;
1902;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1903;;
1904
1905; QI is zero-extended to wider modes by shifting left and then performing
1906; a logical shift right to insert the zeroes. This avoids the need to use
1907; another register.
1908
1909(define_expand "zero_extendqihi2"
1910 [(set (match_operand:HI 0 "register_operand" "")
1911 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1912 "")
1913
1914(define_insn_and_split "*zero_extendqihi2_insn"
1915 [(set (match_operand:HI 0 "register_operand" "=r")
1916 (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1917 "ok_for_simple_arith_logic_operands (operands, HImode)"
1918 "#"
1919 "reload_completed"
1920 [(parallel [(set (match_dup 0)
1921 (ashift:HI (match_dup 2) (const_int 8)))
1922 (clobber (reg:CC R_FLAGS))])
1923 (parallel [(set (match_dup 0)
1924 (lshiftrt:HI (match_dup 0) (const_int 8)))
1925 (clobber (reg:CC R_FLAGS))])]
1926{
1927 operands[2] = gen_rtx_SUBREG (HImode, operands[1], 0);
1928}
1929 [(set_attr "type" "multi")])
1930
1931(define_expand "zero_extendqisi2"
1932 [(set (match_operand:SI 0 "register_operand" "")
1933 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1934 "")
1935
1936(define_insn_and_split "*zero_extendqisi2_insn"
1937 [(set (match_operand:SI 0 "register_operand" "=r")
1938 (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1939 "ok_for_simple_arith_logic_operands (operands, SImode)"
1940 "#"
1941 "reload_completed"
1942 [(parallel [(set (match_dup 0)
1943 (ashift:SI (match_dup 2) (const_int 24)))
1944 (clobber (reg:CC R_FLAGS))])
1945 (parallel [(set (match_dup 0)
1946 (lshiftrt:SI (match_dup 0) (const_int 24)))
1947 (clobber (reg:CC R_FLAGS))])]
1948{
1949 operands[2] = gen_rtx_SUBREG (SImode, operands[1], 0);
1950}
1951 [(set_attr "type" "multi")])
1952
1953(define_insn "zero_extendhisi2"
1954 [(set (match_operand:SI 0 "register_operand" "=r")
1955 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
1956 ""
1957 "moviu %0,0"
1958 [(set_attr "type" "imm_reg")])
1959
1960(define_expand "zero_extendsidi2"
1961 [(set (match_operand:DI 0 "register_operand" "")
1962 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
1963 "")
1964
1965(define_insn_and_split "*zero_extendsidi2_insn"
1966 [(set (match_operand:DI 0 "register_operand" "=r")
1967 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1968 "ok_for_simple_arith_logic_operands (operands, DImode)"
1969 "#"
1970 "reload_completed"
1971 [(parallel [(set (match_dup 3) (match_dup 1))
1972 (clobber (reg:CC R_FLAGS))])
1973 (set (match_dup 2) (const_int 0))]
1974{
1975 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1976 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1977}
1978 [(set_attr "type" "multi")])
1979
1980;;
1981;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1982;;
1983;; Bit Test
1984;;
1985;; Only SI mode is supported directly.
1986;;
1987;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1988;;
1989
1990; BITS_BIG_ENDIAN is defined to 1 so operand #1 counts from the MSB.
1991
d049f24a 1992(define_insn "*btst<mode>"
f9f22fee 1993 [(set (reg:CCC R_FLAGS)
d049f24a 1994 (compare:CCC (zero_extract:I
1995 (match_operand:I 0 "register_operand" "r")
f9f22fee 1996 (const_int 1)
1997 (match_operand:QI 1 "const_shift_operand" "K"))
1998 (const_int 0)))]
8992df51 1999 "reload_completed"
d049f24a 2000 "lsr<s> r0,%0,<b>-%1"
8992df51 2001 [(set_attr "type" "logic")])
2002
06904722 2003;;
2004;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2005;;
2006;; Integer overflow tests
2007;;
2008;; Modes QI, HI and SI are supported directly.
2009;;
2010;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2011;;
2012
2013(define_insn "*addv_tst<mode>"
2014 [(set (reg:CCV R_FLAGS)
2015 (compare:CCV (match_operand:I 0 "register_operand" "r")
2016 (unspec:I [(match_operand:I 1 "register_operand" "%r")
2017 (match_operand:I 2 "register_operand" "r")]
2018 UNSPEC_ADDV)))]
2019 "reload_completed"
2020 "add<s> r0,%1,%2"
2021 [(set_attr "type" "arith")])
2022
2023(define_insn "*subv_tst<mode>"
2024 [(set (reg:CCV R_FLAGS)
2025 (compare:CCV (match_operand:I 0 "register_operand" "r")
2026 (unspec:I [(match_operand:I 1 "reg_or_0_operand" "rO")
2027 (match_operand:I 2 "register_operand" "r")]
2028 UNSPEC_SUBV)))]
2029 "reload_completed"
2030 "sub<s> r0,%r1,%2"
2031 [(set_attr "type" "arith")])
2032
2033(define_insn "*negv_tst<mode>"
2034 [(set (reg:CCV R_FLAGS)
2035 (compare:CCV (match_operand:I 0 "register_operand" "r")
2036 (unspec:I [(match_operand:I 1 "register_operand" "r")]
2037 UNSPEC_NEGV)))]
2038 "reload_completed"
2039 "sub<s> r0,r0,%1"
2040 [(set_attr "type" "arith")])
2041
8992df51 2042;;
2043;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2044;;
2045;; Integer comparisons
2046;;
2047;; Modes QI, HI and SI are supported directly.
2048;;
2049;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2050;;
2051
2052(define_insn "*cmp<mode>"
2053 [(set (reg:CC R_FLAGS)
2054 (compare:CC (match_operand:I 0 "register_operand" "r")
2055 (match_operand:I 1 "reg_or_0_operand" "rO")))]
2056 "reload_completed"
2057 "cmp<s> %0,%r1"
2058 [(set_attr "type" "cmp")])
2059
2060(define_insn "*cmp<mode>_sne"
f9f22fee 2061 [(set (reg:CCC R_FLAGS)
2062 (compare:CCC (not:I (match_operand:I 0 "register_operand" "r"))
2063 (const_int -1)))]
8992df51 2064 "reload_completed"
2065 "cmp<s> r0,%0"
2066 [(set_attr "type" "cmp")])
2067
2068;;
2069;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2070;;
2071;; Single float operations
2072;;
2073;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2074;;
2075
2076(define_insn "addsf3"
2077 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2078 (plus:SF (match_operand:SF 1 "fp_reg_operand" "%f")
2079 (match_operand:SF 2 "fp_reg_operand" "f")))]
2080 "TARGET_FPU"
2081 "fadd %0,%1,%2"
2082 [(set_attr "type" "fp")])
2083
2084(define_insn "subsf3"
2085 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2086 (minus:SF (match_operand:SF 1 "fp_reg_operand" "f")
2087 (match_operand:SF 2 "fp_reg_operand" "f")))]
2088 "TARGET_FPU"
2089 "fsub %0,%1,%2"
2090 [(set_attr "type" "fp")])
2091
2092(define_insn "mulsf3"
2093 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2094 (mult:SF (match_operand:SF 1 "fp_reg_operand" "%f")
2095 (match_operand:SF 2 "fp_reg_operand" "f")))]
2096 "TARGET_FPU"
2097 "fmult %0,%1,%2"
2098 [(set_attr "type" "fp")])
2099
2100(define_insn "divsf3"
2101 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2102 (div:SF (match_operand:SF 1 "fp_reg_operand" "f")
2103 (match_operand:SF 2 "fp_reg_operand" "f")))]
2104 "TARGET_FPU"
2105 "fdiv %0,%1,%2"
2106 [(set_attr "type" "fdiv")])
2107
2108(define_insn "sqrtsf2"
2109 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2110 (sqrt:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
2111 "TARGET_FPU"
2112 "fsqrt %0,%1"
2113 [(set_attr "type" "fsqrt")])
2114
2115(define_insn "negsf2"
2116 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2117 (neg:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
2118 "TARGET_FPU"
2119 "fneg %0,%1"
2120 [(set_attr "type" "fmove")])
2121
2122(define_insn "abssf2"
2123 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2124 (abs:SF (match_operand:SF 1 "fp_reg_operand" "f")))]
2125 "TARGET_FPU"
2126 "fabs %0,%1"
2127 [(set_attr "type" "fmove")])
2128
2129(define_expand "copysignsf3"
2130 [(match_operand:SF 0 "register_operand" "")
2131 (match_operand:SF 1 "nonmemory_operand" "")
2132 (match_operand:SF 2 "register_operand" "")]
2133 "TARGET_FPU && !TARGET_FPU_IEEE"
2134{
2135 visium_expand_copysign (operands, SFmode);
2136 DONE;
2137})
2138
2139;;
2140;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2141;;
2142;; Single float <-> single integer conversions for !TARGET_FPU_IEEE
2143;;
2144;; An FMOVE instruction converts a signalling NaN (zero high order bit of the
2145;; mantissa) to a quiet NaN (-1). This is acceptable when the data to be
2146;; moved is in fact a floating-point number, but to avoid nasty surprises
2147;; integers must in general be kept out of the floating-point registers.
b395382f 2148;; TARGET_HARD_REGNO_MODE_OK thus only allows SFmode in these registers.
8992df51 2149;; However, since FTOI and ITOF use floating-point registers for both their
2150;; inputs and outputs, to use these instructions integers must transiently
2151;; occupy such registers. To disguise this from the compiler, UNSPECs are
2152;; used for floating-point operations on integers and floating from general
2153;; register to floating-point register and fixing in the reverse direction
2154;; are only split into the individual UNSPEC operations after reload.
2155;;
2156;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2157;;
2158
2159(define_insn "*fload_no_ieee"
2160 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2161 (unspec:SF [(match_operand:SI 1 "register_operand" "r")] UNSPEC_FLOAD))]
2162 "TARGET_FPU && !TARGET_FPU_IEEE"
2163 "fload %0,%1"
2164 [(set_attr "type" "reg_fp")])
2165
2166(define_insn "*itof_no_ieee"
2167 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2168 (unspec:SF [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_ITOF))]
2169 "TARGET_FPU && !TARGET_FPU_IEEE"
2170 "itof %0,%1"
2171 [(set_attr "type" "itof")])
2172
2173(define_insn_and_split "*floatsisf2_no_ieee"
2174 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2175 (float:SF (match_operand:SI 1 "register_operand" "r")))]
2176 "TARGET_FPU && !TARGET_FPU_IEEE"
2177 "#"
2178 "&& reload_completed"
2179 [(set (match_dup 0)
2180 (unspec:SF [(match_dup 1)] UNSPEC_FLOAD))
2181 (set (match_dup 0)
2182 (unspec:SF [(match_dup 0)] UNSPEC_ITOF))]
2183 ""
2184 [(set_attr "type" "multi")])
2185
2186(define_insn "*ftoi_no_ieee"
2187 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2188 (unspec:SF [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_FTOI))]
2189 "TARGET_FPU && !TARGET_FPU_IEEE"
2190 "ftoi %0,%1"
2191 [(set_attr "type" "ftoi")])
2192
2193(define_insn "*fstore_no_ieee"
2194 [(set (match_operand:SI 0 "register_operand" "=r")
2195 (unspec:SI [(match_operand:SF 1 "fp_reg_operand" "f")] UNSPEC_FSTORE))]
2196 "TARGET_FPU && !TARGET_FPU_IEEE"
2197 "fstore %0,%1"
2198 [(set_attr "type" "fp_reg")])
2199
2200(define_insn_and_split "fix_truncsfsi2_no_ieee"
2201 [(set (match_operand:SI 0 "register_operand" "=r")
2202 (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" "f"))))
2203 (clobber (match_scratch:SF 2 "=1"))]
2204 "TARGET_FPU && !TARGET_FPU_IEEE"
2205 "#"
2206 "&& reload_completed"
2207 [(set (match_dup 1)
2208 (unspec:SF [(match_dup 1)] UNSPEC_FTOI))
2209 (set (match_dup 0)
2210 (unspec:SI [(match_dup 1)] UNSPEC_FSTORE))]
2211 ""
2212 [(set_attr "type" "multi")])
2213
2214;;
2215;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2216;;
2217;; Single float <-> single integer conversions
2218;;
2219;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2220;;
2221
2222(define_insn "*itof"
2223 [(set (match_operand:SF 0 "fp_reg_operand" "=f")
2224 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2225 "TARGET_FPU_IEEE"
2226 "itof %0,%1"
2227 [(set_attr "type" "itof")])
2228
2229(define_expand "floatsisf2"
2230 [(set (match_operand:SF 0 "fp_reg_operand" "")
2231 (float:SF (match_operand:SI 1 "register_operand" "")))]
2232 "TARGET_FPU"
2233 "")
2234
2235(define_insn "*ftoi"
2236 [(set (match_operand:SI 0 "register_operand" "=f")
2237 (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" "f"))))]
2238 "TARGET_FPU_IEEE"
2239 "ftoi %0,%1"
2240 [(set_attr "type" "ftoi")])
2241
2242(define_expand "fix_truncsfsi2"
2243 [(set (match_operand:SI 0 "register_operand" "")
2244 (fix:SI (fix:SF (match_operand:SF 1 "fp_reg_operand" ""))))]
2245 "TARGET_FPU"
2246{
2247 if (!TARGET_FPU_IEEE)
2248 {
2249 emit_insn (gen_fix_truncsfsi2_no_ieee (operands[0], operands[1]));
2250 DONE;
2251 }
2252})
2253
2254;;
2255;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2256;;
2257;; Single float comparisons
2258;;
2259;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2260;;
2261
2262(define_insn "*cmpsf_fp"
2263 [(set (reg:CCFP R_FLAGS)
2264 (compare:CCFP (match_operand:SF 0 "fp_reg_or_0_operand" "fG")
2265 (match_operand:SF 1 "fp_reg_or_0_operand" "fG")))]
2266 "TARGET_FPU && reload_completed"
2267 "fcmp r0,%f0,%f1"
2268 [(set_attr "type" "fcmp")])
2269
2270(define_insn "*cmpsf_fpe"
2271 [(set (reg:CCFPE R_FLAGS)
2272 (compare:CCFPE (match_operand:SF 0 "fp_reg_or_0_operand" "fG")
2273 (match_operand:SF 1 "fp_reg_or_0_operand" "fG")))]
2274 "TARGET_FPU && reload_completed"
2275 "fcmpe r0,%f0,%f1"
2276 [(set_attr "type" "fcmp")])
2277
2278;;
2279;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2280;;
2281;; Conditional branch instructions
2282;;
2283;; Note - we do not specify the two instructions necessary to perform
2284;; a compare-and-branch in the cbranch<mode>4 pattern because that would
2285;; allow the comparison to be moved away from the jump before the reload
2286;; pass has completed. That would be problematical because reload can
2287;; generate instructions in between which would clobber the CC register.
2288;;
2289;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2290;;
2291
2292(define_expand "cbranch<mode>4"
2293 [(set (pc)
f9f22fee 2294 (if_then_else (match_operator 0 "ordered_comparison_operator"
8992df51 2295 [(match_operand:I 1 "register_operand")
2296 (match_operand:I 2 "reg_or_0_operand")])
2297 (label_ref (match_operand 3 ""))
2298 (pc)))]
2299 ""
2300)
2301
2302(define_insn_and_split "*cbranch<mode>4_insn"
2303 [(set (pc)
f9f22fee 2304 (if_then_else (match_operator 0 "ordered_comparison_operator"
8992df51 2305 [(match_operand:I 1 "register_operand" "r")
2306 (match_operand:I 2 "reg_or_0_operand" "rO")])
2307 (label_ref (match_operand 3 ""))
2308 (pc)))]
2309 ""
2310 "#"
2311 "reload_completed"
2312 [(const_int 0)]
2313{
2314 visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
2315 operands[3]);
2316 DONE;
2317}
2318 [(set_attr "type" "cmp")])
2319
06904722 2320(define_insn_and_split "*cbranch<mode>4_addv_insn"
2321 [(set (pc)
2322 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2323 [(match_operand:I 1 "register_operand" "r")
2324 (unspec:I [(match_operand:I 2 "register_operand" "%r")
2325 (match_operand:I 3 "register_operand" "r")]
2326 UNSPEC_ADDV)])
2327 (label_ref (match_operand 4 ""))
2328 (pc)))]
2329 ""
2330 "#"
2331 "reload_completed"
2332 [(const_int 0)]
2333{
2334 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2335 XEXP (operands[0], 1), operands[4]);
2336 DONE;
2337}
2338 [(set_attr "type" "cmp")])
2339
2340(define_insn_and_split "*cbranch<mode>4_subv_insn"
2341 [(set (pc)
2342 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2343 [(match_operand:I 1 "register_operand" "r")
2344 (unspec:I [(match_operand:I 2 "reg_or_0_operand" "rO")
2345 (match_operand:I 3 "register_operand" "r")]
2346 UNSPEC_SUBV)])
2347 (label_ref (match_operand 4 ""))
2348 (pc)))]
2349 ""
2350 "#"
2351 "reload_completed"
2352 [(const_int 0)]
2353{
2354 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2355 XEXP (operands[0], 1), operands[4]);
2356 DONE;
2357}
2358 [(set_attr "type" "cmp")])
2359
2360(define_insn_and_split "*cbranch<mode>4_negv_insn"
2361 [(set (pc)
2362 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
2363 [(match_operand:I 1 "register_operand" "r")
2364 (unspec:I [(match_operand:I 2 "register_operand" "r")]
2365 UNSPEC_NEGV)])
2366 (label_ref (match_operand 3 ""))
2367 (pc)))]
2368 ""
2369 "#"
2370 "reload_completed"
2371 [(const_int 0)]
2372{
2373 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2374 XEXP (operands[0], 1), operands[3]);
2375 DONE;
2376}
2377 [(set_attr "type" "cmp")])
2378
d049f24a 2379(define_insn_and_split "*cbranch<mode>4_btst_insn"
8992df51 2380 [(set (pc)
f9f22fee 2381 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
d049f24a 2382 [(zero_extract:I
2383 (match_operand:I 1 "register_operand" "r")
8992df51 2384 (const_int 1)
2385 (match_operand:QI 2 "const_shift_operand" "K"))
2386 (const_int 0)])
2387 (label_ref (match_operand 3 ""))
2388 (pc)))]
2389 ""
2390 "#"
2391 "reload_completed"
2392 [(const_int 0)]
2393{
2394 visium_split_cbranch (GET_CODE (operands[0]), XEXP (operands[0], 0),
2395 XEXP (operands[0], 1), operands[3]);
2396 DONE;
2397}
2398 [(set_attr "type" "cmp")])
2399
2400(define_expand "cbranchsf4"
2401 [(set (pc)
2402 (if_then_else (match_operator 0 "visium_fp_comparison_operator"
2403 [(match_operand:SF 1 "fp_reg_operand")
2404 (match_operand:SF 2 "fp_reg_or_0_operand")])
2405 (label_ref (match_operand 3 ""))
2406 (pc)))]
2407 "TARGET_FPU"
2408)
2409
2410(define_insn_and_split "*cbranchsf4_insn"
2411 [(set (pc)
2412 (if_then_else (match_operator 0 "visium_fp_comparison_operator"
2413 [(match_operand:SF 1 "fp_reg_operand" "f")
2414 (match_operand:SF 2 "fp_reg_or_0_operand" "fG")])
2415 (label_ref (match_operand 3 ""))
2416 (pc)))]
2417 "TARGET_FPU"
2418 "#"
2419 "&& reload_completed"
2420 [(const_int 0)]
2421{
2422 visium_split_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
2423 operands[3]);
2424 DONE;
2425}
2426 [(set_attr "type" "fcmp")])
2427
2428; Now match both normal and inverted branches.
2429
2430(define_insn "*normal_branch"
2431 [(set (pc)
2432 (if_then_else (match_operator 1 "visium_branch_operator"
2433 [(reg R_FLAGS) (const_int 0)])
2434 (label_ref (match_operand 0 ""))
2435 (pc)))]
2436 "reload_completed"
2437{
2438 return output_cbranch (operands[0], GET_CODE (operands[1]),
2439 GET_MODE (XEXP (operands[1], 0)), 0, insn);
2440}
2441 [(set_attr "type" "branch")])
2442
2443(define_insn "*inverted_branch"
2444 [(set (pc)
2445 (if_then_else (match_operator 1 "visium_branch_operator"
2446 [(reg R_FLAGS) (const_int 0)])
2447 (pc)
2448 (label_ref (match_operand 0 ""))))]
2449 "reload_completed"
2450{
2451 return output_cbranch (operands[0], GET_CODE (operands[1]),
2452 GET_MODE (XEXP (operands[1], 0)), 1, insn);
2453}
2454 [(set_attr "type" "branch")])
2455
2456; And then match both normal and inverted returns.
2457
2458(define_insn "*cond_<return_str>return"
2459 [(set (pc)
2460 (if_then_else (match_operator 0 "visium_branch_operator"
2461 [(reg R_FLAGS) (const_int 0)])
2462 (any_return)
2463 (pc)))]
2464 "<return_pred> && reload_completed"
2465{
2466 return output_cbranch (pc_rtx, GET_CODE (operands[0]),
2467 GET_MODE (XEXP (operands[0], 0)), 0, insn);
2468}
2469 [(set_attr "type" "ret")])
2470
2471(define_insn "*inverted_cond_<return_str>return"
2472 [(set (pc)
2473 (if_then_else (match_operator 0 "visium_branch_operator"
2474 [(reg R_FLAGS) (const_int 0)])
2475 (pc)
2476 (any_return)))]
2477 "<return_pred> && reload_completed"
2478{
2479 return output_cbranch (pc_rtx, GET_CODE (operands[0]),
2480 GET_MODE (XEXP (operands[0], 0)), 1, insn);
2481}
2482 [(set_attr "type" "ret")])
2483
2484;;
2485;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2486;;
2487;; Unconditional branch instructions
2488;;
2489;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2490;;
2491
2492(define_insn "jump"
2493 [(set (pc)
2494 (label_ref (match_operand 0 "" "")))]
2495 ""
2496{
2497 return output_ubranch (operands[0], insn);
2498}
2499 [(set_attr "type" "branch")])
2500
2501(define_insn "indirect_jump"
2502 [(set (pc)
2503 (match_operand:SI 0 "register_operand" "r"))]
2504 ""
2505 "bra tr,%0,r0%# ;indirect jump"
2506 [(set_attr "type" "abs_branch")])
2507
2508(define_insn "tablejump"
2509 [(set (pc)
2510 (match_operand:SI 0 "register_operand" "r"))
2511 (use (label_ref (match_operand 1 "" "")))]
2512 ""
2513 "bra tr,%0,r0%# ;tablejump"
2514 [(set_attr "type" "abs_branch")])
2515
d049f24a 2516;;
2517;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2518;;
2519;; trap instructions
2520;;
2521;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2522;;
2523
2524(define_insn "trap"
2525 [(trap_if (const_int 1) (const_int 0))]
2526 ""
2527 "stop 0,r0"
2528 [(set_attr "type" "trap")])
2529
8992df51 2530;;
2531;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2532;;
2533;; Subprogram call instructions
2534;;
2535;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2536;;
2537
2538; Subroutine call instruction returning no value. Operand 0 is the function
2539; to call; operand 1 is the number of bytes of arguments pushed (in mode
2540; 'SImode', except it is normally a 'const_int'); operand 2 is the number of
2541; registers used as operands.
2542
2543(define_expand "call"
2544 [(parallel [(call (match_operand 0 "" "")
2545 (match_operand 1 "" ""))
2546 (use (match_operand 2 "" ""))
2547 (clobber (match_dup 3))])]
2548 ""
2549{
2550 if (GET_CODE (XEXP (operands[0], 0)) != REG)
2551 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2552
2553 if (!operands[2])
2554 operands[2] = const0_rtx;
2555
2556 operands[3] = gen_rtx_REG (Pmode, R_LINK);
2557})
2558
2559(define_insn "*call_internal"
2560 [(call (mem:SI (match_operand:SI 0 "register_operand" "l,!r"))
2561 (match_operand 1 "" ""))
2562 (use (match_operand 2 "" ""))
2563 (clobber (match_operand 3 "" ""))]
2564 "!SIBLING_CALL_P (insn)"
2565 "bra tr,%0,%3%# ;call"
2566 [(set_attr "type" "call")])
2567
2568; Subroutine call instruction returning a value. Operand 0 is the hard
2569; register in which the value is returned. There are three more operands, the
2570; same as the three operands of the 'call' instruction (but with numbers
2571; increased by one).
2572
2573(define_expand "call_value"
2574 [(parallel [(set (match_operand 0 "register_operand" "")
2575 (call (match_operand 1 "" "")
2576 (match_operand 2 "" "")))
2577 (use (match_operand 3 "" ""))
2578 (clobber (match_dup 4))])]
2579 ""
2580{
2581 if (GET_CODE (XEXP (operands[1], 0)) != REG)
2582 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2583
2584 if (!operands[3])
2585 operands[3] = const0_rtx;
2586
2587 operands[4] = gen_rtx_REG (Pmode, R_LINK);
2588})
2589
2590(define_insn "*call_value_internal"
2591 [(set (match_operand 0 "register_operand" "")
2592 (call (mem:SI (match_operand:SI 1 "register_operand" "l,!r"))
2593 (match_operand 2 "" "")))
2594 (use (match_operand 3 "" ""))
2595 (clobber (match_operand 4 "" ""))]
2596 "!SIBLING_CALL_P (insn)"
2597 "bra tr,%1,%4%# ;call value"
2598 [(set_attr "type" "call")])
2599
2600; Tail calls are similar, except that the link register is not used. But
2601; we don't use r0 as the destination register of the branch because we want
2602; the Branch Pre-decode Logic of the GR6 to use the Address Load Array to
2603; predict the branch target.
2604
2605(define_expand "sibcall"
2606 [(parallel [(call (match_operand 0 "" "")
2607 (match_operand 1 "" ""))
2608 (use (match_operand 2 "" ""))
2609 (clobber (match_dup 3))])]
2610 ""
2611{
2612 if (GET_CODE (XEXP (operands[0], 0)) != REG)
2613 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2614
2615 if (!operands[2])
2616 operands[2] = const0_rtx;
2617
2618 operands[3] = gen_rtx_SCRATCH (SImode);
2619})
2620
2621(define_insn "*sibcall_internal"
2622 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
2623 (match_operand 1 "" ""))
2624 (use (match_operand 2 "" ""))
2625 (clobber (match_scratch:SI 3 "=0"))]
2626 "SIBLING_CALL_P (insn)"
2627 "bra tr,%0,%0%# ;sibcall"
2628 [(set_attr "type" "call")])
2629
2630(define_expand "sibcall_value"
2631 [(parallel [(set (match_operand 0 "register_operand" "")
2632 (call (match_operand 1 "" "")
2633 (match_operand 2 "" "")))
2634 (use (match_operand 3 "" ""))
2635 (clobber (match_dup 4))])]
2636 ""
2637{
2638 if (GET_CODE (XEXP (operands[1], 0)) != REG)
2639 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2640
2641 if (!operands[3])
2642 operands[3] = const0_rtx;
2643
2644 operands[4] = gen_rtx_SCRATCH (SImode);
2645})
2646
2647(define_insn "*sibcall_value_internal"
2648 [(set (match_operand 0 "register_operand" "")
2649 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
2650 (match_operand 2 "" "")))
2651 (use (match_operand 3 "" ""))
2652 (clobber (match_scratch:SI 4 "=1"))]
2653 "SIBLING_CALL_P (insn)"
2654 "bra tr,%1,%1%# ;sibcall value"
2655 [(set_attr "type" "call")])
2656
2657; Call subroutine returning any type.
2658(define_expand "untyped_call"
2659 [(parallel [(call (match_operand 0 "" "")
2660 (const_int 0))
2661 (match_operand 1 "" "")
2662 (match_operand 2 "" "")])]
2663 ""
2664{
2665 int i;
2666
7f265a08 2667 emit_call_insn (gen_call (operands[0], const0_rtx, NULL));
8992df51 2668
2669 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2670 {
2671 rtx set = XVECEXP (operands[2], 0, i);
2672 emit_move_insn (SET_DEST (set), SET_SRC (set));
2673 }
2674
2675 /* The optimizer does not know that the call sets the function value
2676 registers we stored in the result block. We avoid problems by
2677 claiming that all hard registers are used and clobbered at this
2678 point. */
2679 emit_insn (gen_blockage ());
2680
2681 DONE;
2682})
2683
2684;;
2685;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2686;;
2687;; Compare-and-store instructions
2688;;
2689;; Modes QI, HI, SI and SF are supported directly.
2690;;
2691;; Note - we do not specify the two instructions necessary to perform
2692;; a compare-and-store in the cstore<mode>4 pattern because that would
2693;; allow the comparison to be moved away from the store before the reload
2694;; pass has completed. That would be problematical because reload can
2695;; generate instructions in between which would clobber the CC register.
2696;;
2697;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2698;;
2699
2700(define_expand "cstore<mode>4"
2701 [(set (match_operand:SI 0)
2702 (match_operator:SI 1 "visium_int_cstore_operator"
2703 [(match_operand:I 2 "register_operand")
2704 (match_operand:I 3 "reg_or_0_operand")]))]
2705 ""
2706{
2707 visium_expand_int_cstore (operands, <MODE>mode);
2708 DONE;
2709})
2710
2711(define_insn_and_split "*cstore<mode>4_insn"
2712 [(set (match_operand:SI 0 "register_operand" "=r")
2713 (ltu:SI (match_operand:I 1 "register_operand" "r")
2714 (match_operand:I 2 "reg_or_0_operand" "rO")))]
2715 ""
2716 "#"
2717 "reload_completed"
2718 [(const_int 0)]
2719{
2720 visium_split_cstore (SET, operands[0], NULL_RTX,
2721 LTU, operands[1], operands[2]);
2722 DONE;
2723}
2724 [(set_attr "type" "cmp")])
2725
2726(define_insn_and_split "*neg_cstore<mode>4_insn"
2727 [(set (match_operand:SI 0 "register_operand" "=r")
2728 (neg:SI (ltu:SI (match_operand:I 1 "register_operand" "r")
2729 (match_operand:I 2 "reg_or_0_operand" "rO"))))]
2730 ""
2731 "#"
2732 "reload_completed"
2733 [(const_int 0)]
2734{
2735 visium_split_cstore (NEG, operands[0], NULL_RTX,
2736 LTU, operands[1], operands[2]);
2737 DONE;
2738}
2739 [(set_attr "type" "cmp")])
2740
2741(define_insn_and_split "*<add_str>_cstore<mode>4_insn"
2742 [(set (match_operand:SI 0 "register_operand" "=r")
2743 (any_add:SI (match_operand:SI 1 "register_operand" "r")
2744 (ltu:SI (match_operand:I 2 "register_operand" "r")
2745 (match_operand:I 3 "reg_or_0_operand" "rO"))))]
2746 ""
2747 "#"
2748 "reload_completed"
2749 [(const_int 0)]
2750{
2751 visium_split_cstore (<add_op>, operands[0], operands[1],
2752 LTU, operands[2], operands[3]);
2753 DONE;
2754}
2755 [(set_attr "type" "cmp")])
2756
2757(define_insn_and_split "*cstore<mode>4_sne_insn"
2758 [(set (match_operand:SI 0 "register_operand" "=r")
2759 (ltu:SI (not:I (match_operand:I 1 "register_operand" "r"))
2760 (const_int -1)))]
2761 ""
2762 "#"
2763 "reload_completed"
2764 [(const_int 0)]
2765{
2766 visium_split_cstore (SET, operands[0], NULL_RTX,
2767 LTU, gen_rtx_NOT (<MODE>mode, operands[1]), constm1_rtx);
2768 DONE;
2769}
2770 [(set_attr "type" "cmp")])
2771
2772(define_insn_and_split "*neg_cstore<mode>4_sne_insn"
2773 [(set (match_operand:SI 0 "register_operand" "=r")
2774 (neg:SI (ltu:SI (not:I (match_operand:I 1 "register_operand" "r"))
2775 (const_int -1))))]
2776 ""
2777 "#"
2778 "reload_completed"
2779 [(const_int 0)]
2780{
2781 visium_split_cstore (NEG, operands[0], NULL_RTX,
2782 LTU, gen_rtx_NOT (<MODE>mode, operands[1]), constm1_rtx);
2783 DONE;
2784}
2785 [(set_attr "type" "cmp")])
2786
2787(define_insn_and_split "*<add_str>_cstore<mode>4_sne_insn"
2788 [(set (match_operand:SI 0 "register_operand" "=r")
2789 (any_add:SI (match_operand:SI 1 "register_operand" "r")
2790 (ltu:SI (not:I (match_operand:I 2 "register_operand" "r"))
2791 (const_int -1))))]
2792 ""
2793 "#"
2794 "reload_completed"
2795 [(const_int 0)]
2796{
2797 visium_split_cstore (<add_op>, operands[0], operands[1],
2798 LTU, gen_rtx_NOT (<MODE>mode, operands[2]), constm1_rtx);
2799 DONE;
2800}
2801 [(set_attr "type" "cmp")])
2802
2803(define_expand "cstoresf4"
2804 [(set (match_operand:SI 0)
2805 (match_operator:SI 1 "visium_fp_cstore_operator"
2806 [(match_operand:SF 2 "fp_reg_operand")
2807 (match_operand:SF 3 "fp_reg_or_0_operand")]))]
2808 "TARGET_FPU"
2809{
2810 visium_expand_fp_cstore (operands, SFmode);
2811 DONE;
2812})
2813
2814(define_insn_and_split "*cstoresf4_insn"
2815 [(set (match_operand:SI 0 "register_operand" "=r")
2816 (lt:SI (match_operand:SF 1 "fp_reg_or_0_operand" "fG")
2817 (match_operand:SF 2 "fp_reg_or_0_operand" "fG")))]
2818 "TARGET_FPU"
2819 "#"
2820 "&& reload_completed"
2821 [(const_int 0)]
2822{
2823 visium_split_cstore (SET, operands [0], NULL_RTX,
2824 LT, operands[1], operands[2]);
2825 DONE;
2826}
2827 [(set_attr "type" "fcmp")])
2828
2829(define_insn_and_split "*neg_cstoresf4_insn"
2830 [(set (match_operand:SI 0 "register_operand" "=r")
2831 (neg:SI (lt:SI (match_operand:SF 1 "fp_reg_or_0_operand" "fG")
2832 (match_operand:SF 2 "fp_reg_or_0_operand" "fG"))))]
2833 "TARGET_FPU"
2834 "#"
2835 "&& reload_completed"
2836 [(const_int 0)]
2837{
2838 visium_split_cstore (NEG, operands [0], NULL_RTX,
2839 LT, operands[1], operands[2]);
2840 DONE;
2841}
2842 [(set_attr "type" "fcmp")])
2843
2844(define_insn_and_split "*<add_str>_cstoresf4_insn"
2845 [(set (match_operand:SI 0 "register_operand" "=r")
2846 (any_add:SI (match_operand:SI 1 "register_operand" "r")
2847 (lt:SI (match_operand:SF 2 "fp_reg_or_0_operand" "fG")
2848 (match_operand:SF 3 "fp_reg_or_0_operand" "fG"))))]
2849 "TARGET_FPU"
2850 "#"
2851 "&& reload_completed"
2852 [(const_int 0)]
2853{
2854 visium_split_cstore (<add_op>, operands [0], operands[1],
2855 LT, operands[2], operands[3]);
2856 DONE;
2857}
2858 [(set_attr "type" "fcmp")])
2859
2860;;
2861;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2862;;
2863;; RTL pro/epilogue support
2864;;
2865;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2866;;
2867
2868; Expand prologue in RTL
2869(define_expand "prologue"
2870 [(const_int 0)]
2871 ""
2872{
2873 visium_expand_prologue ();
2874 DONE;
2875})
2876
2877; Expand epilogue in RTL
2878(define_expand "epilogue"
2879 [(return)]
2880 ""
2881{
2882 visium_expand_epilogue ();
2883})
2884
2885; Expand epilogue without a final jump in RTL
2886(define_expand "sibcall_epilogue"
2887 [(return)]
2888 ""
2889{
2890 visium_expand_epilogue ();
2891 DONE;
2892})
2893
2894; The artificial dependency on the link register is to prevent the
2895; frame instruction from being put in a call delay slot, which can
2896; confuse the CFI machinery.
2897
2898(define_insn "stack_save"
2899 [(set (reg:SI R_FP) (reg:SI R_SP))
2900 (use (reg:SI R_LINK))
2901 (clobber (reg:CC R_FLAGS))]
2902 "reload_completed"
2903 "move.l fp,sp ;stack_save"
2904 [(set_attr "type" "logic")])
2905
2906; The construct (mem:BLK (scratch)) is considered to alias all other
2907; memory accesses. Thus it can be used as a memory barrier in stack
2908; deallocation patterns.
2909
2910(define_insn "stack_restore"
2911 [(set (reg:SI R_SP) (reg:SI R_FP))
2912 (clobber (mem:BLK (scratch)))
2913 (clobber (reg:CC R_FLAGS))]
2914 "reload_completed"
2915 "move.l sp,fp ;stack_restore"
2916 [(set_attr "type" "logic")])
2917
2918(define_insn "stack_pop"
2919 [(set (reg:SI R_SP)
2920 (plus:SI (reg:SI R_SP) (match_operand:SI 0 "add_operand" "J,r")))
2921 (clobber (mem:BLK (scratch)))
2922 (clobber (reg:CC R_FLAGS))]
2923 "reload_completed"
2924 "@
2925 addi sp,%0 ;stack pop
2926 add.l sp,sp,%0 ;stack pop"
2927 [(set_attr "type" "arith")])
2928
2929(define_expand "<return_str>return"
2930 [(any_return)]
2931 "<return_pred>"
2932 "")
2933
2934(define_insn "*<return_str>return_internal"
2935 [(any_return)]
2936 "!visium_interrupt_function_p ()"
2937{
2938 return output_ubranch (pc_rtx, insn);
2939}
2940 [(set_attr "type" "ret")])
2941
2942(define_insn "*return_internal_interrupt"
2943 [(return)]
2944 "visium_interrupt_function_p ()"
2945 "rfi\n\t nop ;return from interrupt"
2946 [(set_attr "type" "rfi")])
2947
2948(define_insn "dsi"
2949 [(unspec_volatile [(const_int 0)] UNSPECV_DSI)]
2950 ""
2951 "dsi"
2952 [(set_attr "type" "dsi")])
2953
2954;;
2955;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2956;;
2957;; NOP (no-op instruction)
2958;;
2959;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2960;;
2961
2962(define_insn "nop"
2963 [(const_int 0)]
2964 ""
2965 "nop ;generated nop"
2966 [(set_attr "type" "nop")])
2967
2968(define_insn "hazard_nop"
2969 [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
2970 ""
2971 "nop ;hazard avoidance nop"
2972 [(set_attr "type" "nop")])
2973
2974(define_insn "blockage"
2975 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2976 ""
2977 ""
2978 [(set_attr "type" "nop")])
2979
2980;;
2981;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2982;;
2983;; String/block operations
2984;;
2985;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2986;;
2987
2988;; String/block move insn.
2989;; Argument 0 is the destination
2990;; Argument 1 is the source
2991;; Argument 2 is the length
2992;; Argument 3 is the alignment
2993
2994(define_expand "movmemsi"
2995 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
2996 (match_operand:BLK 1 "memory_operand" ""))
2997 (use (match_operand:SI 2 "general_operand" ""))
2998 (use (match_operand:SI 3 "const_int_operand" ""))])]
2999 ""
3000{
3001 if (visium_expand_block_move (operands))
3002 DONE;
3003 else
3004 FAIL;
3005})
3006
3007(define_insn "*bmd"
3008 [(set (mem:BLK (reg:SI R_R1))
3009 (mem:BLK (reg:SI R_R2)))
3010 (use (reg:SI R_R3))
3011 (clobber (reg:SI R_R1))
3012 (clobber (reg:SI R_R2))
3013 (clobber (reg:SI R_R3))
3014 (clobber (reg:SI R_R4))
3015 (clobber (reg:SI R_R5))
3016 (clobber (reg:SI R_R6))]
3017 "TARGET_BMI"
3018 "bmd r1,r2,r3"
3019 [(set_attr "type" "bmi")])
3020
3021;; String/block set insn.
3022;; Argument 0 is the destination
3023;; Argument 1 is the length
3024;; Argument 2 is the value
3025;; Argument 3 is the alignment
3026
3027(define_expand "setmemsi"
3028 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3029 (match_operand 2 "nonmemory_operand" ""))
3030 (use (match_operand:SI 1 "general_operand" ""))
3031 (use (match_operand:SI 3 "const_int_operand" ""))])]
3032 ""
3033{
3034 if (visium_expand_block_set (operands))
3035 DONE;
3036 else
3037 FAIL;
3038})