]>
Commit | Line | Data |
---|---|---|
ba8ab355 | 1 | ;;- Machine description for Intel 80960 chip for GNU C compiler |
b72f00af | 2 | ;; Copyright (C) 1992, 1995, 1998, 2001 Free Software Foundation, Inc. |
ba8ab355 JW |
3 | ;; Contributed by Steven McGeady, Intel Corp. |
4 | ;; Additional work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson | |
5 | ;; Converted to GCC 2.0 by Jim Wilson and Michael Tiemann, Cygnus Support. | |
6 | ||
7ec022b2 | 7 | ;; This file is part of GCC. |
ba8ab355 | 8 | |
7ec022b2 | 9 | ;; GCC is free software; you can redistribute it and/or modify |
ba8ab355 JW |
10 | ;; it under the terms of the GNU General Public License as published by |
11 | ;; the Free Software Foundation; either version 2, or (at your option) | |
12 | ;; any later version. | |
13 | ||
7ec022b2 | 14 | ;; GCC is distributed in the hope that it will be useful, |
ba8ab355 JW |
15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | ;; GNU General Public License for more details. | |
18 | ||
19 | ;; You should have received a copy of the GNU General Public License | |
7ec022b2 | 20 | ;; along with GCC; see the file COPYING. If not, write to |
3f63df56 RK |
21 | ;; the Free Software Foundation, 59 Temple Place - Suite 330, |
22 | ;; Boston, MA 02111-1307, USA. | |
ba8ab355 JW |
23 | |
24 | ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. | |
25 | \f | |
bc9c7a36 JW |
26 | ;; There are very few (4) 'f' registers, they can't be loaded/stored from/to |
27 | ;; memory, and some instructions explicitly require them, so we get better | |
0a1379a0 | 28 | ;; code by discouraging pseudo-registers from being allocated to them. |
bc9c7a36 JW |
29 | ;; However, we do want to allow all patterns which can store to them to |
30 | ;; include them in their constraints, so we always use '*f' in a destination | |
31 | ;; constraint except when 'f' is the only alternative. | |
32 | \f | |
ba8ab355 JW |
33 | ;; Insn attributes which describe the i960. |
34 | ||
35 | ;; Modscan is not used, since the compiler never emits any of these insns. | |
36 | (define_attr "type" | |
37 | "move,arith,alu2,mult,div,modscan,load,store,branch,call,address,compare,fpload,fpstore,fpmove,fpcvt,fpcc,fpadd,fpmul,fpdiv,multi,misc" | |
38 | (const_string "arith")) | |
39 | ||
40 | ;; Length (in # of insns). | |
41 | (define_attr "length" "" | |
42 | (cond [(eq_attr "type" "load,fpload") | |
43 | (if_then_else (match_operand 1 "symbolic_memory_operand" "") | |
44 | (const_int 2) | |
45 | (const_int 1)) | |
46 | (eq_attr "type" "store,fpstore") | |
47 | (if_then_else (match_operand 0 "symbolic_memory_operand" "") | |
48 | (const_int 2) | |
49 | (const_int 1)) | |
50 | (eq_attr "type" "address") | |
51 | (const_int 2)] | |
52 | (const_int 1))) | |
53 | ||
54 | (define_asm_attributes | |
55 | [(set_attr "length" "1") | |
56 | (set_attr "type" "multi")]) | |
57 | ||
58 | ;; (define_function_unit {name} {num-units} {n-users} {test} | |
c8e18a2b | 59 | ;; {ready-delay} {issue-delay} [{conflict-list}]) |
ba8ab355 JW |
60 | |
61 | ;; The integer ALU | |
62 | (define_function_unit "alu" 2 0 (eq_attr "type" "arith,compare,move,address") 1 0) | |
63 | (define_function_unit "alu" 2 0 (eq_attr "type" "alu2") 2 0) | |
64 | (define_function_unit "alu" 2 0 (eq_attr "type" "mult") 5 0) | |
65 | (define_function_unit "alu" 2 0 (eq_attr "type" "div") 35 0) | |
66 | (define_function_unit "alu" 2 0 (eq_attr "type" "modscan") 3 0) | |
67 | ||
68 | ;; Memory with load-delay of 1 (i.e., 2 cycle load). | |
69 | (define_function_unit "memory" 1 0 (eq_attr "type" "load,fpload") 2 0) | |
70 | ||
71 | ;; Floating point operations. | |
72 | (define_function_unit "fp" 1 2 (eq_attr "type" "fpmove") 5 0) | |
73 | (define_function_unit "fp" 1 2 (eq_attr "type" "fpcvt") 35 0) | |
74 | (define_function_unit "fp" 1 2 (eq_attr "type" "fpcc") 10 0) | |
75 | (define_function_unit "fp" 1 2 (eq_attr "type" "fpadd") 10 0) | |
76 | (define_function_unit "fp" 1 2 (eq_attr "type" "fpmul") 20 0) | |
77 | (define_function_unit "fp" 1 2 (eq_attr "type" "fpdiv") 35 0) | |
78 | \f | |
79 | ;; Compare instructions. | |
80 | ;; This controls RTL generation and register allocation. | |
81 | ||
82 | ;; We generate RTL for comparisons and branches by having the cmpxx | |
83 | ;; patterns store away the operands. Then, the scc and bcc patterns | |
84 | ;; emit RTL for both the compare and the branch. | |
85 | ;; | |
38e01259 | 86 | ;; We start with the DEFINE_EXPANDs, then DEFINE_INSNs to match |
ba8ab355 JW |
87 | ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc |
88 | ;; insns that actually require more than one machine instruction. | |
89 | ||
90 | ;; Put cmpsi first because it is expected to be the most common. | |
91 | ||
92 | (define_expand "cmpsi" | |
93 | [(set (reg:CC 36) | |
94 | (compare:CC (match_operand:SI 0 "nonimmediate_operand" "") | |
95 | (match_operand:SI 1 "general_operand" "")))] | |
96 | "" | |
97 | " | |
98 | { | |
99 | i960_compare_op0 = operands[0]; | |
100 | i960_compare_op1 = operands[1]; | |
101 | DONE; | |
102 | }") | |
103 | ||
104 | (define_expand "cmpdf" | |
105 | [(set (reg:CC 36) | |
106 | (compare:CC (match_operand:DF 0 "register_operand" "r") | |
107 | (match_operand:DF 1 "nonmemory_operand" "rGH")))] | |
108 | "TARGET_NUMERICS" | |
109 | " | |
110 | { | |
111 | i960_compare_op0 = operands[0]; | |
112 | i960_compare_op1 = operands[1]; | |
113 | DONE; | |
114 | }") | |
115 | ||
116 | (define_expand "cmpsf" | |
117 | [(set (reg:CC 36) | |
118 | (compare:CC (match_operand:SF 0 "register_operand" "r") | |
119 | (match_operand:SF 1 "nonmemory_operand" "rGH")))] | |
120 | "TARGET_NUMERICS" | |
121 | " | |
122 | { | |
123 | i960_compare_op0 = operands[0]; | |
124 | i960_compare_op1 = operands[1]; | |
125 | DONE; | |
126 | }") | |
127 | ||
128 | ;; Now the DEFINE_INSNs for the compare and scc cases. First the compares. | |
129 | ||
130 | (define_insn "" | |
131 | [(set (reg:CC 36) | |
132 | (compare:CC (match_operand:SI 0 "register_operand" "d") | |
133 | (match_operand:SI 1 "arith_operand" "dI")))] | |
134 | "" | |
135 | "cmpi %0,%1" | |
136 | [(set_attr "type" "compare")]) | |
137 | ||
138 | (define_insn "" | |
139 | [(set (reg:CC_UNS 36) | |
140 | (compare:CC_UNS (match_operand:SI 0 "register_operand" "d") | |
141 | (match_operand:SI 1 "arith_operand" "dI")))] | |
142 | "" | |
143 | "cmpo %0,%1" | |
144 | [(set_attr "type" "compare")]) | |
145 | ||
146 | (define_insn "" | |
147 | [(set (reg:CC 36) | |
148 | (compare:CC (match_operand:DF 0 "register_operand" "r") | |
149 | (match_operand:DF 1 "nonmemory_operand" "rGH")))] | |
150 | "TARGET_NUMERICS" | |
151 | "cmprl %0,%1" | |
152 | [(set_attr "type" "fpcc")]) | |
153 | ||
154 | (define_insn "" | |
155 | [(set (reg:CC 36) | |
156 | (compare:CC (match_operand:SF 0 "register_operand" "r") | |
157 | (match_operand:SF 1 "nonmemory_operand" "rGH")))] | |
158 | "TARGET_NUMERICS" | |
159 | "cmpr %0,%1" | |
160 | [(set_attr "type" "fpcc")]) | |
161 | ||
162 | ;; Instruction definitions for branch-on-bit-set and clear insns. | |
163 | ||
164 | (define_insn "" | |
165 | [(set (pc) | |
166 | (if_then_else | |
c77e04ae | 167 | (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "d") |
ba8ab355 | 168 | (const_int 1) |
c77e04ae | 169 | (match_operand:SI 1 "arith_operand" "dI")) |
ba8ab355 | 170 | (const_int 0)) |
c77e04ae | 171 | (label_ref (match_operand 2 "" "")) |
ba8ab355 JW |
172 | (pc)))] |
173 | "" | |
c77e04ae | 174 | "bbs%+ %1,%0,%l2" |
ba8ab355 JW |
175 | [(set_attr "type" "branch")]) |
176 | ||
177 | (define_insn "" | |
178 | [(set (pc) | |
179 | (if_then_else | |
c77e04ae | 180 | (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "d") |
ba8ab355 | 181 | (const_int 1) |
c77e04ae | 182 | (match_operand:SI 1 "arith_operand" "dI")) |
ba8ab355 | 183 | (const_int 0)) |
c77e04ae | 184 | (label_ref (match_operand 2 "" "")) |
ba8ab355 JW |
185 | (pc)))] |
186 | "" | |
c77e04ae | 187 | "bbc%+ %1,%0,%l2" |
ba8ab355 JW |
188 | [(set_attr "type" "branch")]) |
189 | ||
190 | (define_insn "" | |
191 | [(set (pc) | |
192 | (if_then_else | |
c77e04ae | 193 | (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "d") |
ba8ab355 | 194 | (const_int 1) |
c77e04ae | 195 | (match_operand:SI 1 "arith_operand" "dI")) |
ba8ab355 | 196 | (const_int 0)) |
c77e04ae | 197 | (label_ref (match_operand 2 "" "")) |
ba8ab355 JW |
198 | (pc)))] |
199 | "" | |
c77e04ae | 200 | "bbs%+ %1,%0,%l2" |
ba8ab355 JW |
201 | [(set_attr "type" "branch")]) |
202 | ||
203 | (define_insn "" | |
204 | [(set (pc) | |
205 | (if_then_else | |
c77e04ae | 206 | (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "d") |
ba8ab355 | 207 | (const_int 1) |
c77e04ae | 208 | (match_operand:SI 1 "arith_operand" "dI")) |
ba8ab355 | 209 | (const_int 0)) |
c77e04ae | 210 | (label_ref (match_operand 2 "" "")) |
ba8ab355 JW |
211 | (pc)))] |
212 | "" | |
c77e04ae | 213 | "bbc%+ %1,%0,%l2" |
ba8ab355 JW |
214 | [(set_attr "type" "branch")]) |
215 | ||
216 | ;; ??? These will never match. The LOG_LINKs necessary to make these match | |
217 | ;; are not created by flow. These remain as a reminder to make this work | |
218 | ;; some day. | |
219 | ||
220 | (define_insn "" | |
221 | [(set (reg:CC 36) | |
222 | (compare (match_operand:SI 0 "arith_operand" "d") | |
997718c7 | 223 | (match_operand:SI 1 "arith_operand" "+d"))) |
ba8ab355 JW |
224 | (set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))] |
225 | "0" | |
226 | "cmpinci %0,%1" | |
227 | [(set_attr "type" "compare")]) | |
228 | ||
229 | (define_insn "" | |
230 | [(set (reg:CC_UNS 36) | |
231 | (compare (match_operand:SI 0 "arith_operand" "d") | |
997718c7 | 232 | (match_operand:SI 1 "arith_operand" "+d"))) |
ba8ab355 JW |
233 | (set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))] |
234 | "0" | |
235 | "cmpinco %0,%1" | |
236 | [(set_attr "type" "compare")]) | |
237 | ||
238 | (define_insn "" | |
239 | [(set (reg:CC 36) | |
240 | (compare (match_operand:SI 0 "arith_operand" "d") | |
997718c7 | 241 | (match_operand:SI 1 "arith_operand" "+d"))) |
ba8ab355 JW |
242 | (set (match_dup 1) (minus:SI (match_dup 1) (const_int 1)))] |
243 | "0" | |
244 | "cmpdeci %0,%1" | |
245 | [(set_attr "type" "compare")]) | |
246 | ||
247 | (define_insn "" | |
248 | [(set (reg:CC_UNS 36) | |
249 | (compare (match_operand:SI 0 "arith_operand" "d") | |
997718c7 | 250 | (match_operand:SI 1 "arith_operand" "+d"))) |
ba8ab355 JW |
251 | (set (match_dup 1) (minus:SI (match_dup 1) (const_int 1)))] |
252 | "0" | |
253 | "cmpdeco %0,%1" | |
254 | [(set_attr "type" "compare")]) | |
255 | \f | |
256 | ;; Templates to store result of condition. | |
257 | ;; '1' is stored if condition is true. | |
258 | ;; '0' is stored if condition is false. | |
259 | ;; These should use predicate "general_operand", since | |
260 | ;; gcc seems to be creating mem references which use these | |
261 | ;; templates. | |
262 | ||
263 | (define_expand "seq" | |
264 | [(set (match_operand:SI 0 "general_operand" "=d") | |
bc1aa946 | 265 | (eq:SI (match_dup 1) (const_int 0)))] |
ba8ab355 JW |
266 | "" |
267 | " | |
268 | { | |
269 | operands[1] = gen_compare_reg (EQ, i960_compare_op0, i960_compare_op1); | |
270 | }") | |
271 | ||
272 | (define_expand "sne" | |
273 | [(set (match_operand:SI 0 "general_operand" "=d") | |
bc1aa946 | 274 | (ne:SI (match_dup 1) (const_int 0)))] |
ba8ab355 JW |
275 | "" |
276 | " | |
277 | { | |
278 | operands[1] = gen_compare_reg (NE, i960_compare_op0, i960_compare_op1); | |
279 | }") | |
280 | ||
281 | (define_expand "sgt" | |
282 | [(set (match_operand:SI 0 "general_operand" "=d") | |
bc1aa946 | 283 | (gt:SI (match_dup 1) (const_int 0)))] |
ba8ab355 JW |
284 | "" |
285 | " | |
286 | { | |
287 | operands[1] = gen_compare_reg (GT, i960_compare_op0, i960_compare_op1); | |
288 | }") | |
289 | ||
290 | (define_expand "sgtu" | |
291 | [(set (match_operand:SI 0 "general_operand" "=d") | |
bc1aa946 | 292 | (gtu:SI (match_dup 1) (const_int 0)))] |
ba8ab355 JW |
293 | "" |
294 | " | |
295 | { | |
296 | operands[1] = gen_compare_reg (GTU, i960_compare_op0, i960_compare_op1); | |
297 | }") | |
298 | ||
299 | (define_expand "slt" | |
300 | [(set (match_operand:SI 0 "general_operand" "=d") | |
bc1aa946 | 301 | (lt:SI (match_dup 1) (const_int 0)))] |
ba8ab355 JW |
302 | "" |
303 | " | |
304 | { | |
305 | operands[1] = gen_compare_reg (LT, i960_compare_op0, i960_compare_op1); | |
306 | }") | |
307 | ||
308 | (define_expand "sltu" | |
309 | [(set (match_operand:SI 0 "general_operand" "=d") | |
bc1aa946 | 310 | (ltu:SI (match_dup 1) (const_int 0)))] |
ba8ab355 JW |
311 | "" |
312 | " | |
313 | { | |
314 | operands[1] = gen_compare_reg (LTU, i960_compare_op0, i960_compare_op1); | |
315 | }") | |
316 | ||
317 | (define_expand "sge" | |
318 | [(set (match_operand:SI 0 "general_operand" "=d") | |
bc1aa946 | 319 | (ge:SI (match_dup 1) (const_int 0)))] |
ba8ab355 JW |
320 | "" |
321 | " | |
322 | { | |
323 | operands[1] = gen_compare_reg (GE, i960_compare_op0, i960_compare_op1); | |
324 | }") | |
325 | ||
326 | (define_expand "sgeu" | |
327 | [(set (match_operand:SI 0 "general_operand" "=d") | |
bc1aa946 | 328 | (geu:SI (match_dup 1) (const_int 0)))] |
ba8ab355 JW |
329 | "" |
330 | " | |
331 | { | |
332 | operands[1] = gen_compare_reg (GEU, i960_compare_op0, i960_compare_op1); | |
333 | }") | |
334 | ||
335 | (define_expand "sle" | |
336 | [(set (match_operand:SI 0 "general_operand" "=d") | |
bc1aa946 | 337 | (le:SI (match_dup 1) (const_int 0)))] |
ba8ab355 JW |
338 | "" |
339 | " | |
340 | { | |
341 | operands[1] = gen_compare_reg (LE, i960_compare_op0, i960_compare_op1); | |
342 | }") | |
343 | ||
344 | (define_expand "sleu" | |
345 | [(set (match_operand:SI 0 "general_operand" "=d") | |
bc1aa946 | 346 | (leu:SI (match_dup 1) (const_int 0)))] |
ba8ab355 JW |
347 | "" |
348 | " | |
349 | { | |
350 | operands[1] = gen_compare_reg (LEU, i960_compare_op0, i960_compare_op1); | |
351 | }") | |
352 | ||
ef64fa15 TG |
353 | (define_insn "" |
354 | [(set (match_operand:SI 0 "general_operand" "=d") | |
355 | (eq:SI (match_operand:SI 1 "register_operand" "d") (const_int 0)))] | |
356 | "" | |
357 | "shro %1,1,%0" | |
358 | [(set_attr "type" "alu2")]) | |
359 | ||
ba8ab355 JW |
360 | (define_insn "" |
361 | [(set (match_operand:SI 0 "general_operand" "=d") | |
bc1aa946 | 362 | (match_operator:SI 1 "comparison_operator" [(reg:CC 36) (const_int 0)]))] |
ba8ab355 | 363 | "" |
4ec74aeb | 364 | "test%C1 %0" |
ba8ab355 JW |
365 | [(set_attr "type" "compare")]) |
366 | ||
367 | (define_insn "" | |
368 | [(set (match_operand:SI 0 "general_operand" "=d") | |
bc1aa946 | 369 | (match_operator:SI 1 "comparison_operator" [(reg:CC_UNS 36) (const_int 0)]))] |
ba8ab355 | 370 | "" |
4ec74aeb | 371 | "test%C1 %0" |
ba8ab355 JW |
372 | [(set_attr "type" "compare")]) |
373 | \f | |
374 | ;; These control RTL generation for conditional jump insns | |
375 | ;; and match them for register allocation. | |
376 | ||
377 | (define_expand "beq" | |
378 | [(set (pc) | |
379 | (if_then_else (eq (match_dup 1) | |
380 | (const_int 0)) | |
381 | (label_ref (match_operand 0 "" "")) | |
382 | (pc)))] | |
383 | "" | |
384 | " | |
385 | { operands[1] = gen_compare_reg (EQ, i960_compare_op0, i960_compare_op1); }") | |
386 | ||
387 | (define_expand "bne" | |
388 | [(set (pc) | |
389 | (if_then_else (ne (match_dup 1) | |
390 | (const_int 0)) | |
391 | (label_ref (match_operand 0 "" "")) | |
392 | (pc)))] | |
393 | "" | |
394 | " | |
395 | { operands[1] = gen_compare_reg (NE, i960_compare_op0, i960_compare_op1); }") | |
396 | ||
397 | (define_expand "bgt" | |
398 | [(set (pc) | |
399 | (if_then_else (gt (match_dup 1) | |
400 | (const_int 0)) | |
401 | (label_ref (match_operand 0 "" "")) | |
402 | (pc)))] | |
403 | "" | |
404 | " | |
405 | { operands[1] = gen_compare_reg (GT, i960_compare_op0, i960_compare_op1); }") | |
406 | ||
407 | (define_expand "bgtu" | |
408 | [(set (pc) | |
409 | (if_then_else (gtu (match_dup 1) | |
410 | (const_int 0)) | |
411 | (label_ref (match_operand 0 "" "")) | |
412 | (pc)))] | |
413 | "" | |
414 | " | |
415 | { operands[1] = gen_compare_reg (GTU, i960_compare_op0, i960_compare_op1); }") | |
416 | ||
417 | (define_expand "blt" | |
418 | [(set (pc) | |
419 | (if_then_else (lt (match_dup 1) | |
420 | (const_int 0)) | |
421 | (label_ref (match_operand 0 "" "")) | |
422 | (pc)))] | |
423 | "" | |
424 | " | |
425 | { operands[1] = gen_compare_reg (LT, i960_compare_op0, i960_compare_op1); }") | |
426 | ||
427 | (define_expand "bltu" | |
428 | [(set (pc) | |
429 | (if_then_else (ltu (match_dup 1) | |
430 | (const_int 0)) | |
431 | (label_ref (match_operand 0 "" "")) | |
432 | (pc)))] | |
433 | "" | |
434 | " | |
435 | { operands[1] = gen_compare_reg (LTU, i960_compare_op0, i960_compare_op1); }") | |
436 | ||
437 | (define_expand "bge" | |
438 | [(set (pc) | |
439 | (if_then_else (ge (match_dup 1) | |
440 | (const_int 0)) | |
441 | (label_ref (match_operand 0 "" "")) | |
442 | (pc)))] | |
443 | "" | |
444 | " | |
445 | { operands[1] = gen_compare_reg (GE, i960_compare_op0, i960_compare_op1); }") | |
446 | ||
447 | (define_expand "bgeu" | |
448 | [(set (pc) | |
449 | (if_then_else (geu (match_dup 1) | |
450 | (const_int 0)) | |
451 | (label_ref (match_operand 0 "" "")) | |
452 | (pc)))] | |
453 | "" | |
454 | " | |
455 | { operands[1] = gen_compare_reg (GEU, i960_compare_op0, i960_compare_op1); }") | |
456 | ||
457 | (define_expand "ble" | |
458 | [(set (pc) | |
459 | (if_then_else (le (match_dup 1) | |
460 | (const_int 0)) | |
461 | (label_ref (match_operand 0 "" "")) | |
462 | (pc)))] | |
463 | "" | |
464 | " | |
465 | { operands[1] = gen_compare_reg (LE, i960_compare_op0, i960_compare_op1); }") | |
466 | ||
467 | (define_expand "bleu" | |
468 | [(set (pc) | |
469 | (if_then_else (leu (match_dup 1) | |
470 | (const_int 0)) | |
471 | (label_ref (match_operand 0 "" "")) | |
472 | (pc)))] | |
473 | "" | |
474 | " | |
475 | { operands[1] = gen_compare_reg (LEU, i960_compare_op0, i960_compare_op1); }") | |
476 | \f | |
477 | ;; Now the normal branch insns (forward and reverse). | |
478 | ||
479 | (define_insn "" | |
480 | [(set (pc) | |
481 | (if_then_else (match_operator 0 "comparison_operator" | |
482 | [(reg:CC 36) (const_int 0)]) | |
483 | (label_ref (match_operand 1 "" "")) | |
484 | (pc)))] | |
485 | "" | |
eb9c1bb6 | 486 | "b%C0%+ %l1" |
ba8ab355 JW |
487 | [(set_attr "type" "branch")]) |
488 | ||
489 | (define_insn "" | |
490 | [(set (pc) | |
491 | (if_then_else (match_operator 0 "comparison_operator" | |
492 | [(reg:CC 36) (const_int 0)]) | |
493 | (pc) | |
494 | (label_ref (match_operand 1 "" ""))))] | |
495 | "" | |
eb9c1bb6 | 496 | "b%I0%+ %l1" |
ba8ab355 JW |
497 | [(set_attr "type" "branch")]) |
498 | ||
499 | (define_insn "" | |
500 | [(set (pc) | |
501 | (if_then_else (match_operator 0 "comparison_operator" | |
502 | [(reg:CC_UNS 36) (const_int 0)]) | |
503 | (label_ref (match_operand 1 "" "")) | |
504 | (pc)))] | |
505 | "" | |
eb9c1bb6 | 506 | "b%C0%+ %l1" |
ba8ab355 JW |
507 | [(set_attr "type" "branch")]) |
508 | ||
509 | (define_insn "" | |
510 | [(set (pc) | |
511 | (if_then_else (match_operator 0 "comparison_operator" | |
512 | [(reg:CC_UNS 36) (const_int 0)]) | |
513 | (pc) | |
514 | (label_ref (match_operand 1 "" ""))))] | |
515 | "" | |
eb9c1bb6 | 516 | "b%I0%+ %l1" |
ba8ab355 JW |
517 | [(set_attr "type" "branch")]) |
518 | ||
519 | (define_insn "" | |
520 | [(set (pc) | |
521 | (if_then_else | |
522 | (match_operator 0 "comparison_operator" | |
523 | [(match_operand:SI 1 "arith_operand" "d") | |
524 | (match_operand:SI 2 "arith_operand" "dI")]) | |
525 | (label_ref (match_operand 3 "" "")) | |
526 | (pc)))] | |
527 | "" | |
eb9c1bb6 | 528 | "cmp%S0%B0%R0%+ %2,%1,%l3" |
ba8ab355 JW |
529 | [(set_attr "type" "branch")]) |
530 | ||
531 | (define_insn "" | |
532 | [(set (pc) | |
533 | (if_then_else | |
534 | (match_operator 0 "comparison_operator" | |
535 | [(match_operand:SI 1 "arith_operand" "d") | |
536 | (match_operand:SI 2 "arith_operand" "dI")]) | |
537 | (pc) | |
538 | (label_ref (match_operand 3 "" ""))))] | |
539 | "" | |
eb9c1bb6 | 540 | "cmp%S0%B0%X0%+ %2,%1,%l3" |
ba8ab355 JW |
541 | [(set_attr "type" "branch")]) |
542 | \f | |
a157febd GK |
543 | ;; Now the trap instructions. The i960 appears to only have conditional |
544 | ;; traps... | |
545 | ||
546 | (define_insn ("trap") | |
547 | [(trap_if (const_int 1) (const_int 0))] | |
548 | "" | |
cff27f1d | 549 | "cmpo g0,g0 ; faulte.t") |
a157febd GK |
550 | |
551 | (define_expand "conditional_trap" | |
552 | [(trap_if (match_operator 0 "comparison_operator" | |
553 | [(match_dup 2) (const_int 0)]) | |
554 | (match_operand 1 "const_int_operand" "i"))] | |
555 | "" | |
556 | " | |
557 | { | |
558 | operands[2] = gen_compare_reg (GET_CODE (operands[0]), | |
559 | i960_compare_op0, i960_compare_op1); | |
560 | }") | |
561 | ||
562 | (define_insn "" | |
563 | [(trap_if (match_operator 0 "comparison_operator" | |
564 | [(reg:CC 36) (const_int 0)]) | |
565 | (match_operand 1 "const_int_operand" "i"))] | |
566 | "" | |
567 | "fault%C0.f") | |
568 | ||
569 | (define_insn "" | |
570 | [(trap_if (match_operator 0 "comparison_operator" | |
571 | [(reg:CC_UNS 36) (const_int 0)]) | |
572 | (match_operand 1 "const_int_operand" "i"))] | |
573 | "" | |
574 | "fault%C0.f") | |
575 | \f | |
ba8ab355 | 576 | ;; Normal move instructions. |
2296cba3 | 577 | ;; This code is based on the sparc machine description. |
ba8ab355 JW |
578 | |
579 | (define_expand "movsi" | |
580 | [(set (match_operand:SI 0 "general_operand" "") | |
581 | (match_operand:SI 1 "general_operand" ""))] | |
582 | "" | |
583 | " | |
584 | { | |
585 | if (emit_move_sequence (operands, SImode)) | |
586 | DONE; | |
587 | }") | |
588 | ||
589 | ;; The store case can not be separate, because reload may convert a register | |
590 | ;; to register move insn to a store (or load) insn without rerecognizing | |
591 | ;; the insn. | |
592 | ||
e770968b JW |
593 | ;; The i960 does not have any store constant to memory instruction. However, |
594 | ;; the calling convention is defined so that the arg pointer when it is not | |
595 | ;; overwise being used is zero. Thus, we can handle store zero to memory | |
596 | ;; by storing an unused arg pointer. The arg pointer will be unused if | |
6c535c69 | 597 | ;; current_function_args_size is zero and this is not a stdarg |
f719a85d RK |
598 | ;; function. This value of the former variable is not valid until after |
599 | ;; all rtl generation is complete, including function inlining (because a | |
600 | ;; function that doesn't need an arg pointer may be inlined into a function | |
601 | ;; that does need an arg pointer), so we must also check that | |
602 | ;; rtx_equal_function_value_matters is zero. | |
ba8ab355 JW |
603 | |
604 | (define_insn "" | |
605 | [(set (match_operand:SI 0 "general_operand" "=d,d,d,m") | |
606 | (match_operand:SI 1 "general_operand" "dI,i,m,dJ"))] | |
e770968b | 607 | "(current_function_args_size == 0 |
f719a85d | 608 | && current_function_stdarg == 0 |
e770968b | 609 | && rtx_equal_function_value_matters == 0) |
ba8ab355 JW |
610 | && (register_operand (operands[0], SImode) |
611 | || register_operand (operands[1], SImode) | |
612 | || operands[1] == const0_rtx)" | |
613 | "* | |
614 | { | |
615 | switch (which_alternative) | |
616 | { | |
617 | case 0: | |
618 | if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES) | |
619 | { | |
620 | if (GET_CODE (operands[1]) == REG) | |
621 | return \"lda (%1),%0\"; | |
622 | else | |
623 | return \"lda %1,%0\"; | |
624 | } | |
625 | return \"mov %1,%0\"; | |
626 | case 1: | |
627 | return i960_output_ldconst (operands[0], operands[1]); | |
628 | case 2: | |
629 | return \"ld %1,%0\"; | |
630 | case 3: | |
631 | if (operands[1] == const0_rtx) | |
632 | return \"st g14,%0\"; | |
633 | return \"st %1,%0\"; | |
1943c2c1 KG |
634 | default: |
635 | abort(); | |
ba8ab355 JW |
636 | } |
637 | }" | |
638 | [(set_attr "type" "move,address,load,store") | |
639 | (set_attr "length" "*,3,*,*")]) | |
640 | ||
641 | (define_insn "" | |
642 | [(set (match_operand:SI 0 "general_operand" "=d,d,d,m") | |
643 | (match_operand:SI 1 "general_operand" "dI,i,m,d"))] | |
e770968b | 644 | "(current_function_args_size != 0 |
f719a85d | 645 | || current_function_stdarg != 0 |
e770968b | 646 | || rtx_equal_function_value_matters != 0) |
ba8ab355 JW |
647 | && (register_operand (operands[0], SImode) |
648 | || register_operand (operands[1], SImode))" | |
649 | "* | |
650 | { | |
651 | switch (which_alternative) | |
652 | { | |
653 | case 0: | |
654 | if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES) | |
655 | { | |
656 | if (GET_CODE (operands[1]) == REG) | |
657 | return \"lda (%1),%0\"; | |
658 | else | |
659 | return \"lda %1,%0\"; | |
660 | } | |
661 | return \"mov %1,%0\"; | |
662 | case 1: | |
663 | return i960_output_ldconst (operands[0], operands[1]); | |
664 | case 2: | |
665 | return \"ld %1,%0\"; | |
666 | case 3: | |
667 | return \"st %1,%0\"; | |
1943c2c1 KG |
668 | default: |
669 | abort(); | |
ba8ab355 JW |
670 | } |
671 | }" | |
672 | [(set_attr "type" "move,address,load,store") | |
673 | (set_attr "length" "*,3,*,*")]) | |
674 | ||
675 | (define_expand "movhi" | |
676 | [(set (match_operand:HI 0 "general_operand" "") | |
677 | (match_operand:HI 1 "general_operand" ""))] | |
678 | "" | |
679 | " | |
680 | { | |
681 | if (emit_move_sequence (operands, HImode)) | |
682 | DONE; | |
683 | }") | |
684 | ||
685 | ;; Special pattern for zero stores to memory for functions which don't use | |
686 | ;; the arg pointer. | |
687 | ||
688 | ;; The store case can not be separate. See above. | |
689 | (define_insn "" | |
690 | [(set (match_operand:HI 0 "general_operand" "=d,d,d,m") | |
691 | (match_operand:HI 1 "general_operand" "dI,i,m,dJ"))] | |
e770968b | 692 | "(current_function_args_size == 0 |
f719a85d | 693 | && current_function_stdarg == 0 |
e770968b | 694 | && rtx_equal_function_value_matters == 0) |
ba8ab355 JW |
695 | && (register_operand (operands[0], HImode) |
696 | || register_operand (operands[1], HImode) | |
697 | || operands[1] == const0_rtx)" | |
698 | "* | |
699 | { | |
700 | switch (which_alternative) | |
701 | { | |
702 | case 0: | |
703 | if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES) | |
704 | { | |
705 | if (GET_CODE (operands[1]) == REG) | |
706 | return \"lda (%1),%0\"; | |
707 | else | |
708 | return \"lda %1,%0\"; | |
709 | } | |
710 | return \"mov %1,%0\"; | |
711 | case 1: | |
712 | return i960_output_ldconst (operands[0], operands[1]); | |
713 | case 2: | |
714 | return \"ldos %1,%0\"; | |
715 | case 3: | |
716 | if (operands[1] == const0_rtx) | |
717 | return \"stos g14,%0\"; | |
718 | return \"stos %1,%0\"; | |
1943c2c1 KG |
719 | default: |
720 | abort(); | |
ba8ab355 JW |
721 | } |
722 | }" | |
723 | [(set_attr "type" "move,misc,load,store") | |
724 | (set_attr "length" "*,3,*,*")]) | |
725 | ||
726 | ;; The store case can not be separate. See above. | |
727 | (define_insn "" | |
728 | [(set (match_operand:HI 0 "general_operand" "=d,d,d,m") | |
729 | (match_operand:HI 1 "general_operand" "dI,i,m,d"))] | |
e770968b | 730 | "(current_function_args_size != 0 |
f719a85d | 731 | || current_function_stdarg != 0 |
e770968b | 732 | || rtx_equal_function_value_matters != 0) |
ba8ab355 JW |
733 | && (register_operand (operands[0], HImode) |
734 | || register_operand (operands[1], HImode))" | |
735 | "* | |
736 | { | |
737 | switch (which_alternative) | |
738 | { | |
739 | case 0: | |
740 | if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES) | |
741 | { | |
742 | if (GET_CODE (operands[1]) == REG) | |
743 | return \"lda (%1),%0\"; | |
744 | else | |
745 | return \"lda %1,%0\"; | |
746 | } | |
747 | return \"mov %1,%0\"; | |
748 | case 1: | |
749 | return i960_output_ldconst (operands[0], operands[1]); | |
750 | case 2: | |
751 | return \"ldos %1,%0\"; | |
752 | case 3: | |
753 | return \"stos %1,%0\"; | |
1943c2c1 KG |
754 | default: |
755 | abort(); | |
ba8ab355 JW |
756 | } |
757 | }" | |
758 | [(set_attr "type" "move,misc,load,store") | |
759 | (set_attr "length" "*,3,*,*")]) | |
760 | ||
761 | (define_expand "movqi" | |
762 | [(set (match_operand:QI 0 "general_operand" "") | |
763 | (match_operand:QI 1 "general_operand" ""))] | |
764 | "" | |
765 | " | |
766 | { | |
767 | if (emit_move_sequence (operands, QImode)) | |
768 | DONE; | |
769 | }") | |
770 | ||
771 | ;; The store case can not be separate. See comment above. | |
772 | (define_insn "" | |
773 | [(set (match_operand:QI 0 "general_operand" "=d,d,d,m") | |
774 | (match_operand:QI 1 "general_operand" "dI,i,m,dJ"))] | |
e770968b | 775 | "(current_function_args_size == 0 |
f719a85d | 776 | && current_function_stdarg == 0 |
e770968b | 777 | && rtx_equal_function_value_matters == 0) |
ba8ab355 JW |
778 | && (register_operand (operands[0], QImode) |
779 | || register_operand (operands[1], QImode) | |
780 | || operands[1] == const0_rtx)" | |
781 | "* | |
782 | { | |
783 | switch (which_alternative) | |
784 | { | |
785 | case 0: | |
786 | if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES) | |
787 | { | |
788 | if (GET_CODE (operands[1]) == REG) | |
789 | return \"lda (%1),%0\"; | |
790 | else | |
791 | return \"lda %1,%0\"; | |
792 | } | |
793 | return \"mov %1,%0\"; | |
794 | case 1: | |
795 | return i960_output_ldconst (operands[0], operands[1]); | |
796 | case 2: | |
797 | return \"ldob %1,%0\"; | |
798 | case 3: | |
799 | if (operands[1] == const0_rtx) | |
800 | return \"stob g14,%0\"; | |
801 | return \"stob %1,%0\"; | |
1943c2c1 KG |
802 | default: |
803 | abort(); | |
ba8ab355 JW |
804 | } |
805 | }" | |
806 | [(set_attr "type" "move,misc,load,store") | |
807 | (set_attr "length" "*,3,*,*")]) | |
808 | ||
809 | ;; The store case can not be separate. See comment above. | |
810 | (define_insn "" | |
811 | [(set (match_operand:QI 0 "general_operand" "=d,d,d,m") | |
812 | (match_operand:QI 1 "general_operand" "dI,i,m,d"))] | |
e770968b | 813 | "(current_function_args_size != 0 |
f719a85d | 814 | || current_function_stdarg != 0 |
e770968b | 815 | || rtx_equal_function_value_matters != 0) |
ba8ab355 JW |
816 | && (register_operand (operands[0], QImode) |
817 | || register_operand (operands[1], QImode))" | |
818 | "* | |
819 | { | |
820 | switch (which_alternative) | |
821 | { | |
822 | case 0: | |
823 | if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES) | |
824 | { | |
825 | if (GET_CODE (operands[1]) == REG) | |
826 | return \"lda (%1),%0\"; | |
827 | else | |
828 | return \"lda %1,%0\"; | |
829 | } | |
830 | return \"mov %1,%0\"; | |
831 | case 1: | |
832 | return i960_output_ldconst (operands[0], operands[1]); | |
833 | case 2: | |
834 | return \"ldob %1,%0\"; | |
835 | case 3: | |
836 | return \"stob %1,%0\"; | |
1943c2c1 KG |
837 | default: |
838 | abort(); | |
ba8ab355 JW |
839 | } |
840 | }" | |
841 | [(set_attr "type" "move,misc,load,store") | |
842 | (set_attr "length" "*,3,*,*")]) | |
843 | ||
844 | (define_expand "movdi" | |
845 | [(set (match_operand:DI 0 "general_operand" "") | |
846 | (match_operand:DI 1 "general_operand" ""))] | |
847 | "" | |
848 | " | |
849 | { | |
850 | if (emit_move_sequence (operands, DImode)) | |
851 | DONE; | |
852 | }") | |
853 | ||
854 | ;; The store case can not be separate. See comment above. | |
855 | (define_insn "" | |
1fdf7338 RK |
856 | [(set (match_operand:DI 0 "general_operand" "=d,d,d,d,m,o") |
857 | (match_operand:DI 1 "general_operand" "d,I,i,m,d,J"))] | |
e770968b | 858 | "(current_function_args_size == 0 |
f719a85d | 859 | && current_function_stdarg == 0 |
e770968b | 860 | && rtx_equal_function_value_matters == 0) |
ba8ab355 JW |
861 | && (register_operand (operands[0], DImode) |
862 | || register_operand (operands[1], DImode) | |
863 | || operands[1] == const0_rtx)" | |
864 | "* | |
865 | { | |
866 | switch (which_alternative) | |
867 | { | |
868 | case 0: | |
ba8ab355 | 869 | case 1: |
ba8ab355 | 870 | case 3: |
76d76a0e | 871 | case 4: |
e5e1552a RK |
872 | return i960_output_move_double (operands[0], operands[1]); |
873 | case 2: | |
874 | return i960_output_ldconst (operands[0], operands[1]); | |
1fdf7338 | 875 | case 5: |
e4d26fc7 | 876 | return i960_output_move_double_zero (operands[0]); |
1943c2c1 KG |
877 | default: |
878 | abort(); | |
ba8ab355 JW |
879 | } |
880 | }" | |
1fdf7338 | 881 | [(set_attr "type" "move,move,load,load,store,store")]) |
ba8ab355 JW |
882 | |
883 | ;; The store case can not be separate. See comment above. | |
884 | (define_insn "" | |
1fdf7338 RK |
885 | [(set (match_operand:DI 0 "general_operand" "=d,d,d,d,m") |
886 | (match_operand:DI 1 "general_operand" "d,I,i,m,d"))] | |
e770968b | 887 | "(current_function_args_size != 0 |
f719a85d | 888 | || current_function_stdarg != 0 |
e770968b | 889 | || rtx_equal_function_value_matters != 0) |
ba8ab355 JW |
890 | && (register_operand (operands[0], DImode) |
891 | || register_operand (operands[1], DImode))" | |
892 | "* | |
893 | { | |
894 | switch (which_alternative) | |
895 | { | |
896 | case 0: | |
ba8ab355 | 897 | case 1: |
ba8ab355 | 898 | case 3: |
1fdf7338 | 899 | case 4: |
e5e1552a RK |
900 | return i960_output_move_double (operands[0], operands[1]); |
901 | case 2: | |
902 | return i960_output_ldconst (operands[0], operands[1]); | |
1943c2c1 KG |
903 | default: |
904 | abort(); | |
ba8ab355 JW |
905 | } |
906 | }" | |
1fdf7338 | 907 | [(set_attr "type" "move,move,load,load,store")]) |
ba8ab355 | 908 | |
e5e1552a | 909 | (define_insn "*store_unaligned_di_reg" |
e5e809f4 JL |
910 | [(set (match_operand:DI 0 "general_operand" "=d,m") |
911 | (match_operand:DI 1 "register_operand" "d,d")) | |
912 | (clobber (match_scratch:SI 2 "=X,&d"))] | |
e5e1552a RK |
913 | "" |
914 | "* | |
915 | { | |
e5e809f4 JL |
916 | if (which_alternative == 0) |
917 | return i960_output_move_double (operands[0], operands[1]); | |
918 | ||
c5c76735 | 919 | operands[3] = gen_rtx_MEM (word_mode, operands[2]); |
b72f00af | 920 | operands[4] = adjust_address (operands[3], word_mode, UNITS_PER_WORD); |
e5e1552a RK |
921 | return \"lda %0,%2\;st %1,%3\;st %D1,%4\"; |
922 | }" | |
e5e809f4 | 923 | [(set_attr "type" "move,store")]) |
e5e1552a | 924 | |
ba8ab355 JW |
925 | (define_expand "movti" |
926 | [(set (match_operand:TI 0 "general_operand" "") | |
927 | (match_operand:TI 1 "general_operand" ""))] | |
928 | "" | |
929 | " | |
930 | { | |
931 | if (emit_move_sequence (operands, TImode)) | |
932 | DONE; | |
933 | }") | |
934 | ||
935 | ;; The store case can not be separate. See comment above. | |
936 | (define_insn "" | |
e5e1552a RK |
937 | [(set (match_operand:TI 0 "general_operand" "=d,d,d,d,m,o") |
938 | (match_operand:TI 1 "general_operand" "d,I,i,m,d,J"))] | |
e770968b | 939 | "(current_function_args_size == 0 |
f719a85d | 940 | && current_function_stdarg == 0 |
e770968b | 941 | && rtx_equal_function_value_matters == 0) |
ba8ab355 JW |
942 | && (register_operand (operands[0], TImode) |
943 | || register_operand (operands[1], TImode) | |
944 | || operands[1] == const0_rtx)" | |
945 | "* | |
946 | { | |
947 | switch (which_alternative) | |
948 | { | |
949 | case 0: | |
ba8ab355 | 950 | case 1: |
ba8ab355 | 951 | case 3: |
76d76a0e | 952 | case 4: |
e5e1552a RK |
953 | return i960_output_move_quad (operands[0], operands[1]); |
954 | case 2: | |
955 | return i960_output_ldconst (operands[0], operands[1]); | |
956 | case 5: | |
e4d26fc7 | 957 | return i960_output_move_quad_zero (operands[0]); |
1943c2c1 KG |
958 | default: |
959 | abort(); | |
ba8ab355 JW |
960 | } |
961 | }" | |
e5e1552a | 962 | [(set_attr "type" "move,move,load,load,store,store")]) |
ba8ab355 JW |
963 | |
964 | ;; The store case can not be separate. See comment above. | |
965 | (define_insn "" | |
e5e1552a RK |
966 | [(set (match_operand:TI 0 "general_operand" "=d,d,d,d,m") |
967 | (match_operand:TI 1 "general_operand" "d,I,i,m,d"))] | |
e770968b | 968 | "(current_function_args_size != 0 |
f719a85d | 969 | || current_function_stdarg != 0 |
e770968b | 970 | || rtx_equal_function_value_matters != 0) |
ba8ab355 JW |
971 | && (register_operand (operands[0], TImode) |
972 | || register_operand (operands[1], TImode))" | |
973 | "* | |
974 | { | |
975 | switch (which_alternative) | |
976 | { | |
977 | case 0: | |
ba8ab355 | 978 | case 1: |
ba8ab355 | 979 | case 3: |
e5e1552a RK |
980 | case 4: |
981 | return i960_output_move_quad (operands[0], operands[1]); | |
982 | case 2: | |
983 | return i960_output_ldconst (operands[0], operands[1]); | |
1943c2c1 KG |
984 | default: |
985 | abort(); | |
ba8ab355 JW |
986 | } |
987 | }" | |
e5e1552a RK |
988 | [(set_attr "type" "move,move,load,load,store")]) |
989 | ||
990 | (define_insn "*store_unaligned_ti_reg" | |
e5e809f4 JL |
991 | [(set (match_operand:TI 0 "general_operand" "=d,m") |
992 | (match_operand:TI 1 "register_operand" "d,d")) | |
993 | (clobber (match_scratch:SI 2 "=X,&d"))] | |
e5e1552a RK |
994 | "" |
995 | "* | |
996 | { | |
e5e809f4 JL |
997 | if (which_alternative == 0) |
998 | return i960_output_move_quad (operands[0], operands[1]); | |
999 | ||
c5c76735 | 1000 | operands[3] = gen_rtx_MEM (word_mode, operands[2]); |
b72f00af RK |
1001 | operands[4] = adjust_address (operands[3], word_mode, UNITS_PER_WORD); |
1002 | operands[5] = adjust_address (operands[4], word_mode, UNITS_PER_WORD); | |
1003 | operands[6] = adjust_address (operands[5], word_mode, UNITS_PER_WORD); | |
e5e1552a RK |
1004 | return \"lda %0,%2\;st %1,%3\;st %D1,%4\;st %E1,%5\;st %F1,%6\"; |
1005 | }" | |
e5e809f4 | 1006 | [(set_attr "type" "move,store")]) |
ba8ab355 JW |
1007 | |
1008 | (define_expand "store_multiple" | |
1009 | [(set (match_operand:SI 0 "" "") ;;- dest | |
1010 | (match_operand:SI 1 "" "")) ;;- src | |
1011 | (use (match_operand:SI 2 "" ""))] ;;- nregs | |
1012 | "" | |
1013 | " | |
1014 | { | |
1015 | int regno; | |
1016 | int count; | |
792760b9 | 1017 | int offset = 0; |
ba8ab355 JW |
1018 | |
1019 | if (GET_CODE (operands[0]) != MEM | |
1020 | || GET_CODE (operands[1]) != REG | |
1021 | || GET_CODE (operands[2]) != CONST_INT) | |
1022 | FAIL; | |
1023 | ||
1024 | count = INTVAL (operands[2]); | |
1025 | if (count > 12) | |
1026 | FAIL; | |
1027 | ||
1028 | regno = REGNO (operands[1]); | |
ba8ab355 JW |
1029 | while (count >= 4 && ((regno & 3) == 0)) |
1030 | { | |
792760b9 | 1031 | emit_move_insn (adjust_address (operands[0], TImode, offset), |
c2749e2d | 1032 | gen_rtx_REG (TImode, regno)); |
ba8ab355 JW |
1033 | count -= 4; |
1034 | regno += 4; | |
792760b9 | 1035 | offset += 16; |
ba8ab355 JW |
1036 | } |
1037 | while (count >= 2 && ((regno & 1) == 0)) | |
1038 | { | |
792760b9 | 1039 | emit_move_insn (adjust_address (operands[0], DImode, offset), |
c2749e2d | 1040 | gen_rtx_REG (DImode, regno)); |
ba8ab355 JW |
1041 | count -= 2; |
1042 | regno += 2; | |
792760b9 | 1043 | offset += 8; |
ba8ab355 JW |
1044 | } |
1045 | while (count > 0) | |
1046 | { | |
792760b9 | 1047 | emit_move_insn (adjust_address (operands[0], SImode, offset), |
c2749e2d | 1048 | gen_rtx_REG (SImode, regno)); |
ba8ab355 JW |
1049 | count -= 1; |
1050 | regno += 1; | |
792760b9 | 1051 | offset += 4; |
ba8ab355 JW |
1052 | } |
1053 | DONE; | |
1054 | }") | |
1055 | \f | |
1056 | ;; Floating point move insns | |
1057 | ||
1058 | (define_expand "movdf" | |
1059 | [(set (match_operand:DF 0 "general_operand" "") | |
1060 | (match_operand:DF 1 "fpmove_src_operand" ""))] | |
1061 | "" | |
1062 | " | |
1063 | { | |
1064 | if (emit_move_sequence (operands, DFmode)) | |
1065 | DONE; | |
1066 | }") | |
1067 | ||
1068 | (define_insn "" | |
bc9c7a36 | 1069 | [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m,o") |
76d76a0e | 1070 | (match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d,G"))] |
e770968b | 1071 | "(current_function_args_size == 0 |
f719a85d | 1072 | && current_function_stdarg == 0 |
e770968b | 1073 | && rtx_equal_function_value_matters == 0) |
ba8ab355 JW |
1074 | && (register_operand (operands[0], DFmode) |
1075 | || register_operand (operands[1], DFmode) | |
1076 | || operands[1] == CONST0_RTX (DFmode))" | |
1077 | "* | |
1078 | { | |
1079 | switch (which_alternative) | |
1080 | { | |
1081 | case 0: | |
1082 | if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) | |
1083 | return \"movrl %1,%0\"; | |
1084 | else | |
1085 | return \"movl %1,%0\"; | |
1086 | case 1: | |
1087 | return \"movrl %1,%0\"; | |
1088 | case 2: | |
1089 | return i960_output_ldconst (operands[0], operands[1]); | |
1090 | case 3: | |
1091 | return \"ldl %1,%0\"; | |
1092 | case 4: | |
ba8ab355 | 1093 | return \"stl %1,%0\"; |
76d76a0e | 1094 | case 5: |
b72f00af | 1095 | operands[1] = adjust_address (operands[0], VOIDmode, 4); |
76d76a0e | 1096 | return \"st g14,%0\;st g14,%1\"; |
1943c2c1 KG |
1097 | default: |
1098 | abort(); | |
ba8ab355 JW |
1099 | } |
1100 | }" | |
76d76a0e | 1101 | [(set_attr "type" "move,move,load,fpload,fpstore,fpstore")]) |
ba8ab355 JW |
1102 | |
1103 | (define_insn "" | |
bc9c7a36 | 1104 | [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m") |
ba8ab355 | 1105 | (match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d"))] |
e770968b | 1106 | "(current_function_args_size != 0 |
f719a85d | 1107 | || current_function_stdarg != 0 |
e770968b | 1108 | || rtx_equal_function_value_matters != 0) |
ba8ab355 JW |
1109 | && (register_operand (operands[0], DFmode) |
1110 | || register_operand (operands[1], DFmode))" | |
1111 | "* | |
1112 | { | |
1113 | switch (which_alternative) | |
1114 | { | |
1115 | case 0: | |
1116 | if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) | |
1117 | return \"movrl %1,%0\"; | |
1118 | else | |
1119 | return \"movl %1,%0\"; | |
1120 | case 1: | |
1121 | return \"movrl %1,%0\"; | |
1122 | case 2: | |
1123 | return i960_output_ldconst (operands[0], operands[1]); | |
1124 | case 3: | |
1125 | return \"ldl %1,%0\"; | |
1126 | case 4: | |
1127 | return \"stl %1,%0\"; | |
1943c2c1 KG |
1128 | default: |
1129 | abort(); | |
ba8ab355 JW |
1130 | } |
1131 | }" | |
1132 | [(set_attr "type" "move,move,load,fpload,fpstore")]) | |
1133 | ||
1134 | (define_expand "movsf" | |
1135 | [(set (match_operand:SF 0 "general_operand" "") | |
1136 | (match_operand:SF 1 "fpmove_src_operand" ""))] | |
1137 | "" | |
1138 | " | |
1139 | { | |
1140 | if (emit_move_sequence (operands, SFmode)) | |
1141 | DONE; | |
1142 | }") | |
1143 | ||
1144 | (define_insn "" | |
bc9c7a36 | 1145 | [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m") |
ba8ab355 | 1146 | (match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,dG"))] |
e770968b | 1147 | "(current_function_args_size == 0 |
f719a85d | 1148 | && current_function_stdarg == 0 |
e770968b | 1149 | && rtx_equal_function_value_matters == 0) |
ba8ab355 JW |
1150 | && (register_operand (operands[0], SFmode) |
1151 | || register_operand (operands[1], SFmode) | |
1152 | || operands[1] == CONST0_RTX (SFmode))" | |
1153 | "* | |
1154 | { | |
1155 | switch (which_alternative) | |
1156 | { | |
1157 | case 0: | |
1158 | if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) | |
1159 | return \"movr %1,%0\"; | |
1160 | else | |
1161 | return \"mov %1,%0\"; | |
1162 | case 1: | |
1163 | return \"movr %1,%0\"; | |
1164 | case 2: | |
1165 | return i960_output_ldconst (operands[0], operands[1]); | |
1166 | case 3: | |
1167 | return \"ld %1,%0\"; | |
1168 | case 4: | |
1169 | if (operands[1] == CONST0_RTX (SFmode)) | |
1170 | return \"st g14,%0\"; | |
1171 | return \"st %1,%0\"; | |
1943c2c1 KG |
1172 | default: |
1173 | abort(); | |
ba8ab355 JW |
1174 | } |
1175 | }" | |
1176 | [(set_attr "type" "move,move,load,fpload,fpstore")]) | |
1177 | ||
1178 | (define_insn "" | |
bc9c7a36 | 1179 | [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m") |
ba8ab355 | 1180 | (match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,d"))] |
e770968b | 1181 | "(current_function_args_size != 0 |
f719a85d | 1182 | || current_function_stdarg != 0 |
e770968b | 1183 | || rtx_equal_function_value_matters != 0) |
ba8ab355 JW |
1184 | && (register_operand (operands[0], SFmode) |
1185 | || register_operand (operands[1], SFmode))" | |
1186 | "* | |
1187 | { | |
1188 | switch (which_alternative) | |
1189 | { | |
1190 | case 0: | |
1191 | if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) | |
1192 | return \"movr %1,%0\"; | |
1193 | else | |
1194 | return \"mov %1,%0\"; | |
1195 | case 1: | |
1196 | return \"movr %1,%0\"; | |
1197 | case 2: | |
1198 | return i960_output_ldconst (operands[0], operands[1]); | |
1199 | case 3: | |
1200 | return \"ld %1,%0\"; | |
1201 | case 4: | |
1202 | return \"st %1,%0\"; | |
1943c2c1 KG |
1203 | default: |
1204 | abort(); | |
ba8ab355 JW |
1205 | } |
1206 | }" | |
1207 | [(set_attr "type" "move,move,load,fpload,fpstore")]) | |
1208 | \f | |
1209 | ;; Mixed-mode moves with sign and zero-extension. | |
1210 | ||
1211 | ;; Note that the one starting from HImode comes before those for QImode | |
1212 | ;; so that a constant operand will match HImode, not QImode. | |
1213 | ||
1214 | (define_expand "extendhisi2" | |
1215 | [(set (match_operand:SI 0 "register_operand" "") | |
1216 | (sign_extend:SI | |
1217 | (match_operand:HI 1 "nonimmediate_operand" "")))] | |
1218 | "" | |
1219 | " | |
1220 | { | |
1221 | if (GET_CODE (operand1) == REG | |
1222 | || (GET_CODE (operand1) == SUBREG | |
1223 | && GET_CODE (XEXP (operand1, 0)) == REG)) | |
1224 | { | |
1225 | rtx temp = gen_reg_rtx (SImode); | |
3a598fbe | 1226 | rtx shift_16 = GEN_INT (16); |
ddef6bc7 | 1227 | int op1_subreg_byte = 0; |
ba8ab355 JW |
1228 | |
1229 | if (GET_CODE (operand1) == SUBREG) | |
1230 | { | |
ddef6bc7 JJ |
1231 | op1_subreg_byte = SUBREG_BYTE (operand1); |
1232 | op1_subreg_byte /= GET_MODE_SIZE (SImode); | |
1233 | op1_subreg_byte *= GET_MODE_SIZE (SImode); | |
ba8ab355 JW |
1234 | operand1 = SUBREG_REG (operand1); |
1235 | } | |
0197d76b | 1236 | if (GET_MODE (operand1) != SImode) |
ddef6bc7 | 1237 | operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte); |
ba8ab355 JW |
1238 | |
1239 | emit_insn (gen_ashlsi3 (temp, operand1, shift_16)); | |
1240 | emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); | |
1241 | DONE; | |
1242 | } | |
1243 | }") | |
1244 | ||
1245 | (define_insn "" | |
1246 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1247 | (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] | |
1248 | "" | |
1249 | "ldis %1,%0" | |
1250 | [(set_attr "type" "load")]) | |
1251 | ||
1252 | (define_expand "extendqisi2" | |
1253 | [(set (match_operand:SI 0 "register_operand" "") | |
1254 | (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] | |
1255 | "" | |
1256 | " | |
1257 | { | |
1258 | if (GET_CODE (operand1) == REG | |
1259 | || (GET_CODE (operand1) == SUBREG | |
1260 | && GET_CODE (XEXP (operand1, 0)) == REG)) | |
1261 | { | |
1262 | rtx temp = gen_reg_rtx (SImode); | |
3a598fbe | 1263 | rtx shift_24 = GEN_INT (24); |
ddef6bc7 | 1264 | int op1_subreg_byte = 0; |
ba8ab355 JW |
1265 | |
1266 | if (GET_CODE (operand1) == SUBREG) | |
1267 | { | |
ddef6bc7 JJ |
1268 | op1_subreg_byte = SUBREG_BYTE (operand1); |
1269 | op1_subreg_byte /= GET_MODE_SIZE (SImode); | |
1270 | op1_subreg_byte *= GET_MODE_SIZE (SImode); | |
ba8ab355 JW |
1271 | operand1 = SUBREG_REG (operand1); |
1272 | } | |
0197d76b | 1273 | if (GET_MODE (operand1) != SImode) |
ddef6bc7 | 1274 | operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte); |
ba8ab355 JW |
1275 | |
1276 | emit_insn (gen_ashlsi3 (temp, operand1, shift_24)); | |
1277 | emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); | |
1278 | DONE; | |
1279 | } | |
1280 | }") | |
1281 | ||
1282 | (define_insn "" | |
1283 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1284 | (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] | |
1285 | "" | |
1286 | "ldib %1,%0" | |
1287 | [(set_attr "type" "load")]) | |
1288 | ||
1289 | (define_expand "extendqihi2" | |
1290 | [(set (match_operand:HI 0 "register_operand" "") | |
1291 | (sign_extend:HI | |
1292 | (match_operand:QI 1 "nonimmediate_operand" "")))] | |
1293 | "" | |
1294 | " | |
1295 | { | |
1296 | if (GET_CODE (operand1) == REG | |
1297 | || (GET_CODE (operand1) == SUBREG | |
1298 | && GET_CODE (XEXP (operand1, 0)) == REG)) | |
1299 | { | |
1300 | rtx temp = gen_reg_rtx (SImode); | |
3a598fbe | 1301 | rtx shift_24 = GEN_INT (24); |
ddef6bc7 JJ |
1302 | int op0_subreg_byte = 0; |
1303 | int op1_subreg_byte = 0; | |
ba8ab355 JW |
1304 | |
1305 | if (GET_CODE (operand1) == SUBREG) | |
1306 | { | |
ddef6bc7 JJ |
1307 | op1_subreg_byte = SUBREG_BYTE (operand1); |
1308 | op1_subreg_byte /= GET_MODE_SIZE (SImode); | |
1309 | op1_subreg_byte *= GET_MODE_SIZE (SImode); | |
ba8ab355 JW |
1310 | operand1 = SUBREG_REG (operand1); |
1311 | } | |
0197d76b | 1312 | if (GET_MODE (operand1) != SImode) |
ddef6bc7 | 1313 | operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte); |
ba8ab355 JW |
1314 | |
1315 | if (GET_CODE (operand0) == SUBREG) | |
1316 | { | |
ddef6bc7 JJ |
1317 | op0_subreg_byte = SUBREG_BYTE (operand0); |
1318 | op0_subreg_byte /= GET_MODE_SIZE (SImode); | |
1319 | op0_subreg_byte *= GET_MODE_SIZE (SImode); | |
ba8ab355 JW |
1320 | operand0 = SUBREG_REG (operand0); |
1321 | } | |
1322 | if (GET_MODE (operand0) != SImode) | |
ddef6bc7 | 1323 | operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subreg_byte); |
ba8ab355 JW |
1324 | |
1325 | emit_insn (gen_ashlsi3 (temp, operand1, shift_24)); | |
1326 | emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); | |
1327 | DONE; | |
1328 | } | |
1329 | }") | |
1330 | ||
1331 | (define_insn "" | |
1332 | [(set (match_operand:HI 0 "register_operand" "=d") | |
1333 | (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] | |
1334 | "" | |
1335 | "ldib %1,%0" | |
1336 | [(set_attr "type" "load")]) | |
1337 | ||
1338 | (define_expand "zero_extendhisi2" | |
1339 | [(set (match_operand:SI 0 "register_operand" "") | |
1340 | (zero_extend:SI | |
1341 | (match_operand:HI 1 "nonimmediate_operand" "")))] | |
1342 | "" | |
1343 | " | |
1344 | { | |
1345 | if (GET_CODE (operand1) == REG | |
1346 | || (GET_CODE (operand1) == SUBREG | |
1347 | && GET_CODE (XEXP (operand1, 0)) == REG)) | |
1348 | { | |
1349 | rtx temp = gen_reg_rtx (SImode); | |
3a598fbe | 1350 | rtx shift_16 = GEN_INT (16); |
ddef6bc7 | 1351 | int op1_subreg_byte = 0; |
ba8ab355 JW |
1352 | |
1353 | if (GET_CODE (operand1) == SUBREG) | |
1354 | { | |
ddef6bc7 JJ |
1355 | op1_subreg_byte = SUBREG_BYTE (operand1); |
1356 | op1_subreg_byte /= GET_MODE_SIZE (SImode); | |
1357 | op1_subreg_byte *= GET_MODE_SIZE (SImode); | |
ba8ab355 JW |
1358 | operand1 = SUBREG_REG (operand1); |
1359 | } | |
0197d76b | 1360 | if (GET_MODE (operand1) != SImode) |
ddef6bc7 | 1361 | operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte); |
ba8ab355 JW |
1362 | |
1363 | emit_insn (gen_ashlsi3 (temp, operand1, shift_16)); | |
1364 | emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); | |
1365 | DONE; | |
1366 | } | |
1367 | }") | |
1368 | ||
1369 | (define_insn "" | |
1370 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1371 | (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] | |
1372 | "" | |
1373 | "ldos %1,%0" | |
1374 | [(set_attr "type" "load")]) | |
1375 | ||
2b4bd1bc JW |
1376 | ;; Using shifts here generates much better code than doing an `and 255'. |
1377 | ;; This is mainly because the `and' requires loading the constant separately, | |
1378 | ;; the constant is likely to get optimized, and then the compiler can't | |
1379 | ;; optimize the `and' because it doesn't know that one operand is a constant. | |
1380 | ||
ba8ab355 JW |
1381 | (define_expand "zero_extendqisi2" |
1382 | [(set (match_operand:SI 0 "register_operand" "") | |
1383 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] | |
1384 | "" | |
1385 | " | |
1386 | { | |
1387 | if (GET_CODE (operand1) == REG | |
1388 | || (GET_CODE (operand1) == SUBREG | |
1389 | && GET_CODE (XEXP (operand1, 0)) == REG)) | |
1390 | { | |
1391 | rtx temp = gen_reg_rtx (SImode); | |
3a598fbe | 1392 | rtx shift_24 = GEN_INT (24); |
ddef6bc7 | 1393 | int op1_subreg_byte = 0; |
ba8ab355 JW |
1394 | |
1395 | if (GET_CODE (operand1) == SUBREG) | |
1396 | { | |
ddef6bc7 JJ |
1397 | op1_subreg_byte = SUBREG_BYTE (operand1); |
1398 | op1_subreg_byte /= GET_MODE_SIZE (SImode); | |
1399 | op1_subreg_byte *= GET_MODE_SIZE (SImode); | |
1400 | operand1 = SUBREG_REG (operand1); | |
ba8ab355 | 1401 | } |
0197d76b | 1402 | if (GET_MODE (operand1) != SImode) |
ddef6bc7 | 1403 | operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte); |
ba8ab355 JW |
1404 | |
1405 | emit_insn (gen_ashlsi3 (temp, operand1, shift_24)); | |
1406 | emit_insn (gen_lshrsi3 (operand0, temp, shift_24)); | |
1407 | DONE; | |
1408 | } | |
1409 | }") | |
1410 | ||
1411 | (define_insn "" | |
1412 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1413 | (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))] | |
1414 | "" | |
1415 | "ldob %1,%0" | |
1416 | [(set_attr "type" "load")]) | |
1417 | ||
1418 | (define_expand "zero_extendqihi2" | |
1419 | [(set (match_operand:HI 0 "register_operand" "") | |
1420 | (zero_extend:HI | |
1421 | (match_operand:QI 1 "nonimmediate_operand" "")))] | |
1422 | "" | |
1423 | " | |
1424 | { | |
1425 | if (GET_CODE (operand1) == REG | |
1426 | || (GET_CODE (operand1) == SUBREG | |
1427 | && GET_CODE (XEXP (operand1, 0)) == REG)) | |
1428 | { | |
1429 | rtx temp = gen_reg_rtx (SImode); | |
3a598fbe | 1430 | rtx shift_24 = GEN_INT (24); |
ddef6bc7 JJ |
1431 | int op0_subreg_byte = 0; |
1432 | int op1_subreg_byte = 0; | |
ba8ab355 JW |
1433 | |
1434 | if (GET_CODE (operand1) == SUBREG) | |
1435 | { | |
ddef6bc7 | 1436 | op1_subreg_byte = SUBREG_BYTE (operand1); |
ba8ab355 JW |
1437 | operand1 = SUBREG_REG (operand1); |
1438 | } | |
0197d76b | 1439 | if (GET_MODE (operand1) != SImode) |
ddef6bc7 | 1440 | operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte); |
ba8ab355 JW |
1441 | |
1442 | if (GET_CODE (operand0) == SUBREG) | |
1443 | { | |
ddef6bc7 | 1444 | op0_subreg_byte = SUBREG_BYTE (operand0); |
ba8ab355 JW |
1445 | operand0 = SUBREG_REG (operand0); |
1446 | } | |
1447 | if (GET_MODE (operand0) != SImode) | |
ddef6bc7 | 1448 | operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subreg_byte); |
ba8ab355 JW |
1449 | |
1450 | emit_insn (gen_ashlsi3 (temp, operand1, shift_24)); | |
1451 | emit_insn (gen_lshrsi3 (operand0, temp, shift_24)); | |
1452 | DONE; | |
1453 | } | |
1454 | }") | |
1455 | ||
1456 | (define_insn "" | |
1457 | [(set (match_operand:HI 0 "register_operand" "=d") | |
1458 | (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] | |
1459 | "" | |
1460 | "ldob %1,%0" | |
1461 | [(set_attr "type" "load")]) | |
1462 | \f | |
1463 | ;; Conversions between float and double. | |
1464 | ||
1465 | (define_insn "extendsfdf2" | |
bc9c7a36 | 1466 | [(set (match_operand:DF 0 "register_operand" "=*f,d") |
ba8ab355 JW |
1467 | (float_extend:DF (match_operand:SF 1 "fp_arith_operand" "dGH,fGH")))] |
1468 | "TARGET_NUMERICS" | |
1469 | "@ | |
1470 | movr %1,%0 | |
1471 | movrl %1,%0" | |
1472 | [(set_attr "type" "fpmove")]) | |
1473 | ||
1474 | (define_insn "truncdfsf2" | |
1475 | [(set (match_operand:SF 0 "register_operand" "=d") | |
1476 | (float_truncate:SF | |
1477 | (match_operand:DF 1 "fp_arith_operand" "fGH")))] | |
1478 | "TARGET_NUMERICS" | |
1479 | "movr %1,%0" | |
1480 | [(set_attr "type" "fpmove")]) | |
1481 | ||
1482 | ;; Conversion between fixed point and floating point. | |
1483 | ||
1484 | (define_insn "floatsidf2" | |
1485 | [(set (match_operand:DF 0 "register_operand" "=f") | |
1486 | (float:DF (match_operand:SI 1 "register_operand" "d")))] | |
1487 | "TARGET_NUMERICS" | |
1488 | "cvtir %1,%0" | |
1489 | [(set_attr "type" "fpcvt")]) | |
1490 | ||
1491 | (define_insn "floatsisf2" | |
bc9c7a36 | 1492 | [(set (match_operand:SF 0 "register_operand" "=d*f") |
ba8ab355 JW |
1493 | (float:SF (match_operand:SI 1 "register_operand" "d")))] |
1494 | "TARGET_NUMERICS" | |
1495 | "cvtir %1,%0" | |
1496 | [(set_attr "type" "fpcvt")]) | |
1497 | ||
1498 | ;; Convert a float to an actual integer. | |
1499 | ;; Truncation is performed as part of the conversion. | |
1500 | ;; The i960 requires conversion from DFmode to DImode to make | |
1501 | ;; unsigned conversions work properly. | |
1502 | ||
1503 | (define_insn "fixuns_truncdfdi2" | |
1504 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1505 | (unsigned_fix:DI (fix:DF (match_operand:DF 1 "fp_arith_operand" "fGH"))))] | |
1506 | "TARGET_NUMERICS" | |
1507 | "cvtzril %1,%0" | |
1508 | [(set_attr "type" "fpcvt")]) | |
1509 | ||
1510 | (define_insn "fixuns_truncsfdi2" | |
1511 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1512 | (unsigned_fix:DI (fix:SF (match_operand:SF 1 "fp_arith_operand" "fGH"))))] | |
1513 | "TARGET_NUMERICS" | |
1514 | "cvtzril %1,%0" | |
1515 | [(set_attr "type" "fpcvt")]) | |
1516 | ||
1517 | (define_insn "fix_truncdfsi2" | |
1518 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1519 | (fix:SI (fix:DF (match_operand:DF 1 "fp_arith_operand" "fGH"))))] | |
1520 | "TARGET_NUMERICS" | |
1521 | "cvtzri %1,%0" | |
1522 | [(set_attr "type" "fpcvt")]) | |
1523 | ||
1524 | (define_expand "fixuns_truncdfsi2" | |
1525 | [(set (match_operand:SI 0 "register_operand" "") | |
1526 | (unsigned_fix:SI (fix:DF (match_operand:DF 1 "fp_arith_operand" ""))))] | |
1527 | "TARGET_NUMERICS" | |
1528 | " | |
1529 | { | |
1530 | rtx temp = gen_reg_rtx (DImode); | |
c5c76735 JL |
1531 | emit_insn (gen_rtx_SET (VOIDmode, temp, |
1532 | gen_rtx_UNSIGNED_FIX (DImode, | |
1533 | gen_rtx_FIX (DFmode, | |
1534 | operands[1])))); | |
1535 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], | |
1536 | gen_rtx_SUBREG (SImode, temp, 0))); | |
ba8ab355 JW |
1537 | DONE; |
1538 | }") | |
1539 | ||
1540 | (define_insn "fix_truncsfsi2" | |
1541 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1542 | (fix:SI (fix:SF (match_operand:SF 1 "fp_arith_operand" "dfGH"))))] | |
1543 | "TARGET_NUMERICS" | |
1544 | "cvtzri %1,%0" | |
1545 | [(set_attr "type" "fpcvt")]) | |
1546 | ||
1547 | (define_expand "fixuns_truncsfsi2" | |
1548 | [(set (match_operand:SI 0 "register_operand" "") | |
1549 | (unsigned_fix:SI (fix:SF (match_operand:SF 1 "fp_arith_operand" ""))))] | |
1550 | "TARGET_NUMERICS" | |
1551 | " | |
1552 | { | |
1553 | rtx temp = gen_reg_rtx (DImode); | |
c5c76735 JL |
1554 | emit_insn (gen_rtx_SET (VOIDmode, temp, |
1555 | gen_rtx_UNSIGNED_FIX (DImode, | |
1556 | gen_rtx_FIX (SFmode, | |
1557 | operands[1])))); | |
1558 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], | |
1559 | gen_rtx_SUBREG (SImode, temp, 0))); | |
ba8ab355 JW |
1560 | DONE; |
1561 | }") | |
1562 | \f | |
1563 | ;; Arithmetic instructions. | |
1564 | ||
1565 | (define_insn "subsi3" | |
1566 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1567 | (minus:SI (match_operand:SI 1 "arith_operand" "dI") | |
1568 | (match_operand:SI 2 "arith_operand" "dI")))] | |
1569 | "" | |
1570 | "subo %2,%1,%0") | |
1571 | ||
1572 | ;; Try to generate an lda instruction when it would be faster than an | |
1573 | ;; add instruction. | |
1574 | ;; Some assemblers apparently won't accept two addresses added together. | |
1575 | ||
292099cc JW |
1576 | ;; ??? The condition should be improved to reject the case of two |
1577 | ;; symbolic constants. | |
1578 | ||
ba8ab355 JW |
1579 | (define_insn "" |
1580 | [(set (match_operand:SI 0 "register_operand" "=d,d,d") | |
1581 | (plus:SI (match_operand:SI 1 "arith32_operand" "%dn,i,dn") | |
1582 | (match_operand:SI 2 "arith32_operand" "dn,dn,i")))] | |
1583 | "(TARGET_C_SERIES) && (CONSTANT_P (operands[1]) || CONSTANT_P (operands[2]))" | |
1584 | "* | |
1585 | { | |
1586 | if (GET_CODE (operands[1]) == CONST_INT) | |
1587 | { | |
1588 | rtx tmp = operands[1]; | |
1589 | operands[1] = operands[2]; | |
1590 | operands[2] = tmp; | |
1591 | } | |
1592 | if (GET_CODE (operands[2]) == CONST_INT | |
1593 | && GET_CODE (operands[1]) == REG | |
1594 | && i960_last_insn_type != I_TYPE_REG) | |
1595 | { | |
1596 | if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) > -32) | |
1597 | return \"subo %n2,%1,%0\"; | |
1598 | else if (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32) | |
1599 | return \"addo %1,%2,%0\"; | |
1600 | } | |
292099cc JW |
1601 | /* Non-canonical results (op1 == const, op2 != const) have been seen |
1602 | in reload output when both operands were symbols before reload, so | |
1603 | we deal with it here. This may be a fault of the constraints above. */ | |
ba8ab355 | 1604 | if (CONSTANT_P (operands[1])) |
292099cc JW |
1605 | { |
1606 | if (CONSTANT_P (operands[2])) | |
1607 | return \"lda %1+%2,%0\"; | |
1608 | else | |
1609 | return \"lda %1(%2),%0\"; | |
1610 | } | |
ba8ab355 JW |
1611 | return \"lda %2(%1),%0\"; |
1612 | }") | |
1613 | ||
1614 | (define_insn "addsi3" | |
1615 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1616 | (plus:SI (match_operand:SI 1 "signed_arith_operand" "%dI") | |
1617 | (match_operand:SI 2 "signed_arith_operand" "dIK")))] | |
1618 | "" | |
1619 | "* | |
1620 | { | |
4ec74aeb | 1621 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) |
ba8ab355 JW |
1622 | return \"subo %n2,%1,%0\"; |
1623 | if (i960_bypass (insn, operands[1], operands[2], 0)) | |
1624 | return \"addo %2,%1,%0\"; | |
1625 | return \"addo %1,%2,%0\"; | |
1626 | }") | |
1627 | ||
1628 | (define_insn "mulsi3" | |
1629 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1630 | (mult:SI (match_operand:SI 1 "arith_operand" "%dI") | |
1631 | (match_operand:SI 2 "arith_operand" "dI")))] | |
1632 | "" | |
1633 | "* | |
1634 | { | |
1635 | if (i960_bypass (insn, operands[1], operands[2], 0)) | |
1636 | return \"mulo %2,%1,%0\"; | |
1637 | return \"mulo %1,%2,%0\"; | |
1638 | }" | |
1639 | [(set_attr "type" "mult")]) | |
1640 | ||
4ec74aeb JW |
1641 | (define_insn "umulsidi3" |
1642 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1643 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
1644 | (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))] | |
1645 | "" | |
1646 | "* | |
9116497e JW |
1647 | { |
1648 | if (i960_bypass (insn, operands[1], operands[2], 0)) | |
1649 | return \"emul %2,%1,%0\"; | |
1650 | return \"emul %1,%2,%0\"; | |
1651 | }" | |
1652 | [(set_attr "type" "mult")]) | |
1653 | ||
1654 | (define_insn "" | |
1655 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1656 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%d")) | |
21d90119 | 1657 | (match_operand:SI 2 "literal" "I")))] |
9116497e JW |
1658 | "" |
1659 | "* | |
4ec74aeb JW |
1660 | { |
1661 | if (i960_bypass (insn, operands[1], operands[2], 0)) | |
1662 | return \"emul %2,%1,%0\"; | |
1663 | return \"emul %1,%2,%0\"; | |
1664 | }" | |
1665 | [(set_attr "type" "mult")]) | |
1666 | ||
ba8ab355 JW |
1667 | ;; This goes after the move/add/sub/mul instructions |
1668 | ;; because those instructions are better when they apply. | |
1669 | ||
1670 | (define_insn "" | |
1671 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1672 | (match_operand:SI 1 "address_operand" "p"))] | |
1673 | "" | |
1674 | "lda %a1,%0" | |
1675 | [(set_attr "type" "load")]) | |
1676 | ||
1677 | ;; This will never be selected because of an "optimization" that GCC does. | |
1678 | ;; It always converts divides by a power of 2 into a sequence of instructions | |
1679 | ;; that does a right shift, and then corrects the result if it was negative. | |
1680 | ||
1681 | ;; (define_insn "" | |
1682 | ;; [(set (match_operand:SI 0 "register_operand" "=d") | |
1683 | ;; (div:SI (match_operand:SI 1 "arith_operand" "dI") | |
1684 | ;; (match_operand:SI 2 "power2_operand" "nI")))] | |
1685 | ;; "" | |
1686 | ;; "*{ | |
3a598fbe | 1687 | ;; operands[2] = GEN_INT (bitpos (INTVAL (operands[2]))); |
ba8ab355 JW |
1688 | ;; return \"shrdi %2,%1,%0\"; |
1689 | ;; }" | |
1690 | ||
1691 | (define_insn "divsi3" | |
1692 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1693 | (div:SI (match_operand:SI 1 "arith_operand" "dI") | |
1694 | (match_operand:SI 2 "arith_operand" "dI")))] | |
1695 | "" | |
1696 | "divi %2,%1,%0" | |
1697 | [(set_attr "type" "div")]) | |
1698 | ||
1699 | (define_insn "udivsi3" | |
1700 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1701 | (udiv:SI (match_operand:SI 1 "arith_operand" "dI") | |
1702 | (match_operand:SI 2 "arith_operand" "dI")))] | |
1703 | "" | |
1704 | "divo %2,%1,%0" | |
1705 | [(set_attr "type" "div")]) | |
1706 | ||
1707 | ;; We must use `remi' not `modi' here, to ensure that `%' has the effects | |
1708 | ;; specified by the ANSI C standard. | |
1709 | ||
1710 | (define_insn "modsi3" | |
1711 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1712 | (mod:SI (match_operand:SI 1 "arith_operand" "dI") | |
1713 | (match_operand:SI 2 "arith_operand" "dI")))] | |
1714 | "" | |
1715 | "remi %2,%1,%0" | |
1716 | [(set_attr "type" "div")]) | |
1717 | ||
1718 | (define_insn "umodsi3" | |
1719 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1720 | (umod:SI (match_operand:SI 1 "arith_operand" "dI") | |
1721 | (match_operand:SI 2 "arith_operand" "dI")))] | |
1722 | "" | |
1723 | "remo %2,%1,%0" | |
1724 | [(set_attr "type" "div")]) | |
1725 | ||
1726 | ;; And instructions (with complement also). | |
1727 | ||
1728 | (define_insn "andsi3" | |
1729 | [(set (match_operand:SI 0 "register_operand" "=d") | |
5d17176f TG |
1730 | (and:SI (match_operand:SI 1 "register_operand" "%d") |
1731 | (match_operand:SI 2 "logic_operand" "dIM")))] | |
ba8ab355 JW |
1732 | "" |
1733 | "* | |
1734 | { | |
5d17176f TG |
1735 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) |
1736 | return \"andnot %C2,%1,%0\"; | |
ba8ab355 JW |
1737 | if (i960_bypass (insn, operands[1], operands[2], 0)) |
1738 | return \"and %2,%1,%0\"; | |
1739 | return \"and %1,%2,%0\"; | |
1740 | }") | |
1741 | ||
1742 | (define_insn "" | |
1743 | [(set (match_operand:SI 0 "register_operand" "=d") | |
5d17176f TG |
1744 | (and:SI (match_operand:SI 1 "arith_operand" "dI") |
1745 | (match_operand:SI 2 "cmplpower2_operand" "n")))] | |
ba8ab355 JW |
1746 | "" |
1747 | "* | |
1748 | { | |
3a598fbe | 1749 | operands[2] = GEN_INT (bitpos (~INTVAL (operands[2]))); |
5d17176f TG |
1750 | return \"clrbit %2,%1,%0\"; |
1751 | }") | |
1752 | ||
1753 | (define_insn "" | |
1754 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1755 | (and:SI (not:SI (match_operand:SI 1 "register_operand" "d")) | |
1756 | (match_operand:SI 2 "logic_operand" "dIM")))] | |
1757 | "" | |
1758 | "* | |
1759 | { | |
1760 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) | |
1761 | return \"nor %C2,%1,%0\"; | |
ba8ab355 JW |
1762 | if (i960_bypass (insn, operands[1], operands[2], 0)) |
1763 | return \"notand %2,%1,%0\"; | |
1764 | return \"andnot %1,%2,%0\"; | |
1765 | }") | |
1766 | ||
1767 | (define_insn "" | |
1768 | [(set (match_operand:SI 0 "register_operand" "=d") | |
5d17176f TG |
1769 | (ior:SI (not:SI (match_operand:SI 1 "register_operand" "%d")) |
1770 | (not:SI (match_operand:SI 2 "register_operand" "d"))))] | |
ba8ab355 JW |
1771 | "" |
1772 | "* | |
1773 | { | |
1774 | if (i960_bypass (insn, operands[1], operands[2], 0)) | |
1775 | return \"nand %2,%1,%0\"; | |
1776 | return \"nand %1,%2,%0\"; | |
1777 | }") | |
1778 | ||
5d17176f TG |
1779 | (define_insn "iorsi3" |
1780 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1781 | (ior:SI (match_operand:SI 1 "register_operand" "%d") | |
1782 | (match_operand:SI 2 "logic_operand" "dIM")))] | |
1783 | "" | |
1784 | "* | |
1785 | { | |
1786 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) | |
1787 | return \"ornot %C2,%1,%0\"; | |
1788 | if (i960_bypass (insn, operands[1], operands[2], 0)) | |
1789 | return \"or %2,%1,%0\"; | |
1790 | return \"or %1,%2,%0\"; | |
1791 | }") | |
1792 | ||
ba8ab355 JW |
1793 | (define_insn "" |
1794 | [(set (match_operand:SI 0 "register_operand" "=d") | |
5d17176f | 1795 | (ior:SI (match_operand:SI 1 "register_operand" "d") |
4ec74aeb | 1796 | (match_operand:SI 2 "power2_operand" "n")))] |
ba8ab355 JW |
1797 | "" |
1798 | "* | |
1799 | { | |
3a598fbe | 1800 | operands[2] = GEN_INT (bitpos (INTVAL (operands[2]))); |
4ec74aeb | 1801 | return \"setbit %2,%1,%0\"; |
ba8ab355 JW |
1802 | }") |
1803 | ||
1804 | (define_insn "" | |
1805 | [(set (match_operand:SI 0 "register_operand" "=d") | |
5d17176f TG |
1806 | (ior:SI (not:SI (match_operand:SI 1 "register_operand" "d")) |
1807 | (match_operand:SI 2 "logic_operand" "dIM")))] | |
4ec74aeb | 1808 | "" |
5d17176f TG |
1809 | "* |
1810 | { | |
1811 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) | |
1812 | return \"nand %C2,%1,%0\"; | |
1813 | if (i960_bypass (insn, operands[1], operands[2], 0)) | |
1814 | return \"notor %2,%1,%0\"; | |
1815 | return \"ornot %1,%2,%0\"; | |
1816 | }") | |
4ec74aeb JW |
1817 | |
1818 | (define_insn "" | |
1819 | [(set (match_operand:SI 0 "register_operand" "=d") | |
5d17176f TG |
1820 | (and:SI (not:SI (match_operand:SI 1 "register_operand" "%d")) |
1821 | (not:SI (match_operand:SI 2 "register_operand" "d"))))] | |
ba8ab355 JW |
1822 | "" |
1823 | "* | |
1824 | { | |
5d17176f TG |
1825 | if (i960_bypass (insn, operands[1], operands[2], 0)) |
1826 | return \"nor %2,%1,%0\"; | |
1827 | return \"nor %1,%2,%0\"; | |
ba8ab355 JW |
1828 | }") |
1829 | ||
5d17176f | 1830 | (define_insn "xorsi3" |
ba8ab355 | 1831 | [(set (match_operand:SI 0 "register_operand" "=d") |
5d17176f TG |
1832 | (xor:SI (match_operand:SI 1 "register_operand" "%d") |
1833 | (match_operand:SI 2 "logic_operand" "dIM")))] | |
3c9b2130 | 1834 | "" |
5d17176f TG |
1835 | "* |
1836 | { | |
1837 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) | |
1838 | return \"xnor %C2,%1,%0\"; | |
1839 | if (i960_bypass (insn, operands[1], operands[2], 0)) | |
1840 | return \"xor %2,%1,%0\"; | |
1841 | return \"xor %1,%2,%0\"; | |
1842 | }") | |
3c9b2130 | 1843 | |
4ec74aeb JW |
1844 | (define_insn "" |
1845 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1846 | (xor:SI (match_operand:SI 1 "arith_operand" "dI") | |
1847 | (match_operand:SI 2 "power2_operand" "n")))] | |
1848 | "" | |
ba8ab355 JW |
1849 | "* |
1850 | { | |
3a598fbe | 1851 | operands[2] = GEN_INT (bitpos (INTVAL (operands[2]))); |
4ec74aeb | 1852 | return \"notbit %2,%1,%0\"; |
ba8ab355 JW |
1853 | }") |
1854 | ||
4ec74aeb JW |
1855 | (define_insn "" |
1856 | [(set (match_operand:SI 0 "register_operand" "=d") | |
5d17176f TG |
1857 | (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%d") |
1858 | (match_operand:SI 2 "register_operand" "d"))))] | |
ba8ab355 JW |
1859 | "" |
1860 | "* | |
1861 | { | |
1862 | if (i960_bypass (insn, operands[1], operands[2], 0)) | |
5d17176f TG |
1863 | return \"xnor %2,%1,%0\"; |
1864 | return \"xnor %2,%1,%0\"; | |
ba8ab355 JW |
1865 | }") |
1866 | ||
1867 | (define_insn "" | |
1868 | [(set (match_operand:SI 0 "register_operand" "=d") | |
5d17176f TG |
1869 | (ior:SI (ashift:SI (const_int 1) |
1870 | (match_operand:SI 1 "register_operand" "d")) | |
ba8ab355 JW |
1871 | (match_operand:SI 2 "arith_operand" "dI")))] |
1872 | "" | |
5d17176f | 1873 | "setbit %1,%2,%0") |
ba8ab355 | 1874 | |
5d17176f | 1875 | ;; (not (ashift 1 reg)) canonicalizes to (rotate -2 reg) |
ba8ab355 JW |
1876 | (define_insn "" |
1877 | [(set (match_operand:SI 0 "register_operand" "=d") | |
5d17176f TG |
1878 | (and:SI (rotate:SI (const_int -2) |
1879 | (match_operand:SI 1 "register_operand" "d")) | |
1880 | (match_operand:SI 2 "register_operand" "d")))] | |
ba8ab355 | 1881 | "" |
5d17176f | 1882 | "clrbit %1,%2,%0") |
ba8ab355 | 1883 | |
5d17176f TG |
1884 | ;; The above pattern canonicalizes to this when both the input and output |
1885 | ;; are the same pseudo-register. | |
1886 | (define_insn "" | |
c243fc1b | 1887 | [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d") |
5d17176f TG |
1888 | (const_int 1) |
1889 | (match_operand:SI 1 "register_operand" "d")) | |
1890 | (const_int 0))] | |
ba8ab355 | 1891 | "" |
5d17176f | 1892 | "clrbit %1,%0,%0") |
ba8ab355 JW |
1893 | |
1894 | (define_insn "" | |
1895 | [(set (match_operand:SI 0 "register_operand" "=d") | |
5d17176f TG |
1896 | (xor:SI (ashift:SI (const_int 1) |
1897 | (match_operand:SI 1 "register_operand" "d")) | |
1898 | (match_operand:SI 2 "arith_operand" "dI")))] | |
ba8ab355 | 1899 | "" |
5d17176f | 1900 | "notbit %1,%2,%0") |
ba8ab355 JW |
1901 | |
1902 | (define_insn "negsi2" | |
1903 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1904 | (neg:SI (match_operand:SI 1 "arith_operand" "dI")))] | |
1905 | "" | |
1906 | "subo %1,0,%0" | |
1907 | [(set_attr "length" "1")]) | |
1908 | ||
1909 | (define_insn "one_cmplsi2" | |
1910 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1911 | (not:SI (match_operand:SI 1 "arith_operand" "dI")))] | |
1912 | "" | |
1913 | "not %1,%0" | |
1914 | [(set_attr "length" "1")]) | |
1915 | \f | |
1916 | ;; Floating point arithmetic instructions. | |
1917 | ||
1918 | (define_insn "adddf3" | |
bc9c7a36 | 1919 | [(set (match_operand:DF 0 "register_operand" "=d*f") |
ba8ab355 JW |
1920 | (plus:DF (match_operand:DF 1 "fp_arith_operand" "%rGH") |
1921 | (match_operand:DF 2 "fp_arith_operand" "rGH")))] | |
1922 | "TARGET_NUMERICS" | |
1923 | "addrl %1,%2,%0" | |
1924 | [(set_attr "type" "fpadd")]) | |
1925 | ||
1926 | (define_insn "addsf3" | |
bc9c7a36 | 1927 | [(set (match_operand:SF 0 "register_operand" "=d*f") |
ba8ab355 JW |
1928 | (plus:SF (match_operand:SF 1 "fp_arith_operand" "%rGH") |
1929 | (match_operand:SF 2 "fp_arith_operand" "rGH")))] | |
1930 | "TARGET_NUMERICS" | |
1931 | "addr %1,%2,%0" | |
1932 | [(set_attr "type" "fpadd")]) | |
1933 | ||
1934 | ||
1935 | (define_insn "subdf3" | |
bc9c7a36 | 1936 | [(set (match_operand:DF 0 "register_operand" "=d*f") |
ba8ab355 JW |
1937 | (minus:DF (match_operand:DF 1 "fp_arith_operand" "rGH") |
1938 | (match_operand:DF 2 "fp_arith_operand" "rGH")))] | |
1939 | "TARGET_NUMERICS" | |
1940 | "subrl %2,%1,%0" | |
1941 | [(set_attr "type" "fpadd")]) | |
1942 | ||
1943 | (define_insn "subsf3" | |
bc9c7a36 | 1944 | [(set (match_operand:SF 0 "register_operand" "=d*f") |
ba8ab355 JW |
1945 | (minus:SF (match_operand:SF 1 "fp_arith_operand" "rGH") |
1946 | (match_operand:SF 2 "fp_arith_operand" "rGH")))] | |
1947 | "TARGET_NUMERICS" | |
1948 | "subr %2,%1,%0" | |
1949 | [(set_attr "type" "fpadd")]) | |
1950 | ||
1951 | ||
1952 | (define_insn "muldf3" | |
bc9c7a36 | 1953 | [(set (match_operand:DF 0 "register_operand" "=d*f") |
4ec74aeb | 1954 | (mult:DF (match_operand:DF 1 "fp_arith_operand" "%rGH") |
ba8ab355 JW |
1955 | (match_operand:DF 2 "fp_arith_operand" "rGH")))] |
1956 | "TARGET_NUMERICS" | |
1957 | "mulrl %1,%2,%0" | |
1958 | [(set_attr "type" "fpmul")]) | |
1959 | ||
1960 | (define_insn "mulsf3" | |
bc9c7a36 | 1961 | [(set (match_operand:SF 0 "register_operand" "=d*f") |
4ec74aeb | 1962 | (mult:SF (match_operand:SF 1 "fp_arith_operand" "%rGH") |
ba8ab355 JW |
1963 | (match_operand:SF 2 "fp_arith_operand" "rGH")))] |
1964 | "TARGET_NUMERICS" | |
1965 | "mulr %1,%2,%0" | |
1966 | [(set_attr "type" "fpmul")]) | |
1967 | ||
1968 | ||
1969 | (define_insn "divdf3" | |
bc9c7a36 | 1970 | [(set (match_operand:DF 0 "register_operand" "=d*f") |
ba8ab355 JW |
1971 | (div:DF (match_operand:DF 1 "fp_arith_operand" "rGH") |
1972 | (match_operand:DF 2 "fp_arith_operand" "rGH")))] | |
1973 | "TARGET_NUMERICS" | |
1974 | "divrl %2,%1,%0" | |
1975 | [(set_attr "type" "fpdiv")]) | |
1976 | ||
1977 | (define_insn "divsf3" | |
bc9c7a36 | 1978 | [(set (match_operand:SF 0 "register_operand" "=d*f") |
ba8ab355 JW |
1979 | (div:SF (match_operand:SF 1 "fp_arith_operand" "rGH") |
1980 | (match_operand:SF 2 "fp_arith_operand" "rGH")))] | |
1981 | "TARGET_NUMERICS" | |
1982 | "divr %2,%1,%0" | |
1983 | [(set_attr "type" "fpdiv")]) | |
1984 | ||
1985 | (define_insn "negdf2" | |
bc9c7a36 | 1986 | [(set (match_operand:DF 0 "register_operand" "=d,d*f") |
ba8ab355 JW |
1987 | (neg:DF (match_operand:DF 1 "register_operand" "d,r")))] |
1988 | "" | |
1989 | "* | |
1990 | { | |
1991 | if (which_alternative == 0) | |
1992 | { | |
1993 | if (REGNO (operands[0]) == REGNO (operands[1])) | |
1994 | return \"notbit 31,%D1,%D0\"; | |
1995 | return \"mov %1,%0\;notbit 31,%D1,%D0\"; | |
1996 | } | |
1997 | return \"subrl %1,0f0.0,%0\"; | |
1998 | }" | |
1999 | [(set_attr "type" "fpadd")]) | |
2000 | ||
2001 | (define_insn "negsf2" | |
bc9c7a36 | 2002 | [(set (match_operand:SF 0 "register_operand" "=d,d*f") |
ba8ab355 JW |
2003 | (neg:SF (match_operand:SF 1 "register_operand" "d,r")))] |
2004 | "" | |
2005 | "@ | |
2006 | notbit 31,%1,%0 | |
2007 | subr %1,0f0.0,%0" | |
2008 | [(set_attr "type" "fpadd")]) | |
2009 | ||
2010 | ;;; The abs patterns also work even if the target machine doesn't have | |
2011 | ;;; floating point, because in that case dstreg and srcreg will always be | |
2012 | ;;; less than 32. | |
2013 | ||
2014 | (define_insn "absdf2" | |
bc9c7a36 | 2015 | [(set (match_operand:DF 0 "register_operand" "=d*f") |
ba8ab355 JW |
2016 | (abs:DF (match_operand:DF 1 "register_operand" "df")))] |
2017 | "" | |
2018 | "* | |
2019 | { | |
2020 | int dstreg = REGNO (operands[0]); | |
2021 | int srcreg = REGNO (operands[1]); | |
2022 | ||
2023 | if (dstreg < 32) | |
2024 | { | |
2025 | if (srcreg < 32) | |
2026 | { | |
2027 | if (dstreg != srcreg) | |
2028 | output_asm_insn (\"mov %1,%0\", operands); | |
2029 | return \"clrbit 31,%D1,%D0\"; | |
2030 | } | |
2031 | /* Src is an fp reg. */ | |
2032 | return \"movrl %1,%0\;clrbit 31,%D1,%D0\"; | |
2033 | } | |
2034 | if (srcreg >= 32) | |
2035 | return \"cpysre %1,0f0.0,%0\"; | |
2036 | return \"movrl %1,%0\;cpysre %0,0f0.0,%0\"; | |
2037 | }" | |
2038 | [(set_attr "type" "multi")]) | |
2039 | ||
2040 | (define_insn "abssf2" | |
bc9c7a36 | 2041 | [(set (match_operand:SF 0 "register_operand" "=d*f") |
ba8ab355 JW |
2042 | (abs:SF (match_operand:SF 1 "register_operand" "df")))] |
2043 | "" | |
2044 | "* | |
2045 | { | |
2046 | int dstreg = REGNO (operands[0]); | |
2047 | int srcreg = REGNO (operands[1]); | |
2048 | ||
2049 | if (dstreg < 32 && srcreg < 32) | |
2050 | return \"clrbit 31,%1,%0\"; | |
2051 | ||
2052 | if (dstreg >= 32 && srcreg >= 32) | |
2053 | return \"cpysre %1,0f0.0,%0\"; | |
2054 | ||
2055 | if (dstreg < 32) | |
2056 | return \"movr %1,%0\;clrbit 31,%0,%0\"; | |
2057 | ||
2058 | return \"movr %1,%0\;cpysre %0,0f0.0,%0\"; | |
2059 | }" | |
2060 | [(set_attr "type" "multi")]) | |
2061 | \f | |
2062 | ;; Tetra (16 byte) float support. | |
2063 | ||
87cb2a87 | 2064 | (define_expand "cmptf" |
ba8ab355 | 2065 | [(set (reg:CC 36) |
87cb2a87 RH |
2066 | (compare:CC (match_operand:TF 0 "register_operand" "") |
2067 | (match_operand:TF 1 "nonmemory_operand" "")))] | |
ba8ab355 | 2068 | "TARGET_NUMERICS" |
34a28d1c TG |
2069 | " |
2070 | { | |
2071 | i960_compare_op0 = operands[0]; | |
2072 | i960_compare_op1 = operands[1]; | |
2073 | DONE; | |
2074 | }") | |
2075 | ||
2076 | (define_insn "" | |
2077 | [(set (reg:CC 36) | |
87cb2a87 RH |
2078 | (compare:CC (match_operand:TF 0 "register_operand" "f") |
2079 | (match_operand:TF 1 "nonmemory_operand" "fGH")))] | |
34a28d1c TG |
2080 | "TARGET_NUMERICS" |
2081 | "cmpr %0,%1" | |
ba8ab355 JW |
2082 | [(set_attr "type" "fpcc")]) |
2083 | ||
87cb2a87 RH |
2084 | (define_expand "movtf" |
2085 | [(set (match_operand:TF 0 "general_operand" "") | |
2086 | (match_operand:TF 1 "fpmove_src_operand" ""))] | |
ba8ab355 JW |
2087 | "" |
2088 | " | |
2089 | { | |
87cb2a87 | 2090 | if (emit_move_sequence (operands, TFmode)) |
ba8ab355 JW |
2091 | DONE; |
2092 | }") | |
2093 | ||
2094 | (define_insn "" | |
87cb2a87 RH |
2095 | [(set (match_operand:TF 0 "general_operand" "=r,f,d,d,m") |
2096 | (match_operand:TF 1 "fpmove_src_operand" "r,GH,F,m,d"))] | |
2097 | "register_operand (operands[0], TFmode) | |
2098 | || register_operand (operands[1], TFmode)" | |
ba8ab355 JW |
2099 | "* |
2100 | { | |
2101 | switch (which_alternative) | |
2102 | { | |
2103 | case 0: | |
2104 | if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) | |
2105 | return \"movre %1,%0\"; | |
2106 | else | |
2107 | return \"movq %1,%0\"; | |
2108 | case 1: | |
2109 | return \"movre %1,%0\"; | |
2110 | case 2: | |
2111 | return i960_output_ldconst (operands[0], operands[1]); | |
2112 | case 3: | |
34a28d1c | 2113 | return \"ldt %1,%0\"; |
ba8ab355 | 2114 | case 4: |
34a28d1c | 2115 | return \"stt %1,%0\"; |
1943c2c1 KG |
2116 | default: |
2117 | abort(); | |
ba8ab355 JW |
2118 | } |
2119 | }" | |
2120 | [(set_attr "type" "move,move,load,fpload,fpstore")]) | |
2121 | ||
87cb2a87 RH |
2122 | (define_insn "extendsftf2" |
2123 | [(set (match_operand:TF 0 "register_operand" "=f,d") | |
2124 | (float_extend:TF | |
ba8ab355 JW |
2125 | (match_operand:SF 1 "register_operand" "d,f")))] |
2126 | "TARGET_NUMERICS" | |
2127 | "@ | |
2128 | movr %1,%0 | |
2129 | movre %1,%0" | |
2130 | [(set_attr "type" "fpmove")]) | |
2131 | ||
87cb2a87 RH |
2132 | (define_insn "extenddftf2" |
2133 | [(set (match_operand:TF 0 "register_operand" "=f,d") | |
2134 | (float_extend:TF | |
ba8ab355 JW |
2135 | (match_operand:DF 1 "register_operand" "d,f")))] |
2136 | "TARGET_NUMERICS" | |
2137 | "@ | |
2138 | movrl %1,%0 | |
2139 | movre %1,%0" | |
2140 | [(set_attr "type" "fpmove")]) | |
2141 | ||
87cb2a87 | 2142 | (define_insn "trunctfdf2" |
ba8ab355 JW |
2143 | [(set (match_operand:DF 0 "register_operand" "=d") |
2144 | (float_truncate:DF | |
87cb2a87 | 2145 | (match_operand:TF 1 "register_operand" "f")))] |
ba8ab355 JW |
2146 | "TARGET_NUMERICS" |
2147 | "movrl %1,%0" | |
2148 | [(set_attr "type" "fpmove")]) | |
2149 | ||
87cb2a87 | 2150 | (define_insn "trunctfsf2" |
ba8ab355 JW |
2151 | [(set (match_operand:SF 0 "register_operand" "=d") |
2152 | (float_truncate:SF | |
87cb2a87 | 2153 | (match_operand:TF 1 "register_operand" "f")))] |
ba8ab355 JW |
2154 | "TARGET_NUMERICS" |
2155 | "movr %1,%0" | |
2156 | [(set_attr "type" "fpmove")]) | |
2157 | ||
87cb2a87 RH |
2158 | (define_insn "floatsitf2" |
2159 | [(set (match_operand:TF 0 "register_operand" "=f") | |
2160 | (float:TF (match_operand:SI 1 "register_operand" "d")))] | |
ba8ab355 JW |
2161 | "TARGET_NUMERICS" |
2162 | "cvtir %1,%0" | |
2163 | [(set_attr "type" "fpcvt")]) | |
2164 | ||
87cb2a87 | 2165 | (define_insn "fix_trunctfsi2" |
ba8ab355 | 2166 | [(set (match_operand:SI 0 "register_operand" "=d") |
87cb2a87 | 2167 | (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))] |
ba8ab355 JW |
2168 | "TARGET_NUMERICS" |
2169 | "cvtzri %1,%0" | |
2170 | [(set_attr "type" "fpcvt")]) | |
2171 | ||
87cb2a87 | 2172 | (define_insn "fixuns_trunctfsi2" |
ba8ab355 | 2173 | [(set (match_operand:SI 0 "register_operand" "=d") |
87cb2a87 | 2174 | (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))] |
ba8ab355 JW |
2175 | "TARGET_NUMERICS" |
2176 | "cvtzri %1,%0" | |
2177 | [(set_attr "type" "fpcvt")]) | |
2178 | ||
87cb2a87 RH |
2179 | (define_insn "addtf3" |
2180 | [(set (match_operand:TF 0 "register_operand" "=f") | |
2181 | (plus:TF (match_operand:TF 1 "nonmemory_operand" "%fGH") | |
2182 | (match_operand:TF 2 "nonmemory_operand" "fGH")))] | |
ba8ab355 JW |
2183 | "TARGET_NUMERICS" |
2184 | "addr %1,%2,%0" | |
2185 | [(set_attr "type" "fpadd")]) | |
2186 | ||
87cb2a87 RH |
2187 | (define_insn "subtf3" |
2188 | [(set (match_operand:TF 0 "register_operand" "=f") | |
2189 | (minus:TF (match_operand:TF 1 "nonmemory_operand" "fGH") | |
2190 | (match_operand:TF 2 "nonmemory_operand" "fGH")))] | |
ba8ab355 JW |
2191 | "TARGET_NUMERICS" |
2192 | "subr %2,%1,%0" | |
2193 | [(set_attr "type" "fpadd")]) | |
2194 | ||
87cb2a87 RH |
2195 | (define_insn "multf3" |
2196 | [(set (match_operand:TF 0 "register_operand" "=f") | |
2197 | (mult:TF (match_operand:TF 1 "nonmemory_operand" "%fGH") | |
2198 | (match_operand:TF 2 "nonmemory_operand" "fGH")))] | |
ba8ab355 JW |
2199 | "TARGET_NUMERICS" |
2200 | "mulr %1,%2,%0" | |
2201 | [(set_attr "type" "fpmul")]) | |
2202 | ||
87cb2a87 RH |
2203 | (define_insn "divtf3" |
2204 | [(set (match_operand:TF 0 "register_operand" "=f") | |
2205 | (div:TF (match_operand:TF 1 "nonmemory_operand" "fGH") | |
2206 | (match_operand:TF 2 "nonmemory_operand" "fGH")))] | |
ba8ab355 JW |
2207 | "TARGET_NUMERICS" |
2208 | "divr %2,%1,%0" | |
2209 | [(set_attr "type" "fpdiv")]) | |
2210 | ||
87cb2a87 RH |
2211 | (define_insn "negtf2" |
2212 | [(set (match_operand:TF 0 "register_operand" "=f") | |
2213 | (neg:TF (match_operand:TF 1 "register_operand" "f")))] | |
ba8ab355 JW |
2214 | "TARGET_NUMERICS" |
2215 | "subr %1,0f0.0,%0" | |
2216 | [(set_attr "type" "fpadd")]) | |
2217 | ||
87cb2a87 RH |
2218 | (define_insn "abstf2" |
2219 | [(set (match_operand:TF 0 "register_operand" "=f") | |
2220 | (abs:TF (match_operand:TF 1 "register_operand" "f")))] | |
ba8ab355 JW |
2221 | "(TARGET_NUMERICS)" |
2222 | "cpysre %1,0f0.0,%0" | |
2223 | [(set_attr "type" "fpmove")]) | |
2224 | \f | |
2225 | ;; Arithmetic shift instructions. | |
2226 | ||
2b7794ad JW |
2227 | ;; The shli instruction generates an overflow fault if the sign changes. |
2228 | ;; In the case of overflow, it does not give the natural result, it instead | |
2229 | ;; gives the last shift value before the overflow. We can not use this | |
2230 | ;; instruction because gcc thinks that arithmetic left shift and logical | |
2231 | ;; left shift are identical, and sometimes canonicalizes the logical left | |
2232 | ;; shift to an arithmetic left shift. Therefore we must always use the | |
2233 | ;; logical left shift instruction. | |
2234 | ||
ba8ab355 JW |
2235 | (define_insn "ashlsi3" |
2236 | [(set (match_operand:SI 0 "register_operand" "=d") | |
2237 | (ashift:SI (match_operand:SI 1 "arith_operand" "dI") | |
2238 | (match_operand:SI 2 "arith_operand" "dI")))] | |
2239 | "" | |
2b7794ad | 2240 | "shlo %2,%1,%0" |
ba8ab355 JW |
2241 | [(set_attr "type" "alu2")]) |
2242 | ||
2243 | (define_insn "ashrsi3" | |
2244 | [(set (match_operand:SI 0 "register_operand" "=d") | |
2245 | (ashiftrt:SI (match_operand:SI 1 "arith_operand" "dI") | |
2246 | (match_operand:SI 2 "arith_operand" "dI")))] | |
2247 | "" | |
2248 | "shri %2,%1,%0" | |
2249 | [(set_attr "type" "alu2")]) | |
2250 | ||
2251 | (define_insn "lshrsi3" | |
2252 | [(set (match_operand:SI 0 "register_operand" "=d") | |
2253 | (lshiftrt:SI (match_operand:SI 1 "arith_operand" "dI") | |
2254 | (match_operand:SI 2 "arith_operand" "dI")))] | |
2255 | "" | |
2256 | "shro %2,%1,%0" | |
2257 | [(set_attr "type" "alu2")]) | |
2258 | \f | |
2259 | ;; Unconditional and other jump instructions. | |
2260 | ||
2261 | (define_insn "jump" | |
2262 | [(set (pc) | |
2263 | (label_ref (match_operand 0 "" "")))] | |
2264 | "" | |
2265 | "b %l0" | |
2266 | [(set_attr "type" "branch")]) | |
2267 | ||
2268 | (define_insn "indirect_jump" | |
369f5d84 | 2269 | [(set (pc) (match_operand:SI 0 "address_operand" "p"))] |
ba8ab355 | 2270 | "" |
369f5d84 | 2271 | "bx %a0" |
ba8ab355 JW |
2272 | [(set_attr "type" "branch")]) |
2273 | ||
2274 | (define_insn "tablejump" | |
2275 | [(set (pc) (match_operand:SI 0 "register_operand" "d")) | |
2276 | (use (label_ref (match_operand 1 "" "")))] | |
2277 | "" | |
e5e809f4 JL |
2278 | "* |
2279 | { | |
2280 | if (flag_pic) | |
2281 | return \"bx %l1(%0)\"; | |
2282 | else | |
2283 | return \"bx (%0)\"; | |
2284 | }" | |
ba8ab355 JW |
2285 | [(set_attr "type" "branch")]) |
2286 | ||
2287 | ;;- jump to subroutine | |
2288 | ||
2289 | (define_expand "call" | |
3a6f7177 | 2290 | [(call (match_operand:SI 0 "memory_operand" "m") |
7c080174 | 2291 | (match_operand:SI 1 "immediate_operand" "i"))] |
ba8ab355 JW |
2292 | "" |
2293 | " | |
2294 | { | |
41552736 RH |
2295 | emit_call_insn (gen_call_internal (operands[0], operands[1], |
2296 | virtual_outgoing_args_rtx)); | |
ba8ab355 JW |
2297 | DONE; |
2298 | }") | |
2299 | ||
eff864ab JW |
2300 | ;; We need a call saved register allocated for the match_scratch, so we use |
2301 | ;; 'l' because all local registers are call saved. | |
2302 | ||
b6744f97 JW |
2303 | ;; ??? I would prefer to use a match_scratch here, but match_scratch allocated |
2304 | ;; registers can't be used for spills. In a function with lots of calls, | |
2305 | ;; local-alloc may allocate all local registers to a match_scratch, leaving | |
2306 | ;; no local registers available for spills. | |
2307 | ||
7c080174 | 2308 | (define_insn "call_internal" |
3a6f7177 | 2309 | [(call (match_operand:SI 0 "memory_operand" "m") |
7c080174 JW |
2310 | (match_operand:SI 1 "immediate_operand" "i")) |
2311 | (use (match_operand:SI 2 "address_operand" "p")) | |
b6744f97 | 2312 | (clobber (reg:SI 19))] |
ba8ab355 | 2313 | "" |
7c080174 | 2314 | "* return i960_output_call_insn (operands[0], operands[1], operands[2], |
b6744f97 | 2315 | insn);" |
ba8ab355 JW |
2316 | [(set_attr "type" "call")]) |
2317 | ||
2318 | (define_expand "call_value" | |
2319 | [(set (match_operand 0 "register_operand" "=d") | |
3a6f7177 | 2320 | (call (match_operand:SI 1 "memory_operand" "m") |
ba8ab355 JW |
2321 | (match_operand:SI 2 "immediate_operand" "i")))] |
2322 | "" | |
2323 | " | |
2324 | { | |
41552736 RH |
2325 | emit_call_insn (gen_call_value_internal (operands[0], operands[1], |
2326 | operands[2], | |
2327 | virtual_outgoing_args_rtx)); | |
ba8ab355 JW |
2328 | DONE; |
2329 | }") | |
2330 | ||
eff864ab JW |
2331 | ;; We need a call saved register allocated for the match_scratch, so we use |
2332 | ;; 'l' because all local registers are call saved. | |
2333 | ||
7c080174 | 2334 | (define_insn "call_value_internal" |
ba8ab355 | 2335 | [(set (match_operand 0 "register_operand" "=d") |
3a6f7177 | 2336 | (call (match_operand:SI 1 "memory_operand" "m") |
7c080174 JW |
2337 | (match_operand:SI 2 "immediate_operand" "i"))) |
2338 | (use (match_operand:SI 3 "address_operand" "p")) | |
b6744f97 | 2339 | (clobber (reg:SI 19))] |
ba8ab355 | 2340 | "" |
7c080174 | 2341 | "* return i960_output_call_insn (operands[1], operands[2], operands[3], |
b6744f97 | 2342 | insn);" |
ba8ab355 JW |
2343 | [(set_attr "type" "call")]) |
2344 | ||
2345 | (define_insn "return" | |
2346 | [(return)] | |
2347 | "" | |
2348 | "* return i960_output_ret_insn (insn);" | |
2349 | [(set_attr "type" "branch")]) | |
2350 | ||
0bc02db4 MS |
2351 | ;; A return instruction. Used only by nonlocal_goto to change the |
2352 | ;; stack pointer, frame pointer, previous frame pointer and the return | |
2353 | ;; instruction pointer. | |
2354 | (define_insn "ret" | |
d337d653 | 2355 | [(set (pc) (unspec_volatile [(reg:SI 16)] 3))] |
0bc02db4 MS |
2356 | "" |
2357 | "ret" | |
2358 | [(set_attr "type" "branch") | |
2359 | (set_attr "length" "1")]) | |
2360 | ||
2361 | (define_expand "nonlocal_goto" | |
2362 | [(match_operand:SI 0 "" "") | |
2363 | (match_operand:SI 1 "general_operand" "") | |
2364 | (match_operand:SI 2 "general_operand" "") | |
2365 | (match_operand:SI 3 "general_operand" "")] | |
2366 | "" | |
2367 | " | |
2368 | { | |
a45f3331 JW |
2369 | rtx chain = operands[0]; |
2370 | rtx handler = operands[1]; | |
0bc02db4 | 2371 | rtx stack = operands[2]; |
0bc02db4 MS |
2372 | |
2373 | /* We must restore the stack pointer, frame pointer, previous frame | |
2374 | pointer and the return instruction pointer. Since the ret | |
2375 | instruction does all this for us with one instruction, we arrange | |
2376 | everything so that ret will do everything we need done. */ | |
2377 | ||
0bc02db4 MS |
2378 | /* First, we must flush the register windows, so that we can modify |
2379 | the saved local registers on the stack directly and because we | |
2380 | are going to change the previous frame pointer. */ | |
2381 | ||
2382 | emit_insn (gen_flush_register_windows ()); | |
2383 | ||
a45f3331 JW |
2384 | /* Load the static chain value for the containing fn into fp. This is needed |
2385 | because STACK refers to fp. */ | |
2386 | emit_move_insn (hard_frame_pointer_rtx, chain); | |
2387 | ||
2388 | /* Now move the adjusted value into the pfp register for the following return | |
2389 | instruction. */ | |
2390 | emit_move_insn (gen_rtx (REG, SImode, 16), | |
2391 | plus_constant (hard_frame_pointer_rtx, -64)); | |
2392 | ||
0bc02db4 | 2393 | /* Next, we put the address that we want to transfer to, into the |
a45f3331 | 2394 | saved $rip value in the frame. Once we ret below, that value |
0bc02db4 MS |
2395 | will be loaded into the pc (IP). */ |
2396 | ||
2397 | emit_move_insn (gen_rtx (MEM, SImode, | |
a45f3331 | 2398 | plus_constant (hard_frame_pointer_rtx, -56)), |
157229c3 | 2399 | handler); |
0bc02db4 | 2400 | |
a45f3331 JW |
2401 | /* Next, we put stack into the saved $sp value in the frame. */ |
2402 | emit_move_insn (gen_rtx (MEM, SImode, | |
2403 | plus_constant (hard_frame_pointer_rtx, -60)), | |
157229c3 | 2404 | stack); |
0bc02db4 MS |
2405 | |
2406 | /* And finally, we can now just ret to get all the values saved | |
2407 | above into all the right registers, and also, all the local | |
2408 | register that were in use in the function, are restored from | |
2409 | their saved values (from the call instruction) on the stack | |
2410 | because we are very careful to ret from the exact save area in | |
2411 | use during the original call. */ | |
2412 | ||
d337d653 | 2413 | emit_jump_insn (gen_ret ()); |
0bc02db4 MS |
2414 | emit_barrier (); |
2415 | DONE; | |
2416 | }") | |
2417 | ||
2418 | ;; Special insn to flush register windows. | |
2419 | (define_insn "flush_register_windows" | |
2420 | [(unspec_volatile [(const_int 0)] 1)] | |
2421 | "" | |
2422 | "flushreg" | |
2423 | [(set_attr "type" "misc") | |
2424 | (set_attr "length" "1")]) | |
2425 | ||
ba8ab355 JW |
2426 | (define_insn "nop" |
2427 | [(const_int 0)] | |
2428 | "" | |
2429 | "") | |
2430 | \f | |
2431 | ;; Various peephole optimizations for multiple-word moves, loads, and stores. | |
2432 | ;; Multiple register moves. | |
2433 | ||
2434 | ;; Matched 5/28/91 | |
2435 | (define_peephole | |
2436 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2437 | (match_operand:SI 1 "register_operand" "r")) | |
2438 | (set (match_operand:SI 2 "register_operand" "=r") | |
2439 | (match_operand:SI 3 "register_operand" "r")) | |
2440 | (set (match_operand:SI 4 "register_operand" "=r") | |
2441 | (match_operand:SI 5 "register_operand" "r")) | |
2442 | (set (match_operand:SI 6 "register_operand" "=r") | |
2443 | (match_operand:SI 7 "register_operand" "r"))] | |
2444 | "((REGNO (operands[0]) & 3) == 0) | |
2445 | && ((REGNO (operands[1]) & 3) == 0) | |
2446 | && (REGNO (operands[0]) + 1 == REGNO (operands[2])) | |
2447 | && (REGNO (operands[1]) + 1 == REGNO (operands[3])) | |
2448 | && (REGNO (operands[0]) + 2 == REGNO (operands[4])) | |
2449 | && (REGNO (operands[1]) + 2 == REGNO (operands[5])) | |
2450 | && (REGNO (operands[0]) + 3 == REGNO (operands[6])) | |
2451 | && (REGNO (operands[1]) + 3 == REGNO (operands[7]))" | |
2452 | "movq %1,%0") | |
2453 | ||
2454 | ;; Matched 4/17/92 | |
2455 | (define_peephole | |
2456 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2457 | (match_operand:DI 1 "register_operand" "r")) | |
2458 | (set (match_operand:DI 2 "register_operand" "=r") | |
2459 | (match_operand:DI 3 "register_operand" "r"))] | |
2460 | "((REGNO (operands[0]) & 3) == 0) | |
2461 | && ((REGNO (operands[1]) & 3) == 0) | |
2462 | && (REGNO (operands[0]) + 2 == REGNO (operands[2])) | |
2463 | && (REGNO (operands[1]) + 2 == REGNO (operands[3]))" | |
2464 | "movq %1,%0") | |
2465 | ||
2466 | ;; Matched 4/17/92 | |
2467 | (define_peephole | |
2468 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2469 | (match_operand:DI 1 "register_operand" "r")) | |
2470 | (set (match_operand:SI 2 "register_operand" "=r") | |
2471 | (match_operand:SI 3 "register_operand" "r")) | |
2472 | (set (match_operand:SI 4 "register_operand" "=r") | |
2473 | (match_operand:SI 5 "register_operand" "r"))] | |
2474 | "((REGNO (operands[0]) & 3) == 0) | |
2475 | && ((REGNO (operands[1]) & 3) == 0) | |
2476 | && (REGNO (operands[0]) + 2 == REGNO (operands[2])) | |
2477 | && (REGNO (operands[1]) + 2 == REGNO (operands[3])) | |
2478 | && (REGNO (operands[0]) + 3 == REGNO (operands[4])) | |
2479 | && (REGNO (operands[1]) + 3 == REGNO (operands[5]))" | |
2480 | "movq %1,%0") | |
2481 | ||
2482 | ;; Matched 4/17/92 | |
2483 | (define_peephole | |
2484 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2485 | (match_operand:SI 1 "register_operand" "r")) | |
2486 | (set (match_operand:SI 2 "register_operand" "=r") | |
2487 | (match_operand:SI 3 "register_operand" "r")) | |
2488 | (set (match_operand:DI 4 "register_operand" "=r") | |
2489 | (match_operand:DI 5 "register_operand" "r"))] | |
2490 | "((REGNO (operands[0]) & 3) == 0) | |
2491 | && ((REGNO (operands[1]) & 3) == 0) | |
2492 | && (REGNO (operands[0]) + 1 == REGNO (operands[2])) | |
2493 | && (REGNO (operands[1]) + 1 == REGNO (operands[3])) | |
2494 | && (REGNO (operands[0]) + 2 == REGNO (operands[4])) | |
2495 | && (REGNO (operands[1]) + 2 == REGNO (operands[5]))" | |
2496 | "movq %1,%0") | |
2497 | ||
2498 | ;; Matched 4/17/92 | |
2499 | (define_peephole | |
2500 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2501 | (match_operand:DI 1 "register_operand" "r")) | |
2502 | (set (match_operand:SI 2 "register_operand" "=r") | |
2503 | (match_operand:SI 3 "register_operand" "r"))] | |
2504 | "((REGNO (operands[0]) & 3) == 0) | |
2505 | && ((REGNO (operands[1]) & 3) == 0) | |
2506 | && (REGNO (operands[0]) + 2 == REGNO (operands[2])) | |
2507 | && (REGNO (operands[1]) + 2 == REGNO (operands[3]))" | |
2508 | "movt %1,%0") | |
2509 | ||
2510 | ;; Matched 5/28/91 | |
2511 | (define_peephole | |
2512 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2513 | (match_operand:SI 1 "register_operand" "r")) | |
2514 | (set (match_operand:SI 2 "register_operand" "=r") | |
2515 | (match_operand:SI 3 "register_operand" "r")) | |
2516 | (set (match_operand:SI 4 "register_operand" "=r") | |
2517 | (match_operand:SI 5 "register_operand" "r"))] | |
2518 | "((REGNO (operands[0]) & 3) == 0) | |
2519 | && ((REGNO (operands[1]) & 3) == 0) | |
2520 | && (REGNO (operands[0]) + 1 == REGNO (operands[2])) | |
2521 | && (REGNO (operands[1]) + 1 == REGNO (operands[3])) | |
2522 | && (REGNO (operands[0]) + 2 == REGNO (operands[4])) | |
2523 | && (REGNO (operands[1]) + 2 == REGNO (operands[5]))" | |
2524 | "movt %1,%0") | |
2525 | ||
2526 | ;; Matched 5/28/91 | |
2527 | (define_peephole | |
2528 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2529 | (match_operand:SI 1 "register_operand" "r")) | |
2530 | (set (match_operand:SI 2 "register_operand" "=r") | |
2531 | (match_operand:SI 3 "register_operand" "r"))] | |
2532 | "((REGNO (operands[0]) & 1) == 0) | |
2533 | && ((REGNO (operands[1]) & 1) == 0) | |
2534 | && (REGNO (operands[0]) + 1 == REGNO (operands[2])) | |
2535 | && (REGNO (operands[1]) + 1 == REGNO (operands[3]))" | |
2536 | "movl %1,%0") | |
2537 | \f | |
2538 | ; Multiple register loads. | |
2539 | ||
2540 | ;; Matched 6/15/91 | |
2541 | (define_peephole | |
2542 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2543 | (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") | |
2544 | (match_operand:SI 2 "immediate_operand" "n")))) | |
2545 | (set (match_operand:SI 3 "register_operand" "=r") | |
2546 | (mem:SI (plus:SI (match_dup 1) | |
2547 | (match_operand:SI 4 "immediate_operand" "n")))) | |
2548 | (set (match_operand:SI 5 "register_operand" "=r") | |
2549 | (mem:SI (plus:SI (match_dup 1) | |
2550 | (match_operand:SI 6 "immediate_operand" "n")))) | |
2551 | (set (match_operand:SI 7 "register_operand" "=r") | |
2552 | (mem:SI (plus:SI (match_dup 1) | |
2553 | (match_operand:SI 8 "immediate_operand" "n"))))] | |
2554 | "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0) | |
2555 | && (REGNO (operands[1]) != REGNO (operands[0])) | |
2556 | && (REGNO (operands[0]) + 1 == REGNO (operands[3])) | |
2557 | && (REGNO (operands[1]) != REGNO (operands[3])) | |
2558 | && (REGNO (operands[0]) + 2 == REGNO (operands[5])) | |
2559 | && (REGNO (operands[1]) != REGNO (operands[5])) | |
2560 | && (REGNO (operands[0]) + 3 == REGNO (operands[7])) | |
2561 | && (INTVAL (operands[2]) + 4 == INTVAL (operands[4])) | |
2562 | && (INTVAL (operands[2]) + 8 == INTVAL (operands[6])) | |
2563 | && (INTVAL (operands[2]) + 12 == INTVAL (operands[8])))" | |
2564 | "ldq %2(%1),%0") | |
2565 | ||
2566 | ;; Matched 5/28/91 | |
2567 | (define_peephole | |
2568 | [(set (match_operand:DF 0 "register_operand" "=d") | |
2569 | (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d") | |
2570 | (match_operand:SI 2 "immediate_operand" "n")))) | |
2571 | (set (match_operand:DF 3 "register_operand" "=d") | |
2572 | (mem:DF (plus:SI (match_dup 1) | |
2573 | (match_operand:SI 4 "immediate_operand" "n"))))] | |
2574 | "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0) | |
2575 | && (REGNO (operands[1]) != REGNO (operands[0])) | |
2576 | && (REGNO (operands[0]) + 2 == REGNO (operands[3])) | |
2577 | && (REGNO (operands[1]) != REGNO (operands[3])) | |
2578 | && (INTVAL (operands[2]) + 8 == INTVAL (operands[4])))" | |
2579 | "ldq %2(%1),%0") | |
2580 | ||
2581 | ;; Matched 1/24/92 | |
2582 | (define_peephole | |
2583 | [(set (match_operand:DI 0 "register_operand" "=d") | |
2584 | (mem:DI (plus:SI (match_operand:SI 1 "register_operand" "d") | |
2585 | (match_operand:SI 2 "immediate_operand" "n")))) | |
2586 | (set (match_operand:DI 3 "register_operand" "=d") | |
2587 | (mem:DI (plus:SI (match_dup 1) | |
2588 | (match_operand:SI 4 "immediate_operand" "n"))))] | |
2589 | "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0) | |
2590 | && (REGNO (operands[1]) != REGNO (operands[0])) | |
2591 | && (REGNO (operands[0]) + 2 == REGNO (operands[3])) | |
2592 | && (REGNO (operands[1]) != REGNO (operands[3])) | |
2593 | && (INTVAL (operands[2]) + 8 == INTVAL (operands[4])))" | |
2594 | "ldq %2(%1),%0") | |
2595 | ||
2596 | ;; Matched 4/17/92 | |
2597 | (define_peephole | |
2598 | [(set (match_operand:SI 0 "register_operand" "=d") | |
2599 | (mem:SI (match_operand:SI 1 "register_operand" "d"))) | |
2600 | (set (match_operand:SI 2 "register_operand" "=d") | |
2601 | (mem:SI (plus:SI (match_dup 1) | |
2602 | (match_operand:SI 3 "immediate_operand" "n")))) | |
2603 | (set (match_operand:SI 4 "register_operand" "=d") | |
2604 | (mem:SI (plus:SI (match_dup 1) | |
2605 | (match_operand:SI 5 "immediate_operand" "n")))) | |
2606 | (set (match_operand:SI 6 "register_operand" "=d") | |
2607 | (mem:SI (plus:SI (match_dup 1) | |
2608 | (match_operand:SI 7 "immediate_operand" "n"))))] | |
2609 | "(i960_si_ti (operands[1], 0) && ((REGNO (operands[0]) & 3) == 0) | |
2610 | && (REGNO (operands[1]) != REGNO (operands[0])) | |
2611 | && (REGNO (operands[0]) + 1 == REGNO (operands[2])) | |
2612 | && (REGNO (operands[1]) != REGNO (operands[2])) | |
2613 | && (REGNO (operands[0]) + 2 == REGNO (operands[4])) | |
2614 | && (REGNO (operands[1]) != REGNO (operands[4])) | |
2615 | && (REGNO (operands[0]) + 3 == REGNO (operands[6])) | |
2616 | && (INTVAL (operands[3]) == 4) | |
2617 | && (INTVAL (operands[5]) == 8) | |
2618 | && (INTVAL (operands[7]) == 12))" | |
2619 | "ldq (%1),%0") | |
2620 | ||
2621 | ;; Matched 5/28/91 | |
2622 | (define_peephole | |
2623 | [(set (match_operand:SI 0 "register_operand" "=d") | |
2624 | (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "d") | |
2625 | (match_operand:SI 2 "immediate_operand" "n")))) | |
2626 | (set (match_operand:SI 3 "register_operand" "=d") | |
2627 | (mem:SI (plus:SI (match_dup 1) | |
2628 | (match_operand:SI 4 "immediate_operand" "n")))) | |
2629 | (set (match_operand:SI 5 "register_operand" "=d") | |
2630 | (mem:SI (plus:SI (match_dup 1) | |
2631 | (match_operand:SI 6 "immediate_operand" "n"))))] | |
2632 | "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0) | |
2633 | && (REGNO (operands[1]) != REGNO (operands[0])) | |
2634 | && (REGNO (operands[0]) + 1 == REGNO (operands[3])) | |
2635 | && (REGNO (operands[1]) != REGNO (operands[3])) | |
2636 | && (REGNO (operands[0]) + 2 == REGNO (operands[5])) | |
2637 | && (INTVAL (operands[2]) + 4 == INTVAL (operands[4])) | |
2638 | && (INTVAL (operands[2]) + 8 == INTVAL (operands[6])))" | |
2639 | "ldt %2(%1),%0") | |
2640 | ||
2641 | ;; Matched 6/15/91 | |
2642 | (define_peephole | |
2643 | [(set (match_operand:SI 0 "register_operand" "=d") | |
2644 | (mem:SI (match_operand:SI 1 "register_operand" "d"))) | |
2645 | (set (match_operand:SI 2 "register_operand" "=d") | |
2646 | (mem:SI (plus:SI (match_dup 1) | |
2647 | (match_operand:SI 3 "immediate_operand" "n")))) | |
2648 | (set (match_operand:SI 4 "register_operand" "=d") | |
2649 | (mem:SI (plus:SI (match_dup 1) | |
2650 | (match_operand:SI 5 "immediate_operand" "n"))))] | |
2651 | "(i960_si_ti (operands[1], 0) && ((REGNO (operands[0]) & 3) == 0) | |
2652 | && (REGNO (operands[1]) != REGNO (operands[0])) | |
2653 | && (REGNO (operands[0]) + 1 == REGNO (operands[2])) | |
2654 | && (REGNO (operands[1]) != REGNO (operands[2])) | |
2655 | && (REGNO (operands[0]) + 2 == REGNO (operands[4])) | |
2656 | && (INTVAL (operands[3]) == 4) | |
2657 | && (INTVAL (operands[5]) == 8))" | |
2658 | "ldt (%1),%0") | |
2659 | ||
2660 | ;; Matched 5/28/91 | |
2661 | (define_peephole | |
2662 | [(set (match_operand:SI 0 "register_operand" "=d") | |
2663 | (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "d") | |
2664 | (match_operand:SI 2 "immediate_operand" "n")))) | |
2665 | (set (match_operand:SI 3 "register_operand" "=d") | |
2666 | (mem:SI (plus:SI (match_dup 1) | |
2667 | (match_operand:SI 4 "immediate_operand" "n"))))] | |
2668 | "(i960_si_di (operands[1], operands[2]) && ((REGNO (operands[0]) & 1) == 0) | |
2669 | && (REGNO (operands[1]) != REGNO (operands[0])) | |
2670 | && (REGNO (operands[0]) + 1 == REGNO (operands[3])) | |
2671 | && (INTVAL (operands[2]) + 4 == INTVAL (operands[4])))" | |
2672 | "ldl %2(%1),%0") | |
2673 | ||
2674 | ;; Matched 5/28/91 | |
2675 | (define_peephole | |
2676 | [(set (match_operand:SI 0 "register_operand" "=d") | |
2677 | (mem:SI (match_operand:SI 1 "register_operand" "d"))) | |
2678 | (set (match_operand:SI 2 "register_operand" "=d") | |
2679 | (mem:SI (plus:SI (match_dup 1) | |
2680 | (match_operand:SI 3 "immediate_operand" "n"))))] | |
2681 | "(i960_si_di (operands[1], 0) && ((REGNO (operands[0]) & 1) == 0) | |
2682 | && (REGNO (operands[1]) != REGNO (operands[0])) | |
2683 | && (REGNO (operands[0]) + 1 == REGNO (operands[2])) | |
2684 | && (INTVAL (operands[3]) == 4))" | |
2685 | "ldl (%1),%0") | |
2686 | \f | |
2687 | ; Multiple register stores. | |
2688 | ||
2689 | ;; Matched 5/28/91 | |
2690 | (define_peephole | |
2691 | [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d") | |
2692 | (match_operand:SI 1 "immediate_operand" "n"))) | |
2693 | (match_operand:SI 2 "register_operand" "d")) | |
2694 | (set (mem:SI (plus:SI (match_dup 0) | |
2695 | (match_operand:SI 3 "immediate_operand" "n"))) | |
2696 | (match_operand:SI 4 "register_operand" "d")) | |
2697 | (set (mem:SI (plus:SI (match_dup 0) | |
2698 | (match_operand:SI 5 "immediate_operand" "n"))) | |
2699 | (match_operand:SI 6 "register_operand" "d")) | |
2700 | (set (mem:SI (plus:SI (match_dup 0) | |
2701 | (match_operand:SI 7 "immediate_operand" "n"))) | |
2702 | (match_operand:SI 8 "register_operand" "d"))] | |
2703 | "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0) | |
2704 | && (REGNO (operands[2]) + 1 == REGNO (operands[4])) | |
2705 | && (REGNO (operands[2]) + 2 == REGNO (operands[6])) | |
2706 | && (REGNO (operands[2]) + 3 == REGNO (operands[8])) | |
2707 | && (INTVAL (operands[1]) + 4 == INTVAL (operands[3])) | |
2708 | && (INTVAL (operands[1]) + 8 == INTVAL (operands[5])) | |
2709 | && (INTVAL (operands[1]) + 12 == INTVAL (operands[7])))" | |
2710 | "stq %2,%1(%0)") | |
2711 | ||
2712 | ;; Matched 6/16/91 | |
2713 | (define_peephole | |
2714 | [(set (mem:DF (plus:SI (match_operand:SI 0 "register_operand" "d") | |
2715 | (match_operand:SI 1 "immediate_operand" "n"))) | |
2716 | (match_operand:DF 2 "register_operand" "d")) | |
2717 | (set (mem:DF (plus:SI (match_dup 0) | |
2718 | (match_operand:SI 3 "immediate_operand" "n"))) | |
2719 | (match_operand:DF 4 "register_operand" "d"))] | |
2720 | "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0) | |
2721 | && (REGNO (operands[2]) + 2 == REGNO (operands[4])) | |
2722 | && (INTVAL (operands[1]) + 8 == INTVAL (operands[3])))" | |
2723 | "stq %2,%1(%0)") | |
2724 | ||
2725 | ;; Matched 4/17/92 | |
2726 | (define_peephole | |
2727 | [(set (mem:DI (plus:SI (match_operand:SI 0 "register_operand" "d") | |
2728 | (match_operand:SI 1 "immediate_operand" "n"))) | |
2729 | (match_operand:DI 2 "register_operand" "d")) | |
2730 | (set (mem:DI (plus:SI (match_dup 0) | |
2731 | (match_operand:SI 3 "immediate_operand" "n"))) | |
2732 | (match_operand:DI 4 "register_operand" "d"))] | |
2733 | "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0) | |
2734 | && (REGNO (operands[2]) + 2 == REGNO (operands[4])) | |
2735 | && (INTVAL (operands[1]) + 8 == INTVAL (operands[3])))" | |
2736 | "stq %2,%1(%0)") | |
2737 | ||
2738 | ;; Matched 1/23/92 | |
2739 | (define_peephole | |
2740 | [(set (mem:SI (match_operand:SI 0 "register_operand" "d")) | |
2741 | (match_operand:SI 1 "register_operand" "d")) | |
2742 | (set (mem:SI (plus:SI (match_dup 0) | |
2743 | (match_operand:SI 2 "immediate_operand" "n"))) | |
2744 | (match_operand:SI 3 "register_operand" "d")) | |
2745 | (set (mem:SI (plus:SI (match_dup 0) | |
2746 | (match_operand:SI 4 "immediate_operand" "n"))) | |
2747 | (match_operand:SI 5 "register_operand" "d")) | |
2748 | (set (mem:SI (plus:SI (match_dup 0) | |
2749 | (match_operand:SI 6 "immediate_operand" "n"))) | |
2750 | (match_operand:SI 7 "register_operand" "d"))] | |
2751 | "(i960_si_ti (operands[0], 0) && ((REGNO (operands[1]) & 3) == 0) | |
2752 | && (REGNO (operands[1]) + 1 == REGNO (operands[3])) | |
2753 | && (REGNO (operands[1]) + 2 == REGNO (operands[5])) | |
2754 | && (REGNO (operands[1]) + 3 == REGNO (operands[7])) | |
2755 | && (INTVAL (operands[2]) == 4) | |
2756 | && (INTVAL (operands[4]) == 8) | |
2757 | && (INTVAL (operands[6]) == 12))" | |
2758 | "stq %1,(%0)") | |
2759 | ||
2760 | ;; Matched 5/29/91 | |
2761 | (define_peephole | |
2762 | [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d") | |
2763 | (match_operand:SI 1 "immediate_operand" "n"))) | |
2764 | (match_operand:SI 2 "register_operand" "d")) | |
2765 | (set (mem:SI (plus:SI (match_dup 0) | |
2766 | (match_operand:SI 3 "immediate_operand" "n"))) | |
2767 | (match_operand:SI 4 "register_operand" "d")) | |
2768 | (set (mem:SI (plus:SI (match_dup 0) | |
2769 | (match_operand:SI 5 "immediate_operand" "n"))) | |
2770 | (match_operand:SI 6 "register_operand" "d"))] | |
2771 | "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0) | |
2772 | && (REGNO (operands[2]) + 1 == REGNO (operands[4])) | |
2773 | && (REGNO (operands[2]) + 2 == REGNO (operands[6])) | |
2774 | && (INTVAL (operands[1]) + 4 == INTVAL (operands[3])) | |
2775 | && (INTVAL (operands[1]) + 8 == INTVAL (operands[5])))" | |
2776 | "stt %2,%1(%0)") | |
2777 | ||
2778 | ;; Matched 5/29/91 | |
2779 | (define_peephole | |
2780 | [(set (mem:SI (match_operand:SI 0 "register_operand" "d")) | |
2781 | (match_operand:SI 1 "register_operand" "d")) | |
2782 | (set (mem:SI (plus:SI (match_dup 0) | |
2783 | (match_operand:SI 2 "immediate_operand" "n"))) | |
2784 | (match_operand:SI 3 "register_operand" "d")) | |
2785 | (set (mem:SI (plus:SI (match_dup 0) | |
2786 | (match_operand:SI 4 "immediate_operand" "n"))) | |
2787 | (match_operand:SI 5 "register_operand" "d"))] | |
2788 | "(i960_si_ti (operands[0], 0) && ((REGNO (operands[1]) & 3) == 0) | |
2789 | && (REGNO (operands[1]) + 1 == REGNO (operands[3])) | |
2790 | && (REGNO (operands[1]) + 2 == REGNO (operands[5])) | |
2791 | && (INTVAL (operands[2]) == 4) | |
2792 | && (INTVAL (operands[4]) == 8))" | |
2793 | "stt %1,(%0)") | |
2794 | ||
2795 | ;; Matched 5/28/91 | |
2796 | (define_peephole | |
2797 | [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d") | |
2798 | (match_operand:SI 1 "immediate_operand" "n"))) | |
2799 | (match_operand:SI 2 "register_operand" "d")) | |
2800 | (set (mem:SI (plus:SI (match_dup 0) | |
2801 | (match_operand:SI 3 "immediate_operand" "n"))) | |
2802 | (match_operand:SI 4 "register_operand" "d"))] | |
2803 | "(i960_si_di (operands[0], operands[1]) && ((REGNO (operands[2]) & 1) == 0) | |
2804 | && (REGNO (operands[2]) + 1 == REGNO (operands[4])) | |
2805 | && (INTVAL (operands[1]) + 4 == INTVAL (operands[3])))" | |
2806 | "stl %2,%1(%0)") | |
2807 | ||
2808 | ;; Matched 5/28/91 | |
2809 | (define_peephole | |
2810 | [(set (mem:SI (match_operand:SI 0 "register_operand" "d")) | |
2811 | (match_operand:SI 1 "register_operand" "d")) | |
2812 | (set (mem:SI (plus:SI (match_dup 0) | |
2813 | (match_operand:SI 2 "immediate_operand" "n"))) | |
2814 | (match_operand:SI 3 "register_operand" "d"))] | |
2815 | "(i960_si_di (operands[0], 0) && ((REGNO (operands[1]) & 1) == 0) | |
2816 | && (REGNO (operands[1]) + 1 == REGNO (operands[3])) | |
2817 | && (INTVAL (operands[2]) == 4))" | |
2818 | "stl %1,(%0)") |