]> gcc.gnu.org Git - gcc.git/blame - gcc/config/mips/mips.md
(duplicate_loop_exit_test): Initialize copy to zero.
[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
bb621ad7
JW
4;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
5;; Brendan Eich, brendan@microunity.com.
6;; Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
8ef30996
MM
7
8;; This file is part of GNU CC.
9
10;; GNU CC is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
13;; any later version.
14
15;; GNU CC is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU CC; see the file COPYING. If not, write to
22;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
24\f
25
26;; ....................
27;;
28;; Attributes
29;;
30;; ....................
31
32;; Classification of each insn.
33;; branch conditional branch
34;; jump unconditional jump
35;; call unconditional call
36;; load load instruction(s)
37;; store store instruction(s)
38;; move data movement within same register set
39;; xfer transfer to/from coprocessor
40;; hilo transfer of hi/lo registers
41;; arith integer arithmetic instruction
42;; darith double precision integer arithmetic instructions
43;; imul integer multiply
44;; idiv integer divide
45;; icmp integer compare
46;; fadd floating point add/subtract
47;; fmul floating point multiply
48;; fdiv floating point divide
49;; fabs floating point absolute value
50;; fneg floating point negation
51;; fcmp floating point compare
52;; fcvt floating point convert
53;; fsqrt floating point square root
54;; multi multiword sequence (or user asm statements)
55;; nop no operation
8ef30996
MM
56
57(define_attr "type"
c7343333 58 "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
59 (const_string "unknown"))
60
61;; Main data type used by the insn
34b650b3 62(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
8ef30996
MM
63
64;; # instructions (4 bytes each)
65(define_attr "length" "" (const_int 1))
66
6d518002 67;; whether or not an instruction has a mandatory delay slot
8ef30996 68(define_attr "dslot" "no,yes"
c7343333 69 (if_then_else (eq_attr "type" "branch,jump,call,load,xfer,hilo,fcmp")
8ef30996
MM
70 (const_string "yes")
71 (const_string "no")))
72
ddd8ab48
MM
73;; Attribute describing the processor. This attribute must match exactly
74;; with the processor_type enumeration in mips.h.
75
8ef30996 76;; Attribute describing the processor
ddd8ab48
MM
77;; (define_attr "cpu" "default,r3000,r6000,r4000"
78;; (const
79;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000")
80;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000")
81;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")]
82;; (const_string "default"))))
83
bb621ad7 84(define_attr "cpu" "default,r3000,r6000,r4000,r4600"
ddd8ab48 85 (const (symbol_ref "mips_cpu_attr")))
8ef30996
MM
86
87;; Attribute defining whether or not we can use the branch-likely instructions
88;; (MIPS ISA level 2)
89
90(define_attr "branch_likely" "no,yes"
6d518002 91 (const
8ef30996
MM
92 (if_then_else (ge (symbol_ref "mips_isa") (const_int 2))
93 (const_string "yes")
6d518002 94 (const_string "no"))))
8ef30996
MM
95
96
97;; Describe a user's asm statement.
98(define_asm_attributes
99 [(set_attr "type" "multi")])
100
84a92af4
JW
101;; whether or not generating calls to position independent functions
102(define_attr "abicalls" "no,yes"
e0a4e5a5 103 (const (symbol_ref "mips_abicalls_attr")))
84a92af4 104
8ef30996
MM
105\f
106
107;; .........................
108;;
109;; Delay slots, can't describe load/fcmp/xfer delay slots here
110;;
111;; .........................
112
113(define_delay (eq_attr "type" "branch")
114 [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
115 (nil)
bbdb5552 116 (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "1")))])
8ef30996 117
84a92af4
JW
118(define_delay (eq_attr "type" "jump")
119 [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
120 (nil)
121 (nil)])
122
123(define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
8ef30996
MM
124 [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
125 (nil)
126 (nil)])
127
128\f
129
130;; .........................
131;;
132;; Functional units
133;;
134;; .........................
135
136; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
c8e18a2b 137; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
8ef30996
MM
138
139;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
140
141(define_function_unit "memory" 1 0
c7343333 142 (and (eq_attr "type" "load") (eq_attr "cpu" "!r3000"))
8ef30996
MM
143 3 0)
144
145(define_function_unit "memory" 1 0
bb621ad7 146 (and (eq_attr "type" "load") (eq_attr "cpu" "r3000,r4600"))
8ef30996
MM
147 2 0)
148
ddd8ab48 149(define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
8ef30996 150
c3f3d7e1 151(define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
8ef30996 152
bb621ad7
JW
153(define_function_unit "imuldiv" 1 0
154 (eq_attr "type" "hilo")
155 1 3)
156
157(define_function_unit "imuldiv" 1 0
158 (and (eq_attr "type" "imul") (eq_attr "cpu" "!r3000,r4000,r4600"))
159 17 17)
8ef30996 160
bb621ad7 161(define_function_unit "imuldiv" 1 0
8ef30996 162 (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000"))
bb621ad7 163 12 12)
8ef30996 164
bb621ad7
JW
165(define_function_unit "imuldiv" 1 0
166 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
167 10 10)
8ef30996 168
bb621ad7
JW
169(define_function_unit "imuldiv" 1 0
170 (and (eq_attr "type" "idiv") (eq_attr "cpu" "!r3000,r4000,r4600"))
171 38 38)
8ef30996 172
bb621ad7 173(define_function_unit "imuldiv" 1 0
8ef30996 174 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000"))
bb621ad7
JW
175 35 35)
176
177(define_function_unit "imuldiv" 1 0
178 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
179 42 42)
8ef30996 180
bb621ad7 181(define_function_unit "imuldiv" 1 0
8ef30996 182 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
bb621ad7
JW
183 69 69)
184
185(define_function_unit "adder" 1 1
186 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r6000"))
187 3 0)
188
189(define_function_unit "adder" 1 1
190 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r6000"))
191 2 0)
8ef30996
MM
192
193(define_function_unit "adder" 1 1
194 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r6000"))
c8e18a2b 195 4 0)
8ef30996
MM
196
197(define_function_unit "adder" 1 1
198 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000"))
c8e18a2b 199 2 0)
8ef30996
MM
200
201(define_function_unit "adder" 1 1
202 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
c8e18a2b 203 3 0)
8ef30996 204
ddd8ab48 205(define_function_unit "adder" 1 1
bb621ad7 206 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "!r3000,r4600"))
c8e18a2b 207 2 0)
8ef30996 208
ddd8ab48 209(define_function_unit "adder" 1 1
bb621ad7 210 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r4600"))
c8e18a2b 211 1 0)
8ef30996
MM
212
213(define_function_unit "mult" 1 1
bb621ad7 214 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000,r4600")))
c8e18a2b 215 7 0)
8ef30996
MM
216
217(define_function_unit "mult" 1 1
218 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000")))
c8e18a2b 219 4 0)
8ef30996
MM
220
221(define_function_unit "mult" 1 1
222 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
c8e18a2b 223 5 0)
8ef30996 224
bb621ad7
JW
225(define_function_unit "mult" 1 1
226 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600")))
227 8 0)
228
8ef30996
MM
229(define_function_unit "mult" 1 1
230 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000")))
c8e18a2b 231 8 0)
8ef30996
MM
232
233(define_function_unit "mult" 1 1
234 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000")))
c8e18a2b 235 5 0)
8ef30996
MM
236
237(define_function_unit "mult" 1 1
238 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
c8e18a2b 239 6 0)
8ef30996
MM
240
241(define_function_unit "divide" 1 1
bb621ad7 242 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000,r4600")))
c8e18a2b 243 23 0)
8ef30996
MM
244
245(define_function_unit "divide" 1 1
246 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000")))
c8e18a2b 247 12 0)
8ef30996
MM
248
249(define_function_unit "divide" 1 1
250 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
c8e18a2b 251 15 0)
8ef30996
MM
252
253(define_function_unit "divide" 1 1
bb621ad7
JW
254 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600")))
255 32 0)
256
257(define_function_unit "divide" 1 1
258 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000,r4600")))
c8e18a2b 259 36 0)
8ef30996
MM
260
261(define_function_unit "divide" 1 1
262 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000")))
c8e18a2b 263 19 0)
8ef30996
MM
264
265(define_function_unit "divide" 1 1
266 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
c8e18a2b 267 16 0)
8ef30996 268
bb621ad7
JW
269(define_function_unit "divide" 1 1
270 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600")))
271 61 0)
272
273;;; ??? Is this number right?
274(define_function_unit "divide" 1 1
275 (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600")))
276 54 0)
277(define_function_unit "divide" 1 1
278 (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600")))
279 31 0)
280
281;;; ??? Is this number right?
282(define_function_unit "divide" 1 1
283 (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600")))
284 112 0)
285(define_function_unit "divide" 1 1
286 (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600")))
287 60 0)
8ef30996 288
ddd8ab48
MM
289\f
290;; The following functional units do not use the cpu type, and use
291;; much less memory in genattrtab.c.
292
c8e18a2b
TW
293;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0)
294;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
ddd8ab48 295;;
c8e18a2b 296;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0)
ddd8ab48 297;;
c8e18a2b
TW
298;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0)
299;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0)
ddd8ab48 300;;
c8e18a2b
TW
301;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 0)
302;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 0)
ddd8ab48 303;;
c8e18a2b
TW
304;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 0)
305;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 0)
ddd8ab48 306;;
c8e18a2b
TW
307;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 0)
308;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 0)
ddd8ab48 309;;
c8e18a2b
TW
310;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 0)
311;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 0)
ddd8ab48 312;;
c8e18a2b
TW
313;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0)
314;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
ddd8ab48 315
8ef30996
MM
316\f
317;;
318;; ....................
319;;
320;; ADDITION
321;;
322;; ....................
323;;
324
325(define_insn "adddf3"
326 [(set (match_operand:DF 0 "register_operand" "=f")
327 (plus:DF (match_operand:DF 1 "register_operand" "f")
328 (match_operand:DF 2 "register_operand" "f")))]
329 "TARGET_HARD_FLOAT"
330 "add.d\\t%0,%1,%2"
331 [(set_attr "type" "fadd")
332 (set_attr "mode" "DF")
333 (set_attr "length" "1")])
334
335(define_insn "addsf3"
336 [(set (match_operand:SF 0 "register_operand" "=f")
337 (plus:SF (match_operand:SF 1 "register_operand" "f")
338 (match_operand:SF 2 "register_operand" "f")))]
339 "TARGET_HARD_FLOAT"
340 "add.s\\t%0,%1,%2"
341 [(set_attr "type" "fadd")
342 (set_attr "mode" "SF")
343 (set_attr "length" "1")])
344
71cd5224 345(define_expand "addsi3"
8ef30996 346 [(set (match_operand:SI 0 "register_operand" "=d")
71cd5224 347 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
8ef30996
MM
348 (match_operand:SI 2 "arith_operand" "dI")))]
349 ""
71cd5224
RS
350 "
351{
352 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
353 operands[2] = force_reg (SImode, operands[2]);
354}")
355
356(define_insn "addsi3_internal"
357 [(set (match_operand:SI 0 "register_operand" "=d")
358 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
359 (match_operand:SI 2 "arith_operand" "dI")))]
360 "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768"
9b190d1c 361 "addu\\t%0,%z1,%2"
8ef30996
MM
362 [(set_attr "type" "arith")
363 (set_attr "mode" "SI")
364 (set_attr "length" "1")])
365
366(define_expand "adddi3"
367 [(parallel [(set (match_operand:DI 0 "register_operand" "")
368 (plus:DI (match_operand:DI 1 "register_operand" "")
369 (match_operand:DI 2 "arith_operand" "")))
370 (clobber (match_dup 3))])]
bb621ad7 371 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
92b4cee1
MM
372 "
373{
374 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
b0565769 375 operands[2] = force_reg (DImode, operands[2]);
92b4cee1 376
bb621ad7
JW
377 if (TARGET_64BIT)
378 {
379 emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
380 operands[2]));
381 DONE;
382 }
383
92b4cee1
MM
384 operands[3] = gen_reg_rtx (SImode);
385}")
8ef30996
MM
386
387(define_insn "adddi3_internal_1"
388 [(set (match_operand:DI 0 "register_operand" "=d,&d")
389 (plus:DI (match_operand:DI 1 "register_operand" "0,d")
390 (match_operand:DI 2 "register_operand" "d,d")))
391 (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
bb621ad7 392 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
8ef30996
MM
393 "*
394{
395 return (REGNO (operands[0]) == REGNO (operands[1])
396 && REGNO (operands[0]) == REGNO (operands[2]))
397 ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
398 : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
399}"
92b4cee1
MM
400 [(set_attr "type" "darith")
401 (set_attr "mode" "DI")
402 (set_attr "length" "4")])
8ef30996
MM
403
404(define_split
405 [(set (match_operand:DI 0 "register_operand" "")
406 (plus:DI (match_operand:DI 1 "register_operand" "")
407 (match_operand:DI 2 "register_operand" "")))
408 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 409 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
410 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
411 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
412 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
413 && (REGNO (operands[0]) != REGNO (operands[1])
414 || REGNO (operands[0]) != REGNO (operands[2]))"
415
416 [(set (subreg:SI (match_dup 0) 0)
417 (plus:SI (subreg:SI (match_dup 1) 0)
418 (subreg:SI (match_dup 2) 0)))
419
420 (set (match_dup 3)
34b650b3 421 (ltu:SI (subreg:SI (match_dup 0) 0)
8ef30996
MM
422 (subreg:SI (match_dup 2) 0)))
423
424 (set (subreg:SI (match_dup 0) 1)
425 (plus:SI (subreg:SI (match_dup 1) 1)
426 (subreg:SI (match_dup 2) 1)))
427
428 (set (subreg:SI (match_dup 0) 1)
429 (plus:SI (subreg:SI (match_dup 0) 1)
430 (match_dup 3)))]
431 "")
432
433(define_split
434 [(set (match_operand:DI 0 "register_operand" "")
435 (plus:DI (match_operand:DI 1 "register_operand" "")
436 (match_operand:DI 2 "register_operand" "")))
437 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 438 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
439 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
440 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
441 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
442 && (REGNO (operands[0]) != REGNO (operands[1])
443 || REGNO (operands[0]) != REGNO (operands[2]))"
444
445 [(set (subreg:SI (match_dup 0) 1)
446 (plus:SI (subreg:SI (match_dup 1) 1)
447 (subreg:SI (match_dup 2) 1)))
448
449 (set (match_dup 3)
34b650b3 450 (ltu:SI (subreg:SI (match_dup 0) 1)
8ef30996
MM
451 (subreg:SI (match_dup 2) 1)))
452
453 (set (subreg:SI (match_dup 0) 0)
454 (plus:SI (subreg:SI (match_dup 1) 0)
455 (subreg:SI (match_dup 2) 0)))
456
457 (set (subreg:SI (match_dup 0) 0)
458 (plus:SI (subreg:SI (match_dup 0) 0)
459 (match_dup 3)))]
460 "")
461
462(define_insn "adddi3_internal_2"
463 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
464 (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
465 (match_operand:DI 2 "small_int" "P,J,N")))
466 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
bb621ad7 467 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
8ef30996
MM
468 "@
469 addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
470 move\\t%L0,%L1\;move\\t%M0,%M1
471 subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
92b4cee1
MM
472 [(set_attr "type" "darith")
473 (set_attr "mode" "DI")
8ef30996
MM
474 (set_attr "length" "3,2,4")])
475
476(define_split
477 [(set (match_operand:DI 0 "register_operand" "")
478 (plus:DI (match_operand:DI 1 "register_operand" "")
479 (match_operand:DI 2 "small_int" "")))
480 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 481 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
482 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
483 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
484 && INTVAL (operands[2]) > 0"
485
486 [(set (subreg:SI (match_dup 0) 0)
487 (plus:SI (subreg:SI (match_dup 1) 0)
488 (match_dup 2)))
489
490 (set (match_dup 3)
34b650b3 491 (ltu:SI (subreg:SI (match_dup 0) 0)
8ef30996
MM
492 (match_dup 2)))
493
494 (set (subreg:SI (match_dup 0) 1)
495 (plus:SI (subreg:SI (match_dup 1) 1)
496 (match_dup 3)))]
497 "")
498
499(define_split
500 [(set (match_operand:DI 0 "register_operand" "")
501 (plus:DI (match_operand:DI 1 "register_operand" "")
502 (match_operand:DI 2 "small_int" "")))
503 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 504 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
505 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
506 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
507 && INTVAL (operands[2]) > 0"
508
509 [(set (subreg:SI (match_dup 0) 1)
510 (plus:SI (subreg:SI (match_dup 1) 1)
511 (match_dup 2)))
512
513 (set (match_dup 3)
34b650b3 514 (ltu:SI (subreg:SI (match_dup 0) 1)
8ef30996
MM
515 (match_dup 2)))
516
517 (set (subreg:SI (match_dup 0) 0)
518 (plus:SI (subreg:SI (match_dup 1) 0)
519 (match_dup 3)))]
520 "")
bb621ad7
JW
521
522(define_insn "adddi3_internal_3"
523 [(set (match_operand:DI 0 "register_operand" "=d")
524 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ")
525 (match_operand:DI 2 "arith_operand" "dI")))]
526 "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
527 "*
528{
529 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
530 ? \"dsubu\\t%0,%z1,%n2\"
531 : \"daddu\\t%0,%z1,%2\";
532}"
533 [(set_attr "type" "darith")
534 (set_attr "mode" "DI")
535 (set_attr "length" "1")])
536
537
538(define_insn "addsi3_internal_2"
539 [(set (match_operand:DI 0 "register_operand" "=d")
540 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
541 (match_operand:SI 2 "arith_operand" "dI"))))]
542 "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
543 "*
544{
545 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
546 ? \"subu\\t%0,%z1,%n2\"
547 : \"addu\\t%0,%z1,%2\";
548}"
549 [(set_attr "type" "arith")
550 (set_attr "mode" "SI")
551 (set_attr "length" "1")])
552
8ef30996
MM
553\f
554;;
555;; ....................
556;;
557;; SUBTRACTION
558;;
559;; ....................
560;;
561
562(define_insn "subdf3"
563 [(set (match_operand:DF 0 "register_operand" "=f")
564 (minus:DF (match_operand:DF 1 "register_operand" "f")
565 (match_operand:DF 2 "register_operand" "f")))]
566 "TARGET_HARD_FLOAT"
567 "sub.d\\t%0,%1,%2"
568 [(set_attr "type" "fadd")
569 (set_attr "mode" "DF")
570 (set_attr "length" "1")])
571
572(define_insn "subsf3"
573 [(set (match_operand:SF 0 "register_operand" "=f")
574 (minus:SF (match_operand:SF 1 "register_operand" "f")
575 (match_operand:SF 2 "register_operand" "f")))]
576 "TARGET_HARD_FLOAT"
577 "sub.s\\t%0,%1,%2"
578 [(set_attr "type" "fadd")
579 (set_attr "mode" "SF")
580 (set_attr "length" "1")])
581
71cd5224 582(define_expand "subsi3"
8ef30996
MM
583 [(set (match_operand:SI 0 "register_operand" "=d")
584 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
585 (match_operand:SI 2 "arith_operand" "dI")))]
586 ""
71cd5224
RS
587 "
588{
589 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
590 operands[2] = force_reg (SImode, operands[2]);
591}")
592
593(define_insn "subsi3_internal"
594 [(set (match_operand:SI 0 "register_operand" "=d")
595 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
596 (match_operand:SI 2 "arith_operand" "dI")))]
597 "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768"
9b190d1c 598 "subu\\t%0,%z1,%2"
8ef30996
MM
599 [(set_attr "type" "arith")
600 (set_attr "mode" "SI")
601 (set_attr "length" "1")])
602
603(define_expand "subdi3"
604 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
605 (minus:DI (match_operand:DI 1 "register_operand" "d")
606 (match_operand:DI 2 "register_operand" "d")))
607 (clobber (match_dup 3))])]
bb621ad7
JW
608 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
609 "
610{
611 if (TARGET_64BIT)
612 {
613 emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
614 operands[2]));
615 DONE;
616 }
617
618 operands[3] = gen_reg_rtx (SImode);
619}")
8ef30996
MM
620
621(define_insn "subdi3_internal"
622 [(set (match_operand:DI 0 "register_operand" "=d")
623 (minus:DI (match_operand:DI 1 "register_operand" "d")
624 (match_operand:DI 2 "register_operand" "d")))
625 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 626 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
8ef30996
MM
627 "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
628 [(set_attr "type" "darith")
629 (set_attr "mode" "DI")
630 (set_attr "length" "4")])
631
632(define_split
633 [(set (match_operand:DI 0 "register_operand" "")
634 (minus:DI (match_operand:DI 1 "register_operand" "")
635 (match_operand:DI 2 "register_operand" "")))
636 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 637 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
638 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
639 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
640 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
641
642 [(set (match_dup 3)
34b650b3 643 (ltu:SI (subreg:SI (match_dup 1) 0)
6d518002 644 (subreg:SI (match_dup 2) 0)))
8ef30996
MM
645
646 (set (subreg:SI (match_dup 0) 0)
647 (minus:SI (subreg:SI (match_dup 1) 0)
648 (subreg:SI (match_dup 2) 0)))
649
650 (set (subreg:SI (match_dup 0) 1)
651 (minus:SI (subreg:SI (match_dup 1) 1)
652 (subreg:SI (match_dup 2) 1)))
653
654 (set (subreg:SI (match_dup 0) 1)
655 (minus:SI (subreg:SI (match_dup 0) 1)
656 (match_dup 3)))]
657 "")
658
659(define_split
660 [(set (match_operand:DI 0 "register_operand" "")
661 (minus:DI (match_operand:DI 1 "register_operand" "")
662 (match_operand:DI 2 "register_operand" "")))
663 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 664 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
665 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
666 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
667 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
668
669 [(set (match_dup 3)
34b650b3 670 (ltu:SI (subreg:SI (match_dup 1) 1)
6d518002 671 (subreg:SI (match_dup 2) 1)))
8ef30996
MM
672
673 (set (subreg:SI (match_dup 0) 1)
674 (minus:SI (subreg:SI (match_dup 1) 1)
675 (subreg:SI (match_dup 2) 1)))
676
677 (set (subreg:SI (match_dup 0) 0)
678 (minus:SI (subreg:SI (match_dup 1) 0)
679 (subreg:SI (match_dup 2) 0)))
680
681 (set (subreg:SI (match_dup 0) 0)
682 (minus:SI (subreg:SI (match_dup 0) 0)
683 (match_dup 3)))]
684 "")
685
686(define_insn "subdi3_internal_2"
687 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
688 (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
689 (match_operand:DI 2 "small_int" "P,J,N")))
690 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
bb621ad7 691 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
8ef30996
MM
692 "@
693 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
694 move\\t%L0,%L1\;move\\t%M0,%M1
695 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
92b4cee1
MM
696 [(set_attr "type" "darith")
697 (set_attr "mode" "DI")
8ef30996
MM
698 (set_attr "length" "3,2,4")])
699
700(define_split
701 [(set (match_operand:DI 0 "register_operand" "")
702 (minus:DI (match_operand:DI 1 "register_operand" "")
703 (match_operand:DI 2 "small_int" "")))
704 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 705 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
706 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
707 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
708 && INTVAL (operands[2]) > 0"
709
710 [(set (match_dup 3)
34b650b3 711 (ltu:SI (subreg:SI (match_dup 1) 0)
8ef30996
MM
712 (match_dup 2)))
713
714 (set (subreg:SI (match_dup 0) 0)
715 (minus:SI (subreg:SI (match_dup 1) 0)
716 (match_dup 2)))
717
718 (set (subreg:SI (match_dup 0) 1)
719 (minus:SI (subreg:SI (match_dup 1) 1)
720 (match_dup 3)))]
721 "")
722
723(define_split
724 [(set (match_operand:DI 0 "register_operand" "")
725 (minus:DI (match_operand:DI 1 "register_operand" "")
726 (match_operand:DI 2 "small_int" "")))
727 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 728 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
729 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
730 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
731 && INTVAL (operands[2]) > 0"
732
733 [(set (match_dup 3)
34b650b3 734 (ltu:SI (subreg:SI (match_dup 1) 1)
8ef30996
MM
735 (match_dup 2)))
736
737 (set (subreg:SI (match_dup 0) 1)
738 (minus:SI (subreg:SI (match_dup 1) 1)
739 (match_dup 2)))
740
741 (set (subreg:SI (match_dup 0) 0)
742 (minus:SI (subreg:SI (match_dup 1) 0)
743 (match_dup 3)))]
744 "")
745
bb621ad7
JW
746(define_insn "subdi3_internal_3"
747 [(set (match_operand:DI 0 "register_operand" "=d")
748 (minus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ")
749 (match_operand:DI 2 "arith_operand" "dI")))]
750 "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
751 "*
752{
753 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
754 ? \"daddu\\t%0,%z1,%n2\"
755 : \"dsubu\\t%0,%z1,%2\";
756}"
757 [(set_attr "type" "darith")
758 (set_attr "mode" "DI")
759 (set_attr "length" "1")])
760
761
762(define_insn "subsi3_internal_2"
763 [(set (match_operand:DI 0 "register_operand" "=d")
764 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
765 (match_operand:SI 2 "arith_operand" "dI"))))]
766 "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
767 "*
768{
769 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
770 ? \"addu\\t%0,%z1,%n2\"
771 : \"subu\\t%0,%z1,%2\";
772}"
773 [(set_attr "type" "arith")
774 (set_attr "mode" "DI")
775 (set_attr "length" "1")])
776
8ef30996
MM
777\f
778;;
779;; ....................
780;;
781;; MULTIPLICATION
782;;
783;; ....................
784;;
785
786(define_insn "muldf3"
787 [(set (match_operand:DF 0 "register_operand" "=f")
788 (mult:DF (match_operand:DF 1 "register_operand" "f")
789 (match_operand:DF 2 "register_operand" "f")))]
790 "TARGET_HARD_FLOAT"
791 "mul.d\\t%0,%1,%2"
792 [(set_attr "type" "fmul")
793 (set_attr "mode" "DF")
794 (set_attr "length" "1")])
795
796(define_insn "mulsf3"
797 [(set (match_operand:SF 0 "register_operand" "=f")
798 (mult:SF (match_operand:SF 1 "register_operand" "f")
799 (match_operand:SF 2 "register_operand" "f")))]
800 "TARGET_HARD_FLOAT"
801 "mul.s\\t%0,%1,%2"
802 [(set_attr "type" "fmul")
803 (set_attr "mode" "SF")
804 (set_attr "length" "1")])
805
806(define_insn "mulsi3"
807 [(set (match_operand:SI 0 "register_operand" "=d")
808 (mult:SI (match_operand:SI 1 "register_operand" "d")
809 (match_operand:SI 2 "register_operand" "d")))
810 (clobber (reg:SI 64))
811 (clobber (reg:SI 65))]
812 ""
813 "*
814{
815 rtx xoperands[10];
816
817 xoperands[0] = operands[0];
818 xoperands[1] = gen_rtx (REG, SImode, LO_REGNUM);
819
820 output_asm_insn (\"mult\\t%1,%2\", operands);
bb621ad7 821 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
8ef30996
MM
822 return \"\";
823}"
824 [(set_attr "type" "imul")
825 (set_attr "mode" "SI")
826 (set_attr "length" "3")]) ;; mult + mflo + delay
827
bb621ad7
JW
828;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while
829;; a multiply is in progress, it may give an incorrect result. We solve
830;; this by not splitting on the r4000.
831
8ef30996
MM
832(define_split
833 [(set (match_operand:SI 0 "register_operand" "")
834 (mult:SI (match_operand:SI 1 "register_operand" "")
835 (match_operand:SI 2 "register_operand" "")))
836 (clobber (reg:SI 64))
837 (clobber (reg:SI 65))]
bb621ad7 838 "!TARGET_DEBUG_D_MODE && mips_cpu != PROCESSOR_R4000"
8ef30996
MM
839 [(parallel [(set (reg:SI 65) ;; low register
840 (mult:SI (match_dup 1)
841 (match_dup 2)))
842 (clobber (reg:SI 64))])
843 (set (match_dup 0)
844 (reg:SI 65))]
845 "")
846
847(define_insn "mulsi3_internal"
848 [(set (reg:SI 65) ;; low register
849 (mult:SI (match_operand:SI 0 "register_operand" "d")
850 (match_operand:SI 1 "register_operand" "d")))
851 (clobber (reg:SI 64))]
852 ""
853 "mult\\t%0,%1"
854 [(set_attr "type" "imul")
855 (set_attr "mode" "SI")
856 (set_attr "length" "1")])
857
bb621ad7
JW
858(define_insn "muldi3"
859 [(set (match_operand:DI 0 "register_operand" "=d")
860 (mult:DI (match_operand:DI 1 "register_operand" "d")
861 (match_operand:DI 2 "register_operand" "d")))
862 (clobber (reg:DI 64))
863 (clobber (reg:DI 65))]
864 "TARGET_64BIT"
865 "*
866{
867 rtx xoperands[10];
868
869 xoperands[0] = operands[0];
870 xoperands[1] = gen_rtx (REG, DImode, LO_REGNUM);
871
872 output_asm_insn (\"dmult\\t%1,%2\", operands);
873 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
874 return \"\";
875}"
876 [(set_attr "type" "imul")
877 (set_attr "mode" "DI")
878 (set_attr "length" "3")]) ;; mult + mflo + delay
879
880;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while
881;; a multiply is in progress, it may give an incorrect result. We solve
882;; this by not splitting on the r4000.
883
884(define_split
885 [(set (match_operand:DI 0 "register_operand" "")
886 (mult:DI (match_operand:DI 1 "register_operand" "")
887 (match_operand:DI 2 "register_operand" "")))
888 (clobber (reg:DI 64))
889 (clobber (reg:DI 65))]
890 "TARGET_64BIT && !TARGET_DEBUG_D_MODE && mips_cpu != PROCESSOR_R4000"
891 [(parallel [(set (reg:DI 65) ;; low register
892 (mult:DI (match_dup 1)
893 (match_dup 2)))
894 (clobber (reg:DI 64))])
895 (set (match_dup 0)
896 (reg:DI 65))]
897 "")
898
899(define_insn "muldi3_internal"
900 [(set (reg:DI 65) ;; low register
901 (mult:DI (match_operand:DI 0 "register_operand" "d")
902 (match_operand:DI 1 "register_operand" "d")))
903 (clobber (reg:DI 64))]
904 "TARGET_64BIT"
905 "dmult\\t%0,%1"
906 [(set_attr "type" "imul")
907 (set_attr "mode" "DI")
908 (set_attr "length" "1")])
909
910;; In 64 bit mode the mult instruction still writes 32 bits each to HI
911;; and LO, so to do mulsidi3 and umultsidi3 we need to pull the values
912;; out and combine them by hand into the single output register. Not
913;; supported for now.
914
915;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
916
8ef30996
MM
917(define_insn "mulsidi3"
918 [(set (match_operand:DI 0 "register_operand" "=d")
919 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
920 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
bb621ad7
JW
921 (clobber (reg:SI 64))
922 (clobber (reg:SI 65))]
923 "!TARGET_64BIT"
8ef30996
MM
924 "*
925{
926 rtx xoperands[10];
927
928 xoperands[0] = operands[0];
929 xoperands[1] = gen_rtx (REG, DImode, MD_REG_FIRST);
930
931 output_asm_insn (\"mult\\t%1,%2\", operands);
932 output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
933 return \"\";
934}"
935 [(set_attr "type" "imul")
936 (set_attr "mode" "SI")
937 (set_attr "length" "4")]) ;; mult + mflo + mfhi + delay
938
903df3fe
JW
939(define_insn "smulsi3_highpart"
940 [(set (match_operand:SI 0 "register_operand" "=d")
941 (truncate:SI
942 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
943 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
944 (const_int 32))))
945 (clobber (reg:SI 64))
946 (clobber (reg:SI 65))]
947 ""
948 "*
949{
950 rtx xoperands[10];
951
952 xoperands[0] = operands[0];
953 xoperands[1] = gen_rtx (REG, SImode, HI_REGNUM);
954
955 output_asm_insn (\"mult\\t%1,%2\", operands);
9b190d1c 956 output_asm_insn (mips_move_1word (xoperands, insn, TRUE), xoperands);
903df3fe
JW
957 return \"\";
958}"
959 [(set_attr "type" "imul")
960 (set_attr "mode" "SI")
961 (set_attr "length" "3")]) ;; mult + mfhi + delay
962
963(define_split
964 [(set (match_operand:SI 0 "register_operand" "")
965 (truncate:SI
966 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
967 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
968 (const_int 32))))
969 (clobber (reg:SI 64))
970 (clobber (reg:SI 65))]
971 "!TARGET_DEBUG_D_MODE"
972 [(parallel [(set (reg:SI 64) ;; high register
973 (truncate:SI
974 (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
975 (sign_extend:DI (match_dup 2)))
976 (const_int 32))))
977 (clobber (reg:SI 65))])
978 (set (match_dup 0)
979 (reg:SI 64))]
980 "")
981
982(define_insn "smulsi3_highpart_internal"
983 [(set (reg:SI 64) ;; high register
984 (truncate:SI
985 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "d"))
986 (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))
987 (const_int 32))))
988 (clobber (reg:SI 65))]
989 ""
990 "mult\\t%0,%1"
991 [(set_attr "type" "imul")
992 (set_attr "mode" "SI")
993 (set_attr "length" "1")])
994
8ef30996
MM
995(define_insn "umulsidi3"
996 [(set (match_operand:DI 0 "register_operand" "=d")
997 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
998 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
bb621ad7
JW
999 (clobber (reg:SI 64))
1000 (clobber (reg:SI 65))]
1001 "!TARGET_64BIT"
8ef30996
MM
1002 "*
1003{
1004 rtx xoperands[10];
1005
1006 xoperands[0] = operands[0];
1007 xoperands[1] = gen_rtx (REG, DImode, MD_REG_FIRST);
1008
1009 output_asm_insn (\"multu\\t%1,%2\", operands);
1010 output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
1011 return \"\";
1012}"
1013 [(set_attr "type" "imul")
1014 (set_attr "mode" "SI")
1015 (set_attr "length" "4")]) ;; mult + mflo + mfhi + delay
1016
903df3fe
JW
1017(define_insn "umulsi3_highpart"
1018 [(set (match_operand:SI 0 "register_operand" "=d")
1019 (truncate:SI
1020 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1021 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1022 (const_int 32))))
1023 (clobber (reg:SI 64))
1024 (clobber (reg:SI 65))]
1025 ""
1026 "*
1027{
1028 rtx xoperands[10];
1029
1030 xoperands[0] = operands[0];
1031 xoperands[1] = gen_rtx (REG, SImode, HI_REGNUM);
1032
1033 output_asm_insn (\"multu\\t%1,%2\", operands);
9b190d1c 1034 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
903df3fe
JW
1035 return \"\";
1036}"
1037 [(set_attr "type" "imul")
1038 (set_attr "mode" "SI")
1039 (set_attr "length" "3")]) ;; multu + mfhi + delay
1040
1041(define_split
1042 [(set (match_operand:SI 0 "register_operand" "")
1043 (truncate:SI
1044 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1045 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1046 (const_int 32))))
1047 (clobber (reg:SI 64))
1048 (clobber (reg:SI 65))]
1049 "!TARGET_DEBUG_D_MODE"
1050 [(parallel [(set (reg:SI 64) ;; high register
1051 (truncate:SI
1052 (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
1053 (zero_extend:DI (match_dup 2)))
1054 (const_int 32))))
1055 (clobber (reg:SI 65))])
1056 (set (match_dup 0)
1057 (reg:SI 64))]
1058 "")
1059
1060(define_insn "umulsi3_highpart_internal"
1061 [(set (reg:SI 64) ;; high register
1062 (truncate:SI
1063 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "d"))
1064 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))
1065 (const_int 32))))
1066 (clobber (reg:SI 65))]
1067 ""
1068 "multu\\t%0,%1"
1069 [(set_attr "type" "imul")
1070 (set_attr "mode" "SI")
1071 (set_attr "length" "1")])
8ef30996
MM
1072\f
1073;;
1074;; ....................
1075;;
1076;; DIVISION and REMAINDER
1077;;
1078;; ....................
1079;;
1080
1081(define_insn "divdf3"
1082 [(set (match_operand:DF 0 "register_operand" "=f")
1083 (div:DF (match_operand:DF 1 "register_operand" "f")
1084 (match_operand:DF 2 "register_operand" "f")))]
1085 "TARGET_HARD_FLOAT"
1086 "div.d\\t%0,%1,%2"
1087 [(set_attr "type" "fdiv")
1088 (set_attr "mode" "DF")
1089 (set_attr "length" "1")])
1090
1091(define_insn "divsf3"
1092 [(set (match_operand:SF 0 "register_operand" "=f")
1093 (div:SF (match_operand:SF 1 "register_operand" "f")
1094 (match_operand:SF 2 "register_operand" "f")))]
1095 "TARGET_HARD_FLOAT"
1096 "div.s\\t%0,%1,%2"
1097 [(set_attr "type" "fdiv")
1098 (set_attr "mode" "SF")
1099 (set_attr "length" "1")])
1100
1101;; If optimizing, prefer the divmod functions over separate div and
1102;; mod functions, since this will allow using one instruction for both
1103;; the quotient and remainder. At present, the divmod is not moved out
1104;; of loops if it is constant within the loop, so allow -mdebugc to
1105;; use the old method of doing things.
1106
1107;; 64 is the multiply/divide hi register
1108;; 65 is the multiply/divide lo register
1109
bb621ad7
JW
1110;; ??? We can't accept constants here, because the MIPS assembler will replace
1111;; a divide by power of 2 with a shift, and then the remainder is no longer
1112;; available.
1113
8ef30996 1114(define_insn "divmodsi4"
70252580
MM
1115 [(set (match_operand:SI 0 "register_operand" "=d")
1116 (div:SI (match_operand:SI 1 "register_operand" "d")
1117 (match_operand:SI 2 "register_operand" "d")))
1118 (set (match_operand:SI 3 "register_operand" "=d")
1119 (mod:SI (match_dup 1)
1120 (match_dup 2)))
1121 (clobber (reg:SI 64))
1122 (clobber (reg:SI 65))]
34b650b3 1123 "optimize"
8ef30996
MM
1124 "*
1125{
1126 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1127 return \"div\\t%0,%1,%2\";
1128
1129 if (find_reg_note (insn, REG_UNUSED, operands[0]))
1130 return \"rem\\t%3,%1,%2\";
1131
1132 return \"div\\t%0,%1,%2\;mfhi\\t%3\";
1133}"
1134 [(set_attr "type" "idiv")
1135 (set_attr "mode" "SI")
bb621ad7
JW
1136 (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
1137
1138(define_insn "divmoddi4"
1139 [(set (match_operand:DI 0 "register_operand" "=d")
1140 (div:DI (match_operand:DI 1 "register_operand" "d")
1141 (match_operand:DI 2 "register_operand" "d")))
1142 (set (match_operand:DI 3 "register_operand" "=d")
1143 (mod:DI (match_dup 1)
1144 (match_dup 2)))
1145 (clobber (reg:DI 64))
1146 (clobber (reg:DI 65))]
1147 "TARGET_64BIT && optimize"
1148 "*
1149{
1150 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1151 return \"ddiv\\t%0,%1,%2\";
1152
1153 if (find_reg_note (insn, REG_UNUSED, operands[0]))
1154 return \"drem\\t%3,%1,%2\";
1155
1156 return \"ddiv\\t%0,%1,%2\;mfhi\\t%3\";
1157}"
1158 [(set_attr "type" "idiv")
1159 (set_attr "mode" "DI")
1160 (set_attr "length" "15")]) ;; various tests for dividing by 0 and such
8ef30996
MM
1161
1162(define_insn "udivmodsi4"
70252580
MM
1163 [(set (match_operand:SI 0 "register_operand" "=d")
1164 (udiv:SI (match_operand:SI 1 "register_operand" "d")
1165 (match_operand:SI 2 "register_operand" "d")))
1166 (set (match_operand:SI 3 "register_operand" "=d")
1167 (umod:SI (match_dup 1)
1168 (match_dup 2)))
1169 (clobber (reg:SI 64))
1170 (clobber (reg:SI 65))]
34b650b3 1171 "optimize"
8ef30996
MM
1172 "*
1173{
1174 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1175 return \"divu\\t%0,%1,%2\";
1176
1177 if (find_reg_note (insn, REG_UNUSED, operands[0]))
1178 return \"remu\\t%3,%1,%2\";
1179
1180 return \"divu\\t%0,%1,%2\;mfhi\\t%3\";
1181}"
1182 [(set_attr "type" "idiv")
1183 (set_attr "mode" "SI")
bb621ad7
JW
1184 (set_attr "length" "8")]) ;; various tests for dividing by 0 and such
1185
1186(define_insn "udivmoddi4"
1187 [(set (match_operand:DI 0 "register_operand" "=d")
1188 (udiv:DI (match_operand:DI 1 "register_operand" "d")
1189 (match_operand:DI 2 "register_operand" "d")))
1190 (set (match_operand:DI 3 "register_operand" "=d")
1191 (umod:DI (match_dup 1)
1192 (match_dup 2)))
1193 (clobber (reg:DI 64))
1194 (clobber (reg:DI 65))]
1195 "TARGET_64BIT && optimize"
1196 "*
1197{
1198 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1199 return \"ddivu\\t%0,%1,%2\";
1200
1201 if (find_reg_note (insn, REG_UNUSED, operands[0]))
1202 return \"dremu\\t%3,%1,%2\";
1203
1204 return \"ddivu\\t%0,%1,%2\;mfhi\\t%3\";
1205}"
1206 [(set_attr "type" "idiv")
1207 (set_attr "mode" "DI")
1208 (set_attr "length" "8")]) ;; various tests for dividing by 0 and such
8ef30996
MM
1209
1210(define_insn "divsi3"
1211 [(set (match_operand:SI 0 "register_operand" "=d")
1212 (div:SI (match_operand:SI 1 "register_operand" "d")
bb621ad7 1213 (match_operand:SI 2 "nonmemory_operand" "di")))
8ef30996
MM
1214 (clobber (reg:SI 64))
1215 (clobber (reg:SI 65))]
34b650b3 1216 "!optimize"
8ef30996
MM
1217 "div\\t%0,%1,%2"
1218 [(set_attr "type" "idiv")
1219 (set_attr "mode" "SI")
1220 (set_attr "length" "13")]) ;; various tests for dividing by 0 and such
1221
bb621ad7
JW
1222(define_insn "divdi3"
1223 [(set (match_operand:DI 0 "register_operand" "=d")
1224 (div:DI (match_operand:DI 1 "register_operand" "d")
1225 (match_operand:DI 2 "nonmemory_operand" "di")))
1226 (clobber (reg:DI 64))
1227 (clobber (reg:DI 65))]
1228 "TARGET_64BIT && !optimize"
1229 "ddiv\\t%0,%1,%2"
1230 [(set_attr "type" "idiv")
1231 (set_attr "mode" "DI")
1232 (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
1233
8ef30996
MM
1234(define_insn "modsi3"
1235 [(set (match_operand:SI 0 "register_operand" "=d")
1236 (mod:SI (match_operand:SI 1 "register_operand" "d")
bb621ad7 1237 (match_operand:SI 2 "nonmemory_operand" "di")))
8ef30996
MM
1238 (clobber (reg:SI 64))
1239 (clobber (reg:SI 65))]
34b650b3 1240 "!optimize"
8ef30996
MM
1241 "rem\\t%0,%1,%2"
1242 [(set_attr "type" "idiv")
1243 (set_attr "mode" "SI")
bb621ad7
JW
1244 (set_attr "length" "13")]) ;; various tests for dividing by 0 and such
1245
1246(define_insn "moddi3"
1247 [(set (match_operand:DI 0 "register_operand" "=d")
1248 (mod:DI (match_operand:DI 1 "register_operand" "d")
1249 (match_operand:DI 2 "nonmemory_operand" "di")))
1250 (clobber (reg:DI 64))
1251 (clobber (reg:DI 65))]
1252 "TARGET_64BIT && !optimize"
1253 "drem\\t%0,%1,%2"
1254 [(set_attr "type" "idiv")
1255 (set_attr "mode" "DI")
8ef30996
MM
1256 (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
1257
1258(define_insn "udivsi3"
1259 [(set (match_operand:SI 0 "register_operand" "=d")
1260 (udiv:SI (match_operand:SI 1 "register_operand" "d")
bb621ad7 1261 (match_operand:SI 2 "nonmemory_operand" "di")))
8ef30996
MM
1262 (clobber (reg:SI 64))
1263 (clobber (reg:SI 65))]
34b650b3 1264 "!optimize"
8ef30996
MM
1265 "divu\\t%0,%1,%2"
1266 [(set_attr "type" "idiv")
1267 (set_attr "mode" "SI")
bb621ad7
JW
1268 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
1269
1270(define_insn "udivdi3"
1271 [(set (match_operand:DI 0 "register_operand" "=d")
1272 (udiv:DI (match_operand:DI 1 "register_operand" "d")
1273 (match_operand:DI 2 "nonmemory_operand" "di")))
1274 (clobber (reg:DI 64))
1275 (clobber (reg:DI 65))]
1276 "TARGET_64BIT && !optimize"
1277 "ddivu\\t%0,%1,%2"
1278 [(set_attr "type" "idiv")
1279 (set_attr "mode" "DI")
1280 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
8ef30996
MM
1281
1282(define_insn "umodsi3"
1283 [(set (match_operand:SI 0 "register_operand" "=d")
1284 (umod:SI (match_operand:SI 1 "register_operand" "d")
bb621ad7 1285 (match_operand:SI 2 "nonmemory_operand" "di")))
8ef30996
MM
1286 (clobber (reg:SI 64))
1287 (clobber (reg:SI 65))]
34b650b3 1288 "!optimize"
8ef30996
MM
1289 "remu\\t%0,%1,%2"
1290 [(set_attr "type" "idiv")
1291 (set_attr "mode" "SI")
bb621ad7
JW
1292 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
1293
1294(define_insn "umoddi3"
1295 [(set (match_operand:DI 0 "register_operand" "=d")
1296 (umod:DI (match_operand:DI 1 "register_operand" "d")
1297 (match_operand:DI 2 "nonmemory_operand" "di")))
1298 (clobber (reg:DI 64))
1299 (clobber (reg:DI 65))]
1300 "TARGET_64BIT && !optimize"
1301 "dremu\\t%0,%1,%2"
1302 [(set_attr "type" "idiv")
1303 (set_attr "mode" "DI")
1304 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
8ef30996
MM
1305
1306\f
1307;;
1308;; ....................
1309;;
1310;; SQUARE ROOT
1311;;
1312;; ....................
1313
1314(define_insn "sqrtdf2"
1315 [(set (match_operand:DF 0 "register_operand" "=f")
1316 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
1317 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
1318 "sqrt.d\\t%0,%1"
bb621ad7 1319 [(set_attr "type" "fsqrt")
8ef30996
MM
1320 (set_attr "mode" "DF")
1321 (set_attr "length" "1")])
1322
1323(define_insn "sqrtsf2"
1324 [(set (match_operand:SF 0 "register_operand" "=f")
1325 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
1326 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
1327 "sqrt.s\\t%0,%1"
bb621ad7 1328 [(set_attr "type" "fsqrt")
8ef30996
MM
1329 (set_attr "mode" "SF")
1330 (set_attr "length" "1")])
1331
1332\f
1333;;
1334;; ....................
1335;;
1336;; ABSOLUTE VALUE
1337;;
1338;; ....................
1339
1340;; Do not use the integer abs macro instruction, since that signals an
1341;; exception on -2147483648 (sigh).
1342
1343(define_insn "abssi2"
1344 [(set (match_operand:SI 0 "register_operand" "=d")
1345 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
1346 ""
1347 "*
1348{
1349 dslots_jump_total++;
1350 dslots_jump_filled++;
1351 operands[2] = const0_rtx;
1352
bb621ad7
JW
1353 if (REGNO (operands[0]) == REGNO (operands[1]))
1354 {
1355 if (mips_isa >= 2)
1356 return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
1357 else
1358 return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n1:\";
1359 }
1360 else
1361 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
8ef30996
MM
1362}"
1363 [(set_attr "type" "multi")
1364 (set_attr "mode" "SI")
1365 (set_attr "length" "3")])
1366
bb621ad7
JW
1367(define_insn "absdi2"
1368 [(set (match_operand:DI 0 "register_operand" "=d")
1369 (abs:DI (match_operand:DI 1 "register_operand" "d")))]
1370 "TARGET_64BIT"
1371 "*
1372{
1373 dslots_jump_total++;
1374 dslots_jump_filled++;
1375 operands[2] = const0_rtx;
1376
1377 if (REGNO (operands[0]) == REGNO (operands[1]))
1378 return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
1379 else
1380 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
1381}"
1382 [(set_attr "type" "multi")
1383 (set_attr "mode" "DI")
1384 (set_attr "length" "3")])
1385
8ef30996
MM
1386(define_insn "absdf2"
1387 [(set (match_operand:DF 0 "register_operand" "=f")
1388 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
1389 "TARGET_HARD_FLOAT"
1390 "abs.d\\t%0,%1"
1391 [(set_attr "type" "fabs")
1392 (set_attr "mode" "DF")
1393 (set_attr "length" "1")])
1394
1395(define_insn "abssf2"
1396 [(set (match_operand:SF 0 "register_operand" "=f")
1397 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
1398 "TARGET_HARD_FLOAT"
1399 "abs.s\\t%0,%1"
1400 [(set_attr "type" "fabs")
1401 (set_attr "mode" "SF")
1402 (set_attr "length" "1")])
1403
1404\f
1405;;
1406;; ....................
1407;;
1408;; FIND FIRST BIT INSTRUCTION
1409;;
1410;; ....................
1411;;
1412
1413(define_insn "ffssi2"
1414 [(set (match_operand:SI 0 "register_operand" "=&d")
1415 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
7d87c851
MM
1416 (clobber (match_scratch:SI 2 "=&d"))
1417 (clobber (match_scratch:SI 3 "=&d"))]
8ef30996
MM
1418 ""
1419 "*
1420{
1421 dslots_jump_total += 2;
1422 dslots_jump_filled += 2;
1423 operands[4] = const0_rtx;
1424
1425 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1426 return \"%(\\
1427move\\t%0,%z4\\n\\
1428\\tbeq\\t%1,%z4,2f\\n\\
14291:\\tand\\t%2,%1,0x0001\\n\\
1430\\taddu\\t%0,%0,1\\n\\
1431\\tbeq\\t%2,%z4,1b\\n\\
1432\\tsrl\\t%1,%1,1\\n\\
14332:%)\";
1434
1435 return \"%(\\
1436move\\t%0,%z4\\n\\
1437\\tmove\\t%3,%1\\n\\
1438\\tbeq\\t%3,%z4,2f\\n\\
14391:\\tand\\t%2,%3,0x0001\\n\\
1440\\taddu\\t%0,%0,1\\n\\
1441\\tbeq\\t%2,%z4,1b\\n\\
1442\\tsrl\\t%3,%3,1\\n\\
14432:%)\";
1444}"
1445 [(set_attr "type" "multi")
1446 (set_attr "mode" "SI")
1447 (set_attr "length" "6")])
1448
bb621ad7
JW
1449(define_insn "ffsdi2"
1450 [(set (match_operand:DI 0 "register_operand" "=&d")
1451 (ffs:DI (match_operand:DI 1 "register_operand" "d")))
1452 (clobber (match_scratch:DI 2 "=&d"))
1453 (clobber (match_scratch:DI 3 "=&d"))]
1454 "TARGET_64BIT"
1455 "*
1456{
1457 dslots_jump_total += 2;
1458 dslots_jump_filled += 2;
1459 operands[4] = const0_rtx;
1460
1461 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1462 return \"%(\\
1463move\\t%0,%z4\\n\\
1464\\tbeq\\t%1,%z4,2f\\n\\
14651:\\tand\\t%2,%1,0x0001\\n\\
1466\\tdaddu\\t%0,%0,1\\n\\
1467\\tbeq\\t%2,%z4,1b\\n\\
1468\\tdsrl\\t%1,%1,1\\n\\
14692:%)\";
1470
1471 return \"%(\\
1472move\\t%0,%z4\\n\\
1473\\tmove\\t%3,%1\\n\\
1474\\tbeq\\t%3,%z4,2f\\n\\
14751:\\tand\\t%2,%3,0x0001\\n\\
1476\\tdaddu\\t%0,%0,1\\n\\
1477\\tbeq\\t%2,%z4,1b\\n\\
1478\\tdsrl\\t%3,%3,1\\n\\
14792:%)\";
1480}"
1481 [(set_attr "type" "multi")
1482 (set_attr "mode" "DI")
1483 (set_attr "length" "6")])
1484
8ef30996
MM
1485\f
1486;;
1487;; ....................
1488;;
1489;; NEGATION and ONE'S COMPLEMENT
1490;;
1491;; ....................
1492
1493(define_insn "negsi2"
1494 [(set (match_operand:SI 0 "register_operand" "=d")
1495 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
1496 ""
1497 "*
1498{
1499 operands[2] = const0_rtx;
1500 return \"subu\\t%0,%z2,%1\";
1501}"
1502 [(set_attr "type" "arith")
1503 (set_attr "mode" "SI")
1504 (set_attr "length" "1")])
1505
e7d7b3dc 1506(define_expand "negdi2"
8ef30996
MM
1507 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1508 (neg:DI (match_operand:DI 1 "register_operand" "d")))
1509 (clobber (match_dup 2))])]
bb621ad7
JW
1510 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
1511 "
1512{
1513 if (TARGET_64BIT)
1514 {
1515 emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
1516 DONE;
1517 }
1518
1519 operands[2] = gen_reg_rtx (SImode);
1520}")
8ef30996 1521
e7d7b3dc 1522(define_insn "negdi2_internal"
8ef30996
MM
1523 [(set (match_operand:DI 0 "register_operand" "=d")
1524 (neg:DI (match_operand:DI 1 "register_operand" "d")))
1525 (clobber (match_operand:SI 2 "register_operand" "=d"))]
bb621ad7 1526 "! TARGET_64BIT && !TARGET_DEBUG_G_MODE"
8ef30996
MM
1527 "*
1528{
1529 operands[3] = const0_rtx;
1530 return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
1531}"
1532 [(set_attr "type" "darith")
1533 (set_attr "mode" "DI")
1534 (set_attr "length" "4")])
1535
bb621ad7
JW
1536(define_insn "negdi2_internal_2"
1537 [(set (match_operand:DI 0 "register_operand" "=d")
1538 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
1539 "TARGET_64BIT"
1540 "*
1541{
1542 operands[2] = const0_rtx;
1543 return \"dsubu\\t%0,%z2,%1\";
1544}"
1545 [(set_attr "type" "arith")
1546 (set_attr "mode" "DI")
1547 (set_attr "length" "1")])
1548
8ef30996
MM
1549(define_insn "negdf2"
1550 [(set (match_operand:DF 0 "register_operand" "=f")
1551 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1552 "TARGET_HARD_FLOAT"
1553 "neg.d\\t%0,%1"
1554 [(set_attr "type" "fneg")
1555 (set_attr "mode" "DF")
1556 (set_attr "length" "1")])
1557
1558(define_insn "negsf2"
1559 [(set (match_operand:SF 0 "register_operand" "=f")
1560 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1561 "TARGET_HARD_FLOAT"
1562 "neg.s\\t%0,%1"
1563 [(set_attr "type" "fneg")
1564 (set_attr "mode" "SF")
1565 (set_attr "length" "1")])
1566
1567(define_insn "one_cmplsi2"
1568 [(set (match_operand:SI 0 "register_operand" "=d")
1569 (not:SI (match_operand:SI 1 "register_operand" "d")))]
1570 ""
1571 "*
1572{
1573 operands[2] = const0_rtx;
1574 return \"nor\\t%0,%z2,%1\";
1575}"
1576 [(set_attr "type" "arith")
1577 (set_attr "mode" "SI")
1578 (set_attr "length" "1")])
1579
1580(define_insn "one_cmpldi2"
1581 [(set (match_operand:DI 0 "register_operand" "=d")
bb621ad7 1582 (not:DI (match_operand:DI 1 "register_operand" "d")))]
8ef30996
MM
1583 ""
1584 "*
1585{
1586 operands[2] = const0_rtx;
bb621ad7
JW
1587 if (TARGET_64BIT)
1588 return \"nor\\t%0,%z2,%1\";
8ef30996
MM
1589 return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
1590}"
1591 [(set_attr "type" "darith")
1592 (set_attr "mode" "DI")
bb621ad7
JW
1593 (set (attr "length")
1594 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
1595 (const_int 1)
1596 (const_int 2)))])
8ef30996
MM
1597
1598(define_split
1599 [(set (match_operand:DI 0 "register_operand" "")
1600 (not:DI (match_operand:DI 1 "register_operand" "")))]
bb621ad7 1601 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
1602 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1603 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
1604
1605 [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
1606 (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))]
1607 "")
1608
1609;; Simple hack to recognize the "nor" instruction on the MIPS
1610;; This must appear before the normal or patterns, so that the
1611;; combiner will correctly fold things.
1612
1613(define_insn "norsi3"
1614 [(set (match_operand:SI 0 "register_operand" "=d")
1615 (not:SI (ior:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1616 (match_operand:SI 2 "reg_or_0_operand" "dJ"))))]
1617 ""
1618 "nor\\t%0,%z1,%z2"
1619 [(set_attr "type" "arith")
1620 (set_attr "mode" "SI")
1621 (set_attr "length" "1")])
1622
1623(define_insn "nordi3"
1624 [(set (match_operand:DI 0 "register_operand" "=d")
1625 (not:DI (ior:DI (match_operand:DI 1 "register_operand" "d")
1626 (match_operand:DI 2 "register_operand" "d"))))]
1627 ""
bb621ad7
JW
1628 "*
1629{
1630 if (TARGET_64BIT)
1631 return \"nor\\t%0,%z1,%z2\";
1632 return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
1633}"
8ef30996
MM
1634 [(set_attr "type" "darith")
1635 (set_attr "mode" "DI")
bb621ad7
JW
1636 (set (attr "length")
1637 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
1638 (const_int 1)
1639 (const_int 2)))])
8ef30996
MM
1640
1641(define_split
1642 [(set (match_operand:DI 0 "register_operand" "")
1643 (not:DI (ior:DI (match_operand:DI 1 "register_operand" "")
1644 (match_operand:DI 2 "register_operand" ""))))]
bb621ad7 1645 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
1646 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1647 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1648 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1649
1650 [(set (subreg:SI (match_dup 0) 0) (not:SI (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))))
1651 (set (subreg:SI (match_dup 0) 1) (not:SI (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1))))]
1652 "")
1653
1654\f
1655;;
1656;; ....................
1657;;
1658;; LOGICAL
1659;;
1660;; ....................
1661;;
1662
3e89ed5f 1663(define_insn "andsi3"
65437fe8 1664 [(set (match_operand:SI 0 "register_operand" "=d,d")
e2f2127c
MM
1665 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
1666 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
65437fe8
MM
1667 ""
1668 "@
1669 and\\t%0,%1,%2
1670 andi\\t%0,%1,%x2"
1671 [(set_attr "type" "arith")
1672 (set_attr "mode" "SI")
1673 (set_attr "length" "1")])
1674
8ef30996
MM
1675(define_insn "anddi3"
1676 [(set (match_operand:DI 0 "register_operand" "=d")
1677 (and:DI (match_operand:DI 1 "register_operand" "d")
1678 (match_operand:DI 2 "register_operand" "d")))]
bb621ad7
JW
1679 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
1680 "*
1681{
1682 if (TARGET_64BIT)
1683 return \"and\\t%0,%1,%2\";
1684 return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
1685}"
8ef30996
MM
1686 [(set_attr "type" "darith")
1687 (set_attr "mode" "DI")
bb621ad7
JW
1688 (set (attr "length")
1689 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
1690 (const_int 1)
1691 (const_int 2)))])
8ef30996
MM
1692
1693(define_split
1694 [(set (match_operand:DI 0 "register_operand" "")
1695 (and:DI (match_operand:DI 1 "register_operand" "")
1696 (match_operand:DI 2 "register_operand" "")))]
bb621ad7 1697 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
1698 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1699 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1700 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1701
1702 [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
1703 (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
1704 "")
1705
bb621ad7
JW
1706(define_insn "anddi3_internal1"
1707 [(set (match_operand:DI 0 "register_operand" "=d,d")
1708 (and:DI (match_operand:DI 1 "register_operand" "%d,d")
1709 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
1710 "TARGET_64BIT"
1711 "@
1712 and\\t%0,%1,%2
1713 andi\\t%0,%1,%x2"
1714 [(set_attr "type" "arith")
1715 (set_attr "mode" "DI")
1716 (set_attr "length" "1")])
1717
3e89ed5f 1718(define_insn "iorsi3"
65437fe8 1719 [(set (match_operand:SI 0 "register_operand" "=d,d")
e2f2127c
MM
1720 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
1721 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
65437fe8
MM
1722 ""
1723 "@
1724 or\\t%0,%1,%2
1725 ori\\t%0,%1,%x2"
1726 [(set_attr "type" "arith")
1727 (set_attr "mode" "SI")
1728 (set_attr "length" "1")])
1729
bb621ad7
JW
1730;;; ??? There is no iordi3 pattern which accepts 'K' constants when
1731;;; TARGET_64BIT
1732
8ef30996
MM
1733(define_insn "iordi3"
1734 [(set (match_operand:DI 0 "register_operand" "=d")
1735 (ior:DI (match_operand:DI 1 "register_operand" "d")
1736 (match_operand:DI 2 "register_operand" "d")))]
bb621ad7
JW
1737 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
1738 "*
1739{
1740 if (TARGET_64BIT)
1741 return \"or\\t%0,%1,%2\";
1742 return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
1743}"
8ef30996
MM
1744 [(set_attr "type" "darith")
1745 (set_attr "mode" "DI")
bb621ad7
JW
1746 (set (attr "length")
1747 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
1748 (const_int 1)
1749 (const_int 2)))])
8ef30996
MM
1750
1751(define_split
1752 [(set (match_operand:DI 0 "register_operand" "")
1753 (ior:DI (match_operand:DI 1 "register_operand" "")
1754 (match_operand:DI 2 "register_operand" "")))]
bb621ad7 1755 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
1756 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1757 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1758 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1759
1760 [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
1761 (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
1762 "")
1763
3e89ed5f 1764(define_insn "xorsi3"
65437fe8 1765 [(set (match_operand:SI 0 "register_operand" "=d,d")
e2f2127c
MM
1766 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
1767 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
65437fe8
MM
1768 ""
1769 "@
1770 xor\\t%0,%1,%2
1771 xori\\t%0,%1,%x2"
1772 [(set_attr "type" "arith")
1773 (set_attr "mode" "SI")
1774 (set_attr "length" "1")])
1775
bb621ad7
JW
1776;; ??? If delete the 32-bit long long patterns, then could merge this with
1777;; the following xordi3_internal pattern.
8ef30996
MM
1778(define_insn "xordi3"
1779 [(set (match_operand:DI 0 "register_operand" "=d")
1780 (xor:DI (match_operand:DI 1 "register_operand" "d")
1781 (match_operand:DI 2 "register_operand" "d")))]
bb621ad7
JW
1782 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
1783 "*
1784{
1785 if (TARGET_64BIT)
1786 return \"xor\\t%0,%1,%2\";
1787 return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
1788}"
1789 [(set_attr "type" "darith")
8ef30996 1790 (set_attr "mode" "DI")
bb621ad7
JW
1791 (set (attr "length")
1792 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
1793 (const_int 1)
1794 (const_int 2)))])
8ef30996
MM
1795
1796(define_split
1797 [(set (match_operand:DI 0 "register_operand" "")
1798 (xor:DI (match_operand:DI 1 "register_operand" "")
1799 (match_operand:DI 2 "register_operand" "")))]
bb621ad7 1800 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
1801 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1802 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1803 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1804
1805 [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
1806 (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
1807 "")
1808
bb621ad7
JW
1809(define_insn "xordi3_immed"
1810 [(set (match_operand:DI 0 "register_operand" "d")
1811 (xor:DI (match_operand:DI 1 "register_operand" "d")
1812 (match_operand:DI 2 "uns_arith_operand" "K")))]
1813 "TARGET_64BIT"
1814 "xori\\t%0,%1,%x2"
1815 [(set_attr "type" "arith")
1816 (set_attr "mode" "DI")
1817 (set_attr "length" "1")])
1818
8ef30996
MM
1819\f
1820;;
1821;; ....................
1822;;
1823;; TRUNCATION
1824;;
1825;; ....................
1826
1827(define_insn "truncdfsf2"
1828 [(set (match_operand:SF 0 "register_operand" "=f")
1829 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
1830 "TARGET_HARD_FLOAT"
1831 "cvt.s.d\\t%0,%1"
1832 [(set_attr "type" "fcvt")
1833 (set_attr "mode" "SF")
1834 (set_attr "length" "1")])
1835
bb621ad7
JW
1836;; ??? This should be a define expand.
1837;; See the zero_extendsidi2 pattern.
1838(define_insn "truncdisi2"
1839 [(set (match_operand:SI 0 "register_operand" "=d")
1840 (truncate:SI (match_operand:DI 1 "register_operand" "d")))]
1841 "TARGET_64BIT"
1842 "dsll\\t%0,%1,32\;dsra\\t%0,%0,32"
1843 [(set_attr "type" "darith")
1844 (set_attr "mode" "SI")
1845 (set_attr "length" "2")])
1846
1847(define_insn "truncdihi2"
1848 [(set (match_operand:HI 0 "register_operand" "=d")
1849 (truncate:HI (match_operand:DI 1 "register_operand" "d")))]
1850 "TARGET_64BIT"
1851 "andi\\t%0,%1,0xffff"
1852 [(set_attr "type" "darith")
1853 (set_attr "mode" "HI")
1854 (set_attr "length" "1")])
1855
1856(define_insn "truncdiqi2"
1857 [(set (match_operand:QI 0 "register_operand" "=d")
1858 (truncate:QI (match_operand:DI 1 "register_operand" "d")))]
1859 "TARGET_64BIT"
1860 "andi\\t%0,%1,0x00ff"
1861 [(set_attr "type" "darith")
1862 (set_attr "mode" "QI")
1863 (set_attr "length" "1")])
8ef30996
MM
1864\f
1865;;
1866;; ....................
1867;;
1868;; ZERO EXTENSION
1869;;
1870;; ....................
1871
1872;; Extension insns.
1873;; Those for integer source operand
1874;; are ordered widest source type first.
1875
bb621ad7
JW
1876(define_expand "zero_extendsidi2"
1877 [(set (match_operand:DI 0 "register_operand" "")
1878 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
1879 "TARGET_64BIT"
1880 "
1881{
1882 if (optimize && GET_CODE (operands[1]) == MEM)
1883 operands[1] = force_not_mem (operands[1]);
1884
1885 if (GET_CODE (operands[1]) != MEM)
1886 {
1887 rtx op1 = gen_lowpart (DImode, operands[1]);
1888 rtx temp = gen_reg_rtx (DImode);
1889 rtx shift = gen_rtx (CONST_INT, VOIDmode, 32);
1890
1891 emit_insn (gen_ashldi3 (temp, op1, shift));
1892 emit_insn (gen_lshrdi3 (operands[0], temp, shift));
1893 DONE;
1894 }
1895}")
1896
1897(define_insn "zero_extendsidi2_internal"
1898 [(set (match_operand:DI 0 "register_operand" "=d,d")
1899 (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
1900 "TARGET_64BIT"
1901 "* return mips_move_1word (operands, insn, TRUE);"
1902 [(set_attr "type" "load")
1903 (set_attr "mode" "DI")
1904 (set_attr "length" "1,2")])
1905
1906
8ef30996
MM
1907(define_insn "zero_extendhisi2"
1908 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1909 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
1910 ""
1911 "*
1912{
1913 if (which_alternative == 0)
1914 return \"andi\\t%0,%1,0xffff\";
1915 else
1916 return mips_move_1word (operands, insn, TRUE);
1917}"
1918 [(set_attr "type" "arith,load,load")
92b4cee1 1919 (set_attr "mode" "SI")
8ef30996
MM
1920 (set_attr "length" "1,1,2")])
1921
bb621ad7
JW
1922(define_insn "zero_extendhidi2"
1923 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1924 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
1925 "TARGET_64BIT"
1926 "*
1927{
1928 if (which_alternative == 0)
1929 return \"andi\\t%0,%1,0xffff\";
1930 else
1931 return mips_move_1word (operands, insn, TRUE);
1932}"
1933 [(set_attr "type" "arith,load,load")
1934 (set_attr "mode" "DI")
1935 (set_attr "length" "1,1,2")])
1936
8ef30996
MM
1937(define_insn "zero_extendqihi2"
1938 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
1939 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
1940 ""
1941 "*
1942{
1943 if (which_alternative == 0)
1944 return \"andi\\t%0,%1,0x00ff\";
1945 else
1946 return mips_move_1word (operands, insn, TRUE);
1947}"
1948 [(set_attr "type" "arith,load,load")
92b4cee1 1949 (set_attr "mode" "HI")
8ef30996
MM
1950 (set_attr "length" "1,1,2")])
1951
1952(define_insn "zero_extendqisi2"
1953 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1954 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
1955 ""
1956 "*
1957{
1958 if (which_alternative == 0)
1959 return \"andi\\t%0,%1,0x00ff\";
1960 else
1961 return mips_move_1word (operands, insn, TRUE);
1962}"
1963 [(set_attr "type" "arith,load,load")
92b4cee1 1964 (set_attr "mode" "SI")
8ef30996
MM
1965 (set_attr "length" "1,1,2")])
1966
bb621ad7
JW
1967(define_insn "zero_extendqidi2"
1968 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1969 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
1970 "TARGET_64BIT"
1971 "*
1972{
1973 if (which_alternative == 0)
1974 return \"andi\\t%0,%1,0x00ff\";
1975 else
1976 return mips_move_1word (operands, insn, TRUE);
1977}"
1978 [(set_attr "type" "arith,load,load")
1979 (set_attr "mode" "DI")
1980 (set_attr "length" "1,1,2")])
1981
8ef30996
MM
1982\f
1983;;
1984;; ....................
1985;;
1986;; SIGN EXTENSION
1987;;
1988;; ....................
1989
1990;; Extension insns.
1991;; Those for integer source operand
1992;; are ordered widest source type first.
1993
bb621ad7
JW
1994;; ??? This should be a define_expand.
1995
1996(define_insn "extendsidi2"
1997 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1998 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
1999 "TARGET_64BIT"
2000 "*
2001{
2002 if (which_alternative == 0)
2003 return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
2004 return mips_move_1word (operands, insn, FALSE);
2005}"
2006 [(set_attr "type" "arith,load,load")
2007 (set_attr "mode" "DI")
2008 (set_attr "length" "2,1,2")])
2009
8ef30996
MM
2010;; These patterns originally accepted general_operands, however, slightly
2011;; better code is generated by only accepting register_operands, and then
2012;; letting combine generate the lh and lb insns.
2013
bb621ad7
JW
2014(define_expand "extendhidi2"
2015 [(set (match_operand:DI 0 "register_operand" "")
2016 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
2017 "TARGET_64BIT"
2018 "
2019{
2020 if (optimize && GET_CODE (operands[1]) == MEM)
2021 operands[1] = force_not_mem (operands[1]);
2022
2023 if (GET_CODE (operands[1]) != MEM)
2024 {
2025 rtx op1 = gen_lowpart (DImode, operands[1]);
2026 rtx temp = gen_reg_rtx (DImode);
2027 rtx shift = gen_rtx (CONST_INT, VOIDmode, 48);
2028
2029 emit_insn (gen_ashldi3 (temp, op1, shift));
2030 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
2031 DONE;
2032 }
2033}")
2034
2035(define_insn "extendhidi2_internal"
2036 [(set (match_operand:DI 0 "register_operand" "=d,d")
2037 (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
2038 "TARGET_64BIT"
2039 "* return mips_move_1word (operands, insn, FALSE);"
2040 [(set_attr "type" "load")
2041 (set_attr "mode" "DI")
2042 (set_attr "length" "1,2")])
2043
8ef30996
MM
2044(define_expand "extendhisi2"
2045 [(set (match_operand:SI 0 "register_operand" "")
2046 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2047 ""
2048 "
2049{
2050 if (optimize && GET_CODE (operands[1]) == MEM)
2051 operands[1] = force_not_mem (operands[1]);
2052
2053 if (GET_CODE (operands[1]) != MEM)
2054 {
2055 rtx op1 = gen_lowpart (SImode, operands[1]);
2056 rtx temp = gen_reg_rtx (SImode);
2057 rtx shift = gen_rtx (CONST_INT, VOIDmode, 16);
2058
2059 emit_insn (gen_ashlsi3 (temp, op1, shift));
2060 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
2061 DONE;
2062 }
2063}")
2064
2065(define_insn "extendhisi2_internal"
2066 [(set (match_operand:SI 0 "register_operand" "=d,d")
2067 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
2068 ""
2069 "* return mips_move_1word (operands, insn, FALSE);"
92b4cee1
MM
2070 [(set_attr "type" "load")
2071 (set_attr "mode" "SI")
8ef30996
MM
2072 (set_attr "length" "1,2")])
2073
2074(define_expand "extendqihi2"
2075 [(set (match_operand:HI 0 "register_operand" "")
2076 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2077 ""
2078 "
2079{
2080 if (optimize && GET_CODE (operands[1]) == MEM)
2081 operands[1] = force_not_mem (operands[1]);
2082
2083 if (GET_CODE (operands[1]) != MEM)
2084 {
2085 rtx op0 = gen_lowpart (SImode, operands[0]);
2086 rtx op1 = gen_lowpart (SImode, operands[1]);
2087 rtx temp = gen_reg_rtx (SImode);
2088 rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
2089
2090 emit_insn (gen_ashlsi3 (temp, op1, shift));
2091 emit_insn (gen_ashrsi3 (op0, temp, shift));
2092 DONE;
2093 }
2094}")
2095
2096(define_insn "extendqihi2_internal"
2097 [(set (match_operand:HI 0 "register_operand" "=d,d")
2098 (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
2099 ""
2100 "* return mips_move_1word (operands, insn, FALSE);"
92b4cee1
MM
2101 [(set_attr "type" "load")
2102 (set_attr "mode" "SI")
8ef30996
MM
2103 (set_attr "length" "1,2")])
2104
2105
2106(define_expand "extendqisi2"
2107 [(set (match_operand:SI 0 "register_operand" "")
2108 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2109 ""
2110 "
2111{
2112 if (optimize && GET_CODE (operands[1]) == MEM)
2113 operands[1] = force_not_mem (operands[1]);
2114
2115 if (GET_CODE (operands[1]) != MEM)
2116 {
2117 rtx op1 = gen_lowpart (SImode, operands[1]);
2118 rtx temp = gen_reg_rtx (SImode);
2119 rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
2120
2121 emit_insn (gen_ashlsi3 (temp, op1, shift));
2122 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
2123 DONE;
2124 }
2125}")
2126
2127(define_insn "extendqisi2_insn"
2128 [(set (match_operand:SI 0 "register_operand" "=d,d")
2129 (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
2130 ""
2131 "* return mips_move_1word (operands, insn, FALSE);"
92b4cee1
MM
2132 [(set_attr "type" "load")
2133 (set_attr "mode" "SI")
8ef30996
MM
2134 (set_attr "length" "1,2")])
2135
bb621ad7
JW
2136(define_expand "extendqidi2"
2137 [(set (match_operand:DI 0 "register_operand" "")
2138 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
2139 "TARGET_64BIT"
2140 "
2141{
2142 if (optimize && GET_CODE (operands[1]) == MEM)
2143 operands[1] = force_not_mem (operands[1]);
2144
2145 if (GET_CODE (operands[1]) != MEM)
2146 {
2147 rtx op1 = gen_lowpart (DImode, operands[1]);
2148 rtx temp = gen_reg_rtx (DImode);
2149 rtx shift = gen_rtx (CONST_INT, VOIDmode, 56);
2150
2151 emit_insn (gen_ashldi3 (temp, op1, shift));
2152 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
2153 DONE;
2154 }
2155}")
2156
2157(define_insn "extendqidi2_insn"
2158 [(set (match_operand:DI 0 "register_operand" "=d,d")
2159 (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
2160 "TARGET_64BIT"
2161 "* return mips_move_1word (operands, insn, FALSE);"
2162 [(set_attr "type" "load")
2163 (set_attr "mode" "DI")
2164 (set_attr "length" "1,2")])
2165
8ef30996
MM
2166
2167(define_insn "extendsfdf2"
2168 [(set (match_operand:DF 0 "register_operand" "=f")
2169 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2170 "TARGET_HARD_FLOAT"
2171 "cvt.d.s\\t%0,%1"
2172 [(set_attr "type" "fcvt")
2173 (set_attr "mode" "DF")
2174 (set_attr "length" "1")])
2175
2176\f
2177
2178;;
2179;; ....................
2180;;
2181;; CONVERSIONS
2182;;
2183;; ....................
2184
d1460eef
JW
2185;; The SImode scratch register can not be shared with address regs used for
2186;; operand zero, because then the address in the move instruction will be
2187;; clobbered. We mark the scratch register as early clobbered to prevent this.
2188
c7343333 2189(define_insn "fix_truncdfsi2"
8ef30996
MM
2190 [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
2191 (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
d1460eef 2192 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
c7343333 2193 (clobber (match_scratch:DF 3 "=f,*X,f,f"))]
8ef30996
MM
2194 "TARGET_HARD_FLOAT"
2195 "*
2196{
2197 rtx xoperands[10];
2198
2199 if (which_alternative == 1)
2200 return \"trunc.w.d %0,%1,%2\";
2201
2202 output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
2203
2204 xoperands[0] = operands[0];
2205 xoperands[1] = operands[3];
2206 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2207 return \"\";
2208}"
92b4cee1
MM
2209 [(set_attr "type" "fcvt")
2210 (set_attr "mode" "DF")
c7343333 2211 (set_attr "length" "11,9,10,11")])
8ef30996
MM
2212
2213
c7343333 2214(define_insn "fix_truncsfsi2"
8ef30996
MM
2215 [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
2216 (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
d1460eef 2217 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
c7343333 2218 (clobber (match_scratch:SF 3 "=f,*X,f,f"))]
8ef30996
MM
2219 "TARGET_HARD_FLOAT"
2220 "*
2221{
2222 rtx xoperands[10];
2223
2224 if (which_alternative == 1)
2225 return \"trunc.w.s %0,%1,%2\";
2226
2227 output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
2228
2229 xoperands[0] = operands[0];
2230 xoperands[1] = operands[3];
2231 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2232 return \"\";
2233}"
92b4cee1
MM
2234 [(set_attr "type" "fcvt")
2235 (set_attr "mode" "SF")
c7343333 2236 (set_attr "length" "11,9,10,11")])
8ef30996
MM
2237
2238
bb621ad7
JW
2239;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
2240;;; but not in the chapter that describes the FPU. It is not mentioned at all
2241;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
2242
2243;;; Deleting this means that we now need two libgcc2.a libraries. One for
2244;;; the 32 bit calling convention and one for the 64 bit calling convention.
2245
2246;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
2247
2248(define_insn "fix_truncdfdi2"
2249 [(set (match_operand:DI 0 "general_operand" "=d,*f,R,o")
2250 (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
2251 (clobber (match_scratch:DF 2 "=f,*X,f,f"))]
2252 "TARGET_HARD_FLOAT && TARGET_64BIT"
2253 "*
2254{
2255 rtx xoperands[10];
2256
2257 if (which_alternative == 1)
2258 return \"trunc.l.d %0,%1\";
2259
2260 output_asm_insn (\"trunc.l.d %2,%1\", operands);
2261
2262 xoperands[0] = operands[0];
2263 xoperands[1] = operands[2];
2264 output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
2265 return \"\";
2266}"
2267 [(set_attr "type" "fcvt")
2268 (set_attr "mode" "DF")
2269 (set_attr "length" "2,1,2,3")])
2270
2271
2272;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
2273;;; but not in the chapter that describes the FPU. It is not mentioned at all
2274;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
2275(define_insn "fix_truncsfdi2"
2276 [(set (match_operand:DI 0 "general_operand" "=d,*f,R,o")
2277 (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
2278 (clobber (match_scratch:DF 2 "=f,*X,f,f"))]
2279 "TARGET_HARD_FLOAT && TARGET_64BIT"
2280 "*
2281{
2282 rtx xoperands[10];
2283
2284 if (which_alternative == 1)
2285 return \"trunc.l.s %0,%1\";
2286
2287 output_asm_insn (\"trunc.l.s %2,%1\", operands);
2288
2289 xoperands[0] = operands[0];
2290 xoperands[1] = operands[2];
2291 output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
2292 return \"\";
2293}"
2294 [(set_attr "type" "fcvt")
2295 (set_attr "mode" "SF")
2296 (set_attr "length" "2,1,2,3")])
2297
2298
8ef30996 2299(define_insn "floatsidf2"
bbdb5552
MM
2300 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
2301 (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
8ef30996 2302 "TARGET_HARD_FLOAT"
bbdb5552
MM
2303 "*
2304{
2305 dslots_load_total++;
2306 if (GET_CODE (operands[1]) == MEM)
5cccf78f 2307 return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
bbdb5552
MM
2308
2309 return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
2310}"
92b4cee1
MM
2311 [(set_attr "type" "fcvt")
2312 (set_attr "mode" "DF")
bbdb5552 2313 (set_attr "length" "3,4,3")])
8ef30996 2314
c7343333 2315
bb621ad7
JW
2316(define_insn "floatdidf2"
2317 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
2318 (float:DF (match_operand:DI 1 "nonimmediate_operand" "d,R,m")))]
2319 "TARGET_HARD_FLOAT && TARGET_64BIT"
2320 "*
2321{
2322 dslots_load_total++;
2323 if (GET_CODE (operands[1]) == MEM)
2324 return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
2325
2326 return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
2327}"
2328 [(set_attr "type" "fcvt")
2329 (set_attr "mode" "DF")
2330 (set_attr "length" "3,4,3")])
2331
2332
8ef30996 2333(define_insn "floatsisf2"
bbdb5552
MM
2334 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
2335 (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
8ef30996 2336 "TARGET_HARD_FLOAT"
bbdb5552
MM
2337 "*
2338{
2339 dslots_load_total++;
2340 if (GET_CODE (operands[1]) == MEM)
5cccf78f 2341 return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
bbdb5552
MM
2342
2343 return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
2344}"
92b4cee1
MM
2345 [(set_attr "type" "fcvt")
2346 (set_attr "mode" "SF")
bbdb5552
MM
2347 (set_attr "length" "3,4,3")])
2348
8ef30996 2349
bb621ad7
JW
2350(define_insn "floatdisf2"
2351 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
2352 (float:SF (match_operand:DI 1 "nonimmediate_operand" "d,R,m")))]
2353 "TARGET_HARD_FLOAT && TARGET_64BIT"
2354 "*
2355{
2356 dslots_load_total++;
2357 if (GET_CODE (operands[1]) == MEM)
2358 return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
2359
2360 return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
2361}"
2362 [(set_attr "type" "fcvt")
2363 (set_attr "mode" "SF")
2364 (set_attr "length" "3,4,3")])
2365
2366
8ef30996
MM
2367(define_expand "fixuns_truncdfsi2"
2368 [(set (match_operand:SI 0 "register_operand" "")
2369 (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
2370 "TARGET_HARD_FLOAT"
2371 "
2372{
2373 rtx reg1 = gen_reg_rtx (DFmode);
2374 rtx reg2 = gen_reg_rtx (DFmode);
2375 rtx reg3 = gen_reg_rtx (SImode);
2376 rtx label1 = gen_label_rtx ();
2377 rtx label2 = gen_label_rtx ();
2378 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
2379
2380 if (reg1) /* turn off complaints about unreached code */
2381 {
8ef30996
MM
2382 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
2383 do_pending_stack_adjust ();
2384
2385 emit_insn (gen_cmpdf (operands[1], reg1));
2386 emit_jump_insn (gen_bge (label1));
2387
2388 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2389 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
2390 gen_rtx (LABEL_REF, VOIDmode, label2)));
2391 emit_barrier ();
2392
2393 emit_label (label1);
2394 emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
2395 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
2396
2397 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2398 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2399
2400 emit_label (label2);
2401
2402 /* allow REG_NOTES to be set on last insn (labels don't have enough
2403 fields, and can't be used for REG_NOTES anyway). */
2404 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2405 DONE;
2406 }
2407}")
2408
c7343333 2409
bb621ad7
JW
2410(define_expand "fixuns_truncdfdi2"
2411 [(set (match_operand:DI 0 "register_operand" "")
2412 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
2413 "TARGET_HARD_FLOAT && TARGET_64BIT"
2414 "
2415{
2416 rtx reg1 = gen_reg_rtx (DFmode);
2417 rtx reg2 = gen_reg_rtx (DFmode);
2418 rtx reg3 = gen_reg_rtx (DImode);
2419 rtx label1 = gen_label_rtx ();
2420 rtx label2 = gen_label_rtx ();
2421 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
2422
2423 if (reg1) /* turn off complaints about unreached code */
2424 {
2425 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
2426 do_pending_stack_adjust ();
2427
2428 emit_insn (gen_cmpdf (operands[1], reg1));
2429 emit_jump_insn (gen_bge (label1));
2430
2431 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2432 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
2433 gen_rtx (LABEL_REF, VOIDmode, label2)));
2434 emit_barrier ();
2435
2436 emit_label (label1);
2437 emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
2438 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
2439 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2440
2441 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2442 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2443
2444 emit_label (label2);
2445
2446 /* allow REG_NOTES to be set on last insn (labels don't have enough
2447 fields, and can't be used for REG_NOTES anyway). */
2448 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2449 DONE;
2450 }
2451}")
2452
2453
8ef30996
MM
2454(define_expand "fixuns_truncsfsi2"
2455 [(set (match_operand:SI 0 "register_operand" "")
2456 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
2457 "TARGET_HARD_FLOAT"
2458 "
2459{
2460 rtx reg1 = gen_reg_rtx (SFmode);
2461 rtx reg2 = gen_reg_rtx (SFmode);
2462 rtx reg3 = gen_reg_rtx (SImode);
2463 rtx label1 = gen_label_rtx ();
2464 rtx label2 = gen_label_rtx ();
2465 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
2466
2467 if (reg1) /* turn off complaints about unreached code */
2468 {
8ef30996
MM
2469 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
2470 do_pending_stack_adjust ();
2471
2472 emit_insn (gen_cmpsf (operands[1], reg1));
2473 emit_jump_insn (gen_bge (label1));
2474
2475 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2476 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
2477 gen_rtx (LABEL_REF, VOIDmode, label2)));
2478 emit_barrier ();
2479
2480 emit_label (label1);
2481 emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
2482 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
2483
2484 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2485 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2486
2487 emit_label (label2);
2488
2489 /* allow REG_NOTES to be set on last insn (labels don't have enough
2490 fields, and can't be used for REG_NOTES anyway). */
2491 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2492 DONE;
2493 }
2494}")
2495
8ef30996 2496
bb621ad7
JW
2497(define_expand "fixuns_truncsfdi2"
2498 [(set (match_operand:DI 0 "register_operand" "")
2499 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
2500 "TARGET_HARD_FLOAT && TARGET_64BIT"
8ef30996
MM
2501 "
2502{
bb621ad7
JW
2503 rtx reg1 = gen_reg_rtx (SFmode);
2504 rtx reg2 = gen_reg_rtx (SFmode);
2505 rtx reg3 = gen_reg_rtx (DImode);
2506 rtx label1 = gen_label_rtx ();
2507 rtx label2 = gen_label_rtx ();
2508 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
8ef30996 2509
bb621ad7 2510 if (reg1) /* turn off complaints about unreached code */
8ef30996 2511 {
bb621ad7
JW
2512 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
2513 do_pending_stack_adjust ();
8ef30996 2514
bb621ad7
JW
2515 emit_insn (gen_cmpsf (operands[1], reg1));
2516 emit_jump_insn (gen_bge (label1));
8ef30996 2517
bb621ad7
JW
2518 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2519 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
2520 gen_rtx (LABEL_REF, VOIDmode, label2)));
2521 emit_barrier ();
8ef30996 2522
bb621ad7
JW
2523 emit_label (label1);
2524 emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
2525 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
2526 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
8ef30996 2527
bb621ad7
JW
2528 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2529 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
8ef30996 2530
bb621ad7 2531 emit_label (label2);
8ef30996 2532
bb621ad7
JW
2533 /* allow REG_NOTES to be set on last insn (labels don't have enough
2534 fields, and can't be used for REG_NOTES anyway). */
2535 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2536 DONE;
8ef30996 2537 }
bb621ad7 2538}")
8ef30996 2539
bb621ad7
JW
2540\f
2541;;
2542;; ....................
2543;;
2544;; DATA MOVEMENT
2545;;
2546;; ....................
8ef30996 2547
c5563e11
JW
2548;; Bit field extract patterns which use lwl/lwr.
2549
2550;; ??? There should be DImode variants for 64 bit code, but the current
2551;; bitfield scheme can't handle that. We would need to add new optabs
2552;; in order to make that work.
2553
2554;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
2555;; It isn't clear whether this will give better code.
2556
2557(define_expand "extv"
2558 [(set (match_operand:SI 0 "register_operand" "")
2559 (sign_extract:SI (match_operand:QI 1 "memory_operand" "")
2560 (match_operand:SI 2 "immediate_operand" "")
2561 (match_operand:SI 3 "immediate_operand" "")))]
2562 ""
2563 "
2564{
2565 /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
2566 then fail. */
2567 if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
2568 FAIL;
2569
2570 /* This can happen for a 64 bit target, when extracting a value from
2571 a 64 bit union member. extract_bit_field doesn't verify that our
2572 source matches the predicate, so we force it to be a MEM here. */
2573 if (GET_CODE (operands[1]) != MEM)
2574 FAIL;
8ef30996 2575
c5563e11
JW
2576 /* Otherwise, emit a lwl/lwr pair to load the value. */
2577 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
2578 DONE;
2579}")
2580
2581(define_expand "extzv"
2582 [(set (match_operand:SI 0 "register_operand" "")
2583 (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
2584 (match_operand:SI 2 "immediate_operand" "")
2585 (match_operand:SI 3 "immediate_operand" "")))]
2586 ""
2587 "
2588{
2589 /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
2590 then fail. */
2591 if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
2592 FAIL;
2593
2594 /* This can happen for a 64 bit target, when extracting a value from
2595 a 64 bit union member. extract_bit_field doesn't verify that our
2596 source matches the predicate, so we force it to be a MEM here. */
2597 if (GET_CODE (operands[1]) != MEM)
2598 FAIL;
2599
2600 /* Otherwise, emit a lwl/lwr pair to load the value. */
2601 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
2602 DONE;
2603}")
2604
2605(define_expand "insv"
2606 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
2607 (match_operand:SI 1 "immediate_operand" "")
2608 (match_operand:SI 2 "immediate_operand" ""))
2609 (match_operand:SI 3 "register_operand" ""))]
2610 ""
2611 "
2612{
2613 /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
2614 then fail. */
2615 if (INTVAL (operands[1]) != 32 || (INTVAL (operands[2]) % 8) != 0)
2616 FAIL;
2617
2618 /* This can happen for a 64 bit target, when storing into a 32 bit union
2619 member. store_bit_field doesn't verify that our target matches the
2620 predicate, so we force it to be a MEM here. */
2621 if (GET_CODE (operands[0]) != MEM)
2622 FAIL;
2623
2624 /* Otherwise, emit a swl/swr pair to load the value. */
2625 emit_insn (gen_movsi_usw (operands[0], operands[3]));
2626 DONE;
2627}")
2628
2629;; unaligned word moves generated by the bit field patterns
2630
2631(define_insn "movsi_ulw"
2632 [(set (match_operand:SI 0 "register_operand" "=&d,&d")
2633 (unspec [(match_operand:QI 1 "general_operand" "R,o")] 0))]
2634 ""
2635 "*
2636{
2637 rtx offset = const0_rtx;
2638 rtx addr = XEXP (operands[1], 0);
2639 rtx mem_addr = eliminate_constant_term (addr, &offset);
2640 char *ret;
2641
2642 if (TARGET_STATS)
2643 mips_count_memory_refs (operands[1], 2);
2644
2645 /* The stack/frame pointers are always aligned, so we can convert
2646 to the faster lw if we are referencing an aligned stack location. */
2647
2648 if ((INTVAL (offset) & 3) == 0
2649 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
2650 ret = \"lw\\t%0,%1\";
2651 else
2652 ret = \"ulw\\t%0,%1\";
2653
2654 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
2655}"
2656 [(set_attr "type" "load,load")
2657 (set_attr "mode" "SI")
2658 (set_attr "length" "2,4")])
2659
2660(define_insn "movsi_usw"
2661 [(set (match_operand:QI 0 "memory_operand" "=R,o")
2662 (unspec [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
2663 ""
2664 "*
2665{
2666 rtx offset = const0_rtx;
2667 rtx addr = XEXP (operands[0], 0);
2668 rtx mem_addr = eliminate_constant_term (addr, &offset);
2669
2670 if (TARGET_STATS)
2671 mips_count_memory_refs (operands[0], 2);
2672
2673 /* The stack/frame pointers are always aligned, so we can convert
2674 to the faster sw if we are referencing an aligned stack location. */
2675
2676 if ((INTVAL (offset) & 3) == 0
2677 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
2678 return \"sw\\t%1,%0\";
2679
2680 return \"usw\\t%z1,%0\";
2681}"
2682 [(set_attr "type" "store")
2683 (set_attr "mode" "SI")
2684 (set_attr "length" "2,4")])
ed50ab35 2685
8ef30996
MM
2686;; 64-bit integer moves
2687
2688;; Unlike most other insns, the move insns can't be split with
2689;; different predicates, because register spilling and other parts of
2690;; the compiler, have memoized the insn number already.
2691
ed50ab35
MM
2692(define_expand "movdi"
2693 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2694 (match_operand:DI 1 "general_operand" ""))]
2695 ""
2696 "
2697{
2698 if ((reload_in_progress | reload_completed) == 0
2699 && !register_operand (operands[0], DImode)
2700 && !register_operand (operands[1], DImode)
2701 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
2702 && operands[1] != CONST0_RTX (DImode))
2703 {
2704 rtx temp = force_reg (DImode, operands[1]);
2705 emit_move_insn (operands[0], temp);
2706 DONE;
2707 }
2708}")
2709
2710(define_insn "movdi_internal"
6d518002
MM
2711 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*d,*x")
2712 (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,*x,*d"))]
bb621ad7
JW
2713 "!TARGET_64BIT
2714 && (register_operand (operands[0], DImode)
2715 || register_operand (operands[1], DImode)
2716 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
2717 || operands[1] == CONST0_RTX (DImode))"
8ef30996 2718 "* return mips_move_2words (operands, insn); "
6d518002 2719 [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo")
92b4cee1 2720 (set_attr "mode" "DI")
bb621ad7 2721 (set_attr "length" "2,4,2,4,2,4,2,2")])
8ef30996
MM
2722
2723(define_split
2724 [(set (match_operand:DI 0 "register_operand" "")
2725 (match_operand:DI 1 "register_operand" ""))]
bb621ad7 2726 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
2727 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2728 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
2729
2730 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
2731 (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
2732 "")
2733
bb621ad7
JW
2734(define_insn "movdi_internal2"
2735 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*x")
2736 (match_operand:DI 1 "general_operand" " d,S,IKL,Mnis,R,m,dJ,dJ,*x,*d"))]
2737 "TARGET_64BIT
2738 && (register_operand (operands[0], DImode)
2739 || register_operand (operands[1], DImode)
2740 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
2741 || operands[1] == CONST0_RTX (DImode))"
2742 "* return mips_move_2words (operands, insn); "
2743 [(set_attr "type" "move,load,arith,arith,load,load,store,store,hilo,hilo")
2744 (set_attr "mode" "DI")
2745 (set_attr "length" "1,2,1,2,1,2,1,2,1,1")])
2746
8ef30996
MM
2747
2748;; 32-bit Integer moves
2749
2750(define_split
2751 [(set (match_operand:SI 0 "register_operand" "")
2752 (match_operand:SI 1 "large_int" ""))]
26b8e6e5 2753 "!TARGET_DEBUG_D_MODE"
8ef30996
MM
2754 [(set (match_dup 0)
2755 (match_dup 2))
2756 (set (match_dup 0)
2757 (ior:SI (match_dup 0)
2758 (match_dup 3)))]
2759 "
2760{
2761 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff0000);
2762 operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0x0000ffff);
2763}")
2764
2765;; Unlike most other insns, the move insns can't be split with
2766;; different predicates, because register spilling and other parts of
2767;; the compiler, have memoized the insn number already.
2768
f3b39eba
MM
2769(define_expand "movsi"
2770 [(set (match_operand:SI 0 "nonimmediate_operand" "")
2771 (match_operand:SI 1 "general_operand" ""))]
2772 ""
ed50ab35
MM
2773 "
2774{
92544bdf
ILT
2775 /* If we are generating embedded PIC code, and we are referring to a
2776 symbol in the .text section, we must use an offset from the start
2777 of the function. */
2778 if (TARGET_EMBEDDED_PIC
2779 && (GET_CODE (operands[1]) == LABEL_REF
2780 || (GET_CODE (operands[1]) == SYMBOL_REF
2781 && ! SYMBOL_REF_FLAG (operands[1]))))
2782 {
2783 rtx temp;
2784
2785 temp = embedded_pic_offset (operands[1]);
2786 temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
2787 force_reg (SImode, temp));
2788 emit_move_insn (operands[0], force_reg (SImode, temp));
2789 DONE;
2790 }
2791
5a5b76a2
JW
2792 /* If operands[1] is a constant address illegal for pic, then we need to
2793 handle it just like LEGITIMIZE_ADDRESS does. */
2794 if (flag_pic && pic_address_needs_scratch (operands[1]))
2795 {
2796 rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
2797 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
2798
2799 if (! SMALL_INT (temp2))
2800 temp2 = force_reg (SImode, temp2);
2801
2802 emit_move_insn (operands[0], gen_rtx (PLUS, SImode, temp, temp2));
2803 DONE;
2804 }
2805
ed50ab35
MM
2806 if ((reload_in_progress | reload_completed) == 0
2807 && !register_operand (operands[0], SImode)
2808 && !register_operand (operands[1], SImode)
2809 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
2810 {
2811 rtx temp = force_reg (SImode, operands[1]);
2812 emit_move_insn (operands[0], temp);
2813 DONE;
2814 }
2815}")
f3b39eba 2816
0fb5ac6f
MM
2817;; The difference between these two is whether or not ints are allowed
2818;; in FP registers (off by default, use -mdebugh to enable).
2819
2820(define_insn "movsi_internal1"
252e25c6
MM
2821 [(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")
2822 (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
2823 "TARGET_DEBUG_H_MODE
2824 && (register_operand (operands[0], SImode)
2825 || register_operand (operands[1], SImode)
2826 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
bb621ad7 2827 "* return mips_move_1word (operands, insn, FALSE);"
c7343333 2828 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo")
92b4cee1 2829 (set_attr "mode" "SI")
c7343333 2830 (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1")])
8ef30996 2831
0fb5ac6f
MM
2832(define_insn "movsi_internal2"
2833 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*d,*x")
2834 (match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,*x,*d"))]
ed50ab35
MM
2835 "!TARGET_DEBUG_H_MODE
2836 && (register_operand (operands[0], SImode)
2837 || register_operand (operands[1], SImode)
2838 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
bb621ad7 2839 "* return mips_move_1word (operands, insn, FALSE);"
c7343333 2840 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo")
0fb5ac6f 2841 (set_attr "mode" "SI")
c7343333 2842 (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1")])
0fb5ac6f
MM
2843
2844
8ef30996
MM
2845;; 16-bit Integer moves
2846
2847;; Unlike most other insns, the move insns can't be split with
2848;; different predicates, because register spilling and other parts of
2849;; the compiler, have memoized the insn number already.
2850;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
2851
0fb5ac6f
MM
2852(define_expand "movhi"
2853 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2854 (match_operand:HI 1 "general_operand" ""))]
8ef30996 2855 ""
ed50ab35
MM
2856 "
2857{
2858 if ((reload_in_progress | reload_completed) == 0
2859 && !register_operand (operands[0], HImode)
2860 && !register_operand (operands[1], HImode)
2861 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
2862 {
2863 rtx temp = force_reg (HImode, operands[1]);
2864 emit_move_insn (operands[0], temp);
2865 DONE;
2866 }
2867}")
0fb5ac6f
MM
2868
2869;; The difference between these two is whether or not ints are allowed
2870;; in FP registers (off by default, use -mdebugh to enable).
2871
2872(define_insn "movhi_internal1"
252e25c6
MM
2873 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
2874 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
ed50ab35
MM
2875 "TARGET_DEBUG_H_MODE
2876 && (register_operand (operands[0], HImode)
2877 || register_operand (operands[1], HImode)
2878 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
8ef30996
MM
2879 "* return mips_move_1word (operands, insn, TRUE);"
2880 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
92b4cee1 2881 (set_attr "mode" "HI")
8ef30996
MM
2882 (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")])
2883
0fb5ac6f
MM
2884(define_insn "movhi_internal2"
2885 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
2886 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
ed50ab35
MM
2887 "!TARGET_DEBUG_H_MODE
2888 && (register_operand (operands[0], HImode)
2889 || register_operand (operands[1], HImode)
2890 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
0fb5ac6f
MM
2891 "* return mips_move_1word (operands, insn, TRUE);"
2892 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
2893 (set_attr "mode" "HI")
2894 (set_attr "length" "1,1,1,2,1,2,1,1,1,1")])
2895
2896
8ef30996
MM
2897;; 8-bit Integer moves
2898
2899;; Unlike most other insns, the move insns can't be split with
2900;; different predicates, because register spilling and other parts of
2901;; the compiler, have memoized the insn number already.
2902;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
2903
0fb5ac6f
MM
2904(define_expand "movqi"
2905 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2906 (match_operand:QI 1 "general_operand" ""))]
8ef30996 2907 ""
ed50ab35
MM
2908 "
2909{
2910 if ((reload_in_progress | reload_completed) == 0
2911 && !register_operand (operands[0], QImode)
2912 && !register_operand (operands[1], QImode)
2913 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
2914 {
2915 rtx temp = force_reg (QImode, operands[1]);
2916 emit_move_insn (operands[0], temp);
2917 DONE;
2918 }
2919}")
0fb5ac6f
MM
2920
2921;; The difference between these two is whether or not ints are allowed
2922;; in FP registers (off by default, use -mdebugh to enable).
2923
2924(define_insn "movqi_internal1"
252e25c6
MM
2925 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
2926 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
ed50ab35
MM
2927 "TARGET_DEBUG_H_MODE
2928 && (register_operand (operands[0], QImode)
2929 || register_operand (operands[1], QImode)
2930 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
8ef30996
MM
2931 "* return mips_move_1word (operands, insn, TRUE);"
2932 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
92b4cee1 2933 (set_attr "mode" "QI")
8ef30996
MM
2934 (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")])
2935
0fb5ac6f
MM
2936(define_insn "movqi_internal2"
2937 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
2938 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
ed50ab35
MM
2939 "!TARGET_DEBUG_H_MODE
2940 && (register_operand (operands[0], QImode)
2941 || register_operand (operands[1], QImode)
2942 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
0fb5ac6f
MM
2943 "* return mips_move_1word (operands, insn, TRUE);"
2944 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
2945 (set_attr "mode" "QI")
2946 (set_attr "length" "1,1,1,2,1,2,1,1,1,1")])
2947
8ef30996
MM
2948
2949;; 32-bit floating point moves
2950
ed50ab35
MM
2951(define_expand "movsf"
2952 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2953 (match_operand:SF 1 "general_operand" ""))]
2954 ""
2955 "
2956{
2957 if ((reload_in_progress | reload_completed) == 0
2958 && !register_operand (operands[0], SFmode)
2959 && !register_operand (operands[1], SFmode)
2960 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
2961 && operands[1] != CONST0_RTX (SFmode))
2962 {
2963 rtx temp = force_reg (SFmode, operands[1]);
2964 emit_move_insn (operands[0], temp);
2965 DONE;
2966 }
2967}")
2968
b0193a92 2969(define_insn "movsf_internal1"
8ef30996 2970 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
bb621ad7 2971 (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
b0193a92
MM
2972 "TARGET_HARD_FLOAT
2973 && (register_operand (operands[0], SFmode)
2974 || register_operand (operands[1], SFmode)
2975 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
2976 || operands[1] == CONST0_RTX (SFmode))"
8ef30996
MM
2977 "* return mips_move_1word (operands, insn, FALSE);"
2978 [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
92b4cee1 2979 (set_attr "mode" "SF")
8ef30996
MM
2980 (set_attr "length" "1,1,1,2,1,2,1,1,1,1,2,1,2")])
2981
ed50ab35 2982
b0193a92
MM
2983(define_insn "movsf_internal2"
2984 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
bb621ad7 2985 (match_operand:SF 1 "general_operand" " Gd,R,Fm,d,d"))]
b0193a92
MM
2986 "TARGET_SOFT_FLOAT
2987 && (register_operand (operands[0], SFmode)
2988 || register_operand (operands[1], SFmode)
2989 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
2990 || operands[1] == CONST0_RTX (SFmode))"
2991 "* return mips_move_1word (operands, insn, FALSE);"
2992 [(set_attr "type" "move,load,load,store,store")
2993 (set_attr "mode" "SF")
2994 (set_attr "length" "1,1,2,1,2")])
2995
2996
8ef30996
MM
2997;; 64-bit floating point moves
2998
ed50ab35
MM
2999(define_expand "movdf"
3000 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3001 (match_operand:DF 1 "general_operand" ""))]
3002 ""
3003 "
3004{
3005 if ((reload_in_progress | reload_completed) == 0
3006 && !register_operand (operands[0], DFmode)
3007 && !register_operand (operands[1], DFmode)
3008 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
3009 && operands[1] != CONST0_RTX (DFmode))
3010 {
3011 rtx temp = force_reg (DFmode, operands[1]);
3012 emit_move_insn (operands[0], temp);
3013 DONE;
3014 }
3015}")
3016
b0193a92 3017(define_insn "movdf_internal1"
8ef30996 3018 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,o,f,*f,*d,*d,*d,*d,*R,*o")
bb621ad7 3019 (match_operand:DF 1 "general_operand" "f,R,o,fG,fG,F,*d,*f,*d*G,*R,*o*F,*d,*d"))]
64d8baf9 3020 "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
b0193a92
MM
3021 && (register_operand (operands[0], DFmode)
3022 || register_operand (operands[1], DFmode)
3023 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3024 || operands[1] == CONST0_RTX (DFmode))"
8ef30996
MM
3025 "* return mips_move_2words (operands, insn); "
3026 [(set_attr "type" "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
92b4cee1 3027 (set_attr "mode" "DF")
8ef30996
MM
3028 (set_attr "length" "1,2,4,2,4,4,2,2,2,2,4,2,4")])
3029
64d8baf9
JW
3030(define_insn "movdf_internal1a"
3031 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,o,o,f,*d,*d,*d,*o,*R")
3032 (match_operand:DF 1 "general_operand" " f,o,f,G,f,G,F,*F,*o,*R,*d,*d"))]
3033 "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
3034 && (register_operand (operands[0], DFmode)
3035 || register_operand (operands[1], DFmode))
3036 || (GET_CODE (operands [0]) == MEM
3037 && ((GET_CODE (operands[1]) == CONST_INT
3038 && INTVAL (operands[1]) == 0)
3039 || operands[1] == CONST0_RTX (DFmode)))"
3040 "* return mips_move_2words (operands, insn); "
3041 [(set_attr "type" "move,load,store,store,store,store,load,load,load,load,store,store")
3042 (set_attr "mode" "DF")
3043 (set_attr "length" "1,2,1,1,2,2,2,2,2,1,2,1")])
3044
b0193a92
MM
3045(define_insn "movdf_internal2"
3046 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,o")
bb621ad7 3047 (match_operand:DF 1 "general_operand" "dG,R,oF,d,d"))]
b0193a92
MM
3048 "TARGET_SOFT_FLOAT
3049 && (register_operand (operands[0], DFmode)
3050 || register_operand (operands[1], DFmode)
3051 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3052 || operands[1] == CONST0_RTX (DFmode))"
3053 "* return mips_move_2words (operands, insn); "
3054 [(set_attr "type" "move,load,load,store,store")
3055 (set_attr "mode" "DF")
3056 (set_attr "length" "2,2,4,2,4")])
3057
8ef30996
MM
3058(define_split
3059 [(set (match_operand:DF 0 "register_operand" "")
3060 (match_operand:DF 1 "register_operand" ""))]
26b8e6e5 3061 "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3062 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3063 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3064
3065 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
3066 (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
3067 "")
3068
26b8e6e5 3069\f
8ef30996
MM
3070;; Block moves, see mips.c for more details.
3071;; Argument 0 is the destination
3072;; Argument 1 is the source
3073;; Argument 2 is the length
3074;; Argument 3 is the alignment
3075
3076(define_expand "movstrsi"
3077 [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
3078 (mem:BLK (match_operand:BLK 1 "general_operand" "")))
3079 (use (match_operand:SI 2 "arith32_operand" ""))
3080 (use (match_operand:SI 3 "immediate_operand" ""))])]
3081 ""
3082 "
3083{
3084 if (operands[0]) /* avoid unused code messages */
3085 {
3086 expand_block_move (operands);
3087 DONE;
3088 }
3089}")
3090
842eb20e
MM
3091;; Insn generated by block moves
3092
3093(define_insn "movstrsi_internal"
26b8e6e5
MM
3094 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
3095 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
3096 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
3097 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
3098 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
3099 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
3100 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
3101 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
3102 (use (const_int 0))] ;; normal block move
3103 ""
3104 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
842eb20e
MM
3105 [(set_attr "type" "multi")
3106 (set_attr "mode" "none")
3107 (set_attr "length" "20")])
3108
26b8e6e5
MM
3109;; Split a block move into 2 parts, the first part is everything
3110;; except for the last move, and the second part is just the last
3111;; store, which is exactly 1 instruction (ie, not a usw), so it can
3112;; fill a delay slot. This also prevents a bug in delayed branches
3113;; from showing up, which reuses one of the registers in our clobbers.
3114
3115(define_split
3116 [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
3117 (mem:BLK (match_operand:SI 1 "register_operand" "")))
3118 (clobber (match_operand:SI 4 "register_operand" ""))
3119 (clobber (match_operand:SI 5 "register_operand" ""))
3120 (clobber (match_operand:SI 6 "register_operand" ""))
3121 (clobber (match_operand:SI 7 "register_operand" ""))
3122 (use (match_operand:SI 2 "small_int" ""))
3123 (use (match_operand:SI 3 "small_int" ""))
3124 (use (const_int 0))]
3125
3126 "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
3127
3128 ;; All but the last move
3129 [(parallel [(set (mem:BLK (match_dup 0))
3130 (mem:BLK (match_dup 1)))
3131 (clobber (match_dup 4))
3132 (clobber (match_dup 5))
3133 (clobber (match_dup 6))
3134 (clobber (match_dup 7))
3135 (use (match_dup 2))
3136 (use (match_dup 3))
3137 (use (const_int 1))])
3138
3139 ;; The last store, so it can fill a delay slot
3140 (parallel [(set (mem:BLK (match_dup 0))
3141 (mem:BLK (match_dup 1)))
3142 (clobber (match_dup 4))
3143 (clobber (match_dup 5))
3144 (clobber (match_dup 6))
3145 (clobber (match_dup 7))
3146 (use (match_dup 2))
3147 (use (match_dup 3))
3148 (use (const_int 2))])]
3149
3150 "")
3151
3152(define_insn "movstrsi_internal2"
3153 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
3154 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
3155 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
3156 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
3157 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
3158 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
3159 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
3160 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
3161 (use (const_int 1))] ;; all but last store
3162 ""
3163 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
3164 [(set_attr "type" "multi")
3165 (set_attr "mode" "none")
3166 (set_attr "length" "20")])
3167
3168(define_insn "movstrsi_internal3"
3169 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
3170 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
3171 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
3172 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
3173 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
3174 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
3175 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
3176 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
bb621ad7 3177 (use (const_int 2))] ;; just last store of block move
26b8e6e5
MM
3178 ""
3179 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
3180 [(set_attr "type" "store")
3181 (set_attr "mode" "none")
3182 (set_attr "length" "1")])
3183
8ef30996
MM
3184\f
3185;;
3186;; ....................
3187;;
3188;; SHIFTS
3189;;
3190;; ....................
3191
3192(define_insn "ashlsi3"
3193 [(set (match_operand:SI 0 "register_operand" "=d")
3194 (ashift:SI (match_operand:SI 1 "register_operand" "d")
3195 (match_operand:SI 2 "arith_operand" "dI")))]
3196 ""
3197 "*
3198{
3199 if (GET_CODE (operands[2]) == CONST_INT)
3200 operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
3201
3202 return \"sll\\t%0,%1,%2\";
3203}"
3204 [(set_attr "type" "arith")
3205 (set_attr "mode" "SI")
3206 (set_attr "length" "1")])
3207
3208
3209(define_expand "ashldi3"
3210 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3211 (ashift:DI (match_operand:DI 1 "register_operand" "")
3212 (match_operand:SI 2 "arith_operand" "")))
3213 (clobber (match_dup 3))])]
bb621ad7
JW
3214 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3215 "
3216{
3217 if (TARGET_64BIT)
3218 {
3219 emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
3220 operands[2]));
3221 DONE;
3222 }
3223
3224 operands[3] = gen_reg_rtx (SImode);
3225}")
8ef30996
MM
3226
3227
3228(define_insn "ashldi3_internal"
0fb5ac6f 3229 [(set (match_operand:DI 0 "register_operand" "=&d")
8ef30996
MM
3230 (ashift:DI (match_operand:DI 1 "register_operand" "d")
3231 (match_operand:SI 2 "register_operand" "d")))
3232 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 3233 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
8ef30996
MM
3234 "*
3235{
3236 operands[4] = const0_rtx;
3237 dslots_jump_total += 3;
3238 dslots_jump_filled += 2;
3239
3240 return \"sll\\t%3,%2,26\\n\\
3241\\tbgez\\t%3,1f\\n\\
3242\\tsll\\t%M0,%L1,%2\\n\\
3243\\t%(b\\t3f\\n\\
3244\\tmove\\t%L0,%z4%)\\n\\
3245\\n\\
32461:\\n\\
3247\\t%(beq\\t%3,%z4,2f\\n\\
3248\\tsll\\t%M0,%M1,%2%)\\n\\
3249\\n\\
3250\\tsubu\\t%3,%z4,%2\\n\\
3251\\tsrl\\t%3,%L1,%3\\n\\
3252\\tor\\t%M0,%M0,%3\\n\\
32532:\\n\\
3254\\tsll\\t%L0,%L1,%2\\n\\
32553:\";
3256}"
3257 [(set_attr "type" "darith")
3258 (set_attr "mode" "SI")
3259 (set_attr "length" "12")])
3260
3261
3262(define_insn "ashldi3_internal2"
3263 [(set (match_operand:DI 0 "register_operand" "=d")
3264 (ashift:DI (match_operand:DI 1 "register_operand" "d")
3265 (match_operand:SI 2 "small_int" "IJK")))
3266 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 3267 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
8ef30996
MM
3268 "*
3269{
3270 operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
3271 operands[4] = const0_rtx;
3272 return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
3273}"
3274 [(set_attr "type" "darith")
3275 (set_attr "mode" "DI")
3276 (set_attr "length" "2")])
3277
3278
3279(define_split
3280 [(set (match_operand:DI 0 "register_operand" "")
3281 (ashift:DI (match_operand:DI 1 "register_operand" "")
3282 (match_operand:SI 2 "small_int" "")))
3283 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 3284 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3285 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3286 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3287 && (INTVAL (operands[2]) & 32) != 0"
3288
3289 [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
3290 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
3291
3292 "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
3293
3294
3295(define_split
3296 [(set (match_operand:DI 0 "register_operand" "")
3297 (ashift:DI (match_operand:DI 1 "register_operand" "")
3298 (match_operand:SI 2 "small_int" "")))
3299 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 3300 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3301 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3302 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3303 && (INTVAL (operands[2]) & 32) != 0"
3304
3305 [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
3306 (set (subreg:SI (match_dup 0) 1) (const_int 0))]
3307
3308 "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
3309
3310
3311(define_insn "ashldi3_internal3"
3312 [(set (match_operand:DI 0 "register_operand" "=d")
3313 (ashift:DI (match_operand:DI 1 "register_operand" "d")
3314 (match_operand:SI 2 "small_int" "IJK")))
3315 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 3316 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
8ef30996
MM
3317 && (INTVAL (operands[2]) & 63) < 32
3318 && (INTVAL (operands[2]) & 63) != 0"
3319 "*
3320{
3321 int amount = INTVAL (operands[2]);
3322
3323 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
3324 operands[4] = const0_rtx;
3325 operands[5] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
3326
3327 return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
3328}"
3329 [(set_attr "type" "darith")
3330 (set_attr "mode" "DI")
3331 (set_attr "length" "4")])
3332
3333
3334(define_split
3335 [(set (match_operand:DI 0 "register_operand" "")
3336 (ashift:DI (match_operand:DI 1 "register_operand" "")
3337 (match_operand:SI 2 "small_int" "")))
3338 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 3339 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3340 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3341 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3342 && (INTVAL (operands[2]) & 63) < 32
3343 && (INTVAL (operands[2]) & 63) != 0"
3344
3345 [(set (subreg:SI (match_dup 0) 1)
3346 (ashift:SI (subreg:SI (match_dup 1) 1)
3347 (match_dup 2)))
3348
3349 (set (match_dup 3)
3350 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
3351 (match_dup 4)))
3352
3353 (set (subreg:SI (match_dup 0) 1)
3354 (ior:SI (subreg:SI (match_dup 0) 1)
3355 (match_dup 3)))
3356
3357 (set (subreg:SI (match_dup 0) 0)
3358 (ashift:SI (subreg:SI (match_dup 1) 0)
3359 (match_dup 2)))]
3360 "
3361{
3362 int amount = INTVAL (operands[2]);
3363 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
3364 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
3365}")
3366
3367
3368(define_split
3369 [(set (match_operand:DI 0 "register_operand" "")
3370 (ashift:DI (match_operand:DI 1 "register_operand" "")
3371 (match_operand:SI 2 "small_int" "")))
3372 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 3373 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3374 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3375 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3376 && (INTVAL (operands[2]) & 63) < 32
3377 && (INTVAL (operands[2]) & 63) != 0"
3378
3379 [(set (subreg:SI (match_dup 0) 0)
3380 (ashift:SI (subreg:SI (match_dup 1) 0)
3381 (match_dup 2)))
3382
3383 (set (match_dup 3)
3384 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
3385 (match_dup 4)))
3386
3387 (set (subreg:SI (match_dup 0) 0)
3388 (ior:SI (subreg:SI (match_dup 0) 0)
3389 (match_dup 3)))
3390
3391 (set (subreg:SI (match_dup 0) 1)
3392 (ashift:SI (subreg:SI (match_dup 1) 1)
3393 (match_dup 2)))]
3394 "
3395{
3396 int amount = INTVAL (operands[2]);
3397 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
3398 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
3399}")
3400
3401
bb621ad7
JW
3402(define_insn "ashldi3_internal4"
3403 [(set (match_operand:DI 0 "register_operand" "=d")
3404 (ashift:DI (match_operand:DI 1 "register_operand" "d")
3405 (match_operand:SI 2 "arith_operand" "dI")))]
3406 "TARGET_64BIT"
3407 "*
3408{
3409 if (GET_CODE (operands[2]) == CONST_INT)
3410 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
3411
3412 return \"dsll\\t%0,%1,%2\";
3413}"
3414 [(set_attr "type" "arith")
3415 (set_attr "mode" "DI")
3416 (set_attr "length" "1")])
3417
3418
8ef30996
MM
3419(define_insn "ashrsi3"
3420 [(set (match_operand:SI 0 "register_operand" "=d")
3421 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
3422 (match_operand:SI 2 "arith_operand" "dI")))]
3423 ""
3424 "*
3425{
3426 if (GET_CODE (operands[2]) == CONST_INT)
3427 operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
3428
3429 return \"sra\\t%0,%1,%2\";
3430}"
3431 [(set_attr "type" "arith")
3432 (set_attr "mode" "SI")
3433 (set_attr "length" "1")])
3434
3435
3436(define_expand "ashrdi3"
3437 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3438 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
3439 (match_operand:SI 2 "arith_operand" "")))
3440 (clobber (match_dup 3))])]
bb621ad7
JW
3441 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3442 "
3443{
3444 if (TARGET_64BIT)
3445 {
3446 emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
3447 operands[2]));
3448 DONE;
3449 }
3450
3451 operands[3] = gen_reg_rtx (SImode);
3452}")
8ef30996
MM
3453
3454
3455(define_insn "ashrdi3_internal"
0fb5ac6f 3456 [(set (match_operand:DI 0 "register_operand" "=&d")
8ef30996
MM
3457 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3458 (match_operand:SI 2 "register_operand" "d")))
3459 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 3460 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
8ef30996
MM
3461 "*
3462{
3463 operands[4] = const0_rtx;
3464 dslots_jump_total += 3;
3465 dslots_jump_filled += 2;
3466
3467 return \"sll\\t%3,%2,26\\n\\
3468\\tbgez\\t%3,1f\\n\\
3469\\tsra\\t%L0,%M1,%2\\n\\
3470\\t%(b\\t3f\\n\\
3471\\tsra\\t%M0,%M1,31%)\\n\\
3472\\n\\
34731:\\n\\
3474\\t%(beq\\t%3,%z4,2f\\n\\
3475\\tsrl\\t%L0,%L1,%2%)\\n\\
3476\\n\\
3477\\tsubu\\t%3,%z4,%2\\n\\
3478\\tsll\\t%3,%M1,%3\\n\\
3479\\tor\\t%L0,%L0,%3\\n\\
34802:\\n\\
3481\\tsra\\t%M0,%M1,%2\\n\\
34823:\";
3483}"
3484 [(set_attr "type" "darith")
3485 (set_attr "mode" "DI")
3486 (set_attr "length" "12")])
3487
3488
3489(define_insn "ashrdi3_internal2"
3490 [(set (match_operand:DI 0 "register_operand" "=d")
3491 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3492 (match_operand:SI 2 "small_int" "IJK")))
3493 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 3494 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
8ef30996
MM
3495 "*
3496{
3497 operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
3498 return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
3499}"
3500 [(set_attr "type" "darith")
3501 (set_attr "mode" "DI")
3502 (set_attr "length" "2")])
3503
3504
3505(define_split
3506 [(set (match_operand:DI 0 "register_operand" "")
3507 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
3508 (match_operand:SI 2 "small_int" "")))
3509 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 3510 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3511 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3512 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3513 && (INTVAL (operands[2]) & 32) != 0"
3514
3515 [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
3516 (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))]
3517
3518 "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
3519
3520
3521(define_split
3522 [(set (match_operand:DI 0 "register_operand" "")
3523 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
3524 (match_operand:SI 2 "small_int" "")))
3525 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 3526 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3527 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3528 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3529 && (INTVAL (operands[2]) & 32) != 0"
3530
3531 [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
3532 (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
3533
3534 "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
3535
3536
3537(define_insn "ashrdi3_internal3"
3538 [(set (match_operand:DI 0 "register_operand" "=d")
3539 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3540 (match_operand:SI 2 "small_int" "IJK")))
3541 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 3542 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
8ef30996
MM
3543 && (INTVAL (operands[2]) & 63) < 32
3544 && (INTVAL (operands[2]) & 63) != 0"
3545 "*
3546{
3547 int amount = INTVAL (operands[2]);
3548
3549 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
3550 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
3551
3552 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
3553}"
3554 [(set_attr "type" "darith")
3555 (set_attr "mode" "DI")
3556 (set_attr "length" "4")])
3557
3558
3559(define_split
3560 [(set (match_operand:DI 0 "register_operand" "")
3561 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
3562 (match_operand:SI 2 "small_int" "")))
3563 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 3564 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3565 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3566 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3567 && (INTVAL (operands[2]) & 63) < 32
3568 && (INTVAL (operands[2]) & 63) != 0"
3569
3570 [(set (subreg:SI (match_dup 0) 0)
3571 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
3572 (match_dup 2)))
3573
3574 (set (match_dup 3)
3575 (ashift:SI (subreg:SI (match_dup 1) 1)
3576 (match_dup 4)))
3577
3578 (set (subreg:SI (match_dup 0) 0)
3579 (ior:SI (subreg:SI (match_dup 0) 0)
3580 (match_dup 3)))
3581
3582 (set (subreg:SI (match_dup 0) 1)
3583 (ashiftrt:SI (subreg:SI (match_dup 1) 1)
3584 (match_dup 2)))]
3585 "
3586{
3587 int amount = INTVAL (operands[2]);
3588 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
3589 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
3590}")
3591
3592
3593(define_split
3594 [(set (match_operand:DI 0 "register_operand" "")
3595 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
3596 (match_operand:SI 2 "small_int" "")))
3597 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 3598 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3599 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3600 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3601 && (INTVAL (operands[2]) & 63) < 32
3602 && (INTVAL (operands[2]) & 63) != 0"
3603
3604 [(set (subreg:SI (match_dup 0) 1)
3605 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
3606 (match_dup 2)))
3607
3608 (set (match_dup 3)
3609 (ashift:SI (subreg:SI (match_dup 1) 0)
3610 (match_dup 4)))
3611
3612 (set (subreg:SI (match_dup 0) 1)
3613 (ior:SI (subreg:SI (match_dup 0) 1)
3614 (match_dup 3)))
3615
3616 (set (subreg:SI (match_dup 0) 0)
3617 (ashiftrt:SI (subreg:SI (match_dup 1) 0)
3618 (match_dup 2)))]
3619 "
3620{
3621 int amount = INTVAL (operands[2]);
3622 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
3623 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
3624}")
3625
3626
bb621ad7
JW
3627(define_insn "ashrdi3_internal4"
3628 [(set (match_operand:DI 0 "register_operand" "=d")
3629 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3630 (match_operand:SI 2 "arith_operand" "dI")))]
3631 "TARGET_64BIT"
3632 "*
3633{
3634 if (GET_CODE (operands[2]) == CONST_INT)
3635 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
3636
3637 return \"dsra\\t%0,%1,%2\";
3638}"
3639 [(set_attr "type" "arith")
3640 (set_attr "mode" "DI")
3641 (set_attr "length" "1")])
3642
3643
8ef30996
MM
3644(define_insn "lshrsi3"
3645 [(set (match_operand:SI 0 "register_operand" "=d")
3646 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
3647 (match_operand:SI 2 "arith_operand" "dI")))]
3648 ""
3649 "*
3650{
3651 if (GET_CODE (operands[2]) == CONST_INT)
3652 operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
3653
3654 return \"srl\\t%0,%1,%2\";
3655}"
3656 [(set_attr "type" "arith")
3657 (set_attr "mode" "SI")
3658 (set_attr "length" "1")])
3659
3660
3661(define_expand "lshrdi3"
3662 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3663 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
3664 (match_operand:SI 2 "arith_operand" "")))
3665 (clobber (match_dup 3))])]
bb621ad7
JW
3666 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3667 "
3668{
3669 if (TARGET_64BIT)
3670 {
3671 emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
3672 operands[2]));
3673 DONE;
3674 }
3675
3676 operands[3] = gen_reg_rtx (SImode);
3677}")
8ef30996
MM
3678
3679
3680(define_insn "lshrdi3_internal"
3681 [(set (match_operand:DI 0 "register_operand" "=&d")
3682 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3683 (match_operand:SI 2 "register_operand" "d")))
3684 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 3685 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
8ef30996
MM
3686 "*
3687{
3688 operands[4] = const0_rtx;
3689 dslots_jump_total += 3;
3690 dslots_jump_filled += 2;
3691
3692 return \"sll\\t%3,%2,26\\n\\
3693\\tbgez\\t%3,1f\\n\\
3694\\tsrl\\t%L0,%M1,%2\\n\\
3695\\t%(b\\t3f\\n\\
3696\\tmove\\t%M0,%z4%)\\n\\
3697\\n\\
36981:\\n\\
3699\\t%(beq\\t%3,%z4,2f\\n\\
3700\\tsrl\\t%L0,%L1,%2%)\\n\\
3701\\n\\
3702\\tsubu\\t%3,%z4,%2\\n\\
3703\\tsll\\t%3,%M1,%3\\n\\
3704\\tor\\t%L0,%L0,%3\\n\\
37052:\\n\\
3706\\tsrl\\t%M0,%M1,%2\\n\\
37073:\";
3708}"
3709 [(set_attr "type" "darith")
3710 (set_attr "mode" "DI")
3711 (set_attr "length" "12")])
3712
3713
3714(define_insn "lshrdi3_internal2"
3715 [(set (match_operand:DI 0 "register_operand" "=d")
3716 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3717 (match_operand:SI 2 "small_int" "IJK")))
3718 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 3719 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
8ef30996
MM
3720 "*
3721{
3722 operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
3723 operands[4] = const0_rtx;
3724 return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
3725}"
3726 [(set_attr "type" "darith")
3727 (set_attr "mode" "DI")
3728 (set_attr "length" "2")])
3729
3730
3731(define_split
3732 [(set (match_operand:DI 0 "register_operand" "")
3733 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
3734 (match_operand:SI 2 "small_int" "")))
3735 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 3736 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3737 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3738 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3739 && (INTVAL (operands[2]) & 32) != 0"
3740
3741 [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
3742 (set (subreg:SI (match_dup 0) 1) (const_int 0))]
3743
3744 "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
3745
3746
3747(define_split
3748 [(set (match_operand:DI 0 "register_operand" "")
3749 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
3750 (match_operand:SI 2 "small_int" "")))
3751 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 3752 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3753 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3754 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3755 && (INTVAL (operands[2]) & 32) != 0"
3756
3757 [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
3758 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
3759
3760 "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
3761
3762
3763(define_insn "lshrdi3_internal3"
3764 [(set (match_operand:DI 0 "register_operand" "=d")
3765 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3766 (match_operand:SI 2 "small_int" "IJK")))
3767 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 3768 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
8ef30996
MM
3769 && (INTVAL (operands[2]) & 63) < 32
3770 && (INTVAL (operands[2]) & 63) != 0"
3771 "*
3772{
3773 int amount = INTVAL (operands[2]);
3774
3775 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
3776 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
3777
3778 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
3779}"
3780 [(set_attr "type" "darith")
3781 (set_attr "mode" "DI")
3782 (set_attr "length" "4")])
3783
3784
3785(define_split
3786 [(set (match_operand:DI 0 "register_operand" "")
3787 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
3788 (match_operand:SI 2 "small_int" "")))
3789 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 3790 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3791 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3792 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3793 && (INTVAL (operands[2]) & 63) < 32
3794 && (INTVAL (operands[2]) & 63) != 0"
3795
3796 [(set (subreg:SI (match_dup 0) 0)
3797 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
3798 (match_dup 2)))
3799
3800 (set (match_dup 3)
3801 (ashift:SI (subreg:SI (match_dup 1) 1)
3802 (match_dup 4)))
3803
3804 (set (subreg:SI (match_dup 0) 0)
3805 (ior:SI (subreg:SI (match_dup 0) 0)
3806 (match_dup 3)))
3807
3808 (set (subreg:SI (match_dup 0) 1)
3809 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
3810 (match_dup 2)))]
3811 "
3812{
3813 int amount = INTVAL (operands[2]);
3814 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
3815 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
3816}")
3817
3818
3819(define_split
3820 [(set (match_operand:DI 0 "register_operand" "")
3821 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
3822 (match_operand:SI 2 "small_int" "")))
3823 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 3824 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3825 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
3826 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3827 && (INTVAL (operands[2]) & 63) < 32
3828 && (INTVAL (operands[2]) & 63) != 0"
3829
3830 [(set (subreg:SI (match_dup 0) 1)
3831 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
3832 (match_dup 2)))
3833
3834 (set (match_dup 3)
3835 (ashift:SI (subreg:SI (match_dup 1) 0)
3836 (match_dup 4)))
3837
3838 (set (subreg:SI (match_dup 0) 1)
3839 (ior:SI (subreg:SI (match_dup 0) 1)
3840 (match_dup 3)))
3841
3842 (set (subreg:SI (match_dup 0) 0)
3843 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
3844 (match_dup 2)))]
3845 "
3846{
3847 int amount = INTVAL (operands[2]);
3848 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
3849 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
3850}")
3851
bb621ad7
JW
3852
3853(define_insn "lshrdi3_internal4"
3854 [(set (match_operand:DI 0 "register_operand" "=d")
3855 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3856 (match_operand:SI 2 "arith_operand" "dI")))]
3857 "TARGET_64BIT"
3858 "*
3859{
3860 if (GET_CODE (operands[2]) == CONST_INT)
3861 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
3862
3863 return \"dsrl\\t%0,%1,%2\";
3864}"
3865 [(set_attr "type" "arith")
3866 (set_attr "mode" "DI")
3867 (set_attr "length" "1")])
3868
8ef30996
MM
3869\f
3870;;
3871;; ....................
3872;;
3873;; COMPARISONS
3874;;
3875;; ....................
3876
3877;; Flow here is rather complex:
3878;;
bb621ad7 3879;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
8ef30996
MM
3880;; arguments into the branch_cmp array, and the type into
3881;; branch_type. No RTL is generated.
3882;;
3883;; 2) The appropriate branch define_expand is called, which then
3884;; creates the appropriate RTL for the comparison and branch.
3885;; Different CC modes are used, based on what type of branch is
3886;; done, so that we can constrain things appropriately. There
3887;; are assumptions in the rest of GCC that break if we fold the
3888;; operands into the branchs for integer operations, and use cc0
34b650b3
MM
3889;; for floating point, so we use the fp status register instead.
3890;; If needed, an appropriate temporary is created to hold the
3891;; of the integer compare.
8ef30996
MM
3892
3893(define_expand "cmpsi"
3894 [(set (cc0)
3895 (compare:CC (match_operand:SI 0 "register_operand" "")
3896 (match_operand:SI 1 "arith_operand" "")))]
3897 ""
3898 "
3899{
3900 if (operands[0]) /* avoid unused code message */
3901 {
3902 branch_cmp[0] = operands[0];
3903 branch_cmp[1] = operands[1];
3904 branch_type = CMP_SI;
3905 DONE;
3906 }
3907}")
3908
3909(define_expand "tstsi"
3910 [(set (cc0)
3911 (match_operand:SI 0 "register_operand" ""))]
3912 ""
3913 "
3914{
3915 if (operands[0]) /* avoid unused code message */
3916 {
3917 branch_cmp[0] = operands[0];
3918 branch_cmp[1] = const0_rtx;
3919 branch_type = CMP_SI;
3920 DONE;
3921 }
3922}")
3923
bb621ad7
JW
3924(define_expand "cmpdi"
3925 [(set (cc0)
3926 (compare:CC (match_operand:DI 0 "register_operand" "")
3927 (match_operand:DI 1 "arith_operand" "")))]
3928 "TARGET_64BIT"
3929 "
3930{
3931 if (operands[0]) /* avoid unused code message */
3932 {
3933 branch_cmp[0] = operands[0];
3934 branch_cmp[1] = operands[1];
3935 branch_type = CMP_DI;
3936 DONE;
3937 }
3938}")
3939
3940(define_expand "tstdi"
3941 [(set (cc0)
3942 (match_operand:DI 0 "register_operand" ""))]
3943 "TARGET_64BIT"
3944 "
3945{
3946 if (operands[0]) /* avoid unused code message */
3947 {
3948 branch_cmp[0] = operands[0];
3949 branch_cmp[1] = const0_rtx;
3950 branch_type = CMP_DI;
3951 DONE;
3952 }
3953}")
3954
8ef30996
MM
3955(define_expand "cmpdf"
3956 [(set (cc0)
3957 (compare:CC_FP (match_operand:DF 0 "register_operand" "")
3958 (match_operand:DF 1 "register_operand" "")))]
3959 "TARGET_HARD_FLOAT"
3960 "
3961{
3962 if (operands[0]) /* avoid unused code message */
3963 {
3964 branch_cmp[0] = operands[0];
3965 branch_cmp[1] = operands[1];
3966 branch_type = CMP_DF;
3967 DONE;
3968 }
3969}")
3970
8ef30996
MM
3971(define_expand "cmpsf"
3972 [(set (cc0)
3973 (compare:CC_FP (match_operand:SF 0 "register_operand" "")
3974 (match_operand:SF 1 "register_operand" "")))]
3975 "TARGET_HARD_FLOAT"
3976 "
3977{
3978 if (operands[0]) /* avoid unused code message */
3979 {
3980 branch_cmp[0] = operands[0];
3981 branch_cmp[1] = operands[1];
3982 branch_type = CMP_SF;
3983 DONE;
3984 }
3985}")
3986
8ef30996
MM
3987\f
3988;;
3989;; ....................
3990;;
3991;; CONDITIONAL BRANCHES
3992;;
3993;; ....................
3994
34b650b3 3995(define_insn "branch_fp_ne"
8ef30996 3996 [(set (pc)
34b650b3
MM
3997 (if_then_else (ne:CC_FP (reg:CC_FP 66)
3998 (const_int 0))
3999 (match_operand 0 "pc_or_label_operand" "")
4000 (match_operand 1 "pc_or_label_operand" "")))]
bb621ad7 4001 "TARGET_HARD_FLOAT"
8ef30996
MM
4002 "*
4003{
8ef30996 4004 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
34b650b3 4005 return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\";
8ef30996
MM
4006}"
4007 [(set_attr "type" "branch")
4008 (set_attr "mode" "none")
34b650b3 4009 (set_attr "length" "1")])
8ef30996 4010
34b650b3 4011(define_insn "branch_fp_ne_rev"
8ef30996 4012 [(set (pc)
34b650b3
MM
4013 (if_then_else (ne:CC_REV_FP (reg:CC_REV_FP 66)
4014 (const_int 0))
4015 (match_operand 0 "pc_or_label_operand" "")
4016 (match_operand 1 "pc_or_label_operand" "")))]
bb621ad7 4017 "TARGET_HARD_FLOAT"
8ef30996
MM
4018 "*
4019{
8ef30996 4020 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
34b650b3 4021 return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\";
8ef30996
MM
4022}"
4023 [(set_attr "type" "branch")
4024 (set_attr "mode" "none")
34b650b3 4025 (set_attr "length" "1")])
8ef30996 4026
34b650b3 4027(define_insn "branch_fp_eq"
8ef30996 4028 [(set (pc)
34b650b3
MM
4029 (if_then_else (eq:CC_FP (reg:CC_FP 66)
4030 (const_int 0))
4031 (match_operand 0 "pc_or_label_operand" "")
4032 (match_operand 1 "pc_or_label_operand" "")))]
bb621ad7 4033 "TARGET_HARD_FLOAT"
8ef30996
MM
4034 "*
4035{
4036 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
34b650b3 4037 return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\";
8ef30996
MM
4038}"
4039 [(set_attr "type" "branch")
4040 (set_attr "mode" "none")
4041 (set_attr "length" "1")])
4042
34b650b3 4043(define_insn "branch_fp_eq_rev"
8ef30996 4044 [(set (pc)
34b650b3
MM
4045 (if_then_else (eq:CC_REV_FP (reg:CC_REV_FP 66)
4046 (const_int 0))
4047 (match_operand 0 "pc_or_label_operand" "")
4048 (match_operand 1 "pc_or_label_operand" "")))]
bb621ad7 4049 "TARGET_HARD_FLOAT"
8ef30996
MM
4050 "*
4051{
4052 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
34b650b3 4053 return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\";
8ef30996
MM
4054}"
4055 [(set_attr "type" "branch")
4056 (set_attr "mode" "none")
4057 (set_attr "length" "1")])
4058
34b650b3
MM
4059
4060(define_insn "branch_zero"
8ef30996 4061 [(set (pc)
34b650b3 4062 (if_then_else (match_operator:SI 0 "cmp_op"
81723db9 4063 [(match_operand:SI 1 "register_operand" "d")
34b650b3
MM
4064 (const_int 0)])
4065 (match_operand 2 "pc_or_label_operand" "")
4066 (match_operand 3 "pc_or_label_operand" "")))]
8ef30996
MM
4067 ""
4068 "*
4069{
4070 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
34b650b3
MM
4071 if (operands[2] != pc_rtx)
4072 { /* normal jump */
4073 switch (GET_CODE (operands[0]))
4074 {
4075 case EQ: return \"%*beq%?\\t%z1,%.,%2\";
4076 case NE: return \"%*bne%?\\t%z1,%.,%2\";
4077 case GTU: return \"%*bne%?\\t%z1,%.,%2\";
4078 case LEU: return \"%*beq%?\\t%z1,%.,%2\";
4079 case GEU: return \"%*j\\t%2\";
81723db9 4080 case LTU: return \"%*bne%?\\t%.,%.,%2\";
34b650b3 4081 }
8ef30996 4082
34b650b3 4083 return \"%*b%C0z%?\\t%z1,%2\";
8ef30996 4084 }
34b650b3
MM
4085 else
4086 { /* inverted jump */
4087 switch (GET_CODE (operands[0]))
4088 {
4089 case EQ: return \"%*bne%?\\t%z1,%.,%3\";
4090 case NE: return \"%*beq%?\\t%z1,%.,%3\";
4091 case GTU: return \"%*beq%?\\t%z1,%.,%3\";
4092 case LEU: return \"%*bne%?\\t%z1,%.,%3\";
81723db9 4093 case GEU: return \"%*beq%?\\t%.,%.,%3\";
34b650b3
MM
4094 case LTU: return \"%*j\\t%3\";
4095 }
8ef30996 4096
34b650b3
MM
4097 return \"%*b%N0z%?\\t%z1,%3\";
4098 }
8ef30996
MM
4099}"
4100 [(set_attr "type" "branch")
4101 (set_attr "mode" "none")
4102 (set_attr "length" "1")])
4103
8ef30996 4104
bb621ad7
JW
4105(define_insn "branch_zero_di"
4106 [(set (pc)
4107 (if_then_else (match_operator:DI 0 "cmp_op"
4108 [(match_operand:DI 1 "register_operand" "d")
4109 (const_int 0)])
4110 (match_operand 2 "pc_or_label_operand" "")
4111 (match_operand 3 "pc_or_label_operand" "")))]
4112 ""
4113 "*
4114{
4115 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
4116 if (operands[2] != pc_rtx)
4117 { /* normal jump */
4118 switch (GET_CODE (operands[0]))
4119 {
4120 case EQ: return \"%*beq%?\\t%z1,%.,%2\";
4121 case NE: return \"%*bne%?\\t%z1,%.,%2\";
4122 case GTU: return \"%*bne%?\\t%z1,%.,%2\";
4123 case LEU: return \"%*beq%?\\t%z1,%.,%2\";
4124 case GEU: return \"%*j\\t%2\";
4125 case LTU: return \"%*bne%?\\t%.,%.,%2\";
4126 }
4127
4128 return \"%*b%C0z%?\\t%z1,%2\";
4129 }
4130 else
4131 { /* inverted jump */
4132 switch (GET_CODE (operands[0]))
4133 {
4134 case EQ: return \"%*bne%?\\t%z1,%.,%3\";
4135 case NE: return \"%*beq%?\\t%z1,%.,%3\";
4136 case GTU: return \"%*beq%?\\t%z1,%.,%3\";
4137 case LEU: return \"%*bne%?\\t%z1,%.,%3\";
4138 case GEU: return \"%*beq%?\\t%.,%.,%3\";
4139 case LTU: return \"%*j\\t%3\";
4140 }
4141
4142 return \"%*b%N0z%?\\t%z1,%3\";
4143 }
4144}"
4145 [(set_attr "type" "branch")
4146 (set_attr "mode" "none")
4147 (set_attr "length" "1")])
4148
4149
34b650b3 4150(define_insn "branch_equality"
8ef30996 4151 [(set (pc)
34b650b3
MM
4152 (if_then_else (match_operator:SI 0 "equality_op"
4153 [(match_operand:SI 1 "register_operand" "d")
4154 (match_operand:SI 2 "register_operand" "d")])
4155 (match_operand 3 "pc_or_label_operand" "")
4156 (match_operand 4 "pc_or_label_operand" "")))]
8ef30996
MM
4157 ""
4158 "*
4159{
4160 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
34b650b3
MM
4161 return (operands[3] != pc_rtx)
4162 ? \"%*b%C0%?\\t%z1,%z2,%3\"
4163 : \"%*b%N0%?\\t%z1,%z2,%4\";
8ef30996
MM
4164}"
4165 [(set_attr "type" "branch")
4166 (set_attr "mode" "none")
34b650b3
MM
4167 (set_attr "length" "1")])
4168
8ef30996 4169
bb621ad7
JW
4170(define_insn "branch_equality_di"
4171 [(set (pc)
4172 (if_then_else (match_operator:DI 0 "equality_op"
4173 [(match_operand:DI 1 "register_operand" "d")
4174 (match_operand:DI 2 "register_operand" "d")])
4175 (match_operand 3 "pc_or_label_operand" "")
4176 (match_operand 4 "pc_or_label_operand" "")))]
4177 ""
4178 "*
4179{
4180 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
4181 return (operands[3] != pc_rtx)
4182 ? \"%*b%C0%?\\t%z1,%z2,%3\"
4183 : \"%*b%N0%?\\t%z1,%z2,%4\";
4184}"
4185 [(set_attr "type" "branch")
4186 (set_attr "mode" "none")
4187 (set_attr "length" "1")])
4188
4189
8ef30996
MM
4190(define_expand "beq"
4191 [(set (pc)
4192 (if_then_else (eq:CC_EQ (cc0)
4193 (const_int 0))
4194 (label_ref (match_operand 0 "" ""))
4195 (pc)))]
4196 ""
4197 "
4198{
4199 if (operands[0]) /* avoid unused code warning */
4200 {
4201 gen_conditional_branch (operands, EQ);
4202 DONE;
4203 }
4204}")
4205
4206(define_expand "bne"
4207 [(set (pc)
4208 (if_then_else (ne:CC_EQ (cc0)
4209 (const_int 0))
4210 (label_ref (match_operand 0 "" ""))
4211 (pc)))]
4212 ""
4213 "
4214{
4215 if (operands[0]) /* avoid unused code warning */
4216 {
4217 gen_conditional_branch (operands, NE);
4218 DONE;
4219 }
4220}")
4221
4222(define_expand "bgt"
4223 [(set (pc)
4224 (if_then_else (gt:CC (cc0)
4225 (const_int 0))
4226 (label_ref (match_operand 0 "" ""))
4227 (pc)))]
4228 ""
4229 "
4230{
4231 if (operands[0]) /* avoid unused code warning */
4232 {
4233 gen_conditional_branch (operands, GT);
4234 DONE;
4235 }
4236}")
4237
4238(define_expand "bge"
4239 [(set (pc)
4240 (if_then_else (ge:CC (cc0)
4241 (const_int 0))
4242 (label_ref (match_operand 0 "" ""))
4243 (pc)))]
4244 ""
4245 "
4246{
4247 if (operands[0]) /* avoid unused code warning */
4248 {
4249 gen_conditional_branch (operands, GE);
4250 DONE;
4251 }
4252}")
4253
4254(define_expand "blt"
4255 [(set (pc)
4256 (if_then_else (lt:CC (cc0)
4257 (const_int 0))
4258 (label_ref (match_operand 0 "" ""))
4259 (pc)))]
4260 ""
4261 "
4262{
4263 if (operands[0]) /* avoid unused code warning */
4264 {
4265 gen_conditional_branch (operands, LT);
4266 DONE;
4267 }
4268}")
4269
4270(define_expand "ble"
4271 [(set (pc)
4272 (if_then_else (le:CC (cc0)
4273 (const_int 0))
4274 (label_ref (match_operand 0 "" ""))
4275 (pc)))]
4276 ""
4277 "
4278{
4279 if (operands[0]) /* avoid unused code warning */
4280 {
4281 gen_conditional_branch (operands, LE);
4282 DONE;
4283 }
4284}")
4285
4286(define_expand "bgtu"
4287 [(set (pc)
4288 (if_then_else (gtu:CC (cc0)
4289 (const_int 0))
4290 (label_ref (match_operand 0 "" ""))
4291 (pc)))]
4292 ""
4293 "
4294{
4295 if (operands[0]) /* avoid unused code warning */
4296 {
4297 gen_conditional_branch (operands, GTU);
4298 DONE;
4299 }
4300}")
4301
4302(define_expand "bgeu"
4303 [(set (pc)
4304 (if_then_else (geu:CC (cc0)
4305 (const_int 0))
4306 (label_ref (match_operand 0 "" ""))
4307 (pc)))]
4308 ""
4309 "
4310{
4311 if (operands[0]) /* avoid unused code warning */
4312 {
4313 gen_conditional_branch (operands, GEU);
4314 DONE;
4315 }
4316}")
4317
4318
4319(define_expand "bltu"
4320 [(set (pc)
4321 (if_then_else (ltu:CC (cc0)
4322 (const_int 0))
4323 (label_ref (match_operand 0 "" ""))
4324 (pc)))]
4325 ""
4326 "
4327{
4328 if (operands[0]) /* avoid unused code warning */
4329 {
4330 gen_conditional_branch (operands, LTU);
4331 DONE;
4332 }
4333}")
4334
4335(define_expand "bleu"
4336 [(set (pc)
4337 (if_then_else (leu:CC (cc0)
4338 (const_int 0))
4339 (label_ref (match_operand 0 "" ""))
4340 (pc)))]
4341 ""
4342 "
4343{
4344 if (operands[0]) /* avoid unused code warning */
4345 {
4346 gen_conditional_branch (operands, LEU);
4347 DONE;
4348 }
4349}")
4350
4351\f
4352;;
4353;; ....................
4354;;
4355;; SETTING A REGISTER FROM A COMPARISON
4356;;
4357;; ....................
4358
4359(define_expand "seq"
4360 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3
MM
4361 (eq:SI (match_dup 1)
4362 (match_dup 2)))]
8ef30996
MM
4363 ""
4364 "
4365{
bb621ad7 4366 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
4367 FAIL;
4368
4369 /* set up operands from compare. */
4370 operands[1] = branch_cmp[0];
4371 operands[2] = branch_cmp[1];
4372
bb621ad7 4373 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
34b650b3
MM
4374 {
4375 gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
4376 DONE;
4377 }
4378
8ef30996
MM
4379 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
4380 operands[2] = force_reg (SImode, operands[2]);
4381
4382 /* fall through and generate default code */
4383}")
4384
34b650b3
MM
4385
4386(define_insn "seq_si_zero"
4387 [(set (match_operand:SI 0 "register_operand" "=d")
4388 (eq:SI (match_operand:SI 1 "register_operand" "d")
4389 (const_int 0)))]
8ef30996 4390 ""
34b650b3 4391 "sltu\\t%0,%1,1"
bb621ad7 4392 [(set_attr "type" "arith")
34b650b3
MM
4393 (set_attr "mode" "SI")
4394 (set_attr "length" "1")])
4395
bb621ad7
JW
4396(define_insn "seq_di_zero"
4397 [(set (match_operand:DI 0 "register_operand" "=d")
4398 (eq:DI (match_operand:DI 1 "register_operand" "d")
4399 (const_int 0)))]
4400 "TARGET_64BIT"
4401 "sltu\\t%0,%1,1"
4402 [(set_attr "type" "arith")
4403 (set_attr "mode" "DI")
4404 (set_attr "length" "1")])
4405
34b650b3
MM
4406(define_insn "seq_si"
4407 [(set (match_operand:SI 0 "register_operand" "=d,d")
4408 (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
4409 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
bbdb5552 4410 "TARGET_DEBUG_C_MODE"
8ef30996 4411 "@
8ef30996 4412 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
34b650b3 4413 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
bb621ad7
JW
4414 [(set_attr "type" "arith")
4415 (set_attr "mode" "SI")
4416 (set_attr "length" "2")])
4417
4418(define_split
4419 [(set (match_operand:SI 0 "register_operand" "")
4420 (eq:SI (match_operand:SI 1 "register_operand" "")
4421 (match_operand:SI 2 "uns_arith_operand" "")))]
4422 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
4423 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
4424 [(set (match_dup 0)
4425 (xor:SI (match_dup 1)
4426 (match_dup 2)))
4427 (set (match_dup 0)
4428 (ltu:SI (match_dup 0)
4429 (const_int 1)))]
4430 "")
4431
4432(define_insn "seq_di"
4433 [(set (match_operand:DI 0 "register_operand" "=d,d")
4434 (eq:DI (match_operand:DI 1 "register_operand" "%d,d")
4435 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
4436 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
4437 "@
4438 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
4439 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
4440 [(set_attr "type" "arith")
4441 (set_attr "mode" "DI")
92b4cee1 4442 (set_attr "length" "2")])
8ef30996
MM
4443
4444(define_split
bb621ad7
JW
4445 [(set (match_operand:DI 0 "register_operand" "")
4446 (eq:DI (match_operand:DI 1 "register_operand" "")
4447 (match_operand:DI 2 "uns_arith_operand" "")))]
4448 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
26b8e6e5 4449 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8ef30996 4450 [(set (match_dup 0)
bb621ad7 4451 (xor:DI (match_dup 1)
8ef30996
MM
4452 (match_dup 2)))
4453 (set (match_dup 0)
bb621ad7 4454 (ltu:DI (match_dup 0)
8ef30996
MM
4455 (const_int 1)))]
4456 "")
4457
4458(define_expand "sne"
4459 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3
MM
4460 (ne:SI (match_dup 1)
4461 (match_dup 2)))]
8ef30996
MM
4462 ""
4463 "
4464{
bb621ad7 4465 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
4466 FAIL;
4467
4468 /* set up operands from compare. */
4469 operands[1] = branch_cmp[0];
4470 operands[2] = branch_cmp[1];
4471
bb621ad7 4472 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
34b650b3
MM
4473 {
4474 gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
4475 DONE;
4476 }
4477
8ef30996
MM
4478 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
4479 operands[2] = force_reg (SImode, operands[2]);
4480
4481 /* fall through and generate default code */
4482}")
4483
34b650b3
MM
4484(define_insn "sne_si_zero"
4485 [(set (match_operand:SI 0 "register_operand" "=d")
4486 (ne:SI (match_operand:SI 1 "register_operand" "d")
4487 (const_int 0)))]
8ef30996 4488 ""
34b650b3 4489 "sltu\\t%0,%.,%1"
bb621ad7 4490 [(set_attr "type" "arith")
34b650b3
MM
4491 (set_attr "mode" "SI")
4492 (set_attr "length" "1")])
8ef30996 4493
bb621ad7
JW
4494(define_insn "sne_di_zero"
4495 [(set (match_operand:DI 0 "register_operand" "=d")
4496 (ne:DI (match_operand:DI 1 "register_operand" "d")
4497 (const_int 0)))]
4498 "TARGET_64BIT"
4499 "sltu\\t%0,%.,%1"
4500 [(set_attr "type" "arith")
4501 (set_attr "mode" "DI")
4502 (set_attr "length" "1")])
4503
34b650b3
MM
4504(define_insn "sne_si"
4505 [(set (match_operand:SI 0 "register_operand" "=d,d")
4506 (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
4507 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
bbdb5552 4508 "TARGET_DEBUG_C_MODE"
34b650b3
MM
4509 "@
4510 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
4511 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
bb621ad7 4512 [(set_attr "type" "arith")
92b4cee1
MM
4513 (set_attr "mode" "SI")
4514 (set_attr "length" "2")])
8ef30996
MM
4515
4516(define_split
4517 [(set (match_operand:SI 0 "register_operand" "")
34b650b3
MM
4518 (ne:SI (match_operand:SI 1 "register_operand" "")
4519 (match_operand:SI 2 "uns_arith_operand" "")))]
bbdb5552 4520 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
26b8e6e5 4521 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8ef30996
MM
4522 [(set (match_dup 0)
4523 (xor:SI (match_dup 1)
4524 (match_dup 2)))
4525 (set (match_dup 0)
34b650b3 4526 (gtu:SI (match_dup 0)
8ef30996
MM
4527 (const_int 0)))]
4528 "")
4529
bb621ad7
JW
4530(define_insn "sne_di"
4531 [(set (match_operand:DI 0 "register_operand" "=d,d")
4532 (ne:DI (match_operand:DI 1 "register_operand" "%d,d")
4533 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
4534 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
4535 "@
4536 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
4537 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
4538 [(set_attr "type" "arith")
4539 (set_attr "mode" "DI")
4540 (set_attr "length" "2")])
4541
4542(define_split
4543 [(set (match_operand:DI 0 "register_operand" "")
4544 (ne:DI (match_operand:DI 1 "register_operand" "")
4545 (match_operand:DI 2 "uns_arith_operand" "")))]
4546 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
4547 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
4548 [(set (match_dup 0)
4549 (xor:DI (match_dup 1)
4550 (match_dup 2)))
4551 (set (match_dup 0)
4552 (gtu:DI (match_dup 0)
4553 (const_int 0)))]
4554 "")
4555
8ef30996
MM
4556(define_expand "sgt"
4557 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4558 (gt:SI (match_dup 1)
8ef30996
MM
4559 (match_dup 2)))]
4560 ""
4561 "
4562{
bb621ad7 4563 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
4564 FAIL;
4565
4566 /* set up operands from compare. */
4567 operands[1] = branch_cmp[0];
4568 operands[2] = branch_cmp[1];
4569
bb621ad7 4570 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
34b650b3
MM
4571 {
4572 gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
4573 DONE;
4574 }
4575
8ef30996
MM
4576 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
4577 operands[2] = force_reg (SImode, operands[2]);
4578
4579 /* fall through and generate default code */
4580}")
4581
4582(define_insn "sgt_si"
4583 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4584 (gt:SI (match_operand:SI 1 "register_operand" "d")
8ef30996
MM
4585 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
4586 ""
4587 "slt\\t%0,%z2,%1"
bb621ad7 4588 [(set_attr "type" "arith")
8ef30996
MM
4589 (set_attr "mode" "SI")
4590 (set_attr "length" "1")])
4591
bb621ad7
JW
4592(define_insn "sgt_di"
4593 [(set (match_operand:DI 0 "register_operand" "=d")
4594 (gt:DI (match_operand:DI 1 "register_operand" "d")
4595 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
4596 "TARGET_64BIT"
4597 "slt\\t%0,%z2,%1"
4598 [(set_attr "type" "arith")
4599 (set_attr "mode" "DI")
4600 (set_attr "length" "1")])
4601
8ef30996
MM
4602(define_expand "sge"
4603 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4604 (ge:SI (match_dup 1)
8ef30996
MM
4605 (match_dup 2)))]
4606 ""
4607 "
4608{
bb621ad7 4609 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
4610 FAIL;
4611
4612 /* set up operands from compare. */
4613 operands[1] = branch_cmp[0];
4614 operands[2] = branch_cmp[1];
4615
bb621ad7 4616 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
34b650b3
MM
4617 {
4618 gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
4619 DONE;
4620 }
4621
8ef30996
MM
4622 /* fall through and generate default code */
4623}")
4624
4625(define_insn "sge_si"
4626 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4627 (ge:SI (match_operand:SI 1 "register_operand" "d")
8ef30996 4628 (match_operand:SI 2 "arith_operand" "dI")))]
bbdb5552 4629 "TARGET_DEBUG_C_MODE"
8ef30996 4630 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
bb621ad7 4631 [(set_attr "type" "arith")
8ef30996
MM
4632 (set_attr "mode" "SI")
4633 (set_attr "length" "2")])
4634
4635(define_split
4636 [(set (match_operand:SI 0 "register_operand" "")
34b650b3 4637 (ge:SI (match_operand:SI 1 "register_operand" "")
8ef30996 4638 (match_operand:SI 2 "arith_operand" "")))]
bbdb5552 4639 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
8ef30996 4640 [(set (match_dup 0)
34b650b3 4641 (lt:SI (match_dup 1)
8ef30996
MM
4642 (match_dup 2)))
4643 (set (match_dup 0)
4644 (xor:SI (match_dup 0)
4645 (const_int 1)))]
4646 "")
4647
bb621ad7
JW
4648(define_insn "sge_di"
4649 [(set (match_operand:DI 0 "register_operand" "=d")
4650 (ge:DI (match_operand:DI 1 "register_operand" "d")
4651 (match_operand:DI 2 "arith_operand" "dI")))]
4652 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
4653 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
4654 [(set_attr "type" "arith")
4655 (set_attr "mode" "DI")
4656 (set_attr "length" "2")])
4657
4658(define_split
4659 [(set (match_operand:DI 0 "register_operand" "")
4660 (ge:DI (match_operand:DI 1 "register_operand" "")
4661 (match_operand:DI 2 "arith_operand" "")))]
4662 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
4663 [(set (match_dup 0)
4664 (lt:DI (match_dup 1)
4665 (match_dup 2)))
4666 (set (match_dup 0)
4667 (xor:DI (match_dup 0)
4668 (const_int 1)))]
4669 "")
4670
8ef30996
MM
4671(define_expand "slt"
4672 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4673 (lt:SI (match_dup 1)
8ef30996
MM
4674 (match_dup 2)))]
4675 ""
4676 "
4677{
bb621ad7 4678 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
4679 FAIL;
4680
4681 /* set up operands from compare. */
4682 operands[1] = branch_cmp[0];
4683 operands[2] = branch_cmp[1];
4684
bb621ad7 4685 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
34b650b3
MM
4686 {
4687 gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
4688 DONE;
4689 }
4690
8ef30996
MM
4691 /* fall through and generate default code */
4692}")
4693
4694(define_insn "slt_si"
4695 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4696 (lt:SI (match_operand:SI 1 "register_operand" "d")
8ef30996
MM
4697 (match_operand:SI 2 "arith_operand" "dI")))]
4698 ""
4699 "slt\\t%0,%1,%2"
bb621ad7 4700 [(set_attr "type" "arith")
8ef30996
MM
4701 (set_attr "mode" "SI")
4702 (set_attr "length" "1")])
4703
bb621ad7
JW
4704(define_insn "slt_di"
4705 [(set (match_operand:DI 0 "register_operand" "=d")
4706 (lt:DI (match_operand:DI 1 "register_operand" "d")
4707 (match_operand:DI 2 "arith_operand" "dI")))]
4708 "TARGET_64BIT"
4709 "slt\\t%0,%1,%2"
4710 [(set_attr "type" "arith")
4711 (set_attr "mode" "DI")
4712 (set_attr "length" "1")])
4713
8ef30996
MM
4714(define_expand "sle"
4715 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4716 (le:SI (match_dup 1)
8ef30996
MM
4717 (match_dup 2)))]
4718 ""
4719 "
4720{
bb621ad7 4721 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
4722 FAIL;
4723
4724 /* set up operands from compare. */
4725 operands[1] = branch_cmp[0];
4726 operands[2] = branch_cmp[1];
4727
bb621ad7 4728 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
34b650b3
MM
4729 {
4730 gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
4731 DONE;
4732 }
4733
8ef30996
MM
4734 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
4735 operands[2] = force_reg (SImode, operands[2]);
4736
4737 /* fall through and generate default code */
4738}")
4739
34b650b3
MM
4740(define_insn "sle_si_const"
4741 [(set (match_operand:SI 0 "register_operand" "=d")
4742 (le:SI (match_operand:SI 1 "register_operand" "d")
4743 (match_operand:SI 2 "small_int" "I")))]
4744 "INTVAL (operands[2]) < 32767"
4745 "*
4746{
4747 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
4748 return \"slt\\t%0,%1,%2\";
4749}"
bb621ad7 4750 [(set_attr "type" "arith")
34b650b3
MM
4751 (set_attr "mode" "SI")
4752 (set_attr "length" "1")])
4753
bb621ad7
JW
4754(define_insn "sle_di_const"
4755 [(set (match_operand:DI 0 "register_operand" "=d")
4756 (le:DI (match_operand:DI 1 "register_operand" "d")
4757 (match_operand:DI 2 "small_int" "I")))]
4758 "TARGET_64BIT && INTVAL (operands[2]) < 32767"
4759 "*
4760{
4761 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
4762 return \"slt\\t%0,%1,%2\";
4763}"
4764 [(set_attr "type" "arith")
4765 (set_attr "mode" "DI")
4766 (set_attr "length" "1")])
4767
34b650b3
MM
4768(define_insn "sle_si_reg"
4769 [(set (match_operand:SI 0 "register_operand" "=d")
4770 (le:SI (match_operand:SI 1 "register_operand" "d")
4771 (match_operand:SI 2 "register_operand" "d")))]
bbdb5552 4772 "TARGET_DEBUG_C_MODE"
34b650b3 4773 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
bb621ad7 4774 [(set_attr "type" "arith")
34b650b3
MM
4775 (set_attr "mode" "SI")
4776 (set_attr "length" "2")])
8ef30996
MM
4777
4778(define_split
4779 [(set (match_operand:SI 0 "register_operand" "")
34b650b3 4780 (le:SI (match_operand:SI 1 "register_operand" "")
8ef30996 4781 (match_operand:SI 2 "register_operand" "")))]
bbdb5552 4782 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
8ef30996 4783 [(set (match_dup 0)
34b650b3 4784 (lt:SI (match_dup 2)
8ef30996
MM
4785 (match_dup 1)))
4786 (set (match_dup 0)
4787 (xor:SI (match_dup 0)
4788 (const_int 1)))]
4789 "")
4790
bb621ad7
JW
4791(define_insn "sle_di_reg"
4792 [(set (match_operand:DI 0 "register_operand" "=d")
4793 (le:DI (match_operand:DI 1 "register_operand" "d")
4794 (match_operand:DI 2 "register_operand" "d")))]
4795 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
4796 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
4797 [(set_attr "type" "arith")
4798 (set_attr "mode" "DI")
4799 (set_attr "length" "2")])
4800
4801(define_split
4802 [(set (match_operand:DI 0 "register_operand" "")
4803 (le:DI (match_operand:DI 1 "register_operand" "")
4804 (match_operand:DI 2 "register_operand" "")))]
4805 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
4806 [(set (match_dup 0)
4807 (lt:DI (match_dup 2)
4808 (match_dup 1)))
4809 (set (match_dup 0)
4810 (xor:DI (match_dup 0)
4811 (const_int 1)))]
4812 "")
4813
8ef30996
MM
4814(define_expand "sgtu"
4815 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4816 (gtu:SI (match_dup 1)
8ef30996
MM
4817 (match_dup 2)))]
4818 ""
4819 "
4820{
bb621ad7 4821 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
4822 FAIL;
4823
4824 /* set up operands from compare. */
4825 operands[1] = branch_cmp[0];
4826 operands[2] = branch_cmp[1];
4827
bb621ad7 4828 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
34b650b3
MM
4829 {
4830 gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
4831 DONE;
4832 }
4833
8ef30996
MM
4834 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
4835 operands[2] = force_reg (SImode, operands[2]);
4836
4837 /* fall through and generate default code */
4838}")
4839
4840(define_insn "sgtu_si"
4841 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4842 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8ef30996
MM
4843 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
4844 ""
4845 "sltu\\t%0,%z2,%1"
bb621ad7 4846 [(set_attr "type" "arith")
8ef30996
MM
4847 (set_attr "mode" "SI")
4848 (set_attr "length" "1")])
4849
bb621ad7
JW
4850(define_insn "sgtu_di"
4851 [(set (match_operand:DI 0 "register_operand" "=d")
4852 (gtu:DI (match_operand:DI 1 "register_operand" "d")
4853 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
4854 "TARGET_64BIT"
4855 "sltu\\t%0,%z2,%1"
4856 [(set_attr "type" "arith")
4857 (set_attr "mode" "DI")
4858 (set_attr "length" "1")])
4859
8ef30996
MM
4860(define_expand "sgeu"
4861 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4862 (geu:SI (match_dup 1)
8ef30996
MM
4863 (match_dup 2)))]
4864 ""
4865 "
4866{
bb621ad7 4867 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
4868 FAIL;
4869
4870 /* set up operands from compare. */
4871 operands[1] = branch_cmp[0];
4872 operands[2] = branch_cmp[1];
4873
bb621ad7 4874 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
34b650b3
MM
4875 {
4876 gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
4877 DONE;
4878 }
4879
8ef30996
MM
4880 /* fall through and generate default code */
4881}")
4882
4883(define_insn "sgeu_si"
4884 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4885 (geu:SI (match_operand:SI 1 "register_operand" "d")
8ef30996 4886 (match_operand:SI 2 "arith_operand" "dI")))]
bbdb5552 4887 "TARGET_DEBUG_C_MODE"
8ef30996 4888 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
bb621ad7 4889 [(set_attr "type" "arith")
8ef30996
MM
4890 (set_attr "mode" "SI")
4891 (set_attr "length" "2")])
4892
4893(define_split
4894 [(set (match_operand:SI 0 "register_operand" "")
34b650b3 4895 (geu:SI (match_operand:SI 1 "register_operand" "")
8ef30996 4896 (match_operand:SI 2 "arith_operand" "")))]
bbdb5552 4897 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
8ef30996 4898 [(set (match_dup 0)
34b650b3 4899 (ltu:SI (match_dup 1)
8ef30996
MM
4900 (match_dup 2)))
4901 (set (match_dup 0)
4902 (xor:SI (match_dup 0)
4903 (const_int 1)))]
4904 "")
4905
bb621ad7
JW
4906(define_insn "sgeu_di"
4907 [(set (match_operand:DI 0 "register_operand" "=d")
4908 (geu:DI (match_operand:DI 1 "register_operand" "d")
4909 (match_operand:DI 2 "arith_operand" "dI")))]
4910 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
4911 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
4912 [(set_attr "type" "arith")
4913 (set_attr "mode" "DI")
4914 (set_attr "length" "2")])
4915
4916(define_split
4917 [(set (match_operand:DI 0 "register_operand" "")
4918 (geu:DI (match_operand:DI 1 "register_operand" "")
4919 (match_operand:DI 2 "arith_operand" "")))]
4920 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
4921 [(set (match_dup 0)
4922 (ltu:DI (match_dup 1)
4923 (match_dup 2)))
4924 (set (match_dup 0)
4925 (xor:DI (match_dup 0)
4926 (const_int 1)))]
4927 "")
4928
8ef30996
MM
4929(define_expand "sltu"
4930 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4931 (ltu:SI (match_dup 1)
8ef30996
MM
4932 (match_dup 2)))]
4933 ""
4934 "
4935{
bb621ad7 4936 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
4937 FAIL;
4938
4939 /* set up operands from compare. */
4940 operands[1] = branch_cmp[0];
4941 operands[2] = branch_cmp[1];
4942
bb621ad7 4943 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
34b650b3
MM
4944 {
4945 gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
4946 DONE;
4947 }
4948
8ef30996
MM
4949 /* fall through and generate default code */
4950}")
4951
4952(define_insn "sltu_si"
4953 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4954 (ltu:SI (match_operand:SI 1 "register_operand" "d")
8ef30996
MM
4955 (match_operand:SI 2 "arith_operand" "dI")))]
4956 ""
4957 "sltu\\t%0,%1,%2"
bb621ad7 4958 [(set_attr "type" "arith")
8ef30996
MM
4959 (set_attr "mode" "SI")
4960 (set_attr "length" "1")])
4961
bb621ad7
JW
4962(define_insn "sltu_di"
4963 [(set (match_operand:DI 0 "register_operand" "=d")
4964 (ltu:DI (match_operand:DI 1 "register_operand" "d")
4965 (match_operand:DI 2 "arith_operand" "dI")))]
4966 "TARGET_64BIT"
4967 "sltu\\t%0,%1,%2"
4968 [(set_attr "type" "arith")
4969 (set_attr "mode" "DI")
4970 (set_attr "length" "1")])
4971
8ef30996
MM
4972(define_expand "sleu"
4973 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 4974 (leu:SI (match_dup 1)
8ef30996
MM
4975 (match_dup 2)))]
4976 ""
4977 "
4978{
bb621ad7 4979 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
4980 FAIL;
4981
4982 /* set up operands from compare. */
4983 operands[1] = branch_cmp[0];
4984 operands[2] = branch_cmp[1];
4985
bb621ad7 4986 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
34b650b3
MM
4987 {
4988 gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
4989 DONE;
4990 }
4991
8ef30996
MM
4992 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
4993 operands[2] = force_reg (SImode, operands[2]);
4994
4995 /* fall through and generate default code */
4996}")
4997
34b650b3
MM
4998(define_insn "sleu_si_const"
4999 [(set (match_operand:SI 0 "register_operand" "=d")
5000 (leu:SI (match_operand:SI 1 "register_operand" "d")
5001 (match_operand:SI 2 "small_int" "I")))]
5002 "INTVAL (operands[2]) < 32767"
5003 "*
5004{
5005 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
5006 return \"sltu\\t%0,%1,%2\";
5007}"
bb621ad7 5008 [(set_attr "type" "arith")
34b650b3
MM
5009 (set_attr "mode" "SI")
5010 (set_attr "length" "1")])
5011
bb621ad7
JW
5012(define_insn "sleu_di_const"
5013 [(set (match_operand:DI 0 "register_operand" "=d")
5014 (leu:DI (match_operand:DI 1 "register_operand" "d")
5015 (match_operand:DI 2 "small_int" "I")))]
5016 "TARGET_64BIT && INTVAL (operands[2]) < 32767"
5017 "*
5018{
5019 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
5020 return \"sltu\\t%0,%1,%2\";
5021}"
5022 [(set_attr "type" "arith")
5023 (set_attr "mode" "DI")
5024 (set_attr "length" "1")])
5025
34b650b3
MM
5026(define_insn "sleu_si_reg"
5027 [(set (match_operand:SI 0 "register_operand" "=d")
5028 (leu:SI (match_operand:SI 1 "register_operand" "d")
5029 (match_operand:SI 2 "register_operand" "d")))]
bbdb5552 5030 "TARGET_DEBUG_C_MODE"
34b650b3 5031 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
bb621ad7 5032 [(set_attr "type" "arith")
34b650b3
MM
5033 (set_attr "mode" "SI")
5034 (set_attr "length" "2")])
8ef30996
MM
5035
5036(define_split
5037 [(set (match_operand:SI 0 "register_operand" "")
34b650b3 5038 (leu:SI (match_operand:SI 1 "register_operand" "")
8ef30996 5039 (match_operand:SI 2 "register_operand" "")))]
bbdb5552 5040 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
8ef30996 5041 [(set (match_dup 0)
34b650b3 5042 (ltu:SI (match_dup 2)
8ef30996
MM
5043 (match_dup 1)))
5044 (set (match_dup 0)
5045 (xor:SI (match_dup 0)
5046 (const_int 1)))]
5047 "")
5048
bb621ad7
JW
5049(define_insn "sleu_di_reg"
5050 [(set (match_operand:DI 0 "register_operand" "=d")
5051 (leu:DI (match_operand:DI 1 "register_operand" "d")
5052 (match_operand:DI 2 "register_operand" "d")))]
5053 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5054 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
5055 [(set_attr "type" "arith")
5056 (set_attr "mode" "DI")
5057 (set_attr "length" "2")])
5058
5059(define_split
5060 [(set (match_operand:DI 0 "register_operand" "")
5061 (leu:DI (match_operand:DI 1 "register_operand" "")
5062 (match_operand:DI 2 "register_operand" "")))]
5063 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5064 [(set (match_dup 0)
5065 (ltu:DI (match_dup 2)
5066 (match_dup 1)))
5067 (set (match_dup 0)
5068 (xor:DI (match_dup 0)
5069 (const_int 1)))]
5070 "")
5071
34b650b3
MM
5072\f
5073;;
5074;; ....................
5075;;
5076;; FLOATING POINT COMPARISONS
5077;;
5078;; ....................
5079
5080(define_insn "seq_df"
5081 [(set (reg:CC_FP 66)
5082 (eq:CC_FP (match_operand:DF 0 "register_operand" "f")
5083 (match_operand:DF 1 "register_operand" "f")))]
bb621ad7 5084 "TARGET_HARD_FLOAT"
34b650b3
MM
5085 "*
5086{
5087 rtx xoperands[10];
5088 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5089 xoperands[1] = operands[0];
5090 xoperands[2] = operands[1];
5091
5092 return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5093}"
5094 [(set_attr "type" "fcmp")
5095 (set_attr "mode" "FPSW")
5096 (set_attr "length" "1")])
5097
5098(define_insn "sne_df"
5099 [(set (reg:CC_REV_FP 66)
5100 (ne:CC_REV_FP (match_operand:DF 0 "register_operand" "f")
5101 (match_operand:DF 1 "register_operand" "f")))]
bb621ad7 5102 "TARGET_HARD_FLOAT"
34b650b3
MM
5103 "*
5104{
5105 rtx xoperands[10];
5106 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5107 xoperands[1] = operands[0];
5108 xoperands[2] = operands[1];
5109
5110 return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5111}"
5112 [(set_attr "type" "fcmp")
5113 (set_attr "mode" "FPSW")
5114 (set_attr "length" "1")])
5115
5116(define_insn "slt_df"
5117 [(set (reg:CC_FP 66)
5118 (lt:CC_FP (match_operand:DF 0 "register_operand" "f")
5119 (match_operand:DF 1 "register_operand" "f")))]
bb621ad7 5120 "TARGET_HARD_FLOAT"
34b650b3
MM
5121 "*
5122{
5123 rtx xoperands[10];
5124 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5125 xoperands[1] = operands[0];
5126 xoperands[2] = operands[1];
5127
5128 return mips_fill_delay_slot (\"c.lt.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5129}"
5130 [(set_attr "type" "fcmp")
5131 (set_attr "mode" "FPSW")
5132 (set_attr "length" "1")])
5133
5134(define_insn "sle_df"
5135 [(set (reg:CC_FP 66)
5136 (le:CC_FP (match_operand:DF 0 "register_operand" "f")
5137 (match_operand:DF 1 "register_operand" "f")))]
bb621ad7 5138 "TARGET_HARD_FLOAT"
34b650b3
MM
5139 "*
5140{
5141 rtx xoperands[10];
5142 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5143 xoperands[1] = operands[0];
5144 xoperands[2] = operands[1];
5145
5146 return mips_fill_delay_slot (\"c.le.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5147}"
5148 [(set_attr "type" "fcmp")
5149 (set_attr "mode" "FPSW")
5150 (set_attr "length" "1")])
5151
5152(define_insn "sgt_df"
5153 [(set (reg:CC_FP 66)
5154 (gt:CC_FP (match_operand:DF 0 "register_operand" "f")
5155 (match_operand:DF 1 "register_operand" "f")))]
bb621ad7 5156 "TARGET_HARD_FLOAT"
34b650b3
MM
5157 "*
5158{
5159 rtx xoperands[10];
5160 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5161 xoperands[1] = operands[0];
5162 xoperands[2] = operands[1];
5163
5164 return mips_fill_delay_slot (\"c.lt.d\\t%1,%0\", DELAY_FCMP, xoperands, insn);
5165}"
5166 [(set_attr "type" "fcmp")
5167 (set_attr "mode" "FPSW")
5168 (set_attr "length" "1")])
5169
5170(define_insn "sge_df"
5171 [(set (reg:CC_FP 66)
5172 (ge:CC_FP (match_operand:DF 0 "register_operand" "f")
5173 (match_operand:DF 1 "register_operand" "f")))]
bb621ad7 5174 "TARGET_HARD_FLOAT"
34b650b3
MM
5175 "*
5176{
5177 rtx xoperands[10];
5178 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5179 xoperands[1] = operands[0];
5180 xoperands[2] = operands[1];
5181
5182 return mips_fill_delay_slot (\"c.le.d\\t%1,%0\", DELAY_FCMP, xoperands, insn);
5183}"
5184 [(set_attr "type" "fcmp")
5185 (set_attr "mode" "FPSW")
5186 (set_attr "length" "1")])
5187
5188(define_insn "seq_sf"
5189 [(set (reg:CC_FP 66)
5190 (eq:CC_FP (match_operand:SF 0 "register_operand" "f")
5191 (match_operand:SF 1 "register_operand" "f")))]
bb621ad7 5192 "TARGET_HARD_FLOAT"
34b650b3
MM
5193 "*
5194{
5195 rtx xoperands[10];
5196 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5197 xoperands[1] = operands[0];
5198 xoperands[2] = operands[1];
5199
5200 return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5201}"
5202 [(set_attr "type" "fcmp")
5203 (set_attr "mode" "FPSW")
5204 (set_attr "length" "1")])
5205
5206(define_insn "sne_sf"
5207 [(set (reg:CC_REV_FP 66)
5208 (ne:CC_REV_FP (match_operand:SF 0 "register_operand" "f")
5209 (match_operand:SF 1 "register_operand" "f")))]
bb621ad7 5210 "TARGET_HARD_FLOAT"
34b650b3
MM
5211 "*
5212{
5213 rtx xoperands[10];
5214 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5215 xoperands[1] = operands[0];
5216 xoperands[2] = operands[1];
5217
5218 return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5219}"
5220 [(set_attr "type" "fcmp")
5221 (set_attr "mode" "FPSW")
5222 (set_attr "length" "1")])
5223
5224(define_insn "slt_sf"
5225 [(set (reg:CC_FP 66)
5226 (lt:CC_FP (match_operand:SF 0 "register_operand" "f")
5227 (match_operand:SF 1 "register_operand" "f")))]
bb621ad7 5228 "TARGET_HARD_FLOAT"
34b650b3
MM
5229 "*
5230{
5231 rtx xoperands[10];
5232 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5233 xoperands[1] = operands[0];
5234 xoperands[2] = operands[1];
5235
5236 return mips_fill_delay_slot (\"c.lt.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5237}"
5238 [(set_attr "type" "fcmp")
5239 (set_attr "mode" "FPSW")
5240 (set_attr "length" "1")])
5241
5242(define_insn "sle_sf"
5243 [(set (reg:CC_FP 66)
5244 (le:CC_FP (match_operand:SF 0 "register_operand" "f")
5245 (match_operand:SF 1 "register_operand" "f")))]
bb621ad7 5246 "TARGET_HARD_FLOAT"
34b650b3
MM
5247 "*
5248{
5249 rtx xoperands[10];
5250 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5251 xoperands[1] = operands[0];
5252 xoperands[2] = operands[1];
5253
5254 return mips_fill_delay_slot (\"c.le.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
5255}"
5256 [(set_attr "type" "fcmp")
5257 (set_attr "mode" "FPSW")
5258 (set_attr "length" "1")])
5259
5260(define_insn "sgt_sf"
5261 [(set (reg:CC_FP 66)
5262 (gt:CC_FP (match_operand:SF 0 "register_operand" "f")
5263 (match_operand:SF 1 "register_operand" "f")))]
bb621ad7 5264 "TARGET_HARD_FLOAT"
34b650b3
MM
5265 "*
5266{
5267 rtx xoperands[10];
5268 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5269 xoperands[1] = operands[0];
5270 xoperands[2] = operands[1];
5271
5272 return mips_fill_delay_slot (\"c.lt.s\\t%1,%0\", DELAY_FCMP, xoperands, insn);
5273}"
5274 [(set_attr "type" "fcmp")
5275 (set_attr "mode" "FPSW")
5276 (set_attr "length" "1")])
5277
5278(define_insn "sge_sf"
5279 [(set (reg:CC_FP 66)
5280 (ge:CC_FP (match_operand:SF 0 "register_operand" "f")
5281 (match_operand:SF 1 "register_operand" "f")))]
bb621ad7 5282 "TARGET_HARD_FLOAT"
34b650b3
MM
5283 "*
5284{
5285 rtx xoperands[10];
5286 xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
5287 xoperands[1] = operands[0];
5288 xoperands[2] = operands[1];
5289
5290 return mips_fill_delay_slot (\"c.le.s\\t%1,%0\", DELAY_FCMP, xoperands, insn);
5291}"
5292 [(set_attr "type" "fcmp")
5293 (set_attr "mode" "FPSW")
5294 (set_attr "length" "1")])
5295
8ef30996
MM
5296\f
5297;;
5298;; ....................
5299;;
5300;; UNCONDITIONAL BRANCHES
5301;;
5302;; ....................
5303
5304;; Unconditional branches.
5305
5306(define_insn "jump"
5307 [(set (pc)
5308 (label_ref (match_operand 0 "" "")))]
5309 ""
5310 "*
5311{
5312 if (GET_CODE (operands[0]) == REG)
5313 return \"%*j\\t%0\";
5314 else
5315 return \"%*j\\t%l0\";
5316}"
5317 [(set_attr "type" "jump")
5318 (set_attr "mode" "none")
5319 (set_attr "length" "1")])
5320
bb621ad7
JW
5321(define_expand "indirect_jump"
5322 [(set (pc) (match_operand 0 "register_operand" "d"))]
8ef30996 5323 ""
bb621ad7
JW
5324 "
5325{
5326 rtx dest;
5327
5328 if (operands[0]) /* eliminate unused code warnings */
5329 {
5330 dest = operands[0];
5331 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
5332 operands[0] = copy_to_mode_reg (Pmode, dest);
5333
5334 if (!TARGET_LONG64)
5335 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
5336 else
5337 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
5338
5339 DONE;
5340 }
5341}")
5342
5343(define_insn "indirect_jump_internal1"
5344 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
5345 "!TARGET_LONG64"
5346 "%*j\\t%0"
5347 [(set_attr "type" "jump")
5348 (set_attr "mode" "none")
5349 (set_attr "length" "1")])
5350
5351(define_insn "indirect_jump_internal2"
5352 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
5353 "TARGET_LONG64"
8ef30996
MM
5354 "%*j\\t%0"
5355 [(set_attr "type" "jump")
5356 (set_attr "mode" "none")
5357 (set_attr "length" "1")])
5358
bb621ad7 5359(define_expand "tablejump"
8ef30996 5360 [(set (pc)
bb621ad7 5361 (match_operand 0 "register_operand" "d"))
8ef30996
MM
5362 (use (label_ref (match_operand 1 "" "")))]
5363 ""
bb621ad7
JW
5364 "
5365{
5366 rtx dest;
5367
5368 if (operands[0]) /* eliminate unused code warnings */
5369 {
5370 if (GET_MODE (operands[0]) != Pmode)
5371 abort ();
5372
5373 if (!TARGET_LONG64)
5374 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
5375 else
5376 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
5377
5378 DONE;
5379 }
5380}")
5381
5382(define_insn "tablejump_internal1"
5383 [(set (pc)
5384 (match_operand:SI 0 "register_operand" "d"))
5385 (use (label_ref (match_operand 1 "" "")))]
5386 "!TARGET_LONG64"
5a5b76a2
JW
5387 "*
5388{
5389 /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
5390 if (TARGET_ABICALLS)
5391 output_asm_insn (\".cpadd\\t%0\", operands);
5392 return \"%*j\\t%0\";
5393}"
bb621ad7
JW
5394 [(set_attr "type" "jump")
5395 (set_attr "mode" "none")
5a5b76a2
JW
5396 (set (attr "length")
5397 (if_then_else (eq_attr "abicalls" "yes")
5398 (const_int 2)
5399 (const_int 1)))])
bb621ad7
JW
5400
5401(define_insn "tablejump_internal2"
5402 [(set (pc)
5403 (match_operand:DI 0 "register_operand" "d"))
5404 (use (label_ref (match_operand 1 "" "")))]
5405 "TARGET_LONG64"
5a5b76a2
JW
5406 "*
5407{
5408 /* .cpdadd expands to dadd REG,REG,$gp when pic, and nothing when not pic. */
5409 if (TARGET_ABICALLS)
5410 output_asm_insn (\".cpdadd\\t%0\", operands);
5411 return \"%*j\\t%0\";
5412}"
8ef30996
MM
5413 [(set_attr "type" "jump")
5414 (set_attr "mode" "none")
5a5b76a2
JW
5415 (set (attr "length")
5416 (if_then_else (eq_attr "abicalls" "yes")
5417 (const_int 2)
5418 (const_int 1)))])
8ef30996
MM
5419
5420;; Function return, only allow after optimization, so that we can
5421;; eliminate jumps to jumps if no stack space is used.
5422
0fb5ac6f
MM
5423;; (define_expand "return"
5424;; [(set (pc) (reg:SI 31))]
5425;; "simple_epilogue_p ()"
5426;; "")
5427
5428(define_expand "return"
5429 [(parallel [(return)
5430 (use (reg:SI 31))])]
5431 "simple_epilogue_p ()"
5432 "")
5433
5434(define_insn "return_internal"
5435 [(parallel [(return)
5436 (use (match_operand:SI 0 "register_operand" "d"))])]
5437 ""
5438 "%*j\\t%0"
8ef30996
MM
5439 [(set_attr "type" "jump")
5440 (set_attr "mode" "none")
5441 (set_attr "length" "1")])
5442
e0bfcea5
ILT
5443;; Implement a switch statement when generating embedded PIC code.
5444;; Switches are implemented by `tablejump' when not using -membedded-pic.
5445
5446(define_expand "casesi"
5447 [(set (match_dup 5)
5448 (minus:SI (match_operand:SI 0 "register_operand" "d")
5449 (match_operand:SI 1 "arith_operand" "dI")))
5450 (set (cc0)
5451 (compare:CC (match_dup 5)
5452 (match_operand:SI 2 "arith_operand" "")))
5453 (set (pc)
5454 (if_then_else (gtu (cc0)
5455 (const_int 0))
5456 (label_ref (match_operand 4 "" ""))
5457 (pc)))
5458 (parallel
5459 [(set (pc)
5460 (mem:SI (plus:SI (mult:SI (match_dup 5)
5461 (const_int 4))
5462 (label_ref (match_operand 3 "" "")))))
5463 (clobber (match_scratch:SI 6 ""))
5464 (clobber (reg:SI 31))])]
5465 "TARGET_EMBEDDED_PIC"
5466 "
5467{
5468 /* We need slightly different code for eight byte table entries. */
5469 if (TARGET_LONG64)
5470 abort ();
5471
5472 if (operands[0])
5473 {
5474 rtx reg = gen_reg_rtx (SImode);
5475
e0bfcea5
ILT
5476 /* If the index is too large, go to the default label. */
5477 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
5478 emit_insn (gen_cmpsi (reg, operands[2]));
5479 emit_insn (gen_bgtu (operands[4]));
5480
5481 /* Do the PIC jump. */
5482 emit_insn (gen_casesi_internal (reg, operands[3], gen_reg_rtx (SImode)));
5483
5484 DONE;
5485 }
5486}")
5487
5488;; An embedded PIC switch statement looks like this:
5489;; bal $LS1
5490;; sll $reg,$index,2
5491;; $LS1:
5492;; addu $reg,$reg,$31
5493;; lw $reg,$L1-$LS1($reg)
5494;; addu $reg,$reg,$31
5495;; j $reg
5496;; $L1:
5497;; .word case1-$LS1
5498;; .word case2-$LS1
5499;; ...
5500
5501(define_insn "casesi_internal"
5502 [(set (pc)
5503 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
5504 (const_int 4))
5505 (label_ref (match_operand 1 "" "")))))
5506 (clobber (match_operand:SI 2 "register_operand" "d"))
5507 (clobber (reg:SI 31))]
5508 "TARGET_EMBEDDED_PIC"
5509 "*
5510{
5511 output_asm_insn (\"%(bal\\t%S1\;sll\\t%0,2\\n%S1:\", operands);
5512 output_asm_insn (\"addu\\t%0,%0,$31%)\", operands);
5513 output_asm_insn (\"lw\\t%0,%1-%S1(%0)\;addu\\t%0,%0,$31\", operands);
5514 return \"j\\t%0\";
5515}"
5516 [(set_attr "type" "jump")
5517 (set_attr "mode" "none")
5518 (set_attr "length" "6")])
5519
0fb5ac6f
MM
5520\f
5521;;
5522;; ....................
5523;;
5524;; Function prologue/epilogue
5525;;
5526;; ....................
5527;;
5528
5529(define_expand "prologue"
5530 [(const_int 1)]
5531 ""
5532 "
5533{
5534 if (mips_isa >= 0) /* avoid unused code warnings */
5535 {
5536 mips_expand_prologue ();
5537 DONE;
5538 }
5539}")
5540
d8d5b1e1
MM
5541;; Block any insns from being moved before this point, since the
5542;; profiling call to mcount can use various registers that aren't
5543;; saved or used to pass arguments.
5544
5545(define_insn "blockage"
5546 [(unspec_volatile [(const_int 0)] 0)]
5547 ""
5548 ""
5549 [(set_attr "type" "unknown")
5550 (set_attr "mode" "none")
5551 (set_attr "length" "0")])
5552
0fb5ac6f
MM
5553;; At present, don't expand the epilogue, reorg.c will clobber the
5554;; return register in compiling gen_lowpart (emit-rtl.c).
5555;;
5556;; (define_expand "epilogue"
5557;; [(const_int 2)]
5558;; ""
5559;; "
5560;; {
5561;; if (mips_isa >= 0) /* avoid unused code warnings */
5562;; {
5563;; mips_expand_epilogue ();
5564;; DONE;
5565;; }
5566;; }")
5567
92544bdf
ILT
5568;; When generating embedded PIC code we need to get the address of the
5569;; current function. This specialized instruction does just that.
5570
5571(define_insn "get_fnaddr"
5572 [(set (match_operand 0 "register_operand" "d")
5573 (unspec [(match_operand 1 "" "")] 1))
5574 (clobber (reg:SI 31))]
5575 "TARGET_EMBEDDED_PIC
5576 && GET_CODE (operands[1]) == SYMBOL_REF"
5577 "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
5578 [(set_attr "type" "call")
5579 (set_attr "mode" "none")
5580 (set_attr "length" "4")])
5581
8ef30996
MM
5582\f
5583;;
5584;; ....................
5585;;
5586;; FUNCTION CALLS
5587;;
5588;; ....................
5589
5590;; calls.c now passes a third argument, make saber happy
5591
5592(define_expand "call"
af4a697f 5593 [(parallel [(call (match_operand 0 "memory_operand" "m")
8ef30996 5594 (match_operand 1 "" "i"))
3f1f8d8c
MM
5595 (clobber (reg:SI 31))
5596 (use (match_operand 2 "" "")) ;; next_arg_reg
5597 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
8ef30996
MM
5598 ""
5599 "
5600{
5601 rtx addr;
5602
3f1f8d8c
MM
5603 if (operands[0]) /* eliminate unused code warnings */
5604 {
5605 addr = XEXP (operands[0], 0);
322dce45
RS
5606 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
5607 || ! call_insn_operand (operands[0], VOIDmode))
5608 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
3f1f8d8c
MM
5609
5610 /* In order to pass small structures by value in registers
5611 compatibly with the MIPS compiler, we need to shift the value
5612 into the high part of the register. Function_arg has encoded
5613 a PARALLEL rtx, holding a vector of adjustments to be made
5614 as the next_arg_reg variable, so we split up the insns,
5615 and emit them separately. */
5616
5617 if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
5618 {
5619 rtvec adjust = XVEC (operands[2], 0);
5620 int num = GET_NUM_ELEM (adjust);
5621 int i;
5622
5623 for (i = 0; i < num; i++)
5624 emit_insn (RTVEC_ELT (adjust, i));
5625 }
8ef30996 5626
d1399bd0 5627 emit_call_insn (gen_call_internal1 (operands[0], operands[1],
bb621ad7 5628 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
3f1f8d8c
MM
5629 DONE;
5630 }
8ef30996
MM
5631}")
5632
d1399bd0 5633(define_insn "call_internal1"
322dce45 5634 [(call (match_operand 0 "call_insn_operand" "m")
8ef30996
MM
5635 (match_operand 1 "" "i"))
5636 (clobber (match_operand:SI 2 "register_operand" "=d"))]
84a92af4 5637 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
8ef30996
MM
5638 "*
5639{
5640 register rtx target = XEXP (operands[0], 0);
5641
5642 if (GET_CODE (target) == SYMBOL_REF)
5643 return \"%*jal\\t%0\";
5644
2bba3a75
MM
5645 else if (GET_CODE (target) == CONST_INT)
5646 {
5647 operands[0] = target;
3f1f8d8c 5648 return \"%*%[li\\t%@,%0\\n\\tjal\\t%2,%@%]\";
2bba3a75
MM
5649 }
5650
8ef30996
MM
5651 else
5652 {
5653 operands[0] = target;
3f1f8d8c 5654 return \"%*jal\\t%2,%0\";
8ef30996
MM
5655 }
5656}"
5657 [(set_attr "type" "call")
5658 (set_attr "mode" "none")
5659 (set_attr "length" "1")])
5660
d1399bd0 5661(define_insn "call_internal2"
84a92af4
JW
5662 [(call (match_operand 0 "call_insn_operand" "m")
5663 (match_operand 1 "" "i"))
5664 (clobber (match_operand:SI 2 "register_operand" "=d"))]
5665 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
5666 "*
5667{
5668 register rtx target = XEXP (operands[0], 0);
5669
5670 if (GET_CODE (target) == SYMBOL_REF)
5671 return \"jal\\t%0\";
5672
5673 else if (GET_CODE (target) == CONST_INT)
5674 {
5675 operands[0] = target;
5676 return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
5677 }
5678
5679 else
5680 {
5681 operands[0] = target;
5682 if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
5683 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
5684 else
5685 return \"jal\\t%2,%0\";
5686 }
5687}"
5688 [(set_attr "type" "call")
5689 (set_attr "mode" "none")
5690 (set_attr "length" "2")])
5691
bb621ad7 5692(define_insn "call_internal3a"
d1399bd0
MM
5693 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
5694 (match_operand 1 "" "i"))
5695 (clobber (match_operand:SI 2 "register_operand" "=d"))]
bb621ad7
JW
5696 "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
5697 "%*jal\\t%2,%0"
5698 [(set_attr "type" "call")
5699 (set_attr "mode" "none")
5700 (set_attr "length" "1")])
5701
5702(define_insn "call_internal3b"
5703 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
5704 (match_operand 1 "" "i"))
5705 (clobber (match_operand:SI 2 "register_operand" "=d"))]
5706 "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
d1399bd0
MM
5707 "%*jal\\t%2,%0"
5708 [(set_attr "type" "call")
5709 (set_attr "mode" "none")
5710 (set_attr "length" "1")])
5711
bb621ad7 5712(define_insn "call_internal4a"
84a92af4
JW
5713 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
5714 (match_operand 1 "" "i"))
5715 (clobber (match_operand:SI 2 "register_operand" "=d"))]
bb621ad7 5716 "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
84a92af4
JW
5717 "*
5718{
5719 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
5720 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
5721 else
5722 return \"jal\\t%2,%0\";
5723}"
5724 [(set_attr "type" "call")
5725 (set_attr "mode" "none")
5726 (set_attr "length" "2")])
5727
bb621ad7
JW
5728(define_insn "call_internal4b"
5729 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
5730 (match_operand 1 "" "i"))
5731 (clobber (match_operand:SI 2 "register_operand" "=d"))]
5732 "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
5733 "*
5734{
5735 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
5736 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
5737 else
5738 return \"jal\\t%2,%0\";
5739}"
5740 [(set_attr "type" "call")
5741 (set_attr "mode" "none")
5742 (set_attr "length" "2")])
d1399bd0 5743
8ef30996
MM
5744;; calls.c now passes a fourth argument, make saber happy
5745
5746(define_expand "call_value"
5747 [(parallel [(set (match_operand 0 "register_operand" "=df")
af4a697f 5748 (call (match_operand 1 "memory_operand" "m")
8ef30996 5749 (match_operand 2 "" "i")))
3f1f8d8c
MM
5750 (clobber (reg:SI 31))
5751 (use (match_operand 3 "" ""))])] ;; next_arg_reg
8ef30996
MM
5752 ""
5753 "
5754{
5755 rtx addr;
5756
3f1f8d8c
MM
5757 if (operands[0]) /* eliminate unused code warning */
5758 {
5759 addr = XEXP (operands[1], 0);
322dce45
RS
5760 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
5761 || ! call_insn_operand (operands[1], VOIDmode))
5762 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
3f1f8d8c
MM
5763
5764 /* In order to pass small structures by value in registers
5765 compatibly with the MIPS compiler, we need to shift the value
5766 into the high part of the register. Function_arg has encoded
5767 a PARALLEL rtx, holding a vector of adjustments to be made
5768 as the next_arg_reg variable, so we split up the insns,
5769 and emit them separately. */
5770
5771 if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
5772 {
5773 rtvec adjust = XVEC (operands[3], 0);
5774 int num = GET_NUM_ELEM (adjust);
5775 int i;
5776
5777 for (i = 0; i < num; i++)
5778 emit_insn (RTVEC_ELT (adjust, i));
5779 }
5780
d1399bd0 5781 emit_call_insn (gen_call_value_internal1 (operands[0], operands[1], operands[2],
bb621ad7 5782 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
3f1f8d8c
MM
5783
5784 DONE;
5785 }
8ef30996 5786
8ef30996
MM
5787}")
5788
d1399bd0 5789(define_insn "call_value_internal1"
8ef30996 5790 [(set (match_operand 0 "register_operand" "=df")
322dce45 5791 (call (match_operand 1 "call_insn_operand" "m")
8ef30996
MM
5792 (match_operand 2 "" "i")))
5793 (clobber (match_operand:SI 3 "register_operand" "=d"))]
84a92af4 5794 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
8ef30996
MM
5795 "*
5796{
5797 register rtx target = XEXP (operands[1], 0);
5798
5799 if (GET_CODE (target) == SYMBOL_REF)
5800 return \"%*jal\\t%1\";
5801
2bba3a75
MM
5802 else if (GET_CODE (target) == CONST_INT)
5803 {
5804 operands[1] = target;
3f1f8d8c 5805 return \"%*%[li\\t%@,%1\\n\\tjal\\t%3,%@%]\";
2bba3a75
MM
5806 }
5807
8ef30996
MM
5808 else
5809 {
5810 operands[1] = target;
3f1f8d8c 5811 return \"%*jal\\t%3,%1\";
8ef30996
MM
5812 }
5813}"
5814 [(set_attr "type" "call")
5815 (set_attr "mode" "none")
5816 (set_attr "length" "1")])
5817
d1399bd0 5818(define_insn "call_value_internal2"
84a92af4
JW
5819 [(set (match_operand 0 "register_operand" "=df")
5820 (call (match_operand 1 "call_insn_operand" "m")
5821 (match_operand 2 "" "i")))
5822 (clobber (match_operand:SI 3 "register_operand" "=d"))]
5823 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
5824 "*
5825{
5826 register rtx target = XEXP (operands[1], 0);
5827
5828 if (GET_CODE (target) == SYMBOL_REF)
5829 return \"jal\\t%1\";
5830
5831 else if (GET_CODE (target) == CONST_INT)
5832 {
5833 operands[1] = target;
5834 return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
5835 }
5836
5837 else
5838 {
5839 operands[1] = target;
5840 if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
5841 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
5842 else
5843 return \"jal\\t%3,%1\";
5844 }
5845}"
5846 [(set_attr "type" "call")
5847 (set_attr "mode" "none")
5848 (set_attr "length" "2")])
5849
bb621ad7 5850(define_insn "call_value_internal3a"
d1399bd0
MM
5851 [(set (match_operand 0 "register_operand" "=df")
5852 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
5853 (match_operand 2 "" "i")))
5854 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7
JW
5855 "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
5856 "%*jal\\t%3,%1"
5857 [(set_attr "type" "call")
5858 (set_attr "mode" "none")
5859 (set_attr "length" "1")])
5860
5861(define_insn "call_value_internal3b"
5862 [(set (match_operand 0 "register_operand" "=df")
5863 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
5864 (match_operand 2 "" "i")))
5865 (clobber (match_operand:SI 3 "register_operand" "=d"))]
5866 "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
d1399bd0
MM
5867 "%*jal\\t%3,%1"
5868 [(set_attr "type" "call")
5869 (set_attr "mode" "none")
5870 (set_attr "length" "1")])
5871
bb621ad7 5872(define_insn "call_value_internal4a"
84a92af4
JW
5873 [(set (match_operand 0 "register_operand" "=df")
5874 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
5875 (match_operand 2 "" "i")))
5876 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7
JW
5877 "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
5878 "*
5879{
5880 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
5881 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
5882 else
5883 return \"jal\\t%3,%1\";
5884}"
5885 [(set_attr "type" "call")
5886 (set_attr "mode" "none")
5887 (set_attr "length" "2")])
5888
5889(define_insn "call_value_internal4b"
5890 [(set (match_operand 0 "register_operand" "=df")
5891 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
5892 (match_operand 2 "" "i")))
5893 (clobber (match_operand:SI 3 "register_operand" "=d"))]
5894 "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
84a92af4
JW
5895 "*
5896{
5897 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
5898 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
5899 else
5900 return \"jal\\t%3,%1\";
5901}"
5902 [(set_attr "type" "call")
5903 (set_attr "mode" "none")
5904 (set_attr "length" "2")])
5905
a93821e9
TW
5906;; Call subroutine returning any type.
5907
5908(define_expand "untyped_call"
5909 [(parallel [(call (match_operand 0 "" "")
5910 (const_int 0))
5911 (match_operand 1 "" "")
5912 (match_operand 2 "" "")])]
5913 ""
5914 "
5915{
740b4585 5916 if (operands[0]) /* silence statement not reached warnings */
a93821e9 5917 {
740b4585
MM
5918 int i;
5919
5920 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
a93821e9 5921
740b4585
MM
5922 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5923 {
5924 rtx set = XVECEXP (operands[2], 0, i);
5925 emit_move_insn (SET_DEST (set), SET_SRC (set));
5926 }
a93821e9 5927
740b4585
MM
5928 emit_insn (gen_blockage ());
5929 DONE;
5930 }
a93821e9 5931}")
8ef30996
MM
5932\f
5933;;
5934;; ....................
5935;;
5936;; MISC.
5937;;
5938;; ....................
5939;;
5940
5941(define_insn "nop"
5942 [(const_int 0)]
5943 ""
5944 "%(nop%)"
5945 [(set_attr "type" "nop")
5946 (set_attr "mode" "none")
5947 (set_attr "length" "1")])
5948
5949(define_expand "probe"
5950 [(set (match_dup 0)
5951 (match_dup 1))]
5952 ""
5953 "
5954{
5955 operands[0] = gen_reg_rtx (SImode);
5956 operands[1] = gen_rtx (MEM, SImode, stack_pointer_rtx);
5957 MEM_VOLATILE_P (operands[1]) = TRUE;
5958
5959 /* fall through and generate default code */
5960}")
This page took 0.918842 seconds and 5 git commands to generate.