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