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