]>
Commit | Line | Data |
---|---|---|
8ef30996 MM |
1 | ;; Mips.md Machine Description for MIPS based processors |
2 | ;; Contributed by A. Lichnewsky, lich@inria.inria.fr | |
3 | ;; Changes by Michael Meissner, meissner@osf.org | |
4 | ;; Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. | |
5 | ||
6 | ;; This file is part of GNU CC. | |
7 | ||
8 | ;; GNU CC is free software; you can redistribute it and/or modify | |
9 | ;; it under the terms of the GNU General Public License as published by | |
10 | ;; the Free Software Foundation; either version 2, or (at your option) | |
11 | ;; any later version. | |
12 | ||
13 | ;; GNU CC is distributed in the hope that it will be useful, | |
14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | ;; GNU General Public License for more details. | |
17 | ||
18 | ;; You should have received a copy of the GNU General Public License | |
19 | ;; along with GNU CC; see the file COPYING. If not, write to | |
20 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
21 | ||
22 | \f | |
23 | ||
24 | ;; .................... | |
25 | ;; | |
26 | ;; Attributes | |
27 | ;; | |
28 | ;; .................... | |
29 | ||
30 | ;; Classification of each insn. | |
31 | ;; branch conditional branch | |
32 | ;; jump unconditional jump | |
33 | ;; call unconditional call | |
34 | ;; load load instruction(s) | |
35 | ;; store store instruction(s) | |
36 | ;; move data movement within same register set | |
37 | ;; xfer transfer to/from coprocessor | |
38 | ;; hilo transfer of hi/lo registers | |
39 | ;; arith integer arithmetic instruction | |
40 | ;; darith double precision integer arithmetic instructions | |
41 | ;; imul integer multiply | |
42 | ;; idiv integer divide | |
43 | ;; icmp integer compare | |
44 | ;; fadd floating point add/subtract | |
45 | ;; fmul floating point multiply | |
46 | ;; fdiv floating point divide | |
47 | ;; fabs floating point absolute value | |
48 | ;; fneg floating point negation | |
49 | ;; fcmp floating point compare | |
50 | ;; fcvt floating point convert | |
51 | ;; fsqrt floating point square root | |
52 | ;; multi multiword sequence (or user asm statements) | |
53 | ;; nop no operation | |
8ef30996 MM |
54 | |
55 | (define_attr "type" | |
c7343333 | 56 | "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,multi,nop" |
8ef30996 MM |
57 | (const_string "unknown")) |
58 | ||
59 | ;; Main data type used by the insn | |
34b650b3 | 60 | (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown")) |
8ef30996 MM |
61 | |
62 | ;; # instructions (4 bytes each) | |
63 | (define_attr "length" "" (const_int 1)) | |
64 | ||
6d518002 | 65 | ;; whether or not an instruction has a mandatory delay slot |
8ef30996 | 66 | (define_attr "dslot" "no,yes" |
c7343333 | 67 | (if_then_else (eq_attr "type" "branch,jump,call,load,xfer,hilo,fcmp") |
8ef30996 MM |
68 | (const_string "yes") |
69 | (const_string "no"))) | |
70 | ||
ddd8ab48 MM |
71 | ;; Attribute describing the processor. This attribute must match exactly |
72 | ;; with the processor_type enumeration in mips.h. | |
73 | ||
8ef30996 | 74 | ;; Attribute describing the processor |
ddd8ab48 MM |
75 | ;; (define_attr "cpu" "default,r3000,r6000,r4000" |
76 | ;; (const | |
77 | ;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000") | |
78 | ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000") | |
79 | ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")] | |
80 | ;; (const_string "default")))) | |
81 | ||
82 | (define_attr "cpu" "default,r3000,r6000,r4000" | |
83 | (const (symbol_ref "mips_cpu_attr"))) | |
8ef30996 MM |
84 | |
85 | ;; Attribute defining whether or not we can use the branch-likely instructions | |
86 | ;; (MIPS ISA level 2) | |
87 | ||
88 | (define_attr "branch_likely" "no,yes" | |
6d518002 | 89 | (const |
8ef30996 MM |
90 | (if_then_else (ge (symbol_ref "mips_isa") (const_int 2)) |
91 | (const_string "yes") | |
6d518002 | 92 | (const_string "no")))) |
8ef30996 MM |
93 | |
94 | ||
95 | ;; Describe a user's asm statement. | |
96 | (define_asm_attributes | |
97 | [(set_attr "type" "multi")]) | |
98 | ||
99 | \f | |
100 | ||
101 | ;; ......................... | |
102 | ;; | |
103 | ;; Delay slots, can't describe load/fcmp/xfer delay slots here | |
104 | ;; | |
105 | ;; ......................... | |
106 | ||
107 | (define_delay (eq_attr "type" "branch") | |
108 | [(and (eq_attr "dslot" "no") (eq_attr "length" "1")) | |
109 | (nil) | |
bbdb5552 | 110 | (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "1")))]) |
8ef30996 MM |
111 | |
112 | (define_delay (eq_attr "type" "call,jump") | |
113 | [(and (eq_attr "dslot" "no") (eq_attr "length" "1")) | |
114 | (nil) | |
115 | (nil)]) | |
116 | ||
117 | \f | |
118 | ||
119 | ;; ......................... | |
120 | ;; | |
121 | ;; Functional units | |
122 | ;; | |
123 | ;; ......................... | |
124 | ||
125 | ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY | |
126 | ; TEST READY-DELAY BUSY-DELAY [CONFLICT-LIST]) | |
127 | ||
128 | ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case | |
129 | ||
130 | (define_function_unit "memory" 1 0 | |
c7343333 | 131 | (and (eq_attr "type" "load") (eq_attr "cpu" "!r3000")) |
8ef30996 MM |
132 | 3 0) |
133 | ||
134 | (define_function_unit "memory" 1 0 | |
c7343333 | 135 | (and (eq_attr "type" "load") (eq_attr "cpu" "r3000")) |
8ef30996 MM |
136 | 2 0) |
137 | ||
ddd8ab48 | 138 | (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0) |
8ef30996 | 139 | |
c3f3d7e1 | 140 | (define_function_unit "addr" 1 0 (eq_attr "type" "fcmp") 2 0) |
34b650b3 | 141 | |
c3f3d7e1 MM |
142 | (define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0) |
143 | (define_function_unit "memory" 1 0 (eq_attr "type" "hilo") 3 0) | |
8ef30996 MM |
144 | |
145 | (define_function_unit "imuldiv" 1 1 | |
146 | (and (eq_attr "type" "imul") (eq_attr "cpu" "!r3000,r4000")) | |
147 | 17 34) | |
148 | ||
149 | (define_function_unit "imuldiv" 1 1 | |
150 | (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000")) | |
151 | 12 24) | |
152 | ||
153 | (define_function_unit "imuldiv" 1 1 | |
154 | (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000")) | |
155 | 10 20) | |
156 | ||
157 | (define_function_unit "imuldiv" 1 1 | |
158 | (and (eq_attr "type" "idiv") (eq_attr "cpu" "!r3000,r4000")) | |
159 | 38 76) | |
160 | ||
161 | (define_function_unit "imuldiv" 1 1 | |
162 | (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000")) | |
163 | 35 70) | |
164 | ||
165 | (define_function_unit "imuldiv" 1 1 | |
166 | (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000")) | |
167 | 69 138) | |
168 | ||
169 | (define_function_unit "adder" 1 1 | |
170 | (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r6000")) | |
171 | 4 8) | |
172 | ||
173 | (define_function_unit "adder" 1 1 | |
174 | (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000")) | |
175 | 2 4) | |
176 | ||
177 | (define_function_unit "adder" 1 1 | |
178 | (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000")) | |
179 | 3 6) | |
180 | ||
ddd8ab48 | 181 | (define_function_unit "adder" 1 1 |
8ef30996 MM |
182 | (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "!r3000")) |
183 | 2 4) | |
184 | ||
ddd8ab48 | 185 | (define_function_unit "adder" 1 1 |
8ef30996 MM |
186 | (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000")) |
187 | 1 2) | |
188 | ||
189 | (define_function_unit "mult" 1 1 | |
190 | (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000"))) | |
191 | 7 14) | |
192 | ||
193 | (define_function_unit "mult" 1 1 | |
194 | (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000"))) | |
195 | 4 8) | |
196 | ||
197 | (define_function_unit "mult" 1 1 | |
198 | (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000"))) | |
199 | 5 10) | |
200 | ||
201 | (define_function_unit "mult" 1 1 | |
202 | (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000"))) | |
203 | 8 16) | |
204 | ||
205 | (define_function_unit "mult" 1 1 | |
206 | (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000"))) | |
207 | 5 10) | |
208 | ||
209 | (define_function_unit "mult" 1 1 | |
210 | (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000"))) | |
211 | 6 12) | |
212 | ||
213 | (define_function_unit "divide" 1 1 | |
214 | (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000"))) | |
215 | 23 46) | |
216 | ||
217 | (define_function_unit "divide" 1 1 | |
218 | (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000"))) | |
219 | 12 24) | |
220 | ||
221 | (define_function_unit "divide" 1 1 | |
222 | (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000"))) | |
223 | 15 30) | |
224 | ||
225 | (define_function_unit "divide" 1 1 | |
226 | (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000"))) | |
227 | 36 72) | |
228 | ||
229 | (define_function_unit "divide" 1 1 | |
230 | (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000"))) | |
231 | 19 34) | |
232 | ||
233 | (define_function_unit "divide" 1 1 | |
234 | (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000"))) | |
235 | 16 32) | |
236 | ||
c3f3d7e1 MM |
237 | (define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 108) |
238 | (define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 224) | |
8ef30996 | 239 | |
ddd8ab48 MM |
240 | \f |
241 | ;; The following functional units do not use the cpu type, and use | |
242 | ;; much less memory in genattrtab.c. | |
243 | ||
c7343333 | 244 | ;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0) |
ddd8ab48 MM |
245 | ;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0) |
246 | ;; | |
247 | ;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0) | |
248 | ;; | |
249 | ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0) | |
250 | ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0) | |
251 | ;; | |
252 | ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 34) | |
253 | ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 76) | |
254 | ;; | |
255 | ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 8) | |
256 | ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 4) | |
257 | ;; | |
258 | ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 14) | |
259 | ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 16) | |
260 | ;; | |
261 | ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 46) | |
262 | ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 72) | |
263 | ;; | |
264 | ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 108) | |
265 | ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 224) | |
266 | ||
8ef30996 MM |
267 | \f |
268 | ;; | |
269 | ;; .................... | |
270 | ;; | |
271 | ;; ADDITION | |
272 | ;; | |
273 | ;; .................... | |
274 | ;; | |
275 | ||
276 | (define_insn "adddf3" | |
277 | [(set (match_operand:DF 0 "register_operand" "=f") | |
278 | (plus:DF (match_operand:DF 1 "register_operand" "f") | |
279 | (match_operand:DF 2 "register_operand" "f")))] | |
280 | "TARGET_HARD_FLOAT" | |
281 | "add.d\\t%0,%1,%2" | |
282 | [(set_attr "type" "fadd") | |
283 | (set_attr "mode" "DF") | |
284 | (set_attr "length" "1")]) | |
285 | ||
286 | (define_insn "addsf3" | |
287 | [(set (match_operand:SF 0 "register_operand" "=f") | |
288 | (plus:SF (match_operand:SF 1 "register_operand" "f") | |
289 | (match_operand:SF 2 "register_operand" "f")))] | |
290 | "TARGET_HARD_FLOAT" | |
291 | "add.s\\t%0,%1,%2" | |
292 | [(set_attr "type" "fadd") | |
293 | (set_attr "mode" "SF") | |
294 | (set_attr "length" "1")]) | |
295 | ||
296 | (define_insn "addsi3" | |
297 | [(set (match_operand:SI 0 "register_operand" "=d") | |
298 | (plus:SI (match_operand:SI 1 "arith_operand" "%d") | |
299 | (match_operand:SI 2 "arith_operand" "dI")))] | |
300 | "" | |
301 | "* | |
302 | { | |
303 | return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) | |
304 | ? \"subu\\t%0,%1,%n2\" | |
305 | : \"addu\\t%0,%1,%2\"; | |
306 | }" | |
307 | [(set_attr "type" "arith") | |
308 | (set_attr "mode" "SI") | |
309 | (set_attr "length" "1")]) | |
310 | ||
311 | (define_expand "adddi3" | |
312 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
313 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
314 | (match_operand:DI 2 "arith_operand" ""))) | |
315 | (clobber (match_dup 3))])] | |
316 | "!TARGET_DEBUG_G_MODE" | |
92b4cee1 MM |
317 | " |
318 | { | |
319 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768) | |
320 | operands[2] = force_reg (SImode, operands[2]); | |
321 | ||
322 | operands[3] = gen_reg_rtx (SImode); | |
323 | }") | |
8ef30996 MM |
324 | |
325 | (define_insn "adddi3_internal_1" | |
326 | [(set (match_operand:DI 0 "register_operand" "=d,&d") | |
327 | (plus:DI (match_operand:DI 1 "register_operand" "0,d") | |
328 | (match_operand:DI 2 "register_operand" "d,d"))) | |
329 | (clobber (match_operand:SI 3 "register_operand" "=d,d"))] | |
330 | "!TARGET_DEBUG_G_MODE" | |
331 | "* | |
332 | { | |
333 | return (REGNO (operands[0]) == REGNO (operands[1]) | |
334 | && REGNO (operands[0]) == REGNO (operands[2])) | |
335 | ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\" | |
336 | : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\"; | |
337 | }" | |
92b4cee1 MM |
338 | [(set_attr "type" "darith") |
339 | (set_attr "mode" "DI") | |
340 | (set_attr "length" "4")]) | |
8ef30996 MM |
341 | |
342 | (define_split | |
343 | [(set (match_operand:DI 0 "register_operand" "") | |
344 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
345 | (match_operand:DI 2 "register_operand" ""))) | |
346 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 347 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
348 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
349 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
350 | && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2])) | |
351 | && (REGNO (operands[0]) != REGNO (operands[1]) | |
352 | || REGNO (operands[0]) != REGNO (operands[2]))" | |
353 | ||
354 | [(set (subreg:SI (match_dup 0) 0) | |
355 | (plus:SI (subreg:SI (match_dup 1) 0) | |
356 | (subreg:SI (match_dup 2) 0))) | |
357 | ||
358 | (set (match_dup 3) | |
34b650b3 | 359 | (ltu:SI (subreg:SI (match_dup 0) 0) |
8ef30996 MM |
360 | (subreg:SI (match_dup 2) 0))) |
361 | ||
362 | (set (subreg:SI (match_dup 0) 1) | |
363 | (plus:SI (subreg:SI (match_dup 1) 1) | |
364 | (subreg:SI (match_dup 2) 1))) | |
365 | ||
366 | (set (subreg:SI (match_dup 0) 1) | |
367 | (plus:SI (subreg:SI (match_dup 0) 1) | |
368 | (match_dup 3)))] | |
369 | "") | |
370 | ||
371 | (define_split | |
372 | [(set (match_operand:DI 0 "register_operand" "") | |
373 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
374 | (match_operand:DI 2 "register_operand" ""))) | |
375 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 376 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
377 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
378 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
379 | && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2])) | |
380 | && (REGNO (operands[0]) != REGNO (operands[1]) | |
381 | || REGNO (operands[0]) != REGNO (operands[2]))" | |
382 | ||
383 | [(set (subreg:SI (match_dup 0) 1) | |
384 | (plus:SI (subreg:SI (match_dup 1) 1) | |
385 | (subreg:SI (match_dup 2) 1))) | |
386 | ||
387 | (set (match_dup 3) | |
34b650b3 | 388 | (ltu:SI (subreg:SI (match_dup 0) 1) |
8ef30996 MM |
389 | (subreg:SI (match_dup 2) 1))) |
390 | ||
391 | (set (subreg:SI (match_dup 0) 0) | |
392 | (plus:SI (subreg:SI (match_dup 1) 0) | |
393 | (subreg:SI (match_dup 2) 0))) | |
394 | ||
395 | (set (subreg:SI (match_dup 0) 0) | |
396 | (plus:SI (subreg:SI (match_dup 0) 0) | |
397 | (match_dup 3)))] | |
398 | "") | |
399 | ||
400 | (define_insn "adddi3_internal_2" | |
401 | [(set (match_operand:DI 0 "register_operand" "=d,d,d") | |
402 | (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d") | |
403 | (match_operand:DI 2 "small_int" "P,J,N"))) | |
404 | (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))] | |
405 | "!TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768" | |
406 | "@ | |
407 | addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3 | |
408 | move\\t%L0,%L1\;move\\t%M0,%M1 | |
409 | subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3" | |
92b4cee1 MM |
410 | [(set_attr "type" "darith") |
411 | (set_attr "mode" "DI") | |
8ef30996 MM |
412 | (set_attr "length" "3,2,4")]) |
413 | ||
414 | (define_split | |
415 | [(set (match_operand:DI 0 "register_operand" "") | |
416 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
417 | (match_operand:DI 2 "small_int" ""))) | |
418 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
26b8e6e5 | 419 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
420 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
421 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
422 | && INTVAL (operands[2]) > 0" | |
423 | ||
424 | [(set (subreg:SI (match_dup 0) 0) | |
425 | (plus:SI (subreg:SI (match_dup 1) 0) | |
426 | (match_dup 2))) | |
427 | ||
428 | (set (match_dup 3) | |
34b650b3 | 429 | (ltu:SI (subreg:SI (match_dup 0) 0) |
8ef30996 MM |
430 | (match_dup 2))) |
431 | ||
432 | (set (subreg:SI (match_dup 0) 1) | |
433 | (plus:SI (subreg:SI (match_dup 1) 1) | |
434 | (match_dup 3)))] | |
435 | "") | |
436 | ||
437 | (define_split | |
438 | [(set (match_operand:DI 0 "register_operand" "") | |
439 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
440 | (match_operand:DI 2 "small_int" ""))) | |
441 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
26b8e6e5 | 442 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
443 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
444 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
445 | && INTVAL (operands[2]) > 0" | |
446 | ||
447 | [(set (subreg:SI (match_dup 0) 1) | |
448 | (plus:SI (subreg:SI (match_dup 1) 1) | |
449 | (match_dup 2))) | |
450 | ||
451 | (set (match_dup 3) | |
34b650b3 | 452 | (ltu:SI (subreg:SI (match_dup 0) 1) |
8ef30996 MM |
453 | (match_dup 2))) |
454 | ||
455 | (set (subreg:SI (match_dup 0) 0) | |
456 | (plus:SI (subreg:SI (match_dup 1) 0) | |
457 | (match_dup 3)))] | |
458 | "") | |
459 | \f | |
460 | ;; | |
461 | ;; .................... | |
462 | ;; | |
463 | ;; SUBTRACTION | |
464 | ;; | |
465 | ;; .................... | |
466 | ;; | |
467 | ||
468 | (define_insn "subdf3" | |
469 | [(set (match_operand:DF 0 "register_operand" "=f") | |
470 | (minus:DF (match_operand:DF 1 "register_operand" "f") | |
471 | (match_operand:DF 2 "register_operand" "f")))] | |
472 | "TARGET_HARD_FLOAT" | |
473 | "sub.d\\t%0,%1,%2" | |
474 | [(set_attr "type" "fadd") | |
475 | (set_attr "mode" "DF") | |
476 | (set_attr "length" "1")]) | |
477 | ||
478 | (define_insn "subsf3" | |
479 | [(set (match_operand:SF 0 "register_operand" "=f") | |
480 | (minus:SF (match_operand:SF 1 "register_operand" "f") | |
481 | (match_operand:SF 2 "register_operand" "f")))] | |
482 | "TARGET_HARD_FLOAT" | |
483 | "sub.s\\t%0,%1,%2" | |
484 | [(set_attr "type" "fadd") | |
485 | (set_attr "mode" "SF") | |
486 | (set_attr "length" "1")]) | |
487 | ||
488 | (define_insn "subsi3" | |
489 | [(set (match_operand:SI 0 "register_operand" "=d") | |
490 | (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") | |
491 | (match_operand:SI 2 "arith_operand" "dI")))] | |
492 | "" | |
493 | "* | |
494 | { | |
495 | return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) | |
496 | ? \"addu\\t%0,%z1,%n2\" | |
497 | : \"subu\\t%0,%z1,%2\"; | |
498 | }" | |
499 | [(set_attr "type" "arith") | |
500 | (set_attr "mode" "SI") | |
501 | (set_attr "length" "1")]) | |
502 | ||
503 | (define_expand "subdi3" | |
504 | [(parallel [(set (match_operand:DI 0 "register_operand" "=d") | |
505 | (minus:DI (match_operand:DI 1 "register_operand" "d") | |
506 | (match_operand:DI 2 "register_operand" "d"))) | |
507 | (clobber (match_dup 3))])] | |
508 | "!TARGET_DEBUG_G_MODE" | |
509 | "operands[3] = gen_reg_rtx (SImode);") | |
510 | ||
511 | (define_insn "subdi3_internal" | |
512 | [(set (match_operand:DI 0 "register_operand" "=d") | |
513 | (minus:DI (match_operand:DI 1 "register_operand" "d") | |
514 | (match_operand:DI 2 "register_operand" "d"))) | |
515 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
516 | "!TARGET_DEBUG_G_MODE" | |
517 | "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3" | |
518 | [(set_attr "type" "darith") | |
519 | (set_attr "mode" "DI") | |
520 | (set_attr "length" "4")]) | |
521 | ||
522 | (define_split | |
523 | [(set (match_operand:DI 0 "register_operand" "") | |
524 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
525 | (match_operand:DI 2 "register_operand" ""))) | |
526 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 527 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
528 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
529 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
530 | && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" | |
531 | ||
532 | [(set (match_dup 3) | |
34b650b3 | 533 | (ltu:SI (subreg:SI (match_dup 1) 0) |
6d518002 | 534 | (subreg:SI (match_dup 2) 0))) |
8ef30996 MM |
535 | |
536 | (set (subreg:SI (match_dup 0) 0) | |
537 | (minus:SI (subreg:SI (match_dup 1) 0) | |
538 | (subreg:SI (match_dup 2) 0))) | |
539 | ||
540 | (set (subreg:SI (match_dup 0) 1) | |
541 | (minus:SI (subreg:SI (match_dup 1) 1) | |
542 | (subreg:SI (match_dup 2) 1))) | |
543 | ||
544 | (set (subreg:SI (match_dup 0) 1) | |
545 | (minus:SI (subreg:SI (match_dup 0) 1) | |
546 | (match_dup 3)))] | |
547 | "") | |
548 | ||
549 | (define_split | |
550 | [(set (match_operand:DI 0 "register_operand" "") | |
551 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
552 | (match_operand:DI 2 "register_operand" ""))) | |
553 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 554 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
555 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
556 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
557 | && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" | |
558 | ||
559 | [(set (match_dup 3) | |
34b650b3 | 560 | (ltu:SI (subreg:SI (match_dup 1) 1) |
6d518002 | 561 | (subreg:SI (match_dup 2) 1))) |
8ef30996 MM |
562 | |
563 | (set (subreg:SI (match_dup 0) 1) | |
564 | (minus:SI (subreg:SI (match_dup 1) 1) | |
565 | (subreg:SI (match_dup 2) 1))) | |
566 | ||
567 | (set (subreg:SI (match_dup 0) 0) | |
568 | (minus:SI (subreg:SI (match_dup 1) 0) | |
569 | (subreg:SI (match_dup 2) 0))) | |
570 | ||
571 | (set (subreg:SI (match_dup 0) 0) | |
572 | (minus:SI (subreg:SI (match_dup 0) 0) | |
573 | (match_dup 3)))] | |
574 | "") | |
575 | ||
576 | (define_insn "subdi3_internal_2" | |
577 | [(set (match_operand:DI 0 "register_operand" "=d,d,d") | |
578 | (minus:DI (match_operand:DI 1 "register_operand" "d,d,d") | |
579 | (match_operand:DI 2 "small_int" "P,J,N"))) | |
580 | (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))] | |
581 | "!TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768" | |
582 | "@ | |
583 | sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3 | |
584 | move\\t%L0,%L1\;move\\t%M0,%M1 | |
585 | sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3" | |
92b4cee1 MM |
586 | [(set_attr "type" "darith") |
587 | (set_attr "mode" "DI") | |
8ef30996 MM |
588 | (set_attr "length" "3,2,4")]) |
589 | ||
590 | (define_split | |
591 | [(set (match_operand:DI 0 "register_operand" "") | |
592 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
593 | (match_operand:DI 2 "small_int" ""))) | |
594 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 595 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
596 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
597 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
598 | && INTVAL (operands[2]) > 0" | |
599 | ||
600 | [(set (match_dup 3) | |
34b650b3 | 601 | (ltu:SI (subreg:SI (match_dup 1) 0) |
8ef30996 MM |
602 | (match_dup 2))) |
603 | ||
604 | (set (subreg:SI (match_dup 0) 0) | |
605 | (minus:SI (subreg:SI (match_dup 1) 0) | |
606 | (match_dup 2))) | |
607 | ||
608 | (set (subreg:SI (match_dup 0) 1) | |
609 | (minus:SI (subreg:SI (match_dup 1) 1) | |
610 | (match_dup 3)))] | |
611 | "") | |
612 | ||
613 | (define_split | |
614 | [(set (match_operand:DI 0 "register_operand" "") | |
615 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
616 | (match_operand:DI 2 "small_int" ""))) | |
617 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 618 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
619 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
620 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
621 | && INTVAL (operands[2]) > 0" | |
622 | ||
623 | [(set (match_dup 3) | |
34b650b3 | 624 | (ltu:SI (subreg:SI (match_dup 1) 1) |
8ef30996 MM |
625 | (match_dup 2))) |
626 | ||
627 | (set (subreg:SI (match_dup 0) 1) | |
628 | (minus:SI (subreg:SI (match_dup 1) 1) | |
629 | (match_dup 2))) | |
630 | ||
631 | (set (subreg:SI (match_dup 0) 0) | |
632 | (minus:SI (subreg:SI (match_dup 1) 0) | |
633 | (match_dup 3)))] | |
634 | "") | |
635 | ||
636 | \f | |
637 | ;; | |
638 | ;; .................... | |
639 | ;; | |
640 | ;; MULTIPLICATION | |
641 | ;; | |
642 | ;; .................... | |
643 | ;; | |
644 | ||
645 | (define_insn "muldf3" | |
646 | [(set (match_operand:DF 0 "register_operand" "=f") | |
647 | (mult:DF (match_operand:DF 1 "register_operand" "f") | |
648 | (match_operand:DF 2 "register_operand" "f")))] | |
649 | "TARGET_HARD_FLOAT" | |
650 | "mul.d\\t%0,%1,%2" | |
651 | [(set_attr "type" "fmul") | |
652 | (set_attr "mode" "DF") | |
653 | (set_attr "length" "1")]) | |
654 | ||
655 | (define_insn "mulsf3" | |
656 | [(set (match_operand:SF 0 "register_operand" "=f") | |
657 | (mult:SF (match_operand:SF 1 "register_operand" "f") | |
658 | (match_operand:SF 2 "register_operand" "f")))] | |
659 | "TARGET_HARD_FLOAT" | |
660 | "mul.s\\t%0,%1,%2" | |
661 | [(set_attr "type" "fmul") | |
662 | (set_attr "mode" "SF") | |
663 | (set_attr "length" "1")]) | |
664 | ||
665 | (define_insn "mulsi3" | |
666 | [(set (match_operand:SI 0 "register_operand" "=d") | |
667 | (mult:SI (match_operand:SI 1 "register_operand" "d") | |
668 | (match_operand:SI 2 "register_operand" "d"))) | |
669 | (clobber (reg:SI 64)) | |
670 | (clobber (reg:SI 65))] | |
671 | "" | |
672 | "* | |
673 | { | |
674 | rtx xoperands[10]; | |
675 | ||
676 | xoperands[0] = operands[0]; | |
677 | xoperands[1] = gen_rtx (REG, SImode, LO_REGNUM); | |
678 | ||
679 | output_asm_insn (\"mult\\t%1,%2\", operands); | |
680 | output_asm_insn (mips_move_1word (xoperands, insn), xoperands); | |
681 | return \"\"; | |
682 | }" | |
683 | [(set_attr "type" "imul") | |
684 | (set_attr "mode" "SI") | |
685 | (set_attr "length" "3")]) ;; mult + mflo + delay | |
686 | ||
687 | (define_split | |
688 | [(set (match_operand:SI 0 "register_operand" "") | |
689 | (mult:SI (match_operand:SI 1 "register_operand" "") | |
690 | (match_operand:SI 2 "register_operand" ""))) | |
691 | (clobber (reg:SI 64)) | |
692 | (clobber (reg:SI 65))] | |
26b8e6e5 | 693 | "!TARGET_DEBUG_D_MODE" |
8ef30996 MM |
694 | [(parallel [(set (reg:SI 65) ;; low register |
695 | (mult:SI (match_dup 1) | |
696 | (match_dup 2))) | |
697 | (clobber (reg:SI 64))]) | |
698 | (set (match_dup 0) | |
699 | (reg:SI 65))] | |
700 | "") | |
701 | ||
702 | (define_insn "mulsi3_internal" | |
703 | [(set (reg:SI 65) ;; low register | |
704 | (mult:SI (match_operand:SI 0 "register_operand" "d") | |
705 | (match_operand:SI 1 "register_operand" "d"))) | |
706 | (clobber (reg:SI 64))] | |
707 | "" | |
708 | "mult\\t%0,%1" | |
709 | [(set_attr "type" "imul") | |
710 | (set_attr "mode" "SI") | |
711 | (set_attr "length" "1")]) | |
712 | ||
713 | (define_insn "mulsidi3" | |
714 | [(set (match_operand:DI 0 "register_operand" "=d") | |
715 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
716 | (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))) | |
717 | (clobber (reg:DI 64))] | |
718 | "" | |
719 | "* | |
720 | { | |
721 | rtx xoperands[10]; | |
722 | ||
723 | xoperands[0] = operands[0]; | |
724 | xoperands[1] = gen_rtx (REG, DImode, MD_REG_FIRST); | |
725 | ||
726 | output_asm_insn (\"mult\\t%1,%2\", operands); | |
727 | output_asm_insn (mips_move_2words (xoperands, insn), xoperands); | |
728 | return \"\"; | |
729 | }" | |
730 | [(set_attr "type" "imul") | |
731 | (set_attr "mode" "SI") | |
732 | (set_attr "length" "4")]) ;; mult + mflo + mfhi + delay | |
733 | ||
734 | (define_insn "umulsidi3" | |
735 | [(set (match_operand:DI 0 "register_operand" "=d") | |
736 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
737 | (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))) | |
738 | (clobber (reg:DI 64))] | |
739 | "" | |
740 | "* | |
741 | { | |
742 | rtx xoperands[10]; | |
743 | ||
744 | xoperands[0] = operands[0]; | |
745 | xoperands[1] = gen_rtx (REG, DImode, MD_REG_FIRST); | |
746 | ||
747 | output_asm_insn (\"multu\\t%1,%2\", operands); | |
748 | output_asm_insn (mips_move_2words (xoperands, insn), xoperands); | |
749 | return \"\"; | |
750 | }" | |
751 | [(set_attr "type" "imul") | |
752 | (set_attr "mode" "SI") | |
753 | (set_attr "length" "4")]) ;; mult + mflo + mfhi + delay | |
754 | ||
755 | \f | |
756 | ;; | |
757 | ;; .................... | |
758 | ;; | |
759 | ;; DIVISION and REMAINDER | |
760 | ;; | |
761 | ;; .................... | |
762 | ;; | |
763 | ||
764 | (define_insn "divdf3" | |
765 | [(set (match_operand:DF 0 "register_operand" "=f") | |
766 | (div:DF (match_operand:DF 1 "register_operand" "f") | |
767 | (match_operand:DF 2 "register_operand" "f")))] | |
768 | "TARGET_HARD_FLOAT" | |
769 | "div.d\\t%0,%1,%2" | |
770 | [(set_attr "type" "fdiv") | |
771 | (set_attr "mode" "DF") | |
772 | (set_attr "length" "1")]) | |
773 | ||
774 | (define_insn "divsf3" | |
775 | [(set (match_operand:SF 0 "register_operand" "=f") | |
776 | (div:SF (match_operand:SF 1 "register_operand" "f") | |
777 | (match_operand:SF 2 "register_operand" "f")))] | |
778 | "TARGET_HARD_FLOAT" | |
779 | "div.s\\t%0,%1,%2" | |
780 | [(set_attr "type" "fdiv") | |
781 | (set_attr "mode" "SF") | |
782 | (set_attr "length" "1")]) | |
783 | ||
784 | ;; If optimizing, prefer the divmod functions over separate div and | |
785 | ;; mod functions, since this will allow using one instruction for both | |
786 | ;; the quotient and remainder. At present, the divmod is not moved out | |
787 | ;; of loops if it is constant within the loop, so allow -mdebugc to | |
788 | ;; use the old method of doing things. | |
789 | ||
790 | ;; 64 is the multiply/divide hi register | |
791 | ;; 65 is the multiply/divide lo register | |
792 | ||
793 | (define_insn "divmodsi4" | |
70252580 MM |
794 | [(set (match_operand:SI 0 "register_operand" "=d") |
795 | (div:SI (match_operand:SI 1 "register_operand" "d") | |
796 | (match_operand:SI 2 "register_operand" "d"))) | |
797 | (set (match_operand:SI 3 "register_operand" "=d") | |
798 | (mod:SI (match_dup 1) | |
799 | (match_dup 2))) | |
800 | (clobber (reg:SI 64)) | |
801 | (clobber (reg:SI 65))] | |
34b650b3 | 802 | "optimize" |
8ef30996 MM |
803 | "* |
804 | { | |
805 | if (find_reg_note (insn, REG_UNUSED, operands[3])) | |
806 | return \"div\\t%0,%1,%2\"; | |
807 | ||
808 | if (find_reg_note (insn, REG_UNUSED, operands[0])) | |
809 | return \"rem\\t%3,%1,%2\"; | |
810 | ||
811 | return \"div\\t%0,%1,%2\;mfhi\\t%3\"; | |
812 | }" | |
813 | [(set_attr "type" "idiv") | |
814 | (set_attr "mode" "SI") | |
815 | (set_attr "length" "13")]) ;; various tests for dividing by 0 and such | |
816 | ||
817 | (define_insn "udivmodsi4" | |
70252580 MM |
818 | [(set (match_operand:SI 0 "register_operand" "=d") |
819 | (udiv:SI (match_operand:SI 1 "register_operand" "d") | |
820 | (match_operand:SI 2 "register_operand" "d"))) | |
821 | (set (match_operand:SI 3 "register_operand" "=d") | |
822 | (umod:SI (match_dup 1) | |
823 | (match_dup 2))) | |
824 | (clobber (reg:SI 64)) | |
825 | (clobber (reg:SI 65))] | |
34b650b3 | 826 | "optimize" |
8ef30996 MM |
827 | "* |
828 | { | |
829 | if (find_reg_note (insn, REG_UNUSED, operands[3])) | |
830 | return \"divu\\t%0,%1,%2\"; | |
831 | ||
832 | if (find_reg_note (insn, REG_UNUSED, operands[0])) | |
833 | return \"remu\\t%3,%1,%2\"; | |
834 | ||
835 | return \"divu\\t%0,%1,%2\;mfhi\\t%3\"; | |
836 | }" | |
837 | [(set_attr "type" "idiv") | |
838 | (set_attr "mode" "SI") | |
839 | (set_attr "length" "13")]) ;; various tests for dividing by 0 and such | |
840 | ||
841 | (define_insn "divsi3" | |
842 | [(set (match_operand:SI 0 "register_operand" "=d") | |
843 | (div:SI (match_operand:SI 1 "register_operand" "d") | |
844 | (match_operand:SI 2 "register_operand" "d"))) | |
845 | (clobber (reg:SI 64)) | |
846 | (clobber (reg:SI 65))] | |
34b650b3 | 847 | "!optimize" |
8ef30996 MM |
848 | "div\\t%0,%1,%2" |
849 | [(set_attr "type" "idiv") | |
850 | (set_attr "mode" "SI") | |
851 | (set_attr "length" "13")]) ;; various tests for dividing by 0 and such | |
852 | ||
853 | (define_insn "modsi3" | |
854 | [(set (match_operand:SI 0 "register_operand" "=d") | |
855 | (mod:SI (match_operand:SI 1 "register_operand" "d") | |
856 | (match_operand:SI 2 "register_operand" "d"))) | |
857 | (clobber (reg:SI 64)) | |
858 | (clobber (reg:SI 65))] | |
34b650b3 | 859 | "!optimize" |
8ef30996 MM |
860 | "rem\\t%0,%1,%2" |
861 | [(set_attr "type" "idiv") | |
862 | (set_attr "mode" "SI") | |
863 | (set_attr "length" "14")]) ;; various tests for dividing by 0 and such | |
864 | ||
865 | (define_insn "udivsi3" | |
866 | [(set (match_operand:SI 0 "register_operand" "=d") | |
867 | (udiv:SI (match_operand:SI 1 "register_operand" "d") | |
868 | (match_operand:SI 2 "register_operand" "d"))) | |
869 | (clobber (reg:SI 64)) | |
870 | (clobber (reg:SI 65))] | |
34b650b3 | 871 | "!optimize" |
8ef30996 MM |
872 | "divu\\t%0,%1,%2" |
873 | [(set_attr "type" "idiv") | |
874 | (set_attr "mode" "SI") | |
875 | (set_attr "length" "14")]) ;; various tests for dividing by 0 and such | |
876 | ||
877 | (define_insn "umodsi3" | |
878 | [(set (match_operand:SI 0 "register_operand" "=d") | |
879 | (umod:SI (match_operand:SI 1 "register_operand" "d") | |
880 | (match_operand:SI 2 "register_operand" "d"))) | |
881 | (clobber (reg:SI 64)) | |
882 | (clobber (reg:SI 65))] | |
34b650b3 | 883 | "!optimize" |
8ef30996 MM |
884 | "remu\\t%0,%1,%2" |
885 | [(set_attr "type" "idiv") | |
886 | (set_attr "mode" "SI") | |
887 | (set_attr "length" "14")]) ;; various tests for dividing by 0 and such | |
888 | ||
889 | \f | |
890 | ;; | |
891 | ;; .................... | |
892 | ;; | |
893 | ;; SQUARE ROOT | |
894 | ;; | |
895 | ;; .................... | |
896 | ||
897 | (define_insn "sqrtdf2" | |
898 | [(set (match_operand:DF 0 "register_operand" "=f") | |
899 | (sqrt:DF (match_operand:DF 1 "register_operand" "f")))] | |
900 | "TARGET_HARD_FLOAT && HAVE_SQRT_P()" | |
901 | "sqrt.d\\t%0,%1" | |
902 | [(set_attr "type" "fabs") | |
903 | (set_attr "mode" "DF") | |
904 | (set_attr "length" "1")]) | |
905 | ||
906 | (define_insn "sqrtsf2" | |
907 | [(set (match_operand:SF 0 "register_operand" "=f") | |
908 | (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] | |
909 | "TARGET_HARD_FLOAT && HAVE_SQRT_P()" | |
910 | "sqrt.s\\t%0,%1" | |
911 | [(set_attr "type" "fabs") | |
912 | (set_attr "mode" "SF") | |
913 | (set_attr "length" "1")]) | |
914 | ||
915 | \f | |
916 | ;; | |
917 | ;; .................... | |
918 | ;; | |
919 | ;; ABSOLUTE VALUE | |
920 | ;; | |
921 | ;; .................... | |
922 | ||
923 | ;; Do not use the integer abs macro instruction, since that signals an | |
924 | ;; exception on -2147483648 (sigh). | |
925 | ||
926 | (define_insn "abssi2" | |
927 | [(set (match_operand:SI 0 "register_operand" "=d") | |
928 | (abs:SI (match_operand:SI 1 "register_operand" "d")))] | |
929 | "" | |
930 | "* | |
931 | { | |
932 | dslots_jump_total++; | |
933 | dslots_jump_filled++; | |
934 | operands[2] = const0_rtx; | |
935 | ||
936 | return (REGNO (operands[0]) == REGNO (operands[1])) | |
937 | ? \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n1:\" | |
938 | : \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n1:%)\"; | |
939 | }" | |
940 | [(set_attr "type" "multi") | |
941 | (set_attr "mode" "SI") | |
942 | (set_attr "length" "3")]) | |
943 | ||
944 | (define_insn "absdf2" | |
945 | [(set (match_operand:DF 0 "register_operand" "=f") | |
946 | (abs:DF (match_operand:DF 1 "register_operand" "f")))] | |
947 | "TARGET_HARD_FLOAT" | |
948 | "abs.d\\t%0,%1" | |
949 | [(set_attr "type" "fabs") | |
950 | (set_attr "mode" "DF") | |
951 | (set_attr "length" "1")]) | |
952 | ||
953 | (define_insn "abssf2" | |
954 | [(set (match_operand:SF 0 "register_operand" "=f") | |
955 | (abs:SF (match_operand:SF 1 "register_operand" "f")))] | |
956 | "TARGET_HARD_FLOAT" | |
957 | "abs.s\\t%0,%1" | |
958 | [(set_attr "type" "fabs") | |
959 | (set_attr "mode" "SF") | |
960 | (set_attr "length" "1")]) | |
961 | ||
962 | \f | |
963 | ;; | |
964 | ;; .................... | |
965 | ;; | |
966 | ;; FIND FIRST BIT INSTRUCTION | |
967 | ;; | |
968 | ;; .................... | |
969 | ;; | |
970 | ||
971 | (define_insn "ffssi2" | |
972 | [(set (match_operand:SI 0 "register_operand" "=&d") | |
973 | (ffs:SI (match_operand:SI 1 "register_operand" "d"))) | |
974 | (clobber (match_scratch:SI 2 "d")) | |
975 | (clobber (match_scratch:SI 3 "d"))] | |
976 | "" | |
977 | "* | |
978 | { | |
979 | dslots_jump_total += 2; | |
980 | dslots_jump_filled += 2; | |
981 | operands[4] = const0_rtx; | |
982 | ||
983 | if (optimize && find_reg_note (insn, REG_DEAD, operands[1])) | |
984 | return \"%(\\ | |
985 | move\\t%0,%z4\\n\\ | |
986 | \\tbeq\\t%1,%z4,2f\\n\\ | |
987 | 1:\\tand\\t%2,%1,0x0001\\n\\ | |
988 | \\taddu\\t%0,%0,1\\n\\ | |
989 | \\tbeq\\t%2,%z4,1b\\n\\ | |
990 | \\tsrl\\t%1,%1,1\\n\\ | |
991 | 2:%)\"; | |
992 | ||
993 | return \"%(\\ | |
994 | move\\t%0,%z4\\n\\ | |
995 | \\tmove\\t%3,%1\\n\\ | |
996 | \\tbeq\\t%3,%z4,2f\\n\\ | |
997 | 1:\\tand\\t%2,%3,0x0001\\n\\ | |
998 | \\taddu\\t%0,%0,1\\n\\ | |
999 | \\tbeq\\t%2,%z4,1b\\n\\ | |
1000 | \\tsrl\\t%3,%3,1\\n\\ | |
1001 | 2:%)\"; | |
1002 | }" | |
1003 | [(set_attr "type" "multi") | |
1004 | (set_attr "mode" "SI") | |
1005 | (set_attr "length" "6")]) | |
1006 | ||
1007 | \f | |
1008 | ;; | |
1009 | ;; .................... | |
1010 | ;; | |
1011 | ;; NEGATION and ONE'S COMPLEMENT | |
1012 | ;; | |
1013 | ;; .................... | |
1014 | ||
1015 | (define_insn "negsi2" | |
1016 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1017 | (neg:SI (match_operand:SI 1 "register_operand" "d")))] | |
1018 | "" | |
1019 | "* | |
1020 | { | |
1021 | operands[2] = const0_rtx; | |
1022 | return \"subu\\t%0,%z2,%1\"; | |
1023 | }" | |
1024 | [(set_attr "type" "arith") | |
1025 | (set_attr "mode" "SI") | |
1026 | (set_attr "length" "1")]) | |
1027 | ||
1028 | (define_expand "negdi3" | |
1029 | [(parallel [(set (match_operand:DI 0 "register_operand" "=d") | |
1030 | (neg:DI (match_operand:DI 1 "register_operand" "d"))) | |
1031 | (clobber (match_dup 2))])] | |
1032 | "!TARGET_DEBUG_G_MODE" | |
1033 | "operands[2] = gen_reg_rtx (SImode);") | |
1034 | ||
1035 | (define_insn "negdi3_internal" | |
1036 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1037 | (neg:DI (match_operand:DI 1 "register_operand" "d"))) | |
1038 | (clobber (match_operand:SI 2 "register_operand" "=d"))] | |
1039 | "!TARGET_DEBUG_G_MODE" | |
1040 | "* | |
1041 | { | |
1042 | operands[3] = const0_rtx; | |
1043 | return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\"; | |
1044 | }" | |
1045 | [(set_attr "type" "darith") | |
1046 | (set_attr "mode" "DI") | |
1047 | (set_attr "length" "4")]) | |
1048 | ||
1049 | (define_insn "negdf2" | |
1050 | [(set (match_operand:DF 0 "register_operand" "=f") | |
1051 | (neg:DF (match_operand:DF 1 "register_operand" "f")))] | |
1052 | "TARGET_HARD_FLOAT" | |
1053 | "neg.d\\t%0,%1" | |
1054 | [(set_attr "type" "fneg") | |
1055 | (set_attr "mode" "DF") | |
1056 | (set_attr "length" "1")]) | |
1057 | ||
1058 | (define_insn "negsf2" | |
1059 | [(set (match_operand:SF 0 "register_operand" "=f") | |
1060 | (neg:SF (match_operand:SF 1 "register_operand" "f")))] | |
1061 | "TARGET_HARD_FLOAT" | |
1062 | "neg.s\\t%0,%1" | |
1063 | [(set_attr "type" "fneg") | |
1064 | (set_attr "mode" "SF") | |
1065 | (set_attr "length" "1")]) | |
1066 | ||
1067 | (define_insn "one_cmplsi2" | |
1068 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1069 | (not:SI (match_operand:SI 1 "register_operand" "d")))] | |
1070 | "" | |
1071 | "* | |
1072 | { | |
1073 | operands[2] = const0_rtx; | |
1074 | return \"nor\\t%0,%z2,%1\"; | |
1075 | }" | |
1076 | [(set_attr "type" "arith") | |
1077 | (set_attr "mode" "SI") | |
1078 | (set_attr "length" "1")]) | |
1079 | ||
1080 | (define_insn "one_cmpldi2" | |
1081 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1082 | (not:SI (match_operand:DI 1 "register_operand" "d")))] | |
1083 | "" | |
1084 | "* | |
1085 | { | |
1086 | operands[2] = const0_rtx; | |
1087 | return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\"; | |
1088 | }" | |
1089 | [(set_attr "type" "darith") | |
1090 | (set_attr "mode" "DI") | |
1091 | (set_attr "length" "2")]) | |
1092 | ||
1093 | (define_split | |
1094 | [(set (match_operand:DI 0 "register_operand" "") | |
1095 | (not:DI (match_operand:DI 1 "register_operand" "")))] | |
26b8e6e5 | 1096 | "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
1097 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
1098 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))" | |
1099 | ||
1100 | [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0))) | |
1101 | (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))] | |
1102 | "") | |
1103 | ||
1104 | ;; Simple hack to recognize the "nor" instruction on the MIPS | |
1105 | ;; This must appear before the normal or patterns, so that the | |
1106 | ;; combiner will correctly fold things. | |
1107 | ||
1108 | (define_insn "norsi3" | |
1109 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1110 | (not:SI (ior:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") | |
1111 | (match_operand:SI 2 "reg_or_0_operand" "dJ"))))] | |
1112 | "" | |
1113 | "nor\\t%0,%z1,%z2" | |
1114 | [(set_attr "type" "arith") | |
1115 | (set_attr "mode" "SI") | |
1116 | (set_attr "length" "1")]) | |
1117 | ||
1118 | (define_insn "nordi3" | |
1119 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1120 | (not:DI (ior:DI (match_operand:DI 1 "register_operand" "d") | |
1121 | (match_operand:DI 2 "register_operand" "d"))))] | |
1122 | "" | |
1123 | "nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2" | |
1124 | [(set_attr "type" "darith") | |
1125 | (set_attr "mode" "DI") | |
1126 | (set_attr "length" "2")]) | |
1127 | ||
1128 | (define_split | |
1129 | [(set (match_operand:DI 0 "register_operand" "") | |
1130 | (not:DI (ior:DI (match_operand:DI 1 "register_operand" "") | |
1131 | (match_operand:DI 2 "register_operand" ""))))] | |
26b8e6e5 | 1132 | "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
1133 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
1134 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
1135 | && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" | |
1136 | ||
1137 | [(set (subreg:SI (match_dup 0) 0) (not:SI (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))) | |
1138 | (set (subreg:SI (match_dup 0) 1) (not:SI (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1))))] | |
1139 | "") | |
1140 | ||
1141 | \f | |
1142 | ;; | |
1143 | ;; .................... | |
1144 | ;; | |
1145 | ;; LOGICAL | |
1146 | ;; | |
1147 | ;; .................... | |
1148 | ;; | |
1149 | ||
3e89ed5f | 1150 | (define_insn "andsi3" |
65437fe8 | 1151 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
e2f2127c MM |
1152 | (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d") |
1153 | (match_operand:SI 2 "uns_arith_operand" "d,K")))] | |
65437fe8 MM |
1154 | "" |
1155 | "@ | |
1156 | and\\t%0,%1,%2 | |
1157 | andi\\t%0,%1,%x2" | |
1158 | [(set_attr "type" "arith") | |
1159 | (set_attr "mode" "SI") | |
1160 | (set_attr "length" "1")]) | |
1161 | ||
8ef30996 MM |
1162 | (define_insn "anddi3" |
1163 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1164 | (and:DI (match_operand:DI 1 "register_operand" "d") | |
1165 | (match_operand:DI 2 "register_operand" "d")))] | |
1166 | "!TARGET_DEBUG_G_MODE" | |
1167 | "and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2" | |
1168 | [(set_attr "type" "darith") | |
1169 | (set_attr "mode" "DI") | |
1170 | (set_attr "length" "2")]) | |
1171 | ||
1172 | (define_split | |
1173 | [(set (match_operand:DI 0 "register_operand" "") | |
1174 | (and:DI (match_operand:DI 1 "register_operand" "") | |
1175 | (match_operand:DI 2 "register_operand" "")))] | |
26b8e6e5 | 1176 | "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
1177 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
1178 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
1179 | && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" | |
1180 | ||
1181 | [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))) | |
1182 | (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))] | |
1183 | "") | |
1184 | ||
3e89ed5f | 1185 | (define_insn "iorsi3" |
65437fe8 | 1186 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
e2f2127c MM |
1187 | (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d") |
1188 | (match_operand:SI 2 "uns_arith_operand" "d,K")))] | |
65437fe8 MM |
1189 | "" |
1190 | "@ | |
1191 | or\\t%0,%1,%2 | |
1192 | ori\\t%0,%1,%x2" | |
1193 | [(set_attr "type" "arith") | |
1194 | (set_attr "mode" "SI") | |
1195 | (set_attr "length" "1")]) | |
1196 | ||
8ef30996 MM |
1197 | (define_insn "iordi3" |
1198 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1199 | (ior:DI (match_operand:DI 1 "register_operand" "d") | |
1200 | (match_operand:DI 2 "register_operand" "d")))] | |
1201 | "!TARGET_DEBUG_G_MODE" | |
1202 | "or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2" | |
1203 | [(set_attr "type" "darith") | |
1204 | (set_attr "mode" "DI") | |
1205 | (set_attr "length" "2")]) | |
1206 | ||
1207 | (define_split | |
1208 | [(set (match_operand:DI 0 "register_operand" "") | |
1209 | (ior:DI (match_operand:DI 1 "register_operand" "") | |
1210 | (match_operand:DI 2 "register_operand" "")))] | |
26b8e6e5 | 1211 | "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
1212 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
1213 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
1214 | && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" | |
1215 | ||
1216 | [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))) | |
1217 | (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))] | |
1218 | "") | |
1219 | ||
3e89ed5f | 1220 | (define_insn "xorsi3" |
65437fe8 | 1221 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
e2f2127c MM |
1222 | (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d") |
1223 | (match_operand:SI 2 "uns_arith_operand" "d,K")))] | |
65437fe8 MM |
1224 | "" |
1225 | "@ | |
1226 | xor\\t%0,%1,%2 | |
1227 | xori\\t%0,%1,%x2" | |
1228 | [(set_attr "type" "arith") | |
1229 | (set_attr "mode" "SI") | |
1230 | (set_attr "length" "1")]) | |
1231 | ||
8ef30996 MM |
1232 | (define_insn "xordi3" |
1233 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1234 | (xor:DI (match_operand:DI 1 "register_operand" "d") | |
1235 | (match_operand:DI 2 "register_operand" "d")))] | |
1236 | "!TARGET_DEBUG_G_MODE" | |
1237 | "xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2" | |
1238 | [(set_attr "type" "darith") | |
1239 | (set_attr "mode" "DI") | |
1240 | (set_attr "length" "2")]) | |
1241 | ||
1242 | (define_split | |
1243 | [(set (match_operand:DI 0 "register_operand" "") | |
1244 | (xor:DI (match_operand:DI 1 "register_operand" "") | |
1245 | (match_operand:DI 2 "register_operand" "")))] | |
26b8e6e5 | 1246 | "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
1247 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
1248 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
1249 | && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" | |
1250 | ||
1251 | [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))) | |
1252 | (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))] | |
1253 | "") | |
1254 | ||
1255 | \f | |
1256 | ;; | |
1257 | ;; .................... | |
1258 | ;; | |
1259 | ;; TRUNCATION | |
1260 | ;; | |
1261 | ;; .................... | |
1262 | ||
1263 | (define_insn "truncdfsf2" | |
1264 | [(set (match_operand:SF 0 "register_operand" "=f") | |
1265 | (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] | |
1266 | "TARGET_HARD_FLOAT" | |
1267 | "cvt.s.d\\t%0,%1" | |
1268 | [(set_attr "type" "fcvt") | |
1269 | (set_attr "mode" "SF") | |
1270 | (set_attr "length" "1")]) | |
1271 | ||
1272 | \f | |
1273 | ;; | |
1274 | ;; .................... | |
1275 | ;; | |
1276 | ;; ZERO EXTENSION | |
1277 | ;; | |
1278 | ;; .................... | |
1279 | ||
1280 | ;; Extension insns. | |
1281 | ;; Those for integer source operand | |
1282 | ;; are ordered widest source type first. | |
1283 | ||
1284 | (define_insn "zero_extendhisi2" | |
1285 | [(set (match_operand:SI 0 "register_operand" "=d,d,d") | |
1286 | (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))] | |
1287 | "" | |
1288 | "* | |
1289 | { | |
1290 | if (which_alternative == 0) | |
1291 | return \"andi\\t%0,%1,0xffff\"; | |
1292 | else | |
1293 | return mips_move_1word (operands, insn, TRUE); | |
1294 | }" | |
1295 | [(set_attr "type" "arith,load,load") | |
92b4cee1 | 1296 | (set_attr "mode" "SI") |
8ef30996 MM |
1297 | (set_attr "length" "1,1,2")]) |
1298 | ||
1299 | (define_insn "zero_extendqihi2" | |
1300 | [(set (match_operand:HI 0 "register_operand" "=d,d,d") | |
1301 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))] | |
1302 | "" | |
1303 | "* | |
1304 | { | |
1305 | if (which_alternative == 0) | |
1306 | return \"andi\\t%0,%1,0x00ff\"; | |
1307 | else | |
1308 | return mips_move_1word (operands, insn, TRUE); | |
1309 | }" | |
1310 | [(set_attr "type" "arith,load,load") | |
92b4cee1 | 1311 | (set_attr "mode" "HI") |
8ef30996 MM |
1312 | (set_attr "length" "1,1,2")]) |
1313 | ||
1314 | (define_insn "zero_extendqisi2" | |
1315 | [(set (match_operand:SI 0 "register_operand" "=d,d,d") | |
1316 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))] | |
1317 | "" | |
1318 | "* | |
1319 | { | |
1320 | if (which_alternative == 0) | |
1321 | return \"andi\\t%0,%1,0x00ff\"; | |
1322 | else | |
1323 | return mips_move_1word (operands, insn, TRUE); | |
1324 | }" | |
1325 | [(set_attr "type" "arith,load,load") | |
92b4cee1 | 1326 | (set_attr "mode" "SI") |
8ef30996 MM |
1327 | (set_attr "length" "1,1,2")]) |
1328 | ||
1329 | \f | |
1330 | ;; | |
1331 | ;; .................... | |
1332 | ;; | |
1333 | ;; SIGN EXTENSION | |
1334 | ;; | |
1335 | ;; .................... | |
1336 | ||
1337 | ;; Extension insns. | |
1338 | ;; Those for integer source operand | |
1339 | ;; are ordered widest source type first. | |
1340 | ||
1341 | ;; These patterns originally accepted general_operands, however, slightly | |
1342 | ;; better code is generated by only accepting register_operands, and then | |
1343 | ;; letting combine generate the lh and lb insns. | |
1344 | ||
1345 | (define_expand "extendhisi2" | |
1346 | [(set (match_operand:SI 0 "register_operand" "") | |
1347 | (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] | |
1348 | "" | |
1349 | " | |
1350 | { | |
1351 | if (optimize && GET_CODE (operands[1]) == MEM) | |
1352 | operands[1] = force_not_mem (operands[1]); | |
1353 | ||
1354 | if (GET_CODE (operands[1]) != MEM) | |
1355 | { | |
1356 | rtx op1 = gen_lowpart (SImode, operands[1]); | |
1357 | rtx temp = gen_reg_rtx (SImode); | |
1358 | rtx shift = gen_rtx (CONST_INT, VOIDmode, 16); | |
1359 | ||
1360 | emit_insn (gen_ashlsi3 (temp, op1, shift)); | |
1361 | emit_insn (gen_ashrsi3 (operands[0], temp, shift)); | |
1362 | DONE; | |
1363 | } | |
1364 | }") | |
1365 | ||
1366 | (define_insn "extendhisi2_internal" | |
1367 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
1368 | (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))] | |
1369 | "" | |
1370 | "* return mips_move_1word (operands, insn, FALSE);" | |
92b4cee1 MM |
1371 | [(set_attr "type" "load") |
1372 | (set_attr "mode" "SI") | |
8ef30996 MM |
1373 | (set_attr "length" "1,2")]) |
1374 | ||
1375 | (define_expand "extendqihi2" | |
1376 | [(set (match_operand:HI 0 "register_operand" "") | |
1377 | (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] | |
1378 | "" | |
1379 | " | |
1380 | { | |
1381 | if (optimize && GET_CODE (operands[1]) == MEM) | |
1382 | operands[1] = force_not_mem (operands[1]); | |
1383 | ||
1384 | if (GET_CODE (operands[1]) != MEM) | |
1385 | { | |
1386 | rtx op0 = gen_lowpart (SImode, operands[0]); | |
1387 | rtx op1 = gen_lowpart (SImode, operands[1]); | |
1388 | rtx temp = gen_reg_rtx (SImode); | |
1389 | rtx shift = gen_rtx (CONST_INT, VOIDmode, 24); | |
1390 | ||
1391 | emit_insn (gen_ashlsi3 (temp, op1, shift)); | |
1392 | emit_insn (gen_ashrsi3 (op0, temp, shift)); | |
1393 | DONE; | |
1394 | } | |
1395 | }") | |
1396 | ||
1397 | (define_insn "extendqihi2_internal" | |
1398 | [(set (match_operand:HI 0 "register_operand" "=d,d") | |
1399 | (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))] | |
1400 | "" | |
1401 | "* return mips_move_1word (operands, insn, FALSE);" | |
92b4cee1 MM |
1402 | [(set_attr "type" "load") |
1403 | (set_attr "mode" "SI") | |
8ef30996 MM |
1404 | (set_attr "length" "1,2")]) |
1405 | ||
1406 | ||
1407 | (define_expand "extendqisi2" | |
1408 | [(set (match_operand:SI 0 "register_operand" "") | |
1409 | (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] | |
1410 | "" | |
1411 | " | |
1412 | { | |
1413 | if (optimize && GET_CODE (operands[1]) == MEM) | |
1414 | operands[1] = force_not_mem (operands[1]); | |
1415 | ||
1416 | if (GET_CODE (operands[1]) != MEM) | |
1417 | { | |
1418 | rtx op1 = gen_lowpart (SImode, operands[1]); | |
1419 | rtx temp = gen_reg_rtx (SImode); | |
1420 | rtx shift = gen_rtx (CONST_INT, VOIDmode, 24); | |
1421 | ||
1422 | emit_insn (gen_ashlsi3 (temp, op1, shift)); | |
1423 | emit_insn (gen_ashrsi3 (operands[0], temp, shift)); | |
1424 | DONE; | |
1425 | } | |
1426 | }") | |
1427 | ||
1428 | (define_insn "extendqisi2_insn" | |
1429 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
1430 | (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))] | |
1431 | "" | |
1432 | "* return mips_move_1word (operands, insn, FALSE);" | |
92b4cee1 MM |
1433 | [(set_attr "type" "load") |
1434 | (set_attr "mode" "SI") | |
8ef30996 MM |
1435 | (set_attr "length" "1,2")]) |
1436 | ||
1437 | ||
1438 | (define_insn "extendsfdf2" | |
1439 | [(set (match_operand:DF 0 "register_operand" "=f") | |
1440 | (float_extend:DF (match_operand:SF 1 "register_operand" "f")))] | |
1441 | "TARGET_HARD_FLOAT" | |
1442 | "cvt.d.s\\t%0,%1" | |
1443 | [(set_attr "type" "fcvt") | |
1444 | (set_attr "mode" "DF") | |
1445 | (set_attr "length" "1")]) | |
1446 | ||
1447 | \f | |
1448 | ||
1449 | ;; | |
1450 | ;; .................... | |
1451 | ;; | |
1452 | ;; CONVERSIONS | |
1453 | ;; | |
1454 | ;; .................... | |
1455 | ||
c7343333 | 1456 | (define_insn "fix_truncdfsi2" |
8ef30996 MM |
1457 | [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o") |
1458 | (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f"))) | |
c7343333 MM |
1459 | (clobber (match_scratch:SI 2 "=d,*d,d,d")) |
1460 | (clobber (match_scratch:DF 3 "=f,*X,f,f"))] | |
8ef30996 MM |
1461 | "TARGET_HARD_FLOAT" |
1462 | "* | |
1463 | { | |
1464 | rtx xoperands[10]; | |
1465 | ||
1466 | if (which_alternative == 1) | |
1467 | return \"trunc.w.d %0,%1,%2\"; | |
1468 | ||
1469 | output_asm_insn (\"trunc.w.d %3,%1,%2\", operands); | |
1470 | ||
1471 | xoperands[0] = operands[0]; | |
1472 | xoperands[1] = operands[3]; | |
1473 | output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands); | |
1474 | return \"\"; | |
1475 | }" | |
92b4cee1 MM |
1476 | [(set_attr "type" "fcvt") |
1477 | (set_attr "mode" "DF") | |
c7343333 | 1478 | (set_attr "length" "11,9,10,11")]) |
8ef30996 MM |
1479 | |
1480 | ||
c7343333 | 1481 | (define_insn "fix_truncsfsi2" |
8ef30996 MM |
1482 | [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o") |
1483 | (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f"))) | |
c7343333 MM |
1484 | (clobber (match_scratch:SI 2 "=d,*d,d,d")) |
1485 | (clobber (match_scratch:SF 3 "=f,*X,f,f"))] | |
8ef30996 MM |
1486 | "TARGET_HARD_FLOAT" |
1487 | "* | |
1488 | { | |
1489 | rtx xoperands[10]; | |
1490 | ||
1491 | if (which_alternative == 1) | |
1492 | return \"trunc.w.s %0,%1,%2\"; | |
1493 | ||
1494 | output_asm_insn (\"trunc.w.s %3,%1,%2\", operands); | |
1495 | ||
1496 | xoperands[0] = operands[0]; | |
1497 | xoperands[1] = operands[3]; | |
1498 | output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands); | |
1499 | return \"\"; | |
1500 | }" | |
92b4cee1 MM |
1501 | [(set_attr "type" "fcvt") |
1502 | (set_attr "mode" "SF") | |
c7343333 | 1503 | (set_attr "length" "11,9,10,11")]) |
8ef30996 MM |
1504 | |
1505 | ||
1506 | (define_insn "floatsidf2" | |
bbdb5552 MM |
1507 | [(set (match_operand:DF 0 "register_operand" "=f,f,f") |
1508 | (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))] | |
8ef30996 | 1509 | "TARGET_HARD_FLOAT" |
bbdb5552 MM |
1510 | "* |
1511 | { | |
1512 | dslots_load_total++; | |
1513 | if (GET_CODE (operands[1]) == MEM) | |
5cccf78f | 1514 | return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\"; |
bbdb5552 MM |
1515 | |
1516 | return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\"; | |
1517 | }" | |
92b4cee1 MM |
1518 | [(set_attr "type" "fcvt") |
1519 | (set_attr "mode" "DF") | |
bbdb5552 | 1520 | (set_attr "length" "3,4,3")]) |
8ef30996 | 1521 | |
c7343333 | 1522 | |
8ef30996 | 1523 | (define_insn "floatsisf2" |
bbdb5552 MM |
1524 | [(set (match_operand:SF 0 "register_operand" "=f,f,f") |
1525 | (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))] | |
8ef30996 | 1526 | "TARGET_HARD_FLOAT" |
bbdb5552 MM |
1527 | "* |
1528 | { | |
1529 | dslots_load_total++; | |
1530 | if (GET_CODE (operands[1]) == MEM) | |
5cccf78f | 1531 | return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\"; |
bbdb5552 MM |
1532 | |
1533 | return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\"; | |
1534 | }" | |
92b4cee1 MM |
1535 | [(set_attr "type" "fcvt") |
1536 | (set_attr "mode" "SF") | |
bbdb5552 MM |
1537 | (set_attr "length" "3,4,3")]) |
1538 | ||
8ef30996 MM |
1539 | |
1540 | (define_expand "fixuns_truncdfsi2" | |
1541 | [(set (match_operand:SI 0 "register_operand" "") | |
1542 | (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))] | |
1543 | "TARGET_HARD_FLOAT" | |
1544 | " | |
1545 | { | |
1546 | rtx reg1 = gen_reg_rtx (DFmode); | |
1547 | rtx reg2 = gen_reg_rtx (DFmode); | |
1548 | rtx reg3 = gen_reg_rtx (SImode); | |
1549 | rtx label1 = gen_label_rtx (); | |
1550 | rtx label2 = gen_label_rtx (); | |
1551 | REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31); | |
1552 | ||
1553 | if (reg1) /* turn off complaints about unreached code */ | |
1554 | { | |
1555 | extern rtx gen_cmpdf (); | |
1556 | emit_move_insn (reg1, immed_real_const_1 (offset, DFmode)); | |
1557 | do_pending_stack_adjust (); | |
1558 | ||
1559 | emit_insn (gen_cmpdf (operands[1], reg1)); | |
1560 | emit_jump_insn (gen_bge (label1)); | |
1561 | ||
1562 | emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1])); | |
1563 | emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, | |
1564 | gen_rtx (LABEL_REF, VOIDmode, label2))); | |
1565 | emit_barrier (); | |
1566 | ||
1567 | emit_label (label1); | |
1568 | emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1)); | |
1569 | emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000)); | |
1570 | ||
1571 | emit_insn (gen_fix_truncdfsi2 (operands[0], reg2)); | |
1572 | emit_insn (gen_iorsi3 (operands[0], operands[0], reg3)); | |
1573 | ||
1574 | emit_label (label2); | |
1575 | ||
1576 | /* allow REG_NOTES to be set on last insn (labels don't have enough | |
1577 | fields, and can't be used for REG_NOTES anyway). */ | |
1578 | emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx)); | |
1579 | DONE; | |
1580 | } | |
1581 | }") | |
1582 | ||
c7343333 | 1583 | |
8ef30996 MM |
1584 | (define_expand "fixuns_truncsfsi2" |
1585 | [(set (match_operand:SI 0 "register_operand" "") | |
1586 | (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))] | |
1587 | "TARGET_HARD_FLOAT" | |
1588 | " | |
1589 | { | |
1590 | rtx reg1 = gen_reg_rtx (SFmode); | |
1591 | rtx reg2 = gen_reg_rtx (SFmode); | |
1592 | rtx reg3 = gen_reg_rtx (SImode); | |
1593 | rtx label1 = gen_label_rtx (); | |
1594 | rtx label2 = gen_label_rtx (); | |
1595 | REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31); | |
1596 | ||
1597 | if (reg1) /* turn off complaints about unreached code */ | |
1598 | { | |
1599 | extern rtx gen_cmpsf (); | |
1600 | emit_move_insn (reg1, immed_real_const_1 (offset, SFmode)); | |
1601 | do_pending_stack_adjust (); | |
1602 | ||
1603 | emit_insn (gen_cmpsf (operands[1], reg1)); | |
1604 | emit_jump_insn (gen_bge (label1)); | |
1605 | ||
1606 | emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1])); | |
1607 | emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, | |
1608 | gen_rtx (LABEL_REF, VOIDmode, label2))); | |
1609 | emit_barrier (); | |
1610 | ||
1611 | emit_label (label1); | |
1612 | emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1)); | |
1613 | emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000)); | |
1614 | ||
1615 | emit_insn (gen_fix_truncsfsi2 (operands[0], reg2)); | |
1616 | emit_insn (gen_iorsi3 (operands[0], operands[0], reg3)); | |
1617 | ||
1618 | emit_label (label2); | |
1619 | ||
1620 | /* allow REG_NOTES to be set on last insn (labels don't have enough | |
1621 | fields, and can't be used for REG_NOTES anyway). */ | |
1622 | emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx)); | |
1623 | DONE; | |
1624 | } | |
1625 | }") | |
1626 | ||
1627 | \f | |
1628 | ;; | |
1629 | ;; .................... | |
1630 | ;; | |
1631 | ;; DATA MOVEMENT | |
1632 | ;; | |
1633 | ;; .................... | |
1634 | ||
1635 | ;; unaligned word moves generated by the block moves. | |
8ef30996 MM |
1636 | |
1637 | (define_expand "movsi_unaligned" | |
6d518002 MM |
1638 | [(set (match_operand:SI 0 "general_operand" "") |
1639 | (unspec [(match_operand:SI 1 "general_operand" "")] 0))] | |
8ef30996 MM |
1640 | "" |
1641 | " | |
1642 | { | |
8ef30996 MM |
1643 | extern rtx gen_movsi_ulw (); |
1644 | extern rtx gen_movsi (); | |
1645 | ||
842eb20e MM |
1646 | /* Handle loads. */ |
1647 | if (GET_CODE (operands[0]) == MEM) | |
8ef30996 MM |
1648 | { |
1649 | rtx reg = gen_reg_rtx (SImode); | |
842eb20e MM |
1650 | rtx insn = emit_insn (gen_movsi_ulw (reg, operands[1])); |
1651 | rtx addr = XEXP (operands[0], 0); | |
1652 | if (CONSTANT_P (addr)) | |
1653 | REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUIV, addr, REG_NOTES (insn)); | |
1654 | ||
1655 | if (reg_or_0_operand (operands[1], SImode)) | |
1656 | DONE; | |
8ef30996 | 1657 | |
8ef30996 MM |
1658 | operands[1] = reg; |
1659 | } | |
1660 | ||
1661 | /* Generate appropriate load, store. If not a load or store, | |
1662 | do a normal movsi. */ | |
1663 | if (GET_CODE (operands[0]) != MEM && GET_CODE (operands[1]) != MEM) | |
1664 | { | |
1665 | emit_insn (gen_movsi (operands[0], operands[1])); | |
1666 | DONE; | |
1667 | } | |
1668 | ||
1669 | /* Fall through and generate normal code. */ | |
1670 | }") | |
1671 | ||
1672 | (define_insn "movsi_ulw" | |
1673 | [(set (match_operand:SI 0 "register_operand" "=&d,&d,d,d") | |
6d518002 | 1674 | (unspec [(match_operand:SI 1 "general_operand" "R,o,dIKL,M")] 0))] |
8ef30996 MM |
1675 | "" |
1676 | "* | |
1677 | { | |
1678 | extern rtx eliminate_constant_term (); | |
1679 | enum rtx_code code; | |
1680 | char *ret; | |
6d518002 | 1681 | rtx offset; |
8ef30996 MM |
1682 | rtx addr; |
1683 | rtx mem_addr; | |
1684 | ||
1685 | if (which_alternative != 0) | |
1686 | return mips_move_1word (operands, insn, FALSE); | |
1687 | ||
1688 | if (TARGET_STATS) | |
1689 | mips_count_memory_refs (operands[1], 2); | |
1690 | ||
1691 | /* The stack/frame pointers are always aligned, so we can convert | |
1692 | to the faster lw if we are referencing an aligned stack location. */ | |
1693 | ||
6d518002 | 1694 | offset = const0_rtx; |
8ef30996 MM |
1695 | addr = XEXP (operands[1], 0); |
1696 | mem_addr = eliminate_constant_term (addr, &offset); | |
1697 | ||
6d518002 | 1698 | if ((INTVAL (offset) & (UNITS_PER_WORD-1)) == 0 |
8ef30996 MM |
1699 | && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx)) |
1700 | ret = \"lw\\t%0,%1\"; | |
1701 | ||
1702 | else | |
1703 | { | |
1704 | ret = \"ulw\\t%0,%1\"; | |
1705 | if (TARGET_GAS) | |
1706 | { | |
1707 | enum rtx_code code = GET_CODE (addr); | |
1708 | ||
1709 | if (code == CONST || code == SYMBOL_REF || code == LABEL_REF) | |
1710 | { | |
1711 | operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 1); | |
1712 | ret = \"%[la\\t%2,%1\;ulw\\t%0,0(%2)%]\"; | |
1713 | } | |
1714 | } | |
1715 | } | |
1716 | ||
1717 | return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn); | |
1718 | }" | |
1719 | [(set_attr "type" "load,load,move,arith") | |
92b4cee1 | 1720 | (set_attr "mode" "SI") |
8ef30996 MM |
1721 | (set_attr "length" "2,4,1,2")]) |
1722 | ||
1723 | (define_insn "movsi_usw" | |
1724 | [(set (match_operand:SI 0 "memory_operand" "=R,o") | |
6d518002 | 1725 | (unspec [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 0))] |
8ef30996 MM |
1726 | "" |
1727 | "* | |
1728 | { | |
1729 | extern rtx eliminate_constant_term (); | |
6d518002 | 1730 | rtx offset = const0_rtx; |
8ef30996 MM |
1731 | rtx addr = XEXP (operands[0], 0); |
1732 | rtx mem_addr = eliminate_constant_term (addr, &offset); | |
1733 | ||
1734 | if (TARGET_STATS) | |
1735 | mips_count_memory_refs (operands[0], 2); | |
1736 | ||
1737 | /* The stack/frame pointers are always aligned, so we can convert | |
1738 | to the faster sw if we are referencing an aligned stack location. */ | |
1739 | ||
6d518002 | 1740 | if ((INTVAL (offset) & (UNITS_PER_WORD-1)) == 0 |
8ef30996 MM |
1741 | && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx)) |
1742 | return \"sw\\t%1,%0\"; | |
1743 | ||
1744 | ||
1745 | if (TARGET_GAS) | |
1746 | { | |
1747 | enum rtx_code code = GET_CODE (XEXP (operands[0], 0)); | |
1748 | ||
1749 | if (code == CONST || code == SYMBOL_REF || code == LABEL_REF) | |
1750 | { | |
1751 | operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 1); | |
1752 | return \"%[la\\t%2,%0\;usw\\t%z1,0(%2)%]\"; | |
1753 | } | |
1754 | } | |
1755 | ||
1756 | return \"usw\\t%z1,%0\"; | |
1757 | }" | |
92b4cee1 MM |
1758 | [(set_attr "type" "store") |
1759 | (set_attr "mode" "SI") | |
8ef30996 MM |
1760 | (set_attr "length" "2,4")]) |
1761 | ||
1762 | ;; 64-bit integer moves | |
1763 | ||
1764 | ;; Unlike most other insns, the move insns can't be split with | |
1765 | ;; different predicates, because register spilling and other parts of | |
1766 | ;; the compiler, have memoized the insn number already. | |
1767 | ||
1768 | (define_insn "movdi" | |
6d518002 MM |
1769 | [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*d,*x") |
1770 | (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,*x,*d"))] | |
8ef30996 MM |
1771 | "" |
1772 | "* return mips_move_2words (operands, insn); " | |
6d518002 | 1773 | [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo") |
92b4cee1 | 1774 | (set_attr "mode" "DI") |
6d518002 | 1775 | (set_attr "length" "2,4,2,4,2,4,2,2")]) |
8ef30996 MM |
1776 | |
1777 | (define_split | |
1778 | [(set (match_operand:DI 0 "register_operand" "") | |
1779 | (match_operand:DI 1 "register_operand" ""))] | |
26b8e6e5 | 1780 | "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
1781 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
1782 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))" | |
1783 | ||
1784 | [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0)) | |
1785 | (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))] | |
1786 | "") | |
1787 | ||
1788 | ||
1789 | ;; 32-bit Integer moves | |
1790 | ||
1791 | (define_split | |
1792 | [(set (match_operand:SI 0 "register_operand" "") | |
1793 | (match_operand:SI 1 "large_int" ""))] | |
26b8e6e5 | 1794 | "!TARGET_DEBUG_D_MODE" |
8ef30996 MM |
1795 | [(set (match_dup 0) |
1796 | (match_dup 2)) | |
1797 | (set (match_dup 0) | |
1798 | (ior:SI (match_dup 0) | |
1799 | (match_dup 3)))] | |
1800 | " | |
1801 | { | |
1802 | operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff0000); | |
1803 | operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0x0000ffff); | |
1804 | }") | |
1805 | ||
1806 | ;; Unlike most other insns, the move insns can't be split with | |
1807 | ;; different predicates, because register spilling and other parts of | |
1808 | ;; the compiler, have memoized the insn number already. | |
1809 | ||
f3b39eba MM |
1810 | (define_expand "movsi" |
1811 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
1812 | (match_operand:SI 1 "general_operand" ""))] | |
1813 | "" | |
c7343333 | 1814 | "") |
f3b39eba | 1815 | |
0fb5ac6f MM |
1816 | ;; The difference between these two is whether or not ints are allowed |
1817 | ;; in FP registers (off by default, use -mdebugh to enable). | |
1818 | ||
1819 | (define_insn "movsi_internal1" | |
ddd8ab48 MM |
1820 | [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*fz,*f,*f,*f,*R,*m,*x,*d") |
1821 | (match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*fz,*d,*f,*R,*m,*f,*f,*d,*x"))] | |
0fb5ac6f | 1822 | "TARGET_DEBUG_H_MODE" |
8ef30996 | 1823 | "* return mips_move_1word (operands, insn, TRUE);" |
c7343333 | 1824 | [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo") |
92b4cee1 | 1825 | (set_attr "mode" "SI") |
c7343333 | 1826 | (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1")]) |
8ef30996 | 1827 | |
0fb5ac6f MM |
1828 | (define_insn "movsi_internal2" |
1829 | [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*d,*x") | |
1830 | (match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,*x,*d"))] | |
1831 | "!TARGET_DEBUG_H_MODE" | |
1832 | "* return mips_move_1word (operands, insn, TRUE);" | |
c7343333 | 1833 | [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo") |
0fb5ac6f | 1834 | (set_attr "mode" "SI") |
c7343333 | 1835 | (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1")]) |
0fb5ac6f MM |
1836 | |
1837 | ||
8ef30996 MM |
1838 | ;; 16-bit Integer moves |
1839 | ||
1840 | ;; Unlike most other insns, the move insns can't be split with | |
1841 | ;; different predicates, because register spilling and other parts of | |
1842 | ;; the compiler, have memoized the insn number already. | |
1843 | ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined | |
1844 | ||
0fb5ac6f MM |
1845 | (define_expand "movhi" |
1846 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
1847 | (match_operand:HI 1 "general_operand" ""))] | |
8ef30996 | 1848 | "" |
0fb5ac6f MM |
1849 | "") |
1850 | ||
1851 | ;; The difference between these two is whether or not ints are allowed | |
1852 | ;; in FP registers (off by default, use -mdebugh to enable). | |
1853 | ||
1854 | (define_insn "movhi_internal1" | |
1855 | [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*fz,*x,*d") | |
1856 | (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*fz,*d,*f,*d,*x"))] | |
1857 | "TARGET_DEBUG_H_MODE" | |
8ef30996 MM |
1858 | "* return mips_move_1word (operands, insn, TRUE);" |
1859 | [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo") | |
92b4cee1 | 1860 | (set_attr "mode" "HI") |
8ef30996 MM |
1861 | (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")]) |
1862 | ||
0fb5ac6f MM |
1863 | (define_insn "movhi_internal2" |
1864 | [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d") | |
1865 | (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))] | |
1866 | "!TARGET_DEBUG_H_MODE" | |
1867 | "* return mips_move_1word (operands, insn, TRUE);" | |
1868 | [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo") | |
1869 | (set_attr "mode" "HI") | |
1870 | (set_attr "length" "1,1,1,2,1,2,1,1,1,1")]) | |
1871 | ||
1872 | ||
8ef30996 MM |
1873 | ;; 8-bit Integer moves |
1874 | ||
1875 | ;; Unlike most other insns, the move insns can't be split with | |
1876 | ;; different predicates, because register spilling and other parts of | |
1877 | ;; the compiler, have memoized the insn number already. | |
1878 | ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined | |
1879 | ||
0fb5ac6f MM |
1880 | (define_expand "movqi" |
1881 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
1882 | (match_operand:QI 1 "general_operand" ""))] | |
8ef30996 | 1883 | "" |
0fb5ac6f MM |
1884 | "") |
1885 | ||
1886 | ;; The difference between these two is whether or not ints are allowed | |
1887 | ;; in FP registers (off by default, use -mdebugh to enable). | |
1888 | ||
1889 | (define_insn "movqi_internal1" | |
1890 | [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*fz,*f,*x,*d") | |
1891 | (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*fz,*d,*f,*d,*x"))] | |
1892 | "TARGET_DEBUG_H_MODE" | |
8ef30996 MM |
1893 | "* return mips_move_1word (operands, insn, TRUE);" |
1894 | [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo") | |
92b4cee1 | 1895 | (set_attr "mode" "QI") |
8ef30996 MM |
1896 | (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")]) |
1897 | ||
0fb5ac6f MM |
1898 | (define_insn "movqi_internal2" |
1899 | [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d") | |
1900 | (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))] | |
1901 | "!TARGET_DEBUG_H_MODE" | |
1902 | "* return mips_move_1word (operands, insn, TRUE);" | |
1903 | [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo") | |
1904 | (set_attr "mode" "QI") | |
1905 | (set_attr "length" "1,1,1,2,1,2,1,1,1,1")]) | |
1906 | ||
8ef30996 MM |
1907 | |
1908 | ;; 32-bit floating point moves | |
1909 | ||
1910 | (define_insn "movsf" | |
1911 | [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m") | |
1912 | (match_operand:SF 1 "general_operand" "f,G,R,Em,fG,fG,*d,*f,*Gd,*R,*Em,*d,*d"))] | |
1913 | "" | |
1914 | "* return mips_move_1word (operands, insn, FALSE);" | |
1915 | [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store") | |
92b4cee1 | 1916 | (set_attr "mode" "SF") |
8ef30996 MM |
1917 | (set_attr "length" "1,1,1,2,1,2,1,1,1,1,2,1,2")]) |
1918 | ||
1919 | ;; 64-bit floating point moves | |
1920 | ||
1921 | (define_insn "movdf" | |
1922 | [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,o,f,*f,*d,*d,*d,*d,*R,*o") | |
1923 | (match_operand:DF 1 "general_operand" "f,R,o,fG,fG,E,*d,*f,*dG,*R,*oE,*d,*d"))] | |
1924 | "" | |
1925 | "* return mips_move_2words (operands, insn); " | |
1926 | [(set_attr "type" "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store") | |
92b4cee1 | 1927 | (set_attr "mode" "DF") |
8ef30996 MM |
1928 | (set_attr "length" "1,2,4,2,4,4,2,2,2,2,4,2,4")]) |
1929 | ||
1930 | (define_split | |
1931 | [(set (match_operand:DF 0 "register_operand" "") | |
1932 | (match_operand:DF 1 "register_operand" ""))] | |
26b8e6e5 | 1933 | "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
1934 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
1935 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))" | |
1936 | ||
1937 | [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0)) | |
1938 | (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))] | |
1939 | "") | |
1940 | ||
26b8e6e5 | 1941 | \f |
8ef30996 MM |
1942 | ;; Block moves, see mips.c for more details. |
1943 | ;; Argument 0 is the destination | |
1944 | ;; Argument 1 is the source | |
1945 | ;; Argument 2 is the length | |
1946 | ;; Argument 3 is the alignment | |
1947 | ||
1948 | (define_expand "movstrsi" | |
1949 | [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) | |
1950 | (mem:BLK (match_operand:BLK 1 "general_operand" ""))) | |
1951 | (use (match_operand:SI 2 "arith32_operand" "")) | |
1952 | (use (match_operand:SI 3 "immediate_operand" ""))])] | |
1953 | "" | |
1954 | " | |
1955 | { | |
1956 | if (operands[0]) /* avoid unused code messages */ | |
1957 | { | |
1958 | expand_block_move (operands); | |
1959 | DONE; | |
1960 | } | |
1961 | }") | |
1962 | ||
842eb20e MM |
1963 | ;; Insn generated by block moves |
1964 | ||
1965 | (define_insn "movstrsi_internal" | |
26b8e6e5 MM |
1966 | [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination |
1967 | (match_operand:BLK 1 "memory_operand" "Ro")) ;; source | |
1968 | (clobber (match_scratch:SI 4 "=&d")) ;; temp 1 | |
1969 | (clobber (match_scratch:SI 5 "=&d")) ;; temp 2 | |
1970 | (clobber (match_scratch:SI 6 "=&d")) ;; temp 3 | |
1971 | (clobber (match_scratch:SI 7 "=&d")) ;; temp 4 | |
1972 | (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move | |
1973 | (use (match_operand:SI 3 "small_int" "I")) ;; alignment | |
1974 | (use (const_int 0))] ;; normal block move | |
1975 | "" | |
1976 | "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);" | |
842eb20e MM |
1977 | [(set_attr "type" "multi") |
1978 | (set_attr "mode" "none") | |
1979 | (set_attr "length" "20")]) | |
1980 | ||
26b8e6e5 MM |
1981 | ;; Split a block move into 2 parts, the first part is everything |
1982 | ;; except for the last move, and the second part is just the last | |
1983 | ;; store, which is exactly 1 instruction (ie, not a usw), so it can | |
1984 | ;; fill a delay slot. This also prevents a bug in delayed branches | |
1985 | ;; from showing up, which reuses one of the registers in our clobbers. | |
1986 | ||
1987 | (define_split | |
1988 | [(set (mem:BLK (match_operand:SI 0 "register_operand" "")) | |
1989 | (mem:BLK (match_operand:SI 1 "register_operand" ""))) | |
1990 | (clobber (match_operand:SI 4 "register_operand" "")) | |
1991 | (clobber (match_operand:SI 5 "register_operand" "")) | |
1992 | (clobber (match_operand:SI 6 "register_operand" "")) | |
1993 | (clobber (match_operand:SI 7 "register_operand" "")) | |
1994 | (use (match_operand:SI 2 "small_int" "")) | |
1995 | (use (match_operand:SI 3 "small_int" "")) | |
1996 | (use (const_int 0))] | |
1997 | ||
1998 | "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0" | |
1999 | ||
2000 | ;; All but the last move | |
2001 | [(parallel [(set (mem:BLK (match_dup 0)) | |
2002 | (mem:BLK (match_dup 1))) | |
2003 | (clobber (match_dup 4)) | |
2004 | (clobber (match_dup 5)) | |
2005 | (clobber (match_dup 6)) | |
2006 | (clobber (match_dup 7)) | |
2007 | (use (match_dup 2)) | |
2008 | (use (match_dup 3)) | |
2009 | (use (const_int 1))]) | |
2010 | ||
2011 | ;; The last store, so it can fill a delay slot | |
2012 | (parallel [(set (mem:BLK (match_dup 0)) | |
2013 | (mem:BLK (match_dup 1))) | |
2014 | (clobber (match_dup 4)) | |
2015 | (clobber (match_dup 5)) | |
2016 | (clobber (match_dup 6)) | |
2017 | (clobber (match_dup 7)) | |
2018 | (use (match_dup 2)) | |
2019 | (use (match_dup 3)) | |
2020 | (use (const_int 2))])] | |
2021 | ||
2022 | "") | |
2023 | ||
2024 | (define_insn "movstrsi_internal2" | |
2025 | [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination | |
2026 | (match_operand:BLK 1 "memory_operand" "Ro")) ;; source | |
2027 | (clobber (match_scratch:SI 4 "=&d")) ;; temp 1 | |
2028 | (clobber (match_scratch:SI 5 "=&d")) ;; temp 2 | |
2029 | (clobber (match_scratch:SI 6 "=&d")) ;; temp 3 | |
2030 | (clobber (match_scratch:SI 7 "=&d")) ;; temp 4 | |
2031 | (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move | |
2032 | (use (match_operand:SI 3 "small_int" "I")) ;; alignment | |
2033 | (use (const_int 1))] ;; all but last store | |
2034 | "" | |
2035 | "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);" | |
2036 | [(set_attr "type" "multi") | |
2037 | (set_attr "mode" "none") | |
2038 | (set_attr "length" "20")]) | |
2039 | ||
2040 | (define_insn "movstrsi_internal3" | |
2041 | [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination | |
2042 | (match_operand:BLK 1 "memory_operand" "Ro")) ;; source | |
2043 | (clobber (match_scratch:SI 4 "=&d")) ;; temp 1 | |
2044 | (clobber (match_scratch:SI 5 "=&d")) ;; temp 2 | |
2045 | (clobber (match_scratch:SI 6 "=&d")) ;; temp 3 | |
2046 | (clobber (match_scratch:SI 7 "=&d")) ;; temp 4 | |
2047 | (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move | |
2048 | (use (match_operand:SI 3 "small_int" "I")) ;; alignment | |
2049 | (use (const_int 2))] ;; just last store of block mvoe | |
2050 | "" | |
2051 | "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);" | |
2052 | [(set_attr "type" "store") | |
2053 | (set_attr "mode" "none") | |
2054 | (set_attr "length" "1")]) | |
2055 | ||
8ef30996 MM |
2056 | \f |
2057 | ;; | |
2058 | ;; .................... | |
2059 | ;; | |
2060 | ;; SHIFTS | |
2061 | ;; | |
2062 | ;; .................... | |
2063 | ||
2064 | (define_insn "ashlsi3" | |
2065 | [(set (match_operand:SI 0 "register_operand" "=d") | |
2066 | (ashift:SI (match_operand:SI 1 "register_operand" "d") | |
2067 | (match_operand:SI 2 "arith_operand" "dI")))] | |
2068 | "" | |
2069 | "* | |
2070 | { | |
2071 | if (GET_CODE (operands[2]) == CONST_INT) | |
2072 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f); | |
2073 | ||
2074 | return \"sll\\t%0,%1,%2\"; | |
2075 | }" | |
2076 | [(set_attr "type" "arith") | |
2077 | (set_attr "mode" "SI") | |
2078 | (set_attr "length" "1")]) | |
2079 | ||
2080 | ||
2081 | (define_expand "ashldi3" | |
2082 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
2083 | (ashift:DI (match_operand:DI 1 "register_operand" "") | |
2084 | (match_operand:SI 2 "arith_operand" ""))) | |
2085 | (clobber (match_dup 3))])] | |
2086 | "!TARGET_DEBUG_G_MODE" | |
2087 | "operands[3] = gen_reg_rtx (SImode);") | |
2088 | ||
2089 | ||
2090 | (define_insn "ashldi3_internal" | |
0fb5ac6f | 2091 | [(set (match_operand:DI 0 "register_operand" "=&d") |
8ef30996 MM |
2092 | (ashift:DI (match_operand:DI 1 "register_operand" "d") |
2093 | (match_operand:SI 2 "register_operand" "d"))) | |
2094 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2095 | "!TARGET_DEBUG_G_MODE" | |
2096 | "* | |
2097 | { | |
2098 | operands[4] = const0_rtx; | |
2099 | dslots_jump_total += 3; | |
2100 | dslots_jump_filled += 2; | |
2101 | ||
2102 | return \"sll\\t%3,%2,26\\n\\ | |
2103 | \\tbgez\\t%3,1f\\n\\ | |
2104 | \\tsll\\t%M0,%L1,%2\\n\\ | |
2105 | \\t%(b\\t3f\\n\\ | |
2106 | \\tmove\\t%L0,%z4%)\\n\\ | |
2107 | \\n\\ | |
2108 | 1:\\n\\ | |
2109 | \\t%(beq\\t%3,%z4,2f\\n\\ | |
2110 | \\tsll\\t%M0,%M1,%2%)\\n\\ | |
2111 | \\n\\ | |
2112 | \\tsubu\\t%3,%z4,%2\\n\\ | |
2113 | \\tsrl\\t%3,%L1,%3\\n\\ | |
2114 | \\tor\\t%M0,%M0,%3\\n\\ | |
2115 | 2:\\n\\ | |
2116 | \\tsll\\t%L0,%L1,%2\\n\\ | |
2117 | 3:\"; | |
2118 | }" | |
2119 | [(set_attr "type" "darith") | |
2120 | (set_attr "mode" "SI") | |
2121 | (set_attr "length" "12")]) | |
2122 | ||
2123 | ||
2124 | (define_insn "ashldi3_internal2" | |
2125 | [(set (match_operand:DI 0 "register_operand" "=d") | |
2126 | (ashift:DI (match_operand:DI 1 "register_operand" "d") | |
2127 | (match_operand:SI 2 "small_int" "IJK"))) | |
2128 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2129 | "!TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0" | |
2130 | "* | |
2131 | { | |
2132 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f); | |
2133 | operands[4] = const0_rtx; | |
2134 | return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\"; | |
2135 | }" | |
2136 | [(set_attr "type" "darith") | |
2137 | (set_attr "mode" "DI") | |
2138 | (set_attr "length" "2")]) | |
2139 | ||
2140 | ||
2141 | (define_split | |
2142 | [(set (match_operand:DI 0 "register_operand" "") | |
2143 | (ashift:DI (match_operand:DI 1 "register_operand" "") | |
2144 | (match_operand:SI 2 "small_int" ""))) | |
2145 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 2146 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
2147 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
2148 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
2149 | && (INTVAL (operands[2]) & 32) != 0" | |
2150 | ||
2151 | [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2))) | |
2152 | (set (subreg:SI (match_dup 0) 0) (const_int 0))] | |
2153 | ||
2154 | "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);") | |
2155 | ||
2156 | ||
2157 | (define_split | |
2158 | [(set (match_operand:DI 0 "register_operand" "") | |
2159 | (ashift:DI (match_operand:DI 1 "register_operand" "") | |
2160 | (match_operand:SI 2 "small_int" ""))) | |
2161 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 2162 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
2163 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
2164 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
2165 | && (INTVAL (operands[2]) & 32) != 0" | |
2166 | ||
2167 | [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2))) | |
2168 | (set (subreg:SI (match_dup 0) 1) (const_int 0))] | |
2169 | ||
2170 | "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);") | |
2171 | ||
2172 | ||
2173 | (define_insn "ashldi3_internal3" | |
2174 | [(set (match_operand:DI 0 "register_operand" "=d") | |
2175 | (ashift:DI (match_operand:DI 1 "register_operand" "d") | |
2176 | (match_operand:SI 2 "small_int" "IJK"))) | |
2177 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2178 | "!TARGET_DEBUG_G_MODE | |
2179 | && (INTVAL (operands[2]) & 63) < 32 | |
2180 | && (INTVAL (operands[2]) & 63) != 0" | |
2181 | "* | |
2182 | { | |
2183 | int amount = INTVAL (operands[2]); | |
2184 | ||
2185 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); | |
2186 | operands[4] = const0_rtx; | |
2187 | operands[5] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); | |
2188 | ||
2189 | return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\"; | |
2190 | }" | |
2191 | [(set_attr "type" "darith") | |
2192 | (set_attr "mode" "DI") | |
2193 | (set_attr "length" "4")]) | |
2194 | ||
2195 | ||
2196 | (define_split | |
2197 | [(set (match_operand:DI 0 "register_operand" "") | |
2198 | (ashift:DI (match_operand:DI 1 "register_operand" "") | |
2199 | (match_operand:SI 2 "small_int" ""))) | |
2200 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 2201 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
2202 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
2203 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
2204 | && (INTVAL (operands[2]) & 63) < 32 | |
2205 | && (INTVAL (operands[2]) & 63) != 0" | |
2206 | ||
2207 | [(set (subreg:SI (match_dup 0) 1) | |
2208 | (ashift:SI (subreg:SI (match_dup 1) 1) | |
2209 | (match_dup 2))) | |
2210 | ||
2211 | (set (match_dup 3) | |
2212 | (lshiftrt:SI (subreg:SI (match_dup 1) 0) | |
2213 | (match_dup 4))) | |
2214 | ||
2215 | (set (subreg:SI (match_dup 0) 1) | |
2216 | (ior:SI (subreg:SI (match_dup 0) 1) | |
2217 | (match_dup 3))) | |
2218 | ||
2219 | (set (subreg:SI (match_dup 0) 0) | |
2220 | (ashift:SI (subreg:SI (match_dup 1) 0) | |
2221 | (match_dup 2)))] | |
2222 | " | |
2223 | { | |
2224 | int amount = INTVAL (operands[2]); | |
2225 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); | |
2226 | operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); | |
2227 | }") | |
2228 | ||
2229 | ||
2230 | (define_split | |
2231 | [(set (match_operand:DI 0 "register_operand" "") | |
2232 | (ashift:DI (match_operand:DI 1 "register_operand" "") | |
2233 | (match_operand:SI 2 "small_int" ""))) | |
2234 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 2235 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
2236 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
2237 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
2238 | && (INTVAL (operands[2]) & 63) < 32 | |
2239 | && (INTVAL (operands[2]) & 63) != 0" | |
2240 | ||
2241 | [(set (subreg:SI (match_dup 0) 0) | |
2242 | (ashift:SI (subreg:SI (match_dup 1) 0) | |
2243 | (match_dup 2))) | |
2244 | ||
2245 | (set (match_dup 3) | |
2246 | (lshiftrt:SI (subreg:SI (match_dup 1) 1) | |
2247 | (match_dup 4))) | |
2248 | ||
2249 | (set (subreg:SI (match_dup 0) 0) | |
2250 | (ior:SI (subreg:SI (match_dup 0) 0) | |
2251 | (match_dup 3))) | |
2252 | ||
2253 | (set (subreg:SI (match_dup 0) 1) | |
2254 | (ashift:SI (subreg:SI (match_dup 1) 1) | |
2255 | (match_dup 2)))] | |
2256 | " | |
2257 | { | |
2258 | int amount = INTVAL (operands[2]); | |
2259 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); | |
2260 | operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); | |
2261 | }") | |
2262 | ||
2263 | ||
2264 | (define_insn "ashrsi3" | |
2265 | [(set (match_operand:SI 0 "register_operand" "=d") | |
2266 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "d") | |
2267 | (match_operand:SI 2 "arith_operand" "dI")))] | |
2268 | "" | |
2269 | "* | |
2270 | { | |
2271 | if (GET_CODE (operands[2]) == CONST_INT) | |
2272 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f); | |
2273 | ||
2274 | return \"sra\\t%0,%1,%2\"; | |
2275 | }" | |
2276 | [(set_attr "type" "arith") | |
2277 | (set_attr "mode" "SI") | |
2278 | (set_attr "length" "1")]) | |
2279 | ||
2280 | ||
2281 | (define_expand "ashrdi3" | |
2282 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
2283 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
2284 | (match_operand:SI 2 "arith_operand" ""))) | |
2285 | (clobber (match_dup 3))])] | |
2286 | "!TARGET_DEBUG_G_MODE" | |
2287 | "operands[3] = gen_reg_rtx (SImode);") | |
2288 | ||
2289 | ||
2290 | (define_insn "ashrdi3_internal" | |
0fb5ac6f | 2291 | [(set (match_operand:DI 0 "register_operand" "=&d") |
8ef30996 MM |
2292 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") |
2293 | (match_operand:SI 2 "register_operand" "d"))) | |
2294 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2295 | "!TARGET_DEBUG_G_MODE" | |
2296 | "* | |
2297 | { | |
2298 | operands[4] = const0_rtx; | |
2299 | dslots_jump_total += 3; | |
2300 | dslots_jump_filled += 2; | |
2301 | ||
2302 | return \"sll\\t%3,%2,26\\n\\ | |
2303 | \\tbgez\\t%3,1f\\n\\ | |
2304 | \\tsra\\t%L0,%M1,%2\\n\\ | |
2305 | \\t%(b\\t3f\\n\\ | |
2306 | \\tsra\\t%M0,%M1,31%)\\n\\ | |
2307 | \\n\\ | |
2308 | 1:\\n\\ | |
2309 | \\t%(beq\\t%3,%z4,2f\\n\\ | |
2310 | \\tsrl\\t%L0,%L1,%2%)\\n\\ | |
2311 | \\n\\ | |
2312 | \\tsubu\\t%3,%z4,%2\\n\\ | |
2313 | \\tsll\\t%3,%M1,%3\\n\\ | |
2314 | \\tor\\t%L0,%L0,%3\\n\\ | |
2315 | 2:\\n\\ | |
2316 | \\tsra\\t%M0,%M1,%2\\n\\ | |
2317 | 3:\"; | |
2318 | }" | |
2319 | [(set_attr "type" "darith") | |
2320 | (set_attr "mode" "DI") | |
2321 | (set_attr "length" "12")]) | |
2322 | ||
2323 | ||
2324 | (define_insn "ashrdi3_internal2" | |
2325 | [(set (match_operand:DI 0 "register_operand" "=d") | |
2326 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") | |
2327 | (match_operand:SI 2 "small_int" "IJK"))) | |
2328 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2329 | "!TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0" | |
2330 | "* | |
2331 | { | |
2332 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f); | |
2333 | return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\"; | |
2334 | }" | |
2335 | [(set_attr "type" "darith") | |
2336 | (set_attr "mode" "DI") | |
2337 | (set_attr "length" "2")]) | |
2338 | ||
2339 | ||
2340 | (define_split | |
2341 | [(set (match_operand:DI 0 "register_operand" "") | |
2342 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
2343 | (match_operand:SI 2 "small_int" ""))) | |
2344 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 2345 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
2346 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
2347 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
2348 | && (INTVAL (operands[2]) & 32) != 0" | |
2349 | ||
2350 | [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2))) | |
2351 | (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))] | |
2352 | ||
2353 | "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);") | |
2354 | ||
2355 | ||
2356 | (define_split | |
2357 | [(set (match_operand:DI 0 "register_operand" "") | |
2358 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
2359 | (match_operand:SI 2 "small_int" ""))) | |
2360 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 2361 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
2362 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
2363 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
2364 | && (INTVAL (operands[2]) & 32) != 0" | |
2365 | ||
2366 | [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2))) | |
2367 | (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))] | |
2368 | ||
2369 | "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);") | |
2370 | ||
2371 | ||
2372 | (define_insn "ashrdi3_internal3" | |
2373 | [(set (match_operand:DI 0 "register_operand" "=d") | |
2374 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") | |
2375 | (match_operand:SI 2 "small_int" "IJK"))) | |
2376 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2377 | "!TARGET_DEBUG_G_MODE | |
2378 | && (INTVAL (operands[2]) & 63) < 32 | |
2379 | && (INTVAL (operands[2]) & 63) != 0" | |
2380 | "* | |
2381 | { | |
2382 | int amount = INTVAL (operands[2]); | |
2383 | ||
2384 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); | |
2385 | operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); | |
2386 | ||
2387 | return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\"; | |
2388 | }" | |
2389 | [(set_attr "type" "darith") | |
2390 | (set_attr "mode" "DI") | |
2391 | (set_attr "length" "4")]) | |
2392 | ||
2393 | ||
2394 | (define_split | |
2395 | [(set (match_operand:DI 0 "register_operand" "") | |
2396 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
2397 | (match_operand:SI 2 "small_int" ""))) | |
2398 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 2399 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
2400 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
2401 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
2402 | && (INTVAL (operands[2]) & 63) < 32 | |
2403 | && (INTVAL (operands[2]) & 63) != 0" | |
2404 | ||
2405 | [(set (subreg:SI (match_dup 0) 0) | |
2406 | (lshiftrt:SI (subreg:SI (match_dup 1) 0) | |
2407 | (match_dup 2))) | |
2408 | ||
2409 | (set (match_dup 3) | |
2410 | (ashift:SI (subreg:SI (match_dup 1) 1) | |
2411 | (match_dup 4))) | |
2412 | ||
2413 | (set (subreg:SI (match_dup 0) 0) | |
2414 | (ior:SI (subreg:SI (match_dup 0) 0) | |
2415 | (match_dup 3))) | |
2416 | ||
2417 | (set (subreg:SI (match_dup 0) 1) | |
2418 | (ashiftrt:SI (subreg:SI (match_dup 1) 1) | |
2419 | (match_dup 2)))] | |
2420 | " | |
2421 | { | |
2422 | int amount = INTVAL (operands[2]); | |
2423 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); | |
2424 | operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); | |
2425 | }") | |
2426 | ||
2427 | ||
2428 | (define_split | |
2429 | [(set (match_operand:DI 0 "register_operand" "") | |
2430 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
2431 | (match_operand:SI 2 "small_int" ""))) | |
2432 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 2433 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
2434 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
2435 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
2436 | && (INTVAL (operands[2]) & 63) < 32 | |
2437 | && (INTVAL (operands[2]) & 63) != 0" | |
2438 | ||
2439 | [(set (subreg:SI (match_dup 0) 1) | |
2440 | (lshiftrt:SI (subreg:SI (match_dup 1) 1) | |
2441 | (match_dup 2))) | |
2442 | ||
2443 | (set (match_dup 3) | |
2444 | (ashift:SI (subreg:SI (match_dup 1) 0) | |
2445 | (match_dup 4))) | |
2446 | ||
2447 | (set (subreg:SI (match_dup 0) 1) | |
2448 | (ior:SI (subreg:SI (match_dup 0) 1) | |
2449 | (match_dup 3))) | |
2450 | ||
2451 | (set (subreg:SI (match_dup 0) 0) | |
2452 | (ashiftrt:SI (subreg:SI (match_dup 1) 0) | |
2453 | (match_dup 2)))] | |
2454 | " | |
2455 | { | |
2456 | int amount = INTVAL (operands[2]); | |
2457 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); | |
2458 | operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); | |
2459 | }") | |
2460 | ||
2461 | ||
2462 | (define_insn "lshrsi3" | |
2463 | [(set (match_operand:SI 0 "register_operand" "=d") | |
2464 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") | |
2465 | (match_operand:SI 2 "arith_operand" "dI")))] | |
2466 | "" | |
2467 | "* | |
2468 | { | |
2469 | if (GET_CODE (operands[2]) == CONST_INT) | |
2470 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f); | |
2471 | ||
2472 | return \"srl\\t%0,%1,%2\"; | |
2473 | }" | |
2474 | [(set_attr "type" "arith") | |
2475 | (set_attr "mode" "SI") | |
2476 | (set_attr "length" "1")]) | |
2477 | ||
2478 | ||
2479 | (define_expand "lshrdi3" | |
2480 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
2481 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
2482 | (match_operand:SI 2 "arith_operand" ""))) | |
2483 | (clobber (match_dup 3))])] | |
2484 | "!TARGET_DEBUG_G_MODE" | |
2485 | "operands[3] = gen_reg_rtx (SImode);") | |
2486 | ||
2487 | ||
2488 | (define_insn "lshrdi3_internal" | |
2489 | [(set (match_operand:DI 0 "register_operand" "=&d") | |
2490 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") | |
2491 | (match_operand:SI 2 "register_operand" "d"))) | |
2492 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2493 | "!TARGET_DEBUG_G_MODE" | |
2494 | "* | |
2495 | { | |
2496 | operands[4] = const0_rtx; | |
2497 | dslots_jump_total += 3; | |
2498 | dslots_jump_filled += 2; | |
2499 | ||
2500 | return \"sll\\t%3,%2,26\\n\\ | |
2501 | \\tbgez\\t%3,1f\\n\\ | |
2502 | \\tsrl\\t%L0,%M1,%2\\n\\ | |
2503 | \\t%(b\\t3f\\n\\ | |
2504 | \\tmove\\t%M0,%z4%)\\n\\ | |
2505 | \\n\\ | |
2506 | 1:\\n\\ | |
2507 | \\t%(beq\\t%3,%z4,2f\\n\\ | |
2508 | \\tsrl\\t%L0,%L1,%2%)\\n\\ | |
2509 | \\n\\ | |
2510 | \\tsubu\\t%3,%z4,%2\\n\\ | |
2511 | \\tsll\\t%3,%M1,%3\\n\\ | |
2512 | \\tor\\t%L0,%L0,%3\\n\\ | |
2513 | 2:\\n\\ | |
2514 | \\tsrl\\t%M0,%M1,%2\\n\\ | |
2515 | 3:\"; | |
2516 | }" | |
2517 | [(set_attr "type" "darith") | |
2518 | (set_attr "mode" "DI") | |
2519 | (set_attr "length" "12")]) | |
2520 | ||
2521 | ||
2522 | (define_insn "lshrdi3_internal2" | |
2523 | [(set (match_operand:DI 0 "register_operand" "=d") | |
2524 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") | |
2525 | (match_operand:SI 2 "small_int" "IJK"))) | |
2526 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2527 | "!TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0" | |
2528 | "* | |
2529 | { | |
2530 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f); | |
2531 | operands[4] = const0_rtx; | |
2532 | return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\"; | |
2533 | }" | |
2534 | [(set_attr "type" "darith") | |
2535 | (set_attr "mode" "DI") | |
2536 | (set_attr "length" "2")]) | |
2537 | ||
2538 | ||
2539 | (define_split | |
2540 | [(set (match_operand:DI 0 "register_operand" "") | |
2541 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
2542 | (match_operand:SI 2 "small_int" ""))) | |
2543 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 2544 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
2545 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
2546 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
2547 | && (INTVAL (operands[2]) & 32) != 0" | |
2548 | ||
2549 | [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2))) | |
2550 | (set (subreg:SI (match_dup 0) 1) (const_int 0))] | |
2551 | ||
2552 | "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);") | |
2553 | ||
2554 | ||
2555 | (define_split | |
2556 | [(set (match_operand:DI 0 "register_operand" "") | |
2557 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
2558 | (match_operand:SI 2 "small_int" ""))) | |
2559 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 2560 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
2561 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
2562 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
2563 | && (INTVAL (operands[2]) & 32) != 0" | |
2564 | ||
2565 | [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2))) | |
2566 | (set (subreg:SI (match_dup 0) 0) (const_int 0))] | |
2567 | ||
2568 | "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);") | |
2569 | ||
2570 | ||
2571 | (define_insn "lshrdi3_internal3" | |
2572 | [(set (match_operand:DI 0 "register_operand" "=d") | |
2573 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") | |
2574 | (match_operand:SI 2 "small_int" "IJK"))) | |
2575 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2576 | "!TARGET_DEBUG_G_MODE | |
2577 | && (INTVAL (operands[2]) & 63) < 32 | |
2578 | && (INTVAL (operands[2]) & 63) != 0" | |
2579 | "* | |
2580 | { | |
2581 | int amount = INTVAL (operands[2]); | |
2582 | ||
2583 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); | |
2584 | operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); | |
2585 | ||
2586 | return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\"; | |
2587 | }" | |
2588 | [(set_attr "type" "darith") | |
2589 | (set_attr "mode" "DI") | |
2590 | (set_attr "length" "4")]) | |
2591 | ||
2592 | ||
2593 | (define_split | |
2594 | [(set (match_operand:DI 0 "register_operand" "") | |
2595 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
2596 | (match_operand:SI 2 "small_int" ""))) | |
2597 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 2598 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
2599 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
2600 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
2601 | && (INTVAL (operands[2]) & 63) < 32 | |
2602 | && (INTVAL (operands[2]) & 63) != 0" | |
2603 | ||
2604 | [(set (subreg:SI (match_dup 0) 0) | |
2605 | (lshiftrt:SI (subreg:SI (match_dup 1) 0) | |
2606 | (match_dup 2))) | |
2607 | ||
2608 | (set (match_dup 3) | |
2609 | (ashift:SI (subreg:SI (match_dup 1) 1) | |
2610 | (match_dup 4))) | |
2611 | ||
2612 | (set (subreg:SI (match_dup 0) 0) | |
2613 | (ior:SI (subreg:SI (match_dup 0) 0) | |
2614 | (match_dup 3))) | |
2615 | ||
2616 | (set (subreg:SI (match_dup 0) 1) | |
2617 | (lshiftrt:SI (subreg:SI (match_dup 1) 1) | |
2618 | (match_dup 2)))] | |
2619 | " | |
2620 | { | |
2621 | int amount = INTVAL (operands[2]); | |
2622 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); | |
2623 | operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); | |
2624 | }") | |
2625 | ||
2626 | ||
2627 | (define_split | |
2628 | [(set (match_operand:DI 0 "register_operand" "") | |
2629 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
2630 | (match_operand:SI 2 "small_int" ""))) | |
2631 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
26b8e6e5 | 2632 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE |
8ef30996 MM |
2633 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
2634 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
2635 | && (INTVAL (operands[2]) & 63) < 32 | |
2636 | && (INTVAL (operands[2]) & 63) != 0" | |
2637 | ||
2638 | [(set (subreg:SI (match_dup 0) 1) | |
2639 | (lshiftrt:SI (subreg:SI (match_dup 1) 1) | |
2640 | (match_dup 2))) | |
2641 | ||
2642 | (set (match_dup 3) | |
2643 | (ashift:SI (subreg:SI (match_dup 1) 0) | |
2644 | (match_dup 4))) | |
2645 | ||
2646 | (set (subreg:SI (match_dup 0) 1) | |
2647 | (ior:SI (subreg:SI (match_dup 0) 1) | |
2648 | (match_dup 3))) | |
2649 | ||
2650 | (set (subreg:SI (match_dup 0) 0) | |
2651 | (lshiftrt:SI (subreg:SI (match_dup 1) 0) | |
2652 | (match_dup 2)))] | |
2653 | " | |
2654 | { | |
2655 | int amount = INTVAL (operands[2]); | |
2656 | operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); | |
2657 | operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); | |
2658 | }") | |
2659 | ||
2660 | \f | |
2661 | ;; | |
2662 | ;; .................... | |
2663 | ;; | |
2664 | ;; COMPARISONS | |
2665 | ;; | |
2666 | ;; .................... | |
2667 | ||
2668 | ;; Flow here is rather complex: | |
2669 | ;; | |
2670 | ;; 1) The cmp{si,sf,df} routine is called. It deposits the | |
2671 | ;; arguments into the branch_cmp array, and the type into | |
2672 | ;; branch_type. No RTL is generated. | |
2673 | ;; | |
2674 | ;; 2) The appropriate branch define_expand is called, which then | |
2675 | ;; creates the appropriate RTL for the comparison and branch. | |
2676 | ;; Different CC modes are used, based on what type of branch is | |
2677 | ;; done, so that we can constrain things appropriately. There | |
2678 | ;; are assumptions in the rest of GCC that break if we fold the | |
2679 | ;; operands into the branchs for integer operations, and use cc0 | |
34b650b3 MM |
2680 | ;; for floating point, so we use the fp status register instead. |
2681 | ;; If needed, an appropriate temporary is created to hold the | |
2682 | ;; of the integer compare. | |
8ef30996 MM |
2683 | |
2684 | (define_expand "cmpsi" | |
2685 | [(set (cc0) | |
2686 | (compare:CC (match_operand:SI 0 "register_operand" "") | |
2687 | (match_operand:SI 1 "arith_operand" "")))] | |
2688 | "" | |
2689 | " | |
2690 | { | |
2691 | if (operands[0]) /* avoid unused code message */ | |
2692 | { | |
2693 | branch_cmp[0] = operands[0]; | |
2694 | branch_cmp[1] = operands[1]; | |
2695 | branch_type = CMP_SI; | |
2696 | DONE; | |
2697 | } | |
2698 | }") | |
2699 | ||
2700 | (define_expand "tstsi" | |
2701 | [(set (cc0) | |
2702 | (match_operand:SI 0 "register_operand" ""))] | |
2703 | "" | |
2704 | " | |
2705 | { | |
2706 | if (operands[0]) /* avoid unused code message */ | |
2707 | { | |
2708 | branch_cmp[0] = operands[0]; | |
2709 | branch_cmp[1] = const0_rtx; | |
2710 | branch_type = CMP_SI; | |
2711 | DONE; | |
2712 | } | |
2713 | }") | |
2714 | ||
8ef30996 MM |
2715 | (define_expand "cmpdf" |
2716 | [(set (cc0) | |
2717 | (compare:CC_FP (match_operand:DF 0 "register_operand" "") | |
2718 | (match_operand:DF 1 "register_operand" "")))] | |
2719 | "TARGET_HARD_FLOAT" | |
2720 | " | |
2721 | { | |
2722 | if (operands[0]) /* avoid unused code message */ | |
2723 | { | |
2724 | branch_cmp[0] = operands[0]; | |
2725 | branch_cmp[1] = operands[1]; | |
2726 | branch_type = CMP_DF; | |
2727 | DONE; | |
2728 | } | |
2729 | }") | |
2730 | ||
8ef30996 MM |
2731 | (define_expand "cmpsf" |
2732 | [(set (cc0) | |
2733 | (compare:CC_FP (match_operand:SF 0 "register_operand" "") | |
2734 | (match_operand:SF 1 "register_operand" "")))] | |
2735 | "TARGET_HARD_FLOAT" | |
2736 | " | |
2737 | { | |
2738 | if (operands[0]) /* avoid unused code message */ | |
2739 | { | |
2740 | branch_cmp[0] = operands[0]; | |
2741 | branch_cmp[1] = operands[1]; | |
2742 | branch_type = CMP_SF; | |
2743 | DONE; | |
2744 | } | |
2745 | }") | |
2746 | ||
8ef30996 MM |
2747 | \f |
2748 | ;; | |
2749 | ;; .................... | |
2750 | ;; | |
2751 | ;; CONDITIONAL BRANCHES | |
2752 | ;; | |
2753 | ;; .................... | |
2754 | ||
34b650b3 | 2755 | (define_insn "branch_fp_ne" |
8ef30996 | 2756 | [(set (pc) |
34b650b3 MM |
2757 | (if_then_else (ne:CC_FP (reg:CC_FP 66) |
2758 | (const_int 0)) | |
2759 | (match_operand 0 "pc_or_label_operand" "") | |
2760 | (match_operand 1 "pc_or_label_operand" "")))] | |
8ef30996 MM |
2761 | "" |
2762 | "* | |
2763 | { | |
8ef30996 | 2764 | mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); |
34b650b3 | 2765 | return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\"; |
8ef30996 MM |
2766 | }" |
2767 | [(set_attr "type" "branch") | |
2768 | (set_attr "mode" "none") | |
34b650b3 | 2769 | (set_attr "length" "1")]) |
8ef30996 | 2770 | |
34b650b3 | 2771 | (define_insn "branch_fp_ne_rev" |
8ef30996 | 2772 | [(set (pc) |
34b650b3 MM |
2773 | (if_then_else (ne:CC_REV_FP (reg:CC_REV_FP 66) |
2774 | (const_int 0)) | |
2775 | (match_operand 0 "pc_or_label_operand" "") | |
2776 | (match_operand 1 "pc_or_label_operand" "")))] | |
8ef30996 MM |
2777 | "" |
2778 | "* | |
2779 | { | |
8ef30996 | 2780 | mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); |
34b650b3 | 2781 | return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\"; |
8ef30996 MM |
2782 | }" |
2783 | [(set_attr "type" "branch") | |
2784 | (set_attr "mode" "none") | |
34b650b3 | 2785 | (set_attr "length" "1")]) |
8ef30996 | 2786 | |
34b650b3 | 2787 | (define_insn "branch_fp_eq" |
8ef30996 | 2788 | [(set (pc) |
34b650b3 MM |
2789 | (if_then_else (eq:CC_FP (reg:CC_FP 66) |
2790 | (const_int 0)) | |
2791 | (match_operand 0 "pc_or_label_operand" "") | |
2792 | (match_operand 1 "pc_or_label_operand" "")))] | |
8ef30996 MM |
2793 | "" |
2794 | "* | |
2795 | { | |
2796 | mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); | |
34b650b3 | 2797 | return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\"; |
8ef30996 MM |
2798 | }" |
2799 | [(set_attr "type" "branch") | |
2800 | (set_attr "mode" "none") | |
2801 | (set_attr "length" "1")]) | |
2802 | ||
34b650b3 | 2803 | (define_insn "branch_fp_eq_rev" |
8ef30996 | 2804 | [(set (pc) |
34b650b3 MM |
2805 | (if_then_else (eq:CC_REV_FP (reg:CC_REV_FP 66) |
2806 | (const_int 0)) | |
2807 | (match_operand 0 "pc_or_label_operand" "") | |
2808 | (match_operand 1 "pc_or_label_operand" "")))] | |
8ef30996 MM |
2809 | "" |
2810 | "* | |
2811 | { | |
2812 | mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); | |
34b650b3 | 2813 | return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\"; |
8ef30996 MM |
2814 | }" |
2815 | [(set_attr "type" "branch") | |
2816 | (set_attr "mode" "none") | |
2817 | (set_attr "length" "1")]) | |
2818 | ||
34b650b3 MM |
2819 | |
2820 | (define_insn "branch_zero" | |
8ef30996 | 2821 | [(set (pc) |
34b650b3 | 2822 | (if_then_else (match_operator:SI 0 "cmp_op" |
81723db9 | 2823 | [(match_operand:SI 1 "register_operand" "d") |
34b650b3 MM |
2824 | (const_int 0)]) |
2825 | (match_operand 2 "pc_or_label_operand" "") | |
2826 | (match_operand 3 "pc_or_label_operand" "")))] | |
8ef30996 MM |
2827 | "" |
2828 | "* | |
2829 | { | |
2830 | mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); | |
34b650b3 MM |
2831 | if (operands[2] != pc_rtx) |
2832 | { /* normal jump */ | |
2833 | switch (GET_CODE (operands[0])) | |
2834 | { | |
2835 | case EQ: return \"%*beq%?\\t%z1,%.,%2\"; | |
2836 | case NE: return \"%*bne%?\\t%z1,%.,%2\"; | |
2837 | case GTU: return \"%*bne%?\\t%z1,%.,%2\"; | |
2838 | case LEU: return \"%*beq%?\\t%z1,%.,%2\"; | |
2839 | case GEU: return \"%*j\\t%2\"; | |
81723db9 | 2840 | case LTU: return \"%*bne%?\\t%.,%.,%2\"; |
34b650b3 | 2841 | } |
8ef30996 | 2842 | |
34b650b3 | 2843 | return \"%*b%C0z%?\\t%z1,%2\"; |
8ef30996 | 2844 | } |
34b650b3 MM |
2845 | else |
2846 | { /* inverted jump */ | |
2847 | switch (GET_CODE (operands[0])) | |
2848 | { | |
2849 | case EQ: return \"%*bne%?\\t%z1,%.,%3\"; | |
2850 | case NE: return \"%*beq%?\\t%z1,%.,%3\"; | |
2851 | case GTU: return \"%*beq%?\\t%z1,%.,%3\"; | |
2852 | case LEU: return \"%*bne%?\\t%z1,%.,%3\"; | |
81723db9 | 2853 | case GEU: return \"%*beq%?\\t%.,%.,%3\"; |
34b650b3 MM |
2854 | case LTU: return \"%*j\\t%3\"; |
2855 | } | |
8ef30996 | 2856 | |
34b650b3 MM |
2857 | return \"%*b%N0z%?\\t%z1,%3\"; |
2858 | } | |
8ef30996 MM |
2859 | }" |
2860 | [(set_attr "type" "branch") | |
2861 | (set_attr "mode" "none") | |
2862 | (set_attr "length" "1")]) | |
2863 | ||
8ef30996 | 2864 | |
34b650b3 | 2865 | (define_insn "branch_equality" |
8ef30996 | 2866 | [(set (pc) |
34b650b3 MM |
2867 | (if_then_else (match_operator:SI 0 "equality_op" |
2868 | [(match_operand:SI 1 "register_operand" "d") | |
2869 | (match_operand:SI 2 "register_operand" "d")]) | |
2870 | (match_operand 3 "pc_or_label_operand" "") | |
2871 | (match_operand 4 "pc_or_label_operand" "")))] | |
8ef30996 MM |
2872 | "" |
2873 | "* | |
2874 | { | |
2875 | mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); | |
34b650b3 MM |
2876 | return (operands[3] != pc_rtx) |
2877 | ? \"%*b%C0%?\\t%z1,%z2,%3\" | |
2878 | : \"%*b%N0%?\\t%z1,%z2,%4\"; | |
8ef30996 MM |
2879 | }" |
2880 | [(set_attr "type" "branch") | |
2881 | (set_attr "mode" "none") | |
34b650b3 MM |
2882 | (set_attr "length" "1")]) |
2883 | ||
8ef30996 MM |
2884 | |
2885 | (define_expand "beq" | |
2886 | [(set (pc) | |
2887 | (if_then_else (eq:CC_EQ (cc0) | |
2888 | (const_int 0)) | |
2889 | (label_ref (match_operand 0 "" "")) | |
2890 | (pc)))] | |
2891 | "" | |
2892 | " | |
2893 | { | |
2894 | if (operands[0]) /* avoid unused code warning */ | |
2895 | { | |
2896 | gen_conditional_branch (operands, EQ); | |
2897 | DONE; | |
2898 | } | |
2899 | }") | |
2900 | ||
2901 | (define_expand "bne" | |
2902 | [(set (pc) | |
2903 | (if_then_else (ne:CC_EQ (cc0) | |
2904 | (const_int 0)) | |
2905 | (label_ref (match_operand 0 "" "")) | |
2906 | (pc)))] | |
2907 | "" | |
2908 | " | |
2909 | { | |
2910 | if (operands[0]) /* avoid unused code warning */ | |
2911 | { | |
2912 | gen_conditional_branch (operands, NE); | |
2913 | DONE; | |
2914 | } | |
2915 | }") | |
2916 | ||
2917 | (define_expand "bgt" | |
2918 | [(set (pc) | |
2919 | (if_then_else (gt:CC (cc0) | |
2920 | (const_int 0)) | |
2921 | (label_ref (match_operand 0 "" "")) | |
2922 | (pc)))] | |
2923 | "" | |
2924 | " | |
2925 | { | |
2926 | if (operands[0]) /* avoid unused code warning */ | |
2927 | { | |
2928 | gen_conditional_branch (operands, GT); | |
2929 | DONE; | |
2930 | } | |
2931 | }") | |
2932 | ||
2933 | (define_expand "bge" | |
2934 | [(set (pc) | |
2935 | (if_then_else (ge:CC (cc0) | |
2936 | (const_int 0)) | |
2937 | (label_ref (match_operand 0 "" "")) | |
2938 | (pc)))] | |
2939 | "" | |
2940 | " | |
2941 | { | |
2942 | if (operands[0]) /* avoid unused code warning */ | |
2943 | { | |
2944 | gen_conditional_branch (operands, GE); | |
2945 | DONE; | |
2946 | } | |
2947 | }") | |
2948 | ||
2949 | (define_expand "blt" | |
2950 | [(set (pc) | |
2951 | (if_then_else (lt:CC (cc0) | |
2952 | (const_int 0)) | |
2953 | (label_ref (match_operand 0 "" "")) | |
2954 | (pc)))] | |
2955 | "" | |
2956 | " | |
2957 | { | |
2958 | if (operands[0]) /* avoid unused code warning */ | |
2959 | { | |
2960 | gen_conditional_branch (operands, LT); | |
2961 | DONE; | |
2962 | } | |
2963 | }") | |
2964 | ||
2965 | (define_expand "ble" | |
2966 | [(set (pc) | |
2967 | (if_then_else (le:CC (cc0) | |
2968 | (const_int 0)) | |
2969 | (label_ref (match_operand 0 "" "")) | |
2970 | (pc)))] | |
2971 | "" | |
2972 | " | |
2973 | { | |
2974 | if (operands[0]) /* avoid unused code warning */ | |
2975 | { | |
2976 | gen_conditional_branch (operands, LE); | |
2977 | DONE; | |
2978 | } | |
2979 | }") | |
2980 | ||
2981 | (define_expand "bgtu" | |
2982 | [(set (pc) | |
2983 | (if_then_else (gtu:CC (cc0) | |
2984 | (const_int 0)) | |
2985 | (label_ref (match_operand 0 "" "")) | |
2986 | (pc)))] | |
2987 | "" | |
2988 | " | |
2989 | { | |
2990 | if (operands[0]) /* avoid unused code warning */ | |
2991 | { | |
2992 | gen_conditional_branch (operands, GTU); | |
2993 | DONE; | |
2994 | } | |
2995 | }") | |
2996 | ||
2997 | (define_expand "bgeu" | |
2998 | [(set (pc) | |
2999 | (if_then_else (geu:CC (cc0) | |
3000 | (const_int 0)) | |
3001 | (label_ref (match_operand 0 "" "")) | |
3002 | (pc)))] | |
3003 | "" | |
3004 | " | |
3005 | { | |
3006 | if (operands[0]) /* avoid unused code warning */ | |
3007 | { | |
3008 | gen_conditional_branch (operands, GEU); | |
3009 | DONE; | |
3010 | } | |
3011 | }") | |
3012 | ||
3013 | ||
3014 | (define_expand "bltu" | |
3015 | [(set (pc) | |
3016 | (if_then_else (ltu:CC (cc0) | |
3017 | (const_int 0)) | |
3018 | (label_ref (match_operand 0 "" "")) | |
3019 | (pc)))] | |
3020 | "" | |
3021 | " | |
3022 | { | |
3023 | if (operands[0]) /* avoid unused code warning */ | |
3024 | { | |
3025 | gen_conditional_branch (operands, LTU); | |
3026 | DONE; | |
3027 | } | |
3028 | }") | |
3029 | ||
3030 | (define_expand "bleu" | |
3031 | [(set (pc) | |
3032 | (if_then_else (leu:CC (cc0) | |
3033 | (const_int 0)) | |
3034 | (label_ref (match_operand 0 "" "")) | |
3035 | (pc)))] | |
3036 | "" | |
3037 | " | |
3038 | { | |
3039 | if (operands[0]) /* avoid unused code warning */ | |
3040 | { | |
3041 | gen_conditional_branch (operands, LEU); | |
3042 | DONE; | |
3043 | } | |
3044 | }") | |
3045 | ||
3046 | \f | |
3047 | ;; | |
3048 | ;; .................... | |
3049 | ;; | |
3050 | ;; SETTING A REGISTER FROM A COMPARISON | |
3051 | ;; | |
3052 | ;; .................... | |
3053 | ||
3054 | (define_expand "seq" | |
3055 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 MM |
3056 | (eq:SI (match_dup 1) |
3057 | (match_dup 2)))] | |
8ef30996 MM |
3058 | "" |
3059 | " | |
3060 | { | |
3061 | extern rtx force_reg (); | |
3062 | ||
3063 | if (branch_type != CMP_SI) | |
3064 | FAIL; | |
3065 | ||
3066 | /* set up operands from compare. */ | |
3067 | operands[1] = branch_cmp[0]; | |
3068 | operands[2] = branch_cmp[1]; | |
3069 | ||
bbdb5552 | 3070 | if (!TARGET_DEBUG_C_MODE) |
34b650b3 MM |
3071 | { |
3072 | gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0); | |
3073 | DONE; | |
3074 | } | |
3075 | ||
8ef30996 MM |
3076 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) |
3077 | operands[2] = force_reg (SImode, operands[2]); | |
3078 | ||
3079 | /* fall through and generate default code */ | |
3080 | }") | |
3081 | ||
34b650b3 MM |
3082 | |
3083 | (define_insn "seq_si_zero" | |
3084 | [(set (match_operand:SI 0 "register_operand" "=d") | |
3085 | (eq:SI (match_operand:SI 1 "register_operand" "d") | |
3086 | (const_int 0)))] | |
8ef30996 | 3087 | "" |
34b650b3 MM |
3088 | "sltu\\t%0,%1,1" |
3089 | [(set_attr "type" "arith") | |
3090 | (set_attr "mode" "SI") | |
3091 | (set_attr "length" "1")]) | |
3092 | ||
3093 | (define_insn "seq_si" | |
3094 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
3095 | (eq:SI (match_operand:SI 1 "register_operand" "%d,d") | |
3096 | (match_operand:SI 2 "uns_arith_operand" "d,K")))] | |
bbdb5552 | 3097 | "TARGET_DEBUG_C_MODE" |
8ef30996 | 3098 | "@ |
8ef30996 | 3099 | xor\\t%0,%1,%2\;sltu\\t%0,%0,1 |
34b650b3 | 3100 | xori\\t%0,%1,%2\;sltu\\t%0,%0,1" |
92b4cee1 MM |
3101 | [(set_attr "type" "arith") |
3102 | (set_attr "mode" "SI") | |
3103 | (set_attr "length" "2")]) | |
8ef30996 MM |
3104 | |
3105 | (define_split | |
3106 | [(set (match_operand:SI 0 "register_operand" "") | |
34b650b3 MM |
3107 | (eq:SI (match_operand:SI 1 "register_operand" "") |
3108 | (match_operand:SI 2 "uns_arith_operand" "")))] | |
bbdb5552 | 3109 | "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE |
26b8e6e5 | 3110 | && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)" |
8ef30996 MM |
3111 | [(set (match_dup 0) |
3112 | (xor:SI (match_dup 1) | |
3113 | (match_dup 2))) | |
3114 | (set (match_dup 0) | |
34b650b3 | 3115 | (ltu:SI (match_dup 0) |
8ef30996 MM |
3116 | (const_int 1)))] |
3117 | "") | |
3118 | ||
3119 | (define_expand "sne" | |
3120 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 MM |
3121 | (ne:SI (match_dup 1) |
3122 | (match_dup 2)))] | |
8ef30996 MM |
3123 | "" |
3124 | " | |
3125 | { | |
3126 | extern rtx force_reg (); | |
3127 | ||
3128 | if (branch_type != CMP_SI) | |
3129 | FAIL; | |
3130 | ||
3131 | /* set up operands from compare. */ | |
3132 | operands[1] = branch_cmp[0]; | |
3133 | operands[2] = branch_cmp[1]; | |
3134 | ||
bbdb5552 | 3135 | if (!TARGET_DEBUG_C_MODE) |
34b650b3 MM |
3136 | { |
3137 | gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0); | |
3138 | DONE; | |
3139 | } | |
3140 | ||
8ef30996 MM |
3141 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) |
3142 | operands[2] = force_reg (SImode, operands[2]); | |
3143 | ||
3144 | /* fall through and generate default code */ | |
3145 | }") | |
3146 | ||
34b650b3 MM |
3147 | (define_insn "sne_si_zero" |
3148 | [(set (match_operand:SI 0 "register_operand" "=d") | |
3149 | (ne:SI (match_operand:SI 1 "register_operand" "d") | |
3150 | (const_int 0)))] | |
8ef30996 | 3151 | "" |
34b650b3 MM |
3152 | "sltu\\t%0,%.,%1" |
3153 | [(set_attr "type" "arith") | |
3154 | (set_attr "mode" "SI") | |
3155 | (set_attr "length" "1")]) | |
8ef30996 | 3156 | |
34b650b3 MM |
3157 | (define_insn "sne_si" |
3158 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
3159 | (ne:SI (match_operand:SI 1 "register_operand" "%d,d") | |
3160 | (match_operand:SI 2 "uns_arith_operand" "d,K")))] | |
bbdb5552 | 3161 | "TARGET_DEBUG_C_MODE" |
34b650b3 MM |
3162 | "@ |
3163 | xor\\t%0,%1,%2\;sltu\\t%0,%.,%0 | |
3164 | xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0" | |
92b4cee1 MM |
3165 | [(set_attr "type" "arith") |
3166 | (set_attr "mode" "SI") | |
3167 | (set_attr "length" "2")]) | |
8ef30996 MM |
3168 | |
3169 | (define_split | |
3170 | [(set (match_operand:SI 0 "register_operand" "") | |
34b650b3 MM |
3171 | (ne:SI (match_operand:SI 1 "register_operand" "") |
3172 | (match_operand:SI 2 "uns_arith_operand" "")))] | |
bbdb5552 | 3173 | "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE |
26b8e6e5 | 3174 | && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)" |
8ef30996 MM |
3175 | [(set (match_dup 0) |
3176 | (xor:SI (match_dup 1) | |
3177 | (match_dup 2))) | |
3178 | (set (match_dup 0) | |
34b650b3 | 3179 | (gtu:SI (match_dup 0) |
8ef30996 MM |
3180 | (const_int 0)))] |
3181 | "") | |
3182 | ||
3183 | (define_expand "sgt" | |
3184 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3185 | (gt:SI (match_dup 1) |
8ef30996 MM |
3186 | (match_dup 2)))] |
3187 | "" | |
3188 | " | |
3189 | { | |
3190 | extern rtx force_reg (); | |
3191 | ||
3192 | if (branch_type != CMP_SI) | |
3193 | FAIL; | |
3194 | ||
3195 | /* set up operands from compare. */ | |
3196 | operands[1] = branch_cmp[0]; | |
3197 | operands[2] = branch_cmp[1]; | |
3198 | ||
bbdb5552 | 3199 | if (!TARGET_DEBUG_C_MODE) |
34b650b3 MM |
3200 | { |
3201 | gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0); | |
3202 | DONE; | |
3203 | } | |
3204 | ||
8ef30996 MM |
3205 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0) |
3206 | operands[2] = force_reg (SImode, operands[2]); | |
3207 | ||
3208 | /* fall through and generate default code */ | |
3209 | }") | |
3210 | ||
3211 | (define_insn "sgt_si" | |
3212 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3213 | (gt:SI (match_operand:SI 1 "register_operand" "d") |
8ef30996 MM |
3214 | (match_operand:SI 2 "reg_or_0_operand" "dJ")))] |
3215 | "" | |
3216 | "slt\\t%0,%z2,%1" | |
3217 | [(set_attr "type" "arith") | |
3218 | (set_attr "mode" "SI") | |
3219 | (set_attr "length" "1")]) | |
3220 | ||
3221 | (define_expand "sge" | |
3222 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3223 | (ge:SI (match_dup 1) |
8ef30996 MM |
3224 | (match_dup 2)))] |
3225 | "" | |
3226 | " | |
3227 | { | |
3228 | if (branch_type != CMP_SI) | |
3229 | FAIL; | |
3230 | ||
3231 | /* set up operands from compare. */ | |
3232 | operands[1] = branch_cmp[0]; | |
3233 | operands[2] = branch_cmp[1]; | |
3234 | ||
bbdb5552 | 3235 | if (!TARGET_DEBUG_C_MODE) |
34b650b3 MM |
3236 | { |
3237 | gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0); | |
3238 | DONE; | |
3239 | } | |
3240 | ||
8ef30996 MM |
3241 | /* fall through and generate default code */ |
3242 | }") | |
3243 | ||
3244 | (define_insn "sge_si" | |
3245 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3246 | (ge:SI (match_operand:SI 1 "register_operand" "d") |
8ef30996 | 3247 | (match_operand:SI 2 "arith_operand" "dI")))] |
bbdb5552 | 3248 | "TARGET_DEBUG_C_MODE" |
8ef30996 MM |
3249 | "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001" |
3250 | [(set_attr "type" "arith") | |
3251 | (set_attr "mode" "SI") | |
3252 | (set_attr "length" "2")]) | |
3253 | ||
3254 | (define_split | |
3255 | [(set (match_operand:SI 0 "register_operand" "") | |
34b650b3 | 3256 | (ge:SI (match_operand:SI 1 "register_operand" "") |
8ef30996 | 3257 | (match_operand:SI 2 "arith_operand" "")))] |
bbdb5552 | 3258 | "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE" |
8ef30996 | 3259 | [(set (match_dup 0) |
34b650b3 | 3260 | (lt:SI (match_dup 1) |
8ef30996 MM |
3261 | (match_dup 2))) |
3262 | (set (match_dup 0) | |
3263 | (xor:SI (match_dup 0) | |
3264 | (const_int 1)))] | |
3265 | "") | |
3266 | ||
3267 | (define_expand "slt" | |
3268 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3269 | (lt:SI (match_dup 1) |
8ef30996 MM |
3270 | (match_dup 2)))] |
3271 | "" | |
3272 | " | |
3273 | { | |
3274 | if (branch_type != CMP_SI) | |
3275 | FAIL; | |
3276 | ||
3277 | /* set up operands from compare. */ | |
3278 | operands[1] = branch_cmp[0]; | |
3279 | operands[2] = branch_cmp[1]; | |
3280 | ||
bbdb5552 | 3281 | if (!TARGET_DEBUG_C_MODE) |
34b650b3 MM |
3282 | { |
3283 | gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0); | |
3284 | DONE; | |
3285 | } | |
3286 | ||
8ef30996 MM |
3287 | /* fall through and generate default code */ |
3288 | }") | |
3289 | ||
3290 | (define_insn "slt_si" | |
3291 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3292 | (lt:SI (match_operand:SI 1 "register_operand" "d") |
8ef30996 MM |
3293 | (match_operand:SI 2 "arith_operand" "dI")))] |
3294 | "" | |
3295 | "slt\\t%0,%1,%2" | |
3296 | [(set_attr "type" "arith") | |
3297 | (set_attr "mode" "SI") | |
3298 | (set_attr "length" "1")]) | |
3299 | ||
3300 | (define_expand "sle" | |
3301 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3302 | (le:SI (match_dup 1) |
8ef30996 MM |
3303 | (match_dup 2)))] |
3304 | "" | |
3305 | " | |
3306 | { | |
3307 | extern rtx force_reg (); | |
3308 | ||
3309 | if (branch_type != CMP_SI) | |
3310 | FAIL; | |
3311 | ||
3312 | /* set up operands from compare. */ | |
3313 | operands[1] = branch_cmp[0]; | |
3314 | operands[2] = branch_cmp[1]; | |
3315 | ||
bbdb5552 | 3316 | if (!TARGET_DEBUG_C_MODE) |
34b650b3 MM |
3317 | { |
3318 | gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0); | |
3319 | DONE; | |
3320 | } | |
3321 | ||
8ef30996 MM |
3322 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767) |
3323 | operands[2] = force_reg (SImode, operands[2]); | |
3324 | ||
3325 | /* fall through and generate default code */ | |
3326 | }") | |
3327 | ||
34b650b3 MM |
3328 | (define_insn "sle_si_const" |
3329 | [(set (match_operand:SI 0 "register_operand" "=d") | |
3330 | (le:SI (match_operand:SI 1 "register_operand" "d") | |
3331 | (match_operand:SI 2 "small_int" "I")))] | |
3332 | "INTVAL (operands[2]) < 32767" | |
3333 | "* | |
3334 | { | |
3335 | operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1); | |
3336 | return \"slt\\t%0,%1,%2\"; | |
3337 | }" | |
3338 | [(set_attr "type" "arith") | |
3339 | (set_attr "mode" "SI") | |
3340 | (set_attr "length" "1")]) | |
3341 | ||
3342 | (define_insn "sle_si_reg" | |
3343 | [(set (match_operand:SI 0 "register_operand" "=d") | |
3344 | (le:SI (match_operand:SI 1 "register_operand" "d") | |
3345 | (match_operand:SI 2 "register_operand" "d")))] | |
bbdb5552 | 3346 | "TARGET_DEBUG_C_MODE" |
34b650b3 MM |
3347 | "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001" |
3348 | [(set_attr "type" "arith") | |
3349 | (set_attr "mode" "SI") | |
3350 | (set_attr "length" "2")]) | |
8ef30996 MM |
3351 | |
3352 | (define_split | |
3353 | [(set (match_operand:SI 0 "register_operand" "") | |
34b650b3 | 3354 | (le:SI (match_operand:SI 1 "register_operand" "") |
8ef30996 | 3355 | (match_operand:SI 2 "register_operand" "")))] |
bbdb5552 | 3356 | "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE" |
8ef30996 | 3357 | [(set (match_dup 0) |
34b650b3 | 3358 | (lt:SI (match_dup 2) |
8ef30996 MM |
3359 | (match_dup 1))) |
3360 | (set (match_dup 0) | |
3361 | (xor:SI (match_dup 0) | |
3362 | (const_int 1)))] | |
3363 | "") | |
3364 | ||
3365 | (define_expand "sgtu" | |
3366 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3367 | (gtu:SI (match_dup 1) |
8ef30996 MM |
3368 | (match_dup 2)))] |
3369 | "" | |
3370 | " | |
3371 | { | |
3372 | extern rtx force_reg (); | |
3373 | ||
3374 | if (branch_type != CMP_SI) | |
3375 | FAIL; | |
3376 | ||
3377 | /* set up operands from compare. */ | |
3378 | operands[1] = branch_cmp[0]; | |
3379 | operands[2] = branch_cmp[1]; | |
3380 | ||
bbdb5552 | 3381 | if (!TARGET_DEBUG_C_MODE) |
34b650b3 MM |
3382 | { |
3383 | gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0); | |
3384 | DONE; | |
3385 | } | |
3386 | ||
8ef30996 MM |
3387 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0) |
3388 | operands[2] = force_reg (SImode, operands[2]); | |
3389 | ||
3390 | /* fall through and generate default code */ | |
3391 | }") | |
3392 | ||
3393 | (define_insn "sgtu_si" | |
3394 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3395 | (gtu:SI (match_operand:SI 1 "register_operand" "d") |
8ef30996 MM |
3396 | (match_operand:SI 2 "reg_or_0_operand" "dJ")))] |
3397 | "" | |
3398 | "sltu\\t%0,%z2,%1" | |
3399 | [(set_attr "type" "arith") | |
3400 | (set_attr "mode" "SI") | |
3401 | (set_attr "length" "1")]) | |
3402 | ||
3403 | (define_expand "sgeu" | |
3404 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3405 | (geu:SI (match_dup 1) |
8ef30996 MM |
3406 | (match_dup 2)))] |
3407 | "" | |
3408 | " | |
3409 | { | |
3410 | if (branch_type != CMP_SI) | |
3411 | FAIL; | |
3412 | ||
3413 | /* set up operands from compare. */ | |
3414 | operands[1] = branch_cmp[0]; | |
3415 | operands[2] = branch_cmp[1]; | |
3416 | ||
bbdb5552 | 3417 | if (!TARGET_DEBUG_C_MODE) |
34b650b3 MM |
3418 | { |
3419 | gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0); | |
3420 | DONE; | |
3421 | } | |
3422 | ||
8ef30996 MM |
3423 | /* fall through and generate default code */ |
3424 | }") | |
3425 | ||
3426 | (define_insn "sgeu_si" | |
3427 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3428 | (geu:SI (match_operand:SI 1 "register_operand" "d") |
8ef30996 | 3429 | (match_operand:SI 2 "arith_operand" "dI")))] |
bbdb5552 | 3430 | "TARGET_DEBUG_C_MODE" |
8ef30996 MM |
3431 | "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001" |
3432 | [(set_attr "type" "arith") | |
3433 | (set_attr "mode" "SI") | |
3434 | (set_attr "length" "2")]) | |
3435 | ||
3436 | (define_split | |
3437 | [(set (match_operand:SI 0 "register_operand" "") | |
34b650b3 | 3438 | (geu:SI (match_operand:SI 1 "register_operand" "") |
8ef30996 | 3439 | (match_operand:SI 2 "arith_operand" "")))] |
bbdb5552 | 3440 | "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE" |
8ef30996 | 3441 | [(set (match_dup 0) |
34b650b3 | 3442 | (ltu:SI (match_dup 1) |
8ef30996 MM |
3443 | (match_dup 2))) |
3444 | (set (match_dup 0) | |
3445 | (xor:SI (match_dup 0) | |
3446 | (const_int 1)))] | |
3447 | "") | |
3448 | ||
3449 | (define_expand "sltu" | |
3450 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3451 | (ltu:SI (match_dup 1) |
8ef30996 MM |
3452 | (match_dup 2)))] |
3453 | "" | |
3454 | " | |
3455 | { | |
3456 | if (branch_type != CMP_SI) | |
3457 | FAIL; | |
3458 | ||
3459 | /* set up operands from compare. */ | |
3460 | operands[1] = branch_cmp[0]; | |
3461 | operands[2] = branch_cmp[1]; | |
3462 | ||
bbdb5552 | 3463 | if (!TARGET_DEBUG_C_MODE) |
34b650b3 MM |
3464 | { |
3465 | gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0); | |
3466 | DONE; | |
3467 | } | |
3468 | ||
8ef30996 MM |
3469 | /* fall through and generate default code */ |
3470 | }") | |
3471 | ||
3472 | (define_insn "sltu_si" | |
3473 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3474 | (ltu:SI (match_operand:SI 1 "register_operand" "d") |
8ef30996 MM |
3475 | (match_operand:SI 2 "arith_operand" "dI")))] |
3476 | "" | |
3477 | "sltu\\t%0,%1,%2" | |
3478 | [(set_attr "type" "arith") | |
3479 | (set_attr "mode" "SI") | |
3480 | (set_attr "length" "1")]) | |
3481 | ||
3482 | (define_expand "sleu" | |
3483 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 3484 | (leu:SI (match_dup 1) |
8ef30996 MM |
3485 | (match_dup 2)))] |
3486 | "" | |
3487 | " | |
3488 | { | |
3489 | extern rtx force_reg (); | |
3490 | ||
3491 | if (branch_type != CMP_SI) | |
3492 | FAIL; | |
3493 | ||
3494 | /* set up operands from compare. */ | |
3495 | operands[1] = branch_cmp[0]; | |
3496 | operands[2] = branch_cmp[1]; | |
3497 | ||
bbdb5552 | 3498 | if (!TARGET_DEBUG_C_MODE) |
34b650b3 MM |
3499 | { |
3500 | gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0); | |
3501 | DONE; | |
3502 | } | |
3503 | ||
8ef30996 MM |
3504 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767) |
3505 | operands[2] = force_reg (SImode, operands[2]); | |
3506 | ||
3507 | /* fall through and generate default code */ | |
3508 | }") | |
3509 | ||
34b650b3 MM |
3510 | (define_insn "sleu_si_const" |
3511 | [(set (match_operand:SI 0 "register_operand" "=d") | |
3512 | (leu:SI (match_operand:SI 1 "register_operand" "d") | |
3513 | (match_operand:SI 2 "small_int" "I")))] | |
3514 | "INTVAL (operands[2]) < 32767" | |
3515 | "* | |
3516 | { | |
3517 | operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1); | |
3518 | return \"sltu\\t%0,%1,%2\"; | |
3519 | }" | |
3520 | [(set_attr "type" "arith") | |
3521 | (set_attr "mode" "SI") | |
3522 | (set_attr "length" "1")]) | |
3523 | ||
3524 | (define_insn "sleu_si_reg" | |
3525 | [(set (match_operand:SI 0 "register_operand" "=d") | |
3526 | (leu:SI (match_operand:SI 1 "register_operand" "d") | |
3527 | (match_operand:SI 2 "register_operand" "d")))] | |
bbdb5552 | 3528 | "TARGET_DEBUG_C_MODE" |
34b650b3 MM |
3529 | "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001" |
3530 | [(set_attr "type" "arith") | |
3531 | (set_attr "mode" "SI") | |
3532 | (set_attr "length" "2")]) | |
8ef30996 MM |
3533 | |
3534 | (define_split | |
3535 | [(set (match_operand:SI 0 "register_operand" "") | |
34b650b3 | 3536 | (leu:SI (match_operand:SI 1 "register_operand" "") |
8ef30996 | 3537 | (match_operand:SI 2 "register_operand" "")))] |
bbdb5552 | 3538 | "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE" |
8ef30996 | 3539 | [(set (match_dup 0) |
34b650b3 | 3540 | (ltu:SI (match_dup 2) |
8ef30996 MM |
3541 | (match_dup 1))) |
3542 | (set (match_dup 0) | |
3543 | (xor:SI (match_dup 0) | |
3544 | (const_int 1)))] | |
3545 | "") | |
3546 | ||
34b650b3 MM |
3547 | \f |
3548 | ;; | |
3549 | ;; .................... | |
3550 | ;; | |
3551 | ;; FLOATING POINT COMPARISONS | |
3552 | ;; | |
3553 | ;; .................... | |
3554 | ||
3555 | (define_insn "seq_df" | |
3556 | [(set (reg:CC_FP 66) | |
3557 | (eq:CC_FP (match_operand:DF 0 "register_operand" "f") | |
3558 | (match_operand:DF 1 "register_operand" "f")))] | |
3559 | "" | |
3560 | "* | |
3561 | { | |
3562 | rtx xoperands[10]; | |
3563 | xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); | |
3564 | xoperands[1] = operands[0]; | |
3565 | xoperands[2] = operands[1]; | |
3566 | ||
3567 | return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn); | |
3568 | }" | |
3569 | [(set_attr "type" "fcmp") | |
3570 | (set_attr "mode" "FPSW") | |
3571 | (set_attr "length" "1")]) | |
3572 | ||
3573 | (define_insn "sne_df" | |
3574 | [(set (reg:CC_REV_FP 66) | |
3575 | (ne:CC_REV_FP (match_operand:DF 0 "register_operand" "f") | |
3576 | (match_operand:DF 1 "register_operand" "f")))] | |
3577 | "" | |
3578 | "* | |
3579 | { | |
3580 | rtx xoperands[10]; | |
3581 | xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); | |
3582 | xoperands[1] = operands[0]; | |
3583 | xoperands[2] = operands[1]; | |
3584 | ||
3585 | return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn); | |
3586 | }" | |
3587 | [(set_attr "type" "fcmp") | |
3588 | (set_attr "mode" "FPSW") | |
3589 | (set_attr "length" "1")]) | |
3590 | ||
3591 | (define_insn "slt_df" | |
3592 | [(set (reg:CC_FP 66) | |
3593 | (lt:CC_FP (match_operand:DF 0 "register_operand" "f") | |
3594 | (match_operand:DF 1 "register_operand" "f")))] | |
3595 | "" | |
3596 | "* | |
3597 | { | |
3598 | rtx xoperands[10]; | |
3599 | xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); | |
3600 | xoperands[1] = operands[0]; | |
3601 | xoperands[2] = operands[1]; | |
3602 | ||
3603 | return mips_fill_delay_slot (\"c.lt.d\\t%0,%1\", DELAY_FCMP, xoperands, insn); | |
3604 | }" | |
3605 | [(set_attr "type" "fcmp") | |
3606 | (set_attr "mode" "FPSW") | |
3607 | (set_attr "length" "1")]) | |
3608 | ||
3609 | (define_insn "sle_df" | |
3610 | [(set (reg:CC_FP 66) | |
3611 | (le:CC_FP (match_operand:DF 0 "register_operand" "f") | |
3612 | (match_operand:DF 1 "register_operand" "f")))] | |
3613 | "" | |
3614 | "* | |
3615 | { | |
3616 | rtx xoperands[10]; | |
3617 | xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); | |
3618 | xoperands[1] = operands[0]; | |
3619 | xoperands[2] = operands[1]; | |
3620 | ||
3621 | return mips_fill_delay_slot (\"c.le.d\\t%0,%1\", DELAY_FCMP, xoperands, insn); | |
3622 | }" | |
3623 | [(set_attr "type" "fcmp") | |
3624 | (set_attr "mode" "FPSW") | |
3625 | (set_attr "length" "1")]) | |
3626 | ||
3627 | (define_insn "sgt_df" | |
3628 | [(set (reg:CC_FP 66) | |
3629 | (gt:CC_FP (match_operand:DF 0 "register_operand" "f") | |
3630 | (match_operand:DF 1 "register_operand" "f")))] | |
3631 | "" | |
3632 | "* | |
3633 | { | |
3634 | rtx xoperands[10]; | |
3635 | xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); | |
3636 | xoperands[1] = operands[0]; | |
3637 | xoperands[2] = operands[1]; | |
3638 | ||
3639 | return mips_fill_delay_slot (\"c.lt.d\\t%1,%0\", DELAY_FCMP, xoperands, insn); | |
3640 | }" | |
3641 | [(set_attr "type" "fcmp") | |
3642 | (set_attr "mode" "FPSW") | |
3643 | (set_attr "length" "1")]) | |
3644 | ||
3645 | (define_insn "sge_df" | |
3646 | [(set (reg:CC_FP 66) | |
3647 | (ge:CC_FP (match_operand:DF 0 "register_operand" "f") | |
3648 | (match_operand:DF 1 "register_operand" "f")))] | |
3649 | "" | |
3650 | "* | |
3651 | { | |
3652 | rtx xoperands[10]; | |
3653 | xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); | |
3654 | xoperands[1] = operands[0]; | |
3655 | xoperands[2] = operands[1]; | |
3656 | ||
3657 | return mips_fill_delay_slot (\"c.le.d\\t%1,%0\", DELAY_FCMP, xoperands, insn); | |
3658 | }" | |
3659 | [(set_attr "type" "fcmp") | |
3660 | (set_attr "mode" "FPSW") | |
3661 | (set_attr "length" "1")]) | |
3662 | ||
3663 | (define_insn "seq_sf" | |
3664 | [(set (reg:CC_FP 66) | |
3665 | (eq:CC_FP (match_operand:SF 0 "register_operand" "f") | |
3666 | (match_operand:SF 1 "register_operand" "f")))] | |
3667 | "" | |
3668 | "* | |
3669 | { | |
3670 | rtx xoperands[10]; | |
3671 | xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); | |
3672 | xoperands[1] = operands[0]; | |
3673 | xoperands[2] = operands[1]; | |
3674 | ||
3675 | return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn); | |
3676 | }" | |
3677 | [(set_attr "type" "fcmp") | |
3678 | (set_attr "mode" "FPSW") | |
3679 | (set_attr "length" "1")]) | |
3680 | ||
3681 | (define_insn "sne_sf" | |
3682 | [(set (reg:CC_REV_FP 66) | |
3683 | (ne:CC_REV_FP (match_operand:SF 0 "register_operand" "f") | |
3684 | (match_operand:SF 1 "register_operand" "f")))] | |
3685 | "" | |
3686 | "* | |
3687 | { | |
3688 | rtx xoperands[10]; | |
3689 | xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); | |
3690 | xoperands[1] = operands[0]; | |
3691 | xoperands[2] = operands[1]; | |
3692 | ||
3693 | return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn); | |
3694 | }" | |
3695 | [(set_attr "type" "fcmp") | |
3696 | (set_attr "mode" "FPSW") | |
3697 | (set_attr "length" "1")]) | |
3698 | ||
3699 | (define_insn "slt_sf" | |
3700 | [(set (reg:CC_FP 66) | |
3701 | (lt:CC_FP (match_operand:SF 0 "register_operand" "f") | |
3702 | (match_operand:SF 1 "register_operand" "f")))] | |
3703 | "" | |
3704 | "* | |
3705 | { | |
3706 | rtx xoperands[10]; | |
3707 | xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); | |
3708 | xoperands[1] = operands[0]; | |
3709 | xoperands[2] = operands[1]; | |
3710 | ||
3711 | return mips_fill_delay_slot (\"c.lt.s\\t%0,%1\", DELAY_FCMP, xoperands, insn); | |
3712 | }" | |
3713 | [(set_attr "type" "fcmp") | |
3714 | (set_attr "mode" "FPSW") | |
3715 | (set_attr "length" "1")]) | |
3716 | ||
3717 | (define_insn "sle_sf" | |
3718 | [(set (reg:CC_FP 66) | |
3719 | (le:CC_FP (match_operand:SF 0 "register_operand" "f") | |
3720 | (match_operand:SF 1 "register_operand" "f")))] | |
3721 | "" | |
3722 | "* | |
3723 | { | |
3724 | rtx xoperands[10]; | |
3725 | xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); | |
3726 | xoperands[1] = operands[0]; | |
3727 | xoperands[2] = operands[1]; | |
3728 | ||
3729 | return mips_fill_delay_slot (\"c.le.s\\t%0,%1\", DELAY_FCMP, xoperands, insn); | |
3730 | }" | |
3731 | [(set_attr "type" "fcmp") | |
3732 | (set_attr "mode" "FPSW") | |
3733 | (set_attr "length" "1")]) | |
3734 | ||
3735 | (define_insn "sgt_sf" | |
3736 | [(set (reg:CC_FP 66) | |
3737 | (gt:CC_FP (match_operand:SF 0 "register_operand" "f") | |
3738 | (match_operand:SF 1 "register_operand" "f")))] | |
3739 | "" | |
3740 | "* | |
3741 | { | |
3742 | rtx xoperands[10]; | |
3743 | xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); | |
3744 | xoperands[1] = operands[0]; | |
3745 | xoperands[2] = operands[1]; | |
3746 | ||
3747 | return mips_fill_delay_slot (\"c.lt.s\\t%1,%0\", DELAY_FCMP, xoperands, insn); | |
3748 | }" | |
3749 | [(set_attr "type" "fcmp") | |
3750 | (set_attr "mode" "FPSW") | |
3751 | (set_attr "length" "1")]) | |
3752 | ||
3753 | (define_insn "sge_sf" | |
3754 | [(set (reg:CC_FP 66) | |
3755 | (ge:CC_FP (match_operand:SF 0 "register_operand" "f") | |
3756 | (match_operand:SF 1 "register_operand" "f")))] | |
3757 | "" | |
3758 | "* | |
3759 | { | |
3760 | rtx xoperands[10]; | |
3761 | xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); | |
3762 | xoperands[1] = operands[0]; | |
3763 | xoperands[2] = operands[1]; | |
3764 | ||
3765 | return mips_fill_delay_slot (\"c.le.s\\t%1,%0\", DELAY_FCMP, xoperands, insn); | |
3766 | }" | |
3767 | [(set_attr "type" "fcmp") | |
3768 | (set_attr "mode" "FPSW") | |
3769 | (set_attr "length" "1")]) | |
3770 | ||
8ef30996 MM |
3771 | \f |
3772 | ;; | |
3773 | ;; .................... | |
3774 | ;; | |
3775 | ;; UNCONDITIONAL BRANCHES | |
3776 | ;; | |
3777 | ;; .................... | |
3778 | ||
3779 | ;; Unconditional branches. | |
3780 | ||
3781 | (define_insn "jump" | |
3782 | [(set (pc) | |
3783 | (label_ref (match_operand 0 "" "")))] | |
3784 | "" | |
3785 | "* | |
3786 | { | |
3787 | if (GET_CODE (operands[0]) == REG) | |
3788 | return \"%*j\\t%0\"; | |
3789 | else | |
3790 | return \"%*j\\t%l0\"; | |
3791 | }" | |
3792 | [(set_attr "type" "jump") | |
3793 | (set_attr "mode" "none") | |
3794 | (set_attr "length" "1")]) | |
3795 | ||
3796 | (define_insn "indirect_jump" | |
3797 | [(set (pc) (match_operand:SI 0 "register_operand" "d"))] | |
3798 | "" | |
3799 | "%*j\\t%0" | |
3800 | [(set_attr "type" "jump") | |
3801 | (set_attr "mode" "none") | |
3802 | (set_attr "length" "1")]) | |
3803 | ||
3804 | (define_insn "tablejump" | |
3805 | [(set (pc) | |
3806 | (match_operand:SI 0 "register_operand" "d")) | |
3807 | (use (label_ref (match_operand 1 "" "")))] | |
3808 | "" | |
3809 | "%*j\\t%0" | |
3810 | [(set_attr "type" "jump") | |
3811 | (set_attr "mode" "none") | |
3812 | (set_attr "length" "1")]) | |
3813 | ||
3814 | ;; Function return, only allow after optimization, so that we can | |
3815 | ;; eliminate jumps to jumps if no stack space is used. | |
3816 | ||
0fb5ac6f MM |
3817 | ;; (define_expand "return" |
3818 | ;; [(set (pc) (reg:SI 31))] | |
3819 | ;; "simple_epilogue_p ()" | |
3820 | ;; "") | |
3821 | ||
3822 | (define_expand "return" | |
3823 | [(parallel [(return) | |
3824 | (use (reg:SI 31))])] | |
3825 | "simple_epilogue_p ()" | |
3826 | "") | |
3827 | ||
3828 | (define_insn "return_internal" | |
3829 | [(parallel [(return) | |
3830 | (use (match_operand:SI 0 "register_operand" "d"))])] | |
3831 | "" | |
3832 | "%*j\\t%0" | |
8ef30996 MM |
3833 | [(set_attr "type" "jump") |
3834 | (set_attr "mode" "none") | |
3835 | (set_attr "length" "1")]) | |
3836 | ||
0fb5ac6f MM |
3837 | \f |
3838 | ;; | |
3839 | ;; .................... | |
3840 | ;; | |
3841 | ;; Function prologue/epilogue | |
3842 | ;; | |
3843 | ;; .................... | |
3844 | ;; | |
3845 | ||
3846 | (define_expand "prologue" | |
3847 | [(const_int 1)] | |
3848 | "" | |
3849 | " | |
3850 | { | |
3851 | if (mips_isa >= 0) /* avoid unused code warnings */ | |
3852 | { | |
3853 | mips_expand_prologue (); | |
3854 | DONE; | |
3855 | } | |
3856 | }") | |
3857 | ||
3858 | ;; At present, don't expand the epilogue, reorg.c will clobber the | |
3859 | ;; return register in compiling gen_lowpart (emit-rtl.c). | |
3860 | ;; | |
3861 | ;; (define_expand "epilogue" | |
3862 | ;; [(const_int 2)] | |
3863 | ;; "" | |
3864 | ;; " | |
3865 | ;; { | |
3866 | ;; if (mips_isa >= 0) /* avoid unused code warnings */ | |
3867 | ;; { | |
3868 | ;; mips_expand_epilogue (); | |
3869 | ;; DONE; | |
3870 | ;; } | |
3871 | ;; }") | |
3872 | ||
8ef30996 MM |
3873 | \f |
3874 | ;; | |
3875 | ;; .................... | |
3876 | ;; | |
3877 | ;; FUNCTION CALLS | |
3878 | ;; | |
3879 | ;; .................... | |
3880 | ||
3881 | ;; calls.c now passes a third argument, make saber happy | |
3882 | ||
3883 | (define_expand "call" | |
af4a697f | 3884 | [(parallel [(call (match_operand 0 "memory_operand" "m") |
8ef30996 MM |
3885 | (match_operand 1 "" "i")) |
3886 | (clobber (match_operand 2 "" ""))])] ;; overwrite op2 with $31 | |
3887 | "" | |
3888 | " | |
3889 | { | |
3890 | rtx addr; | |
3891 | ||
3892 | operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 31); | |
3893 | ||
3894 | addr = XEXP (operands[0], 0); | |
af4a697f | 3895 | if (GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr)) |
8ef30996 MM |
3896 | XEXP (operands[0], 0) = force_reg (FUNCTION_MODE, addr); |
3897 | }") | |
3898 | ||
3899 | (define_insn "call_internal" | |
af4a697f | 3900 | [(call (match_operand 0 "memory_operand" "m") |
8ef30996 MM |
3901 | (match_operand 1 "" "i")) |
3902 | (clobber (match_operand:SI 2 "register_operand" "=d"))] | |
3903 | "" | |
3904 | "* | |
3905 | { | |
3906 | register rtx target = XEXP (operands[0], 0); | |
3907 | ||
3908 | if (GET_CODE (target) == SYMBOL_REF) | |
3909 | return \"%*jal\\t%0\"; | |
3910 | ||
3911 | else | |
3912 | { | |
3913 | operands[0] = target; | |
3914 | operands[1] = gen_rtx (REG, SImode, GP_REG_FIRST + 31); | |
3915 | return \"%*jal\\t%1,%0\"; | |
3916 | } | |
3917 | }" | |
3918 | [(set_attr "type" "call") | |
3919 | (set_attr "mode" "none") | |
3920 | (set_attr "length" "1")]) | |
3921 | ||
3922 | ;; calls.c now passes a fourth argument, make saber happy | |
3923 | ||
3924 | (define_expand "call_value" | |
3925 | [(parallel [(set (match_operand 0 "register_operand" "=df") | |
af4a697f | 3926 | (call (match_operand 1 "memory_operand" "m") |
8ef30996 MM |
3927 | (match_operand 2 "" "i"))) |
3928 | (clobber (match_operand 3 "" ""))])] ;; overwrite op3 with $31 | |
3929 | "" | |
3930 | " | |
3931 | { | |
3932 | rtx addr; | |
3933 | ||
3934 | operands[3] = gen_rtx (REG, SImode, GP_REG_FIRST + 31); | |
3935 | ||
3936 | addr = XEXP (operands[1], 0); | |
af4a697f | 3937 | if (GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr)) |
8ef30996 MM |
3938 | XEXP (operands[1], 0) = force_reg (FUNCTION_MODE, addr); |
3939 | }") | |
3940 | ||
3941 | (define_insn "call_value_internal" | |
3942 | [(set (match_operand 0 "register_operand" "=df") | |
af4a697f | 3943 | (call (match_operand 1 "memory_operand" "m") |
8ef30996 MM |
3944 | (match_operand 2 "" "i"))) |
3945 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
3946 | "" | |
3947 | "* | |
3948 | { | |
3949 | register rtx target = XEXP (operands[1], 0); | |
3950 | ||
3951 | if (GET_CODE (target) == SYMBOL_REF) | |
3952 | return \"%*jal\\t%1\"; | |
3953 | ||
3954 | else | |
3955 | { | |
3956 | operands[1] = target; | |
3957 | operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 31); | |
3958 | return \"%*jal\\t%2,%1\"; | |
3959 | } | |
3960 | }" | |
3961 | [(set_attr "type" "call") | |
3962 | (set_attr "mode" "none") | |
3963 | (set_attr "length" "1")]) | |
3964 | ||
3965 | \f | |
3966 | ;; | |
3967 | ;; .................... | |
3968 | ;; | |
3969 | ;; MISC. | |
3970 | ;; | |
3971 | ;; .................... | |
3972 | ;; | |
3973 | ||
3974 | (define_insn "nop" | |
3975 | [(const_int 0)] | |
3976 | "" | |
3977 | "%(nop%)" | |
3978 | [(set_attr "type" "nop") | |
3979 | (set_attr "mode" "none") | |
3980 | (set_attr "length" "1")]) | |
3981 | ||
3982 | (define_expand "probe" | |
3983 | [(set (match_dup 0) | |
3984 | (match_dup 1))] | |
3985 | "" | |
3986 | " | |
3987 | { | |
3988 | operands[0] = gen_reg_rtx (SImode); | |
3989 | operands[1] = gen_rtx (MEM, SImode, stack_pointer_rtx); | |
3990 | MEM_VOLATILE_P (operands[1]) = TRUE; | |
3991 | ||
3992 | /* fall through and generate default code */ | |
3993 | }") | |
3994 | ||
3995 | \f | |
3996 | ;; | |
3997 | ;; Local variables: | |
3998 | ;; mode:emacs-lisp | |
3999 | ;; comment-start: ";; " | |
4000 | ;; eval: (set-syntax-table (copy-sequence (syntax-table))) | |
4001 | ;; eval: (modify-syntax-entry ?[ "(]") | |
4002 | ;; eval: (modify-syntax-entry ?] ")[") | |
4003 | ;; eval: (modify-syntax-entry ?{ "(}") | |
4004 | ;; eval: (modify-syntax-entry ?} "){") | |
4005 | ;; End: |