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