111
|
1 ;; Machine description for Visium.
|
|
2 ;; Copyright (C) 2002-2017 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 UNSPEC_ADDV
|
|
85 UNSPEC_SUBV
|
|
86 UNSPEC_NEGV
|
|
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.
|
|
140 ;trap Trap instructions.
|
|
141
|
|
142 (define_attr "type"
|
|
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"))
|
|
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])
|
|
209 (define_mode_attr b [(QI "8") (HI "16") (SI "32")])
|
|
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 ;;
|
|
243 ;; They are used to define the first instruction of the pairs required by
|
|
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 ""
|
|
254 [(set (reg:CC R_FLAGS)
|
|
255 (compare:CC (match_dup 1) (const_int 0)))
|
|
256 (set (match_dup 0) (match_dup 1))])
|
|
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 ""
|
|
264 [(set (reg:CCNZ R_FLAGS)
|
|
265 (compare:CCNZ (match_dup 1) (const_int 0)))
|
|
266 (set (match_dup 0) (match_dup 1))])
|
|
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 {
|
|
635 visium_split_double_move (operands, DImode);
|
|
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;
|
|
695
|
|
696 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
|
|
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 {
|
|
734 visium_split_double_move (operands, DFmode);
|
|
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
|
|
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
|
|
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
|
|
796 (define_insn "*add<mode>3_insn_set_carry"
|
|
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)))]
|
|
803 "reload_completed"
|
|
804 "add<s> %0,%1,%2"
|
|
805 [(set_attr "type" "arith")])
|
|
806
|
|
807 (define_insn "*add<mode>3_insn_set_overflow"
|
|
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)))]
|
|
814 "reload_completed"
|
|
815 "add<s> %0,%1,%2"
|
|
816 [(set_attr "type" "arith")])
|
|
817
|
|
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
|
|
860 (define_insn "addsi3_insn_set_carry"
|
|
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)))]
|
|
867 "reload_completed"
|
|
868 "@
|
|
869 add.l %0,%1,%2
|
|
870 addi %0,%2"
|
|
871 [(set_attr "type" "arith")])
|
|
872
|
|
873 (define_insn "*addsi3_insn_set_overflow"
|
|
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)))]
|
|
880 "reload_completed"
|
|
881 "@
|
|
882 add.l %0,%1,%2
|
|
883 addi %0,%2"
|
|
884 [(set_attr "type" "arith")])
|
|
885
|
|
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
|
|
892 ; Disfavour the use of add.l because of the early clobber.
|
|
893
|
|
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")
|
|
897 (match_operand:DI 2 "add_operand" " L,J, r")))]
|
|
898 "ok_for_simple_arith_logic_operands (operands, DImode)"
|
|
899 "#"
|
|
900 "reload_completed"
|
|
901 [(const_int 0)]
|
|
902 {
|
|
903 visium_split_double_add (PLUS, operands[0], operands[1], operands[2]);
|
|
904 DONE;
|
|
905 }
|
|
906 [(set_attr "type" "arith2")])
|
|
907
|
|
908 ;;
|
|
909 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
910 ;;
|
|
911 ;; Integer Add with Carry
|
|
912 ;;
|
|
913 ;; Only SI mode is supported.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1011 (define_insn "*sub<mode>3_insn_set_carry"
|
|
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)))]
|
|
1017 "reload_completed"
|
|
1018 "sub<s> %0,%r1,%2"
|
|
1019 [(set_attr "type" "arith")])
|
|
1020
|
|
1021 (define_insn "*sub<mode>3_insn_set_overflow"
|
|
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)))]
|
|
1028 "reload_completed"
|
|
1029 "sub<s> %0,%r1,%2"
|
|
1030 [(set_attr "type" "arith")])
|
|
1031
|
|
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
|
|
1074 (define_insn "subsi3_insn_set_carry"
|
|
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)))]
|
|
1080 "reload_completed"
|
|
1081 "@
|
|
1082 sub.l %0,%r1,%2
|
|
1083 subi %0,%2"
|
|
1084 [(set_attr "type" "arith")])
|
|
1085
|
|
1086 (define_insn "*subsi3_insn_set_overflow"
|
|
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)))]
|
|
1093 "reload_completed"
|
|
1094 "@
|
|
1095 sub.l %0,%1,%2
|
|
1096 subi %0,%2"
|
|
1097 [(set_attr "type" "arith")])
|
|
1098
|
|
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
|
|
1105 ; Disfavour the use of the sub.l because of the early clobber.
|
|
1106
|
|
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")
|
|
1110 (match_operand:DI 2 "add_operand" " L,J, r")))]
|
|
1111 "ok_for_simple_arith_logic_operands (operands, DImode)"
|
|
1112 "#"
|
|
1113 "reload_completed"
|
|
1114 [(const_int 0)]
|
|
1115 {
|
|
1116 visium_split_double_add (MINUS, operands[0], operands[1], operands[2]);
|
|
1117 DONE;
|
|
1118 }
|
|
1119 [(set_attr "type" "arith2")])
|
|
1120
|
|
1121 ;;
|
|
1122 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1123 ;;
|
|
1124 ;; Integer Subtract with Carry
|
|
1125 ;;
|
|
1126 ;; Only SI mode is supported.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1211 (define_insn "negsi2_insn_set_carry"
|
|
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)))]
|
|
1217 "reload_completed"
|
|
1218 "sub.l %0,r0,%1"
|
|
1219 [(set_attr "type" "arith")])
|
|
1220
|
|
1221 (define_insn "*neg<mode>2_insn_set_overflow"
|
|
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)))]
|
|
1227 "reload_completed"
|
|
1228 "sub<s> %0,r0,%1"
|
|
1229 [(set_attr "type" "arith")])
|
|
1230
|
|
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"
|
|
1242 [(const_int 0)]
|
|
1243 {
|
|
1244 visium_split_double_add (MINUS, operands[0], const0_rtx, operands[1]);
|
|
1245 DONE;
|
|
1246 }
|
|
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
|
|
1992 (define_insn "*btst<mode>"
|
|
1993 [(set (reg:CCC R_FLAGS)
|
|
1994 (compare:CCC (zero_extract:I
|
|
1995 (match_operand:I 0 "register_operand" "r")
|
|
1996 (const_int 1)
|
|
1997 (match_operand:QI 1 "const_shift_operand" "K"))
|
|
1998 (const_int 0)))]
|
|
1999 "reload_completed"
|
|
2000 "lsr<s> r0,%0,<b>-%1"
|
|
2001 [(set_attr "type" "logic")])
|
|
2002
|
|
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
|
|
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"
|
|
2061 [(set (reg:CCC R_FLAGS)
|
|
2062 (compare:CCC (not:I (match_operand:I 0 "register_operand" "r"))
|
|
2063 (const_int -1)))]
|
|
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.
|
|
2148 ;; TARGET_HARD_REGNO_MODE_OK thus only allows SFmode in these registers.
|
|
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)
|
|
2294 (if_then_else (match_operator 0 "ordered_comparison_operator"
|
|
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)
|
|
2304 (if_then_else (match_operator 0 "ordered_comparison_operator"
|
|
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
|
|
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
|
|
2379 (define_insn_and_split "*cbranch<mode>4_btst_insn"
|
|
2380 [(set (pc)
|
|
2381 (if_then_else (match_operator 0 "visium_equality_comparison_operator"
|
|
2382 [(zero_extract:I
|
|
2383 (match_operand:I 1 "register_operand" "r")
|
|
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
|
|
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
|
|
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
|
|
2667 emit_call_insn (gen_call (operands[0], const0_rtx, NULL));
|
|
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 })
|