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