]>
Commit | Line | Data |
---|---|---|
8ef30996 | 1 | ;; Mips.md Machine Description for MIPS based processors |
214be03f | 2 | ;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, |
2d2a50c3 | 3 | ;; 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. |
8ef30996 MM |
4 | ;; Contributed by A. Lichnewsky, lich@inria.inria.fr |
5 | ;; Changes by Michael Meissner, meissner@osf.org | |
bb621ad7 JW |
6 | ;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and |
7 | ;; Brendan Eich, brendan@microunity.com. | |
8ef30996 MM |
8 | |
9 | ;; This file is part of GNU CC. | |
10 | ||
11 | ;; GNU CC is free software; you can redistribute it and/or modify | |
12 | ;; it under the terms of the GNU General Public License as published by | |
13 | ;; the Free Software Foundation; either version 2, or (at your option) | |
14 | ;; any later version. | |
15 | ||
16 | ;; GNU CC is distributed in the hope that it will be useful, | |
17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | ;; GNU General Public License for more details. | |
20 | ||
21 | ;; You should have received a copy of the GNU General Public License | |
22 | ;; along with GNU CC; see the file COPYING. If not, write to | |
3f63df56 RK |
23 | ;; the Free Software Foundation, 59 Temple Place - Suite 330, |
24 | ;; Boston, MA 02111-1307, USA. | |
8ef30996 | 25 | |
e19ff60f JW |
26 | ;; ??? Currently does not have define_function_unit support for the R8000. |
27 | ;; Must include new entries for fmadd in addition to existing entries. | |
28 | ||
41f8d041 | 29 | (define_constants |
cafe096b | 30 | [(UNSPEC_GET_FNADDR 4) |
41f8d041 RS |
31 | (UNSPEC_HILO_DELAY 5) |
32 | (UNSPEC_BLOCKAGE 6) | |
33 | (UNSPEC_LOADGP 7) | |
34 | (UNSPEC_SETJMP 8) | |
35 | (UNSPEC_LONGJMP 9) | |
36 | (UNSPEC_EH_RECEIVER 10) | |
37 | (UNSPEC_EH_RETURN 11) | |
38 | (UNSPEC_CONSTTABLE_QI 12) | |
39 | (UNSPEC_CONSTTABLE_HI 13) | |
40 | (UNSPEC_CONSTTABLE_SI 14) | |
41 | (UNSPEC_CONSTTABLE_DI 15) | |
42 | (UNSPEC_CONSTTABLE_SF 16) | |
43 | (UNSPEC_CONSTTABLE_DF 17) | |
44 | (UNSPEC_ALIGN_2 18) | |
45 | (UNSPEC_ALIGN_4 19) | |
cafe096b EC |
46 | (UNSPEC_ALIGN_8 20) |
47 | (UNSPEC_HIGH 22) | |
48 | (UNSPEC_LWL 23) | |
49 | (UNSPEC_LWR 24) | |
50 | (UNSPEC_SWL 25) | |
51 | (UNSPEC_SWR 26) | |
52 | (UNSPEC_LDL 27) | |
53 | (UNSPEC_LDR 28) | |
54 | (UNSPEC_SDL 29) | |
55 | (UNSPEC_SDR 30) | |
56 | ||
57 | ;; Constants used in relocation unspecs. RELOC_GOT_PAGE and RELOC_GOT_DISP | |
58 | ;; are really only available for n32 and n64. However, it is convenient | |
59 | ;; to reuse them for SVR4 PIC, where they represent the local and global | |
60 | ;; forms of R_MIPS_GOT16. | |
61 | (RELOC_GPREL16 100) | |
62 | (RELOC_GOT_HI 101) | |
63 | (RELOC_GOT_LO 102) | |
64 | (RELOC_GOT_PAGE 103) | |
65 | (RELOC_GOT_DISP 104) | |
66 | (RELOC_CALL16 105) | |
67 | (RELOC_CALL_HI 106) | |
68 | (RELOC_CALL_LO 107)]) | |
8ef30996 MM |
69 | \f |
70 | ||
71 | ;; .................... | |
72 | ;; | |
73 | ;; Attributes | |
74 | ;; | |
75 | ;; .................... | |
76 | ||
cafe096b EC |
77 | ;; For jal instructions, this attribute is DIRECT when the target address |
78 | ;; is symbolic and INDIRECT when it is a register. | |
79 | (define_attr "jal" "unset,direct,indirect" | |
80 | (const_string "unset")) | |
81 | ||
82 | ;; True for multi-instruction jal macros. jal is always a macro | |
83 | ;; in SVR4 PIC since it includes an instruction to restore $gp. | |
84 | ;; Direct jals are also macros in NewABI PIC since they load the | |
85 | ;; target address into $25. | |
86 | (define_attr "jal_macro" "no,yes" | |
87 | (cond [(eq_attr "jal" "direct") | |
88 | (symbol_ref "TARGET_ABICALLS != 0") | |
89 | (eq_attr "jal" "indirect") | |
90 | (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")] | |
91 | (const_string "no"))) | |
92 | ||
8ef30996 MM |
93 | ;; Classification of each insn. |
94 | ;; branch conditional branch | |
95 | ;; jump unconditional jump | |
96 | ;; call unconditional call | |
97 | ;; load load instruction(s) | |
98 | ;; store store instruction(s) | |
cafe096b | 99 | ;; prefetch memory prefetch |
8ef30996 MM |
100 | ;; move data movement within same register set |
101 | ;; xfer transfer to/from coprocessor | |
102 | ;; hilo transfer of hi/lo registers | |
103 | ;; arith integer arithmetic instruction | |
104 | ;; darith double precision integer arithmetic instructions | |
cafe096b | 105 | ;; const load constant |
8ef30996 | 106 | ;; imul integer multiply |
1d4047e0 | 107 | ;; imadd integer multiply-add |
8ef30996 MM |
108 | ;; idiv integer divide |
109 | ;; icmp integer compare | |
110 | ;; fadd floating point add/subtract | |
111 | ;; fmul floating point multiply | |
e19ff60f | 112 | ;; fmadd floating point multiply-add |
8ef30996 MM |
113 | ;; fdiv floating point divide |
114 | ;; fabs floating point absolute value | |
115 | ;; fneg floating point negation | |
116 | ;; fcmp floating point compare | |
117 | ;; fcvt floating point convert | |
118 | ;; fsqrt floating point square root | |
5ce6f47b | 119 | ;; frsqrt floating point reciprocal square root |
8ef30996 MM |
120 | ;; multi multiword sequence (or user asm statements) |
121 | ;; nop no operation | |
8ef30996 | 122 | (define_attr "type" |
cafe096b EC |
123 | "unknown,branch,jump,call,load,store,prefetch,move,xfer,hilo,const,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop" |
124 | (cond [(eq_attr "jal" "!unset") | |
125 | (const_string "call")] | |
126 | (const_string "unknown"))) | |
8ef30996 MM |
127 | |
128 | ;; Main data type used by the insn | |
34b650b3 | 129 | (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown")) |
8ef30996 | 130 | |
cafe096b EC |
131 | ;; Is this an extended instruction in mips16 mode? |
132 | (define_attr "extended_mips16" "no,yes" | |
133 | (const_string "no")) | |
134 | ||
0ff83799 MM |
135 | ;; Length (in # of bytes). A conditional branch is allowed only to a |
136 | ;; location within a signed 18-bit offset of the delay slot. If that | |
137 | ;; provides too smal a range, we use the `j' instruction. This | |
138 | ;; instruction takes a 28-bit value, but that value is not an offset. | |
139 | ;; Instead, it's bitwise-ored with the high-order four bits of the | |
140 | ;; instruction in the delay slot, which means it cannot be used to | |
141 | ;; cross a 256MB boundary. We could fall back back on the jr, | |
142 | ;; instruction which allows full access to the entire address space, | |
143 | ;; but we do not do so at present. | |
144 | ||
7a38df19 | 145 | (define_attr "length" "" |
0ff83799 MM |
146 | (cond [(eq_attr "type" "branch") |
147 | (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4)))) | |
148 | (const_int 131072)) | |
852dff61 AO |
149 | (const_int 4) |
150 | (ne (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC") | |
151 | (const_int 0)) | |
152 | (const_int 24) | |
153 | ] (const_int 12)) | |
cafe096b EC |
154 | (eq_attr "type" "const") |
155 | (symbol_ref "mips_const_insns (operands[1]) * 4") | |
156 | (eq_attr "type" "load") | |
157 | (symbol_ref "mips_fetch_insns (operands[1]) * 4") | |
158 | (eq_attr "type" "store") | |
159 | (symbol_ref "mips_fetch_insns (operands[0]) * 4") | |
160 | ;; In the worst case, a call macro will take 8 instructions: | |
161 | ;; | |
162 | ;; lui $25,%call_hi(FOO) | |
163 | ;; addu $25,$25,$28 | |
164 | ;; lw $25,%call_lo(FOO)($25) | |
165 | ;; nop | |
166 | ;; jalr $25 | |
167 | ;; nop | |
168 | ;; lw $gp,X($sp) | |
169 | ;; nop | |
170 | (eq_attr "jal_macro" "yes") | |
171 | (const_int 32) | |
172 | (and (eq_attr "extended_mips16" "yes") | |
173 | (ne (symbol_ref "TARGET_MIPS16") (const_int 0))) | |
174 | (const_int 8) | |
852dff61 | 175 | ] (const_int 4))) |
8ef30996 | 176 | |
ddd8ab48 MM |
177 | ;; Attribute describing the processor. This attribute must match exactly |
178 | ;; with the processor_type enumeration in mips.h. | |
179 | ||
8ef30996 | 180 | ;; Attribute describing the processor |
ddd8ab48 MM |
181 | ;; (define_attr "cpu" "default,r3000,r6000,r4000" |
182 | ;; (const | |
183 | ;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000") | |
184 | ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000") | |
185 | ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")] | |
186 | ;; (const_string "default")))) | |
187 | ||
e19ff60f | 188 | ;; ??? Fix everything that tests this attribute. |
b8eb88d0 | 189 | (define_attr "cpu" |
fcc11c35 | 190 | "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4300,r4600,r4650,r5000,r5400,r5500,r8000,sb1,sr71000" |
ddd8ab48 | 191 | (const (symbol_ref "mips_cpu_attr"))) |
8ef30996 | 192 | |
ec350bdd | 193 | ;; Does the instruction have a mandatory delay slot? |
0ff83799 | 194 | ;; The 3900, is (mostly) mips1, but does not have a mandatory load delay |
7a38df19 | 195 | ;; slot. |
ec350bdd GK |
196 | (define_attr "dslot" "no,yes" |
197 | (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp") | |
198 | (and (eq_attr "type" "load") | |
199 | (and (eq (symbol_ref "mips_isa") (const_int 1)) | |
200 | (and (eq (symbol_ref "mips16") (const_int 0)) | |
201 | (eq_attr "cpu" "!r3900"))))) | |
202 | (const_string "yes") | |
203 | (const_string "no"))) | |
204 | ||
cafe096b EC |
205 | ;; Is it a single instruction? |
206 | (define_attr "single_insn" "no,yes" | |
207 | (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)")) | |
208 | ||
f1ba94dd RH |
209 | ;; Can the instruction be put into a delay slot? |
210 | (define_attr "can_delay" "no,yes" | |
211 | (if_then_else (and (eq_attr "dslot" "no") | |
cafe096b | 212 | (eq_attr "single_insn" "yes")) |
f1ba94dd RH |
213 | (const_string "yes") |
214 | (const_string "no"))) | |
215 | ||
8ef30996 | 216 | ;; Attribute defining whether or not we can use the branch-likely instructions |
8ef30996 MM |
217 | |
218 | (define_attr "branch_likely" "no,yes" | |
6d518002 | 219 | (const |
e9a25f70 | 220 | (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0)) |
8ef30996 | 221 | (const_string "yes") |
6d518002 | 222 | (const_string "no")))) |
8ef30996 MM |
223 | |
224 | ||
225 | ;; Describe a user's asm statement. | |
226 | (define_asm_attributes | |
227 | [(set_attr "type" "multi")]) | |
228 | ||
229 | \f | |
230 | ||
231 | ;; ......................... | |
232 | ;; | |
233 | ;; Delay slots, can't describe load/fcmp/xfer delay slots here | |
234 | ;; | |
235 | ;; ......................... | |
236 | ||
2bcb2ab3 GK |
237 | (define_delay (and (eq_attr "type" "branch") |
238 | (eq (symbol_ref "mips16") (const_int 0))) | |
f1ba94dd | 239 | [(eq_attr "can_delay" "yes") |
8ef30996 | 240 | (nil) |
06e455a9 | 241 | (and (eq_attr "branch_likely" "yes") |
cafe096b | 242 | (eq_attr "can_delay" "yes"))]) |
8ef30996 | 243 | |
84a92af4 | 244 | (define_delay (eq_attr "type" "jump") |
f1ba94dd | 245 | [(eq_attr "can_delay" "yes") |
84a92af4 JW |
246 | (nil) |
247 | (nil)]) | |
248 | ||
cafe096b EC |
249 | (define_delay (and (eq_attr "type" "call") |
250 | (eq_attr "jal_macro" "no")) | |
f1ba94dd | 251 | [(eq_attr "can_delay" "yes") |
8ef30996 MM |
252 | (nil) |
253 | (nil)]) | |
254 | ||
255 | \f | |
256 | ||
257 | ;; ......................... | |
258 | ;; | |
259 | ;; Functional units | |
260 | ;; | |
261 | ;; ......................... | |
262 | ||
263 | ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY | |
c8e18a2b | 264 | ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST]) |
8ef30996 MM |
265 | |
266 | ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case | |
267 | ||
268 | (define_function_unit "memory" 1 0 | |
b8eb88d0 | 269 | (and (eq_attr "type" "load") |
3f7967e3 | 270 | (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000")) |
8ef30996 MM |
271 | 3 0) |
272 | ||
273 | (define_function_unit "memory" 1 0 | |
b8eb88d0 | 274 | (and (eq_attr "type" "load") |
3f7967e3 | 275 | (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000")) |
8ef30996 MM |
276 | 2 0) |
277 | ||
ddd8ab48 | 278 | (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0) |
8ef30996 | 279 | |
c3f3d7e1 | 280 | (define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0) |
8ef30996 | 281 | |
bb621ad7 JW |
282 | (define_function_unit "imuldiv" 1 0 |
283 | (eq_attr "type" "hilo") | |
284 | 1 3) | |
285 | ||
286 | (define_function_unit "imuldiv" 1 0 | |
1d4047e0 | 287 | (and (eq_attr "type" "imul,imadd") |
3f7967e3 | 288 | (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000")) |
bb621ad7 | 289 | 17 17) |
8ef30996 | 290 | |
2bcb2ab3 GK |
291 | ;; On them mips16, we want to stronly discourage a mult from appearing |
292 | ;; after an mflo, since that requires explicit nop instructions. We | |
293 | ;; do this by pretending that mflo ties up the function unit for long | |
294 | ;; enough that the scheduler will ignore load stalls and the like when | |
295 | ;; selecting instructions to between the two instructions. | |
296 | ||
297 | (define_function_unit "imuldiv" 1 0 | |
298 | (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0))) | |
299 | 1 5) | |
300 | ||
bb621ad7 | 301 | (define_function_unit "imuldiv" 1 0 |
1d4047e0 | 302 | (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r3000,r3900")) |
bb621ad7 | 303 | 12 12) |
8ef30996 | 304 | |
bb621ad7 | 305 | (define_function_unit "imuldiv" 1 0 |
1d4047e0 | 306 | (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4000,r4600")) |
bb621ad7 | 307 | 10 10) |
8ef30996 | 308 | |
bb621ad7 | 309 | (define_function_unit "imuldiv" 1 0 |
1d4047e0 | 310 | (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4650")) |
053665d7 ILT |
311 | 4 4) |
312 | ||
313 | (define_function_unit "imuldiv" 1 0 | |
1d4047e0 | 314 | (and (eq_attr "type" "imul,imadd") |
3f7967e3 | 315 | (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120"))) |
8fbaea49 JW |
316 | 1 1) |
317 | ||
318 | (define_function_unit "imuldiv" 1 0 | |
1d4047e0 | 319 | (and (eq_attr "type" "imul,imadd") |
3f7967e3 | 320 | (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120"))) |
8fbaea49 JW |
321 | 4 4) |
322 | ||
323 | (define_function_unit "imuldiv" 1 0 | |
1d4047e0 | 324 | (and (eq_attr "type" "imul,imadd") |
41f9efba | 325 | (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000"))) |
8fbaea49 JW |
326 | 5 5) |
327 | ||
328 | (define_function_unit "imuldiv" 1 0 | |
1d4047e0 | 329 | (and (eq_attr "type" "imul,imadd") |
41f9efba | 330 | (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300"))) |
8fbaea49 JW |
331 | 8 8) |
332 | ||
333 | (define_function_unit "imuldiv" 1 0 | |
1d4047e0 | 334 | (and (eq_attr "type" "imul,imadd") |
b8eb88d0 ILT |
335 | (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000"))) |
336 | 9 9) | |
337 | ||
338 | (define_function_unit "imuldiv" 1 0 | |
339 | (and (eq_attr "type" "idiv") | |
3f7967e3 | 340 | (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000")) |
bb621ad7 | 341 | 38 38) |
8ef30996 | 342 | |
bb621ad7 | 343 | (define_function_unit "imuldiv" 1 0 |
e9a25f70 | 344 | (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900")) |
bb621ad7 JW |
345 | 35 35) |
346 | ||
347 | (define_function_unit "imuldiv" 1 0 | |
348 | (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600")) | |
349 | 42 42) | |
8ef30996 | 350 | |
053665d7 ILT |
351 | (define_function_unit "imuldiv" 1 0 |
352 | (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650")) | |
353 | 36 36) | |
354 | ||
bb621ad7 | 355 | (define_function_unit "imuldiv" 1 0 |
8ef30996 | 356 | (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000")) |
bb621ad7 JW |
357 | 69 69) |
358 | ||
8fbaea49 | 359 | (define_function_unit "imuldiv" 1 0 |
b8eb88d0 | 360 | (and (eq_attr "type" "idiv") |
3f7967e3 | 361 | (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120"))) |
8fbaea49 JW |
362 | 35 35) |
363 | ||
364 | (define_function_unit "imuldiv" 1 0 | |
b8eb88d0 | 365 | (and (eq_attr "type" "idiv") |
3f7967e3 | 366 | (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120"))) |
8fbaea49 JW |
367 | 67 67) |
368 | ||
369 | (define_function_unit "imuldiv" 1 0 | |
b8eb88d0 | 370 | (and (eq_attr "type" "idiv") |
41f9efba | 371 | (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300"))) |
8fbaea49 JW |
372 | 37 37) |
373 | ||
374 | (define_function_unit "imuldiv" 1 0 | |
b8eb88d0 | 375 | (and (eq_attr "type" "idiv") |
41f9efba | 376 | (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300"))) |
8fbaea49 JW |
377 | 69 69) |
378 | ||
b8eb88d0 ILT |
379 | (define_function_unit "imuldiv" 1 0 |
380 | (and (eq_attr "type" "idiv") | |
381 | (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000"))) | |
382 | 36 36) | |
383 | ||
384 | (define_function_unit "imuldiv" 1 0 | |
385 | (and (eq_attr "type" "idiv") | |
386 | (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000"))) | |
387 | 68 68) | |
388 | ||
956d6950 | 389 | ;; The R4300 does *NOT* have a separate Floating Point Unit, instead |
8fbaea49 JW |
390 | ;; the FP hardware is part of the normal ALU circuitry. This means FP |
391 | ;; instructions affect the pipe-line, and no functional unit | |
392 | ;; parallelism can occur on R4300 processors. To force GCC into coding | |
393 | ;; for only a single functional unit, we force the R4300 FP | |
394 | ;; instructions to be processed in the "imuldiv" unit. | |
395 | ||
bb621ad7 | 396 | (define_function_unit "adder" 1 1 |
41f9efba | 397 | (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")) |
bb621ad7 JW |
398 | 3 0) |
399 | ||
400 | (define_function_unit "adder" 1 1 | |
e9a25f70 | 401 | (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000")) |
bb621ad7 | 402 | 2 0) |
8ef30996 | 403 | |
b8eb88d0 ILT |
404 | (define_function_unit "adder" 1 1 |
405 | (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000")) | |
406 | 1 0) | |
407 | ||
8ef30996 | 408 | (define_function_unit "adder" 1 1 |
41f9efba | 409 | (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300")) |
c8e18a2b | 410 | 4 0) |
8ef30996 MM |
411 | |
412 | (define_function_unit "adder" 1 1 | |
e9a25f70 | 413 | (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900")) |
c8e18a2b | 414 | 2 0) |
8ef30996 MM |
415 | |
416 | (define_function_unit "adder" 1 1 | |
417 | (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000")) | |
c8e18a2b | 418 | 3 0) |
8ef30996 | 419 | |
ddd8ab48 | 420 | (define_function_unit "adder" 1 1 |
b8eb88d0 | 421 | (and (eq_attr "type" "fabs,fneg") |
41f9efba | 422 | (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000")) |
c8e18a2b | 423 | 2 0) |
8ef30996 | 424 | |
ddd8ab48 | 425 | (define_function_unit "adder" 1 1 |
e9a25f70 | 426 | (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000")) |
c8e18a2b | 427 | 1 0) |
8ef30996 MM |
428 | |
429 | (define_function_unit "mult" 1 1 | |
b8eb88d0 ILT |
430 | (and (eq_attr "type" "fmul") |
431 | (and (eq_attr "mode" "SF") | |
41f9efba | 432 | (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000"))) |
c8e18a2b | 433 | 7 0) |
8ef30996 MM |
434 | |
435 | (define_function_unit "mult" 1 1 | |
b8eb88d0 | 436 | (and (eq_attr "type" "fmul") |
e9a25f70 | 437 | (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000"))) |
c8e18a2b | 438 | 4 0) |
8ef30996 MM |
439 | |
440 | (define_function_unit "mult" 1 1 | |
b8eb88d0 ILT |
441 | (and (eq_attr "type" "fmul") |
442 | (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000"))) | |
c8e18a2b | 443 | 5 0) |
8ef30996 | 444 | |
bb621ad7 | 445 | (define_function_unit "mult" 1 1 |
b8eb88d0 ILT |
446 | (and (eq_attr "type" "fmul") |
447 | (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650"))) | |
bb621ad7 JW |
448 | 8 0) |
449 | ||
8ef30996 | 450 | (define_function_unit "mult" 1 1 |
b8eb88d0 | 451 | (and (eq_attr "type" "fmul") |
41f9efba | 452 | (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))) |
c8e18a2b | 453 | 8 0) |
8ef30996 MM |
454 | |
455 | (define_function_unit "mult" 1 1 | |
b8eb88d0 | 456 | (and (eq_attr "type" "fmul") |
e9a25f70 | 457 | (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000"))) |
c8e18a2b | 458 | 5 0) |
8ef30996 MM |
459 | |
460 | (define_function_unit "mult" 1 1 | |
b8eb88d0 ILT |
461 | (and (eq_attr "type" "fmul") |
462 | (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000"))) | |
c8e18a2b | 463 | 6 0) |
8ef30996 MM |
464 | |
465 | (define_function_unit "divide" 1 1 | |
b8eb88d0 ILT |
466 | (and (eq_attr "type" "fdiv") |
467 | (and (eq_attr "mode" "SF") | |
41f9efba | 468 | (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000"))) |
c8e18a2b | 469 | 23 0) |
8ef30996 MM |
470 | |
471 | (define_function_unit "divide" 1 1 | |
b8eb88d0 | 472 | (and (eq_attr "type" "fdiv") |
e9a25f70 | 473 | (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900"))) |
c8e18a2b | 474 | 12 0) |
8ef30996 MM |
475 | |
476 | (define_function_unit "divide" 1 1 | |
b8eb88d0 ILT |
477 | (and (eq_attr "type" "fdiv") |
478 | (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000"))) | |
c8e18a2b | 479 | 15 0) |
8ef30996 MM |
480 | |
481 | (define_function_unit "divide" 1 1 | |
b8eb88d0 ILT |
482 | (and (eq_attr "type" "fdiv") |
483 | (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650"))) | |
bb621ad7 JW |
484 | 32 0) |
485 | ||
486 | (define_function_unit "divide" 1 1 | |
b8eb88d0 ILT |
487 | (and (eq_attr "type" "fdiv") |
488 | (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000"))) | |
489 | 21 0) | |
490 | ||
491 | (define_function_unit "divide" 1 1 | |
492 | (and (eq_attr "type" "fdiv") | |
493 | (and (eq_attr "mode" "DF") | |
41f9efba | 494 | (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300"))) |
c8e18a2b | 495 | 36 0) |
8ef30996 MM |
496 | |
497 | (define_function_unit "divide" 1 1 | |
b8eb88d0 | 498 | (and (eq_attr "type" "fdiv") |
e9a25f70 | 499 | (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900"))) |
c8e18a2b | 500 | 19 0) |
8ef30996 MM |
501 | |
502 | (define_function_unit "divide" 1 1 | |
b8eb88d0 ILT |
503 | (and (eq_attr "type" "fdiv") |
504 | (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000"))) | |
c8e18a2b | 505 | 16 0) |
8ef30996 | 506 | |
bb621ad7 | 507 | (define_function_unit "divide" 1 1 |
b8eb88d0 ILT |
508 | (and (eq_attr "type" "fdiv") |
509 | (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650"))) | |
bb621ad7 JW |
510 | 61 0) |
511 | ||
512 | ;;; ??? Is this number right? | |
513 | (define_function_unit "divide" 1 1 | |
5ce6f47b | 514 | (and (eq_attr "type" "fsqrt,frsqrt") |
41f9efba | 515 | (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000"))) |
bb621ad7 | 516 | 54 0) |
b8eb88d0 | 517 | |
bb621ad7 | 518 | (define_function_unit "divide" 1 1 |
5ce6f47b | 519 | (and (eq_attr "type" "fsqrt,frsqrt") |
b8eb88d0 | 520 | (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650"))) |
bb621ad7 JW |
521 | 31 0) |
522 | ||
b8eb88d0 | 523 | (define_function_unit "divide" 1 1 |
5ce6f47b | 524 | (and (eq_attr "type" "fsqrt,frsqrt") |
b8eb88d0 ILT |
525 | (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000"))) |
526 | 21 0) | |
527 | ||
bb621ad7 JW |
528 | ;;; ??? Is this number right? |
529 | (define_function_unit "divide" 1 1 | |
5ce6f47b | 530 | (and (eq_attr "type" "fsqrt,frsqrt") |
41f9efba | 531 | (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000"))) |
bb621ad7 | 532 | 112 0) |
b8eb88d0 | 533 | |
bb621ad7 | 534 | (define_function_unit "divide" 1 1 |
5ce6f47b | 535 | (and (eq_attr "type" "fsqrt,frsqrt") |
b8eb88d0 | 536 | (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650"))) |
bb621ad7 | 537 | 60 0) |
8ef30996 | 538 | |
b8eb88d0 | 539 | (define_function_unit "divide" 1 1 |
5ce6f47b | 540 | (and (eq_attr "type" "fsqrt,frsqrt") |
b8eb88d0 ILT |
541 | (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000"))) |
542 | 36 0) | |
543 | ||
8fbaea49 JW |
544 | ;; R4300 FP instruction classes treated as part of the "imuldiv" |
545 | ;; functional unit: | |
546 | ||
547 | (define_function_unit "imuldiv" 1 0 | |
41f9efba | 548 | (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300")) |
8fbaea49 JW |
549 | 3 3) |
550 | ||
aa4e54c4 | 551 | (define_function_unit "imuldiv" 1 0 |
41f9efba | 552 | (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300")) |
aa4e54c4 JW |
553 | 1 1) |
554 | ||
8fbaea49 | 555 | (define_function_unit "imuldiv" 1 0 |
41f9efba | 556 | (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300"))) |
8fbaea49 JW |
557 | 5 5) |
558 | (define_function_unit "imuldiv" 1 0 | |
41f9efba | 559 | (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300"))) |
8fbaea49 JW |
560 | 8 8) |
561 | ||
562 | (define_function_unit "imuldiv" 1 0 | |
5ce6f47b | 563 | (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt")) |
41f9efba | 564 | (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300"))) |
8fbaea49 JW |
565 | 29 29) |
566 | (define_function_unit "imuldiv" 1 0 | |
5ce6f47b | 567 | (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt")) |
41f9efba | 568 | (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300"))) |
8fbaea49 | 569 | 58 58) |
ddd8ab48 MM |
570 | \f |
571 | ;; The following functional units do not use the cpu type, and use | |
572 | ;; much less memory in genattrtab.c. | |
573 | ||
c8e18a2b TW |
574 | ;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0) |
575 | ;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0) | |
7a38df19 | 576 | ;; |
c8e18a2b | 577 | ;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0) |
7a38df19 | 578 | ;; |
c8e18a2b TW |
579 | ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0) |
580 | ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0) | |
7a38df19 | 581 | ;; |
c8e18a2b TW |
582 | ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 0) |
583 | ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 0) | |
7a38df19 | 584 | ;; |
c8e18a2b TW |
585 | ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 0) |
586 | ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 0) | |
7a38df19 | 587 | ;; |
c8e18a2b TW |
588 | ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 0) |
589 | ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 0) | |
7a38df19 | 590 | ;; |
c8e18a2b TW |
591 | ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 0) |
592 | ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 0) | |
7a38df19 | 593 | ;; |
c8e18a2b TW |
594 | ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0) |
595 | ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0) | |
a0b6cdee | 596 | \f |
5ce6f47b EC |
597 | ;; Include scheduling descriptions. |
598 | ||
599 | (include "5400.md") | |
600 | (include "5500.md") | |
601 | (include "sr71k.md") | |
602 | ||
603 | ||
a0b6cdee GM |
604 | ;; |
605 | ;; .................... | |
606 | ;; | |
607 | ;; CONDITIONAL TRAPS | |
608 | ;; | |
609 | ;; .................... | |
610 | ;; | |
ddd8ab48 | 611 | |
a0b6cdee GM |
612 | (define_insn "trap" |
613 | [(trap_if (const_int 1) (const_int 0))] | |
614 | "" | |
615 | "* | |
616 | { | |
617 | if (ISA_HAS_COND_TRAP) | |
618 | return \"teq\\t$0,$0\"; | |
4dffef52 AO |
619 | else if (TARGET_MIPS16) |
620 | return \"break 0\"; | |
a0b6cdee GM |
621 | else |
622 | return \"break\"; | |
623 | }") | |
624 | ||
625 | (define_expand "conditional_trap" | |
626 | [(trap_if (match_operator 0 "cmp_op" | |
627 | [(match_dup 2) (match_dup 3)]) | |
628 | (match_operand 1 "const_int_operand" ""))] | |
629 | "ISA_HAS_COND_TRAP" | |
630 | " | |
631 | { | |
632 | mips_gen_conditional_trap (operands); | |
633 | DONE; | |
634 | }") | |
635 | ||
636 | ;; Match a TRAP_IF with 2nd arg of 0. The div_trap_* insns match a | |
637 | ;; 2nd arg of any CONST_INT, so this insn must appear first. | |
638 | ;; gen_div_trap always generates TRAP_IF with 2nd arg of 6 or 7. | |
639 | ||
640 | (define_insn "" | |
641 | [(trap_if (match_operator 0 "trap_cmp_op" | |
642 | [(match_operand:SI 1 "reg_or_0_operand" "d") | |
643 | (match_operand:SI 2 "nonmemory_operand" "dI")]) | |
644 | (const_int 0))] | |
645 | "ISA_HAS_COND_TRAP" | |
646 | "t%C0\\t%z1,%z2") | |
8ef30996 MM |
647 | \f |
648 | ;; | |
649 | ;; .................... | |
650 | ;; | |
651 | ;; ADDITION | |
652 | ;; | |
653 | ;; .................... | |
654 | ;; | |
655 | ||
656 | (define_insn "adddf3" | |
657 | [(set (match_operand:DF 0 "register_operand" "=f") | |
658 | (plus:DF (match_operand:DF 1 "register_operand" "f") | |
659 | (match_operand:DF 2 "register_operand" "f")))] | |
46299de9 | 660 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
8ef30996 MM |
661 | "add.d\\t%0,%1,%2" |
662 | [(set_attr "type" "fadd") | |
0ff83799 | 663 | (set_attr "mode" "DF")]) |
8ef30996 MM |
664 | |
665 | (define_insn "addsf3" | |
666 | [(set (match_operand:SF 0 "register_operand" "=f") | |
667 | (plus:SF (match_operand:SF 1 "register_operand" "f") | |
668 | (match_operand:SF 2 "register_operand" "f")))] | |
669 | "TARGET_HARD_FLOAT" | |
670 | "add.s\\t%0,%1,%2" | |
671 | [(set_attr "type" "fadd") | |
0ff83799 | 672 | (set_attr "mode" "SF")]) |
8ef30996 | 673 | |
71cd5224 | 674 | (define_expand "addsi3" |
cafe096b EC |
675 | [(set (match_operand:SI 0 "register_operand" "") |
676 | (plus:SI (match_operand:SI 1 "reg_or_0_operand" "") | |
677 | (match_operand:SI 2 "arith_operand" "")))] | |
8ef30996 | 678 | "" |
71cd5224 RS |
679 | " |
680 | { | |
2bcb2ab3 GK |
681 | /* The mips16 assembler handles -32768 correctly, and so does gas, |
682 | but some other MIPS assemblers think that -32768 needs to be | |
683 | loaded into a register before it can be added in. */ | |
684 | if (! TARGET_MIPS16 | |
685 | && ! TARGET_GAS | |
686 | && GET_CODE (operands[2]) == CONST_INT | |
687 | && INTVAL (operands[2]) == -32768) | |
71cd5224 | 688 | operands[2] = force_reg (SImode, operands[2]); |
4f5bd6d7 AO |
689 | |
690 | /* If a large stack adjustment was forced into a register, we may be | |
691 | asked to generate rtx such as: | |
692 | ||
693 | (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo))) | |
694 | ||
695 | but no such instruction is available in mips16. Handle it by | |
696 | using a temporary. */ | |
697 | if (TARGET_MIPS16 | |
698 | && REGNO (operands[0]) == STACK_POINTER_REGNUM | |
699 | && ((GET_CODE (operands[1]) == REG | |
700 | && REGNO (operands[1]) != STACK_POINTER_REGNUM) | |
701 | || GET_CODE (operands[2]) != CONST_INT)) | |
702 | { | |
703 | rtx tmp = gen_reg_rtx (SImode); | |
704 | ||
705 | emit_move_insn (tmp, operands[1]); | |
706 | emit_insn (gen_addsi3 (tmp, tmp, operands[2])); | |
707 | emit_move_insn (operands[0], tmp); | |
708 | DONE; | |
709 | } | |
71cd5224 RS |
710 | }") |
711 | ||
712 | (define_insn "addsi3_internal" | |
cafe096b EC |
713 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
714 | (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ") | |
715 | (match_operand:SI 2 "arith_operand" "d,Q")))] | |
2bcb2ab3 GK |
716 | "! TARGET_MIPS16 |
717 | && (TARGET_GAS | |
718 | || GET_CODE (operands[2]) != CONST_INT | |
719 | || INTVAL (operands[2]) != -32768)" | |
cafe096b EC |
720 | "@ |
721 | addu\\t%0,%z1,%2 | |
722 | addiu\\t%0,%z1,%2" | |
8ef30996 | 723 | [(set_attr "type" "arith") |
0ff83799 | 724 | (set_attr "mode" "SI")]) |
8ef30996 | 725 | |
2bcb2ab3 GK |
726 | ;; For the mips16, we need to recognize stack pointer additions |
727 | ;; explicitly, since we don't have a constraint for $sp. These insns | |
728 | ;; will be generated by the save_restore_insns functions. | |
729 | ||
730 | (define_insn "" | |
731 | [(set (reg:SI 29) | |
732 | (plus:SI (reg:SI 29) | |
733 | (match_operand:SI 0 "small_int" "I")))] | |
734 | "TARGET_MIPS16" | |
735 | "addu\\t%$,%$,%0" | |
736 | [(set_attr "type" "arith") | |
737 | (set_attr "mode" "SI") | |
738 | (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "") | |
0ff83799 MM |
739 | (const_int 4) |
740 | (const_int 8)))]) | |
2bcb2ab3 GK |
741 | |
742 | (define_insn "" | |
743 | [(set (match_operand:SI 0 "register_operand" "=d") | |
744 | (plus:SI (reg:SI 29) | |
745 | (match_operand:SI 1 "small_int" "I")))] | |
746 | "TARGET_MIPS16" | |
747 | "addu\\t%0,%$,%1" | |
748 | [(set_attr "type" "arith") | |
749 | (set_attr "mode" "SI") | |
750 | (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "") | |
0ff83799 MM |
751 | (const_int 4) |
752 | (const_int 8)))]) | |
2bcb2ab3 GK |
753 | |
754 | (define_insn "" | |
755 | [(set (match_operand:SI 0 "register_operand" "=d,d,d") | |
756 | (plus:SI (match_operand:SI 1 "register_operand" "0,d,d") | |
cafe096b | 757 | (match_operand:SI 2 "arith_operand" "Q,O,d")))] |
2bcb2ab3 GK |
758 | "TARGET_MIPS16 |
759 | && (GET_CODE (operands[1]) != REG | |
760 | || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER | |
761 | || M16_REG_P (REGNO (operands[1])) | |
762 | || REGNO (operands[1]) == ARG_POINTER_REGNUM | |
763 | || REGNO (operands[1]) == FRAME_POINTER_REGNUM | |
764 | || REGNO (operands[1]) == STACK_POINTER_REGNUM) | |
765 | && (GET_CODE (operands[2]) != REG | |
766 | || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER | |
767 | || M16_REG_P (REGNO (operands[2])) | |
768 | || REGNO (operands[2]) == ARG_POINTER_REGNUM | |
769 | || REGNO (operands[2]) == FRAME_POINTER_REGNUM | |
770 | || REGNO (operands[2]) == STACK_POINTER_REGNUM)" | |
771 | "* | |
772 | { | |
773 | if (REGNO (operands[0]) == REGNO (operands[1])) | |
774 | return \"addu\\t%0,%2\"; | |
775 | return \"addu\\t%0,%1,%2\"; | |
776 | }" | |
777 | [(set_attr "type" "arith") | |
778 | (set_attr "mode" "SI") | |
779 | (set_attr_alternative "length" | |
780 | [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "") | |
0ff83799 MM |
781 | (const_int 4) |
782 | (const_int 8)) | |
2bcb2ab3 | 783 | (if_then_else (match_operand:VOID 2 "m16_simm4_1" "") |
0ff83799 MM |
784 | (const_int 4) |
785 | (const_int 8)) | |
786 | (const_int 4)])]) | |
2bcb2ab3 GK |
787 | |
788 | ||
789 | ;; On the mips16, we can sometimes split an add of a constant which is | |
790 | ;; a 4 byte instruction into two adds which are both 2 byte | |
791 | ;; instructions. There are two cases: one where we are adding a | |
792 | ;; constant plus a register to another register, and one where we are | |
793 | ;; simply adding a constant to a register. | |
794 | ||
795 | (define_split | |
796 | [(set (match_operand:SI 0 "register_operand" "") | |
797 | (plus:SI (match_dup 0) | |
798 | (match_operand:SI 1 "const_int_operand" "")))] | |
2ca2d9ee | 799 | "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
800 | && GET_CODE (operands[0]) == REG |
801 | && M16_REG_P (REGNO (operands[0])) | |
802 | && GET_CODE (operands[1]) == CONST_INT | |
803 | && ((INTVAL (operands[1]) > 0x7f | |
804 | && INTVAL (operands[1]) <= 0x7f + 0x7f) | |
805 | || (INTVAL (operands[1]) < - 0x80 | |
806 | && INTVAL (operands[1]) >= - 0x80 - 0x80))" | |
807 | [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) | |
808 | (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))] | |
809 | " | |
810 | { | |
811 | HOST_WIDE_INT val = INTVAL (operands[1]); | |
812 | ||
813 | if (val >= 0) | |
814 | { | |
815 | operands[1] = GEN_INT (0x7f); | |
816 | operands[2] = GEN_INT (val - 0x7f); | |
817 | } | |
818 | else | |
819 | { | |
820 | operands[1] = GEN_INT (- 0x80); | |
821 | operands[2] = GEN_INT (val + 0x80); | |
822 | } | |
823 | }") | |
824 | ||
825 | (define_split | |
826 | [(set (match_operand:SI 0 "register_operand" "") | |
827 | (plus:SI (match_operand:SI 1 "register_operand" "") | |
828 | (match_operand:SI 2 "const_int_operand" "")))] | |
2ca2d9ee | 829 | "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
830 | && GET_CODE (operands[0]) == REG |
831 | && M16_REG_P (REGNO (operands[0])) | |
832 | && GET_CODE (operands[1]) == REG | |
833 | && M16_REG_P (REGNO (operands[1])) | |
834 | && REGNO (operands[0]) != REGNO (operands[1]) | |
835 | && GET_CODE (operands[2]) == CONST_INT | |
836 | && ((INTVAL (operands[2]) > 0x7 | |
837 | && INTVAL (operands[2]) <= 0x7 + 0x7f) | |
838 | || (INTVAL (operands[2]) < - 0x8 | |
839 | && INTVAL (operands[2]) >= - 0x8 - 0x80))" | |
840 | [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) | |
841 | (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))] | |
842 | " | |
843 | { | |
844 | HOST_WIDE_INT val = INTVAL (operands[2]); | |
845 | ||
846 | if (val >= 0) | |
847 | { | |
848 | operands[2] = GEN_INT (0x7); | |
849 | operands[3] = GEN_INT (val - 0x7); | |
850 | } | |
851 | else | |
852 | { | |
853 | operands[2] = GEN_INT (- 0x8); | |
854 | operands[3] = GEN_INT (val + 0x8); | |
855 | } | |
856 | }") | |
857 | ||
8ef30996 MM |
858 | (define_expand "adddi3" |
859 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
cafe096b EC |
860 | (plus:DI (match_operand:DI 1 "register_operand" "") |
861 | (match_operand:DI 2 "arith_operand" ""))) | |
8ef30996 | 862 | (clobber (match_dup 3))])] |
2bcb2ab3 | 863 | "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)" |
92b4cee1 MM |
864 | " |
865 | { | |
2bcb2ab3 GK |
866 | /* The mips16 assembler handles -32768 correctly, and so does gas, |
867 | but some other MIPS assemblers think that -32768 needs to be | |
868 | loaded into a register before it can be added in. */ | |
869 | if (! TARGET_MIPS16 | |
870 | && ! TARGET_GAS | |
871 | && GET_CODE (operands[2]) == CONST_INT | |
872 | && INTVAL (operands[2]) == -32768) | |
b0565769 | 873 | operands[2] = force_reg (DImode, operands[2]); |
92b4cee1 | 874 | |
4f5bd6d7 AO |
875 | /* If a large stack adjustment was forced into a register, we may be |
876 | asked to generate rtx such as: | |
877 | ||
878 | (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo))) | |
879 | ||
880 | but no such instruction is available in mips16. Handle it by | |
881 | using a temporary. */ | |
882 | if (TARGET_MIPS16 | |
883 | && REGNO (operands[0]) == STACK_POINTER_REGNUM | |
884 | && ((GET_CODE (operands[1]) == REG | |
885 | && REGNO (operands[1]) != STACK_POINTER_REGNUM) | |
886 | || GET_CODE (operands[2]) != CONST_INT)) | |
887 | { | |
888 | rtx tmp = gen_reg_rtx (DImode); | |
889 | ||
890 | emit_move_insn (tmp, operands[1]); | |
891 | emit_insn (gen_addsi3 (tmp, tmp, operands[2])); | |
892 | emit_move_insn (operands[0], tmp); | |
893 | DONE; | |
894 | } | |
895 | ||
bb621ad7 JW |
896 | if (TARGET_64BIT) |
897 | { | |
898 | emit_insn (gen_adddi3_internal_3 (operands[0], operands[1], | |
899 | operands[2])); | |
900 | DONE; | |
901 | } | |
902 | ||
92b4cee1 MM |
903 | operands[3] = gen_reg_rtx (SImode); |
904 | }") | |
8ef30996 MM |
905 | |
906 | (define_insn "adddi3_internal_1" | |
907 | [(set (match_operand:DI 0 "register_operand" "=d,&d") | |
908 | (plus:DI (match_operand:DI 1 "register_operand" "0,d") | |
909 | (match_operand:DI 2 "register_operand" "d,d"))) | |
910 | (clobber (match_operand:SI 3 "register_operand" "=d,d"))] | |
2bcb2ab3 | 911 | "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16" |
8ef30996 MM |
912 | "* |
913 | { | |
914 | return (REGNO (operands[0]) == REGNO (operands[1]) | |
915 | && REGNO (operands[0]) == REGNO (operands[2])) | |
916 | ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\" | |
917 | : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\"; | |
918 | }" | |
92b4cee1 MM |
919 | [(set_attr "type" "darith") |
920 | (set_attr "mode" "DI") | |
0ff83799 | 921 | (set_attr "length" "16")]) |
8ef30996 MM |
922 | |
923 | (define_split | |
924 | [(set (match_operand:DI 0 "register_operand" "") | |
925 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
926 | (match_operand:DI 2 "register_operand" ""))) | |
927 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
928 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT |
929 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
930 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
931 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
932 | && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2])) | |
933 | && (REGNO (operands[0]) != REGNO (operands[1]) | |
934 | || REGNO (operands[0]) != REGNO (operands[2]))" | |
935 | ||
936 | [(set (subreg:SI (match_dup 0) 0) | |
937 | (plus:SI (subreg:SI (match_dup 1) 0) | |
938 | (subreg:SI (match_dup 2) 0))) | |
939 | ||
940 | (set (match_dup 3) | |
34b650b3 | 941 | (ltu:SI (subreg:SI (match_dup 0) 0) |
8ef30996 MM |
942 | (subreg:SI (match_dup 2) 0))) |
943 | ||
ddef6bc7 JJ |
944 | (set (subreg:SI (match_dup 0) 4) |
945 | (plus:SI (subreg:SI (match_dup 1) 4) | |
946 | (subreg:SI (match_dup 2) 4))) | |
8ef30996 | 947 | |
ddef6bc7 JJ |
948 | (set (subreg:SI (match_dup 0) 4) |
949 | (plus:SI (subreg:SI (match_dup 0) 4) | |
8ef30996 MM |
950 | (match_dup 3)))] |
951 | "") | |
952 | ||
953 | (define_split | |
954 | [(set (match_operand:DI 0 "register_operand" "") | |
955 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
956 | (match_operand:DI 2 "register_operand" ""))) | |
957 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
958 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT |
959 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
960 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
961 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
962 | && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2])) | |
963 | && (REGNO (operands[0]) != REGNO (operands[1]) | |
964 | || REGNO (operands[0]) != REGNO (operands[2]))" | |
965 | ||
ddef6bc7 JJ |
966 | [(set (subreg:SI (match_dup 0) 4) |
967 | (plus:SI (subreg:SI (match_dup 1) 4) | |
968 | (subreg:SI (match_dup 2) 4))) | |
8ef30996 MM |
969 | |
970 | (set (match_dup 3) | |
ddef6bc7 JJ |
971 | (ltu:SI (subreg:SI (match_dup 0) 4) |
972 | (subreg:SI (match_dup 2) 4))) | |
8ef30996 MM |
973 | |
974 | (set (subreg:SI (match_dup 0) 0) | |
975 | (plus:SI (subreg:SI (match_dup 1) 0) | |
976 | (subreg:SI (match_dup 2) 0))) | |
977 | ||
978 | (set (subreg:SI (match_dup 0) 0) | |
979 | (plus:SI (subreg:SI (match_dup 0) 0) | |
980 | (match_dup 3)))] | |
981 | "") | |
982 | ||
983 | (define_insn "adddi3_internal_2" | |
984 | [(set (match_operand:DI 0 "register_operand" "=d,d,d") | |
985 | (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d") | |
986 | (match_operand:DI 2 "small_int" "P,J,N"))) | |
987 | (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))] | |
2bcb2ab3 | 988 | "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 |
82301b88 JL |
989 | && (TARGET_GAS |
990 | || GET_CODE (operands[2]) != CONST_INT | |
991 | || INTVAL (operands[2]) != -32768)" | |
8ef30996 MM |
992 | "@ |
993 | addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3 | |
994 | move\\t%L0,%L1\;move\\t%M0,%M1 | |
995 | subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3" | |
92b4cee1 MM |
996 | [(set_attr "type" "darith") |
997 | (set_attr "mode" "DI") | |
0ff83799 | 998 | (set_attr "length" "12,8,16")]) |
8ef30996 MM |
999 | |
1000 | (define_split | |
1001 | [(set (match_operand:DI 0 "register_operand" "") | |
1002 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
1003 | (match_operand:DI 2 "small_int" ""))) | |
13c508d9 | 1004 | (clobber (match_operand:SI 3 "register_operand" ""))] |
2bcb2ab3 GK |
1005 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT |
1006 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
1007 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
1008 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
1009 | && INTVAL (operands[2]) > 0" | |
1010 | ||
1011 | [(set (subreg:SI (match_dup 0) 0) | |
1012 | (plus:SI (subreg:SI (match_dup 1) 0) | |
1013 | (match_dup 2))) | |
1014 | ||
1015 | (set (match_dup 3) | |
34b650b3 | 1016 | (ltu:SI (subreg:SI (match_dup 0) 0) |
8ef30996 MM |
1017 | (match_dup 2))) |
1018 | ||
ddef6bc7 JJ |
1019 | (set (subreg:SI (match_dup 0) 4) |
1020 | (plus:SI (subreg:SI (match_dup 1) 4) | |
8ef30996 MM |
1021 | (match_dup 3)))] |
1022 | "") | |
1023 | ||
1024 | (define_split | |
1025 | [(set (match_operand:DI 0 "register_operand" "") | |
1026 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
1027 | (match_operand:DI 2 "small_int" ""))) | |
13c508d9 | 1028 | (clobber (match_operand:SI 3 "register_operand" ""))] |
2bcb2ab3 GK |
1029 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT |
1030 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
1031 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
1032 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
1033 | && INTVAL (operands[2]) > 0" | |
1034 | ||
ddef6bc7 JJ |
1035 | [(set (subreg:SI (match_dup 0) 4) |
1036 | (plus:SI (subreg:SI (match_dup 1) 4) | |
8ef30996 MM |
1037 | (match_dup 2))) |
1038 | ||
1039 | (set (match_dup 3) | |
ddef6bc7 | 1040 | (ltu:SI (subreg:SI (match_dup 0) 4) |
8ef30996 MM |
1041 | (match_dup 2))) |
1042 | ||
1043 | (set (subreg:SI (match_dup 0) 0) | |
1044 | (plus:SI (subreg:SI (match_dup 1) 0) | |
1045 | (match_dup 3)))] | |
1046 | "") | |
bb621ad7 JW |
1047 | |
1048 | (define_insn "adddi3_internal_3" | |
cafe096b EC |
1049 | [(set (match_operand:DI 0 "register_operand" "=d,d") |
1050 | (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ,dJ") | |
1051 | (match_operand:DI 2 "arith_operand" "d,Q")))] | |
2bcb2ab3 GK |
1052 | "TARGET_64BIT |
1053 | && !TARGET_MIPS16 | |
1054 | && (TARGET_GAS | |
1055 | || GET_CODE (operands[2]) != CONST_INT | |
1056 | || INTVAL (operands[2]) != -32768)" | |
cafe096b EC |
1057 | "@ |
1058 | daddu\\t%0,%z1,%2 | |
1059 | daddiu\\t%0,%z1,%2" | |
bb621ad7 | 1060 | [(set_attr "type" "darith") |
0ff83799 | 1061 | (set_attr "mode" "DI")]) |
bb621ad7 | 1062 | |
2bcb2ab3 GK |
1063 | ;; For the mips16, we need to recognize stack pointer additions |
1064 | ;; explicitly, since we don't have a constraint for $sp. These insns | |
1065 | ;; will be generated by the save_restore_insns functions. | |
1066 | ||
1067 | (define_insn "" | |
1068 | [(set (reg:DI 29) | |
1069 | (plus:DI (reg:DI 29) | |
1070 | (match_operand:DI 0 "small_int" "I")))] | |
1071 | "TARGET_MIPS16 && TARGET_64BIT" | |
1072 | "daddu\\t%$,%$,%0" | |
1073 | [(set_attr "type" "arith") | |
1074 | (set_attr "mode" "DI") | |
1075 | (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "") | |
0ff83799 MM |
1076 | (const_int 4) |
1077 | (const_int 8)))]) | |
2bcb2ab3 GK |
1078 | |
1079 | (define_insn "" | |
1080 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1081 | (plus:DI (reg:DI 29) | |
1082 | (match_operand:DI 1 "small_int" "I")))] | |
1083 | "TARGET_MIPS16 && TARGET_64BIT" | |
1084 | "daddu\\t%0,%$,%1" | |
1085 | [(set_attr "type" "arith") | |
1086 | (set_attr "mode" "DI") | |
1087 | (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "") | |
0ff83799 MM |
1088 | (const_int 4) |
1089 | (const_int 8)))]) | |
2bcb2ab3 GK |
1090 | |
1091 | (define_insn "" | |
1092 | [(set (match_operand:DI 0 "register_operand" "=d,d,d") | |
1093 | (plus:DI (match_operand:DI 1 "register_operand" "0,d,d") | |
cafe096b | 1094 | (match_operand:DI 2 "arith_operand" "Q,O,d")))] |
2bcb2ab3 GK |
1095 | "TARGET_MIPS16 && TARGET_64BIT |
1096 | && (GET_CODE (operands[1]) != REG | |
1097 | || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER | |
1098 | || M16_REG_P (REGNO (operands[1])) | |
1099 | || REGNO (operands[1]) == ARG_POINTER_REGNUM | |
1100 | || REGNO (operands[1]) == FRAME_POINTER_REGNUM | |
1101 | || REGNO (operands[1]) == STACK_POINTER_REGNUM) | |
1102 | && (GET_CODE (operands[2]) != REG | |
1103 | || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER | |
1104 | || M16_REG_P (REGNO (operands[2])) | |
1105 | || REGNO (operands[2]) == ARG_POINTER_REGNUM | |
1106 | || REGNO (operands[2]) == FRAME_POINTER_REGNUM | |
1107 | || REGNO (operands[2]) == STACK_POINTER_REGNUM)" | |
1108 | "* | |
1109 | { | |
1110 | if (REGNO (operands[0]) == REGNO (operands[1])) | |
1111 | return \"daddu\\t%0,%2\"; | |
1112 | return \"daddu\\t%0,%1,%2\"; | |
1113 | }" | |
1114 | [(set_attr "type" "arith") | |
1115 | (set_attr "mode" "DI") | |
1116 | (set_attr_alternative "length" | |
1117 | [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "") | |
0ff83799 MM |
1118 | (const_int 4) |
1119 | (const_int 8)) | |
2bcb2ab3 | 1120 | (if_then_else (match_operand:VOID 2 "m16_simm4_1" "") |
0ff83799 MM |
1121 | (const_int 4) |
1122 | (const_int 8)) | |
1123 | (const_int 4)])]) | |
2bcb2ab3 GK |
1124 | |
1125 | ||
1126 | ;; On the mips16, we can sometimes split an add of a constant which is | |
1127 | ;; a 4 byte instruction into two adds which are both 2 byte | |
1128 | ;; instructions. There are two cases: one where we are adding a | |
1129 | ;; constant plus a register to another register, and one where we are | |
1130 | ;; simply adding a constant to a register. | |
1131 | ||
1132 | (define_split | |
1133 | [(set (match_operand:DI 0 "register_operand" "") | |
1134 | (plus:DI (match_dup 0) | |
1135 | (match_operand:DI 1 "const_int_operand" "")))] | |
2ca2d9ee | 1136 | "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
1137 | && GET_CODE (operands[0]) == REG |
1138 | && M16_REG_P (REGNO (operands[0])) | |
1139 | && GET_CODE (operands[1]) == CONST_INT | |
1140 | && ((INTVAL (operands[1]) > 0xf | |
1141 | && INTVAL (operands[1]) <= 0xf + 0xf) | |
1142 | || (INTVAL (operands[1]) < - 0x10 | |
1143 | && INTVAL (operands[1]) >= - 0x10 - 0x10))" | |
1144 | [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1))) | |
1145 | (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))] | |
1146 | " | |
1147 | { | |
1148 | HOST_WIDE_INT val = INTVAL (operands[1]); | |
1149 | ||
1150 | if (val >= 0) | |
1151 | { | |
1152 | operands[1] = GEN_INT (0xf); | |
1153 | operands[2] = GEN_INT (val - 0xf); | |
1154 | } | |
1155 | else | |
1156 | { | |
1157 | operands[1] = GEN_INT (- 0x10); | |
1158 | operands[2] = GEN_INT (val + 0x10); | |
1159 | } | |
1160 | }") | |
1161 | ||
1162 | (define_split | |
1163 | [(set (match_operand:DI 0 "register_operand" "") | |
1164 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
1165 | (match_operand:DI 2 "const_int_operand" "")))] | |
2ca2d9ee | 1166 | "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
1167 | && GET_CODE (operands[0]) == REG |
1168 | && M16_REG_P (REGNO (operands[0])) | |
1169 | && GET_CODE (operands[1]) == REG | |
1170 | && M16_REG_P (REGNO (operands[1])) | |
1171 | && REGNO (operands[0]) != REGNO (operands[1]) | |
1172 | && GET_CODE (operands[2]) == CONST_INT | |
1173 | && ((INTVAL (operands[2]) > 0x7 | |
1174 | && INTVAL (operands[2]) <= 0x7 + 0xf) | |
1175 | || (INTVAL (operands[2]) < - 0x8 | |
1176 | && INTVAL (operands[2]) >= - 0x8 - 0x10))" | |
1177 | [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2))) | |
1178 | (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] | |
1179 | " | |
1180 | { | |
1181 | HOST_WIDE_INT val = INTVAL (operands[2]); | |
1182 | ||
1183 | if (val >= 0) | |
1184 | { | |
1185 | operands[2] = GEN_INT (0x7); | |
1186 | operands[3] = GEN_INT (val - 0x7); | |
1187 | } | |
1188 | else | |
1189 | { | |
1190 | operands[2] = GEN_INT (- 0x8); | |
1191 | operands[3] = GEN_INT (val + 0x8); | |
1192 | } | |
1193 | }") | |
bb621ad7 JW |
1194 | |
1195 | (define_insn "addsi3_internal_2" | |
cafe096b EC |
1196 | [(set (match_operand:DI 0 "register_operand" "=d,d") |
1197 | (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ") | |
1198 | (match_operand:SI 2 "arith_operand" "d,Q"))))] | |
2bcb2ab3 GK |
1199 | "TARGET_64BIT |
1200 | && !TARGET_MIPS16 | |
1201 | && (TARGET_GAS | |
1202 | || GET_CODE (operands[2]) != CONST_INT | |
1203 | || INTVAL (operands[2]) != -32768)" | |
cafe096b EC |
1204 | "@ |
1205 | addu\\t%0,%z1,%2 | |
1206 | addiu\\t%0,%z1,%2" | |
bb621ad7 | 1207 | [(set_attr "type" "arith") |
0ff83799 | 1208 | (set_attr "mode" "SI")]) |
bb621ad7 | 1209 | |
2bcb2ab3 GK |
1210 | (define_insn "" |
1211 | [(set (match_operand:DI 0 "register_operand" "=d,d,d") | |
1212 | (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d") | |
cafe096b | 1213 | (match_operand:SI 2 "arith_operand" "Q,O,d"))))] |
2bcb2ab3 GK |
1214 | "TARGET_MIPS16 && TARGET_64BIT" |
1215 | "* | |
1216 | { | |
1217 | if (REGNO (operands[0]) == REGNO (operands[1])) | |
1218 | return \"addu\\t%0,%2\"; | |
1219 | return \"addu\\t%0,%1,%2\"; | |
1220 | }" | |
1221 | [(set_attr "type" "arith") | |
1222 | (set_attr "mode" "SI") | |
1223 | (set_attr_alternative "length" | |
1224 | [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "") | |
0ff83799 MM |
1225 | (const_int 4) |
1226 | (const_int 8)) | |
2bcb2ab3 | 1227 | (if_then_else (match_operand:VOID 2 "m16_simm4_1" "") |
0ff83799 MM |
1228 | (const_int 4) |
1229 | (const_int 8)) | |
1230 | (const_int 4)])]) | |
2bcb2ab3 | 1231 | |
8ef30996 MM |
1232 | \f |
1233 | ;; | |
1234 | ;; .................... | |
1235 | ;; | |
1236 | ;; SUBTRACTION | |
1237 | ;; | |
1238 | ;; .................... | |
1239 | ;; | |
1240 | ||
1241 | (define_insn "subdf3" | |
1242 | [(set (match_operand:DF 0 "register_operand" "=f") | |
1243 | (minus:DF (match_operand:DF 1 "register_operand" "f") | |
1244 | (match_operand:DF 2 "register_operand" "f")))] | |
46299de9 | 1245 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
8ef30996 MM |
1246 | "sub.d\\t%0,%1,%2" |
1247 | [(set_attr "type" "fadd") | |
0ff83799 | 1248 | (set_attr "mode" "DF")]) |
8ef30996 MM |
1249 | |
1250 | (define_insn "subsf3" | |
1251 | [(set (match_operand:SF 0 "register_operand" "=f") | |
1252 | (minus:SF (match_operand:SF 1 "register_operand" "f") | |
1253 | (match_operand:SF 2 "register_operand" "f")))] | |
1254 | "TARGET_HARD_FLOAT" | |
1255 | "sub.s\\t%0,%1,%2" | |
1256 | [(set_attr "type" "fadd") | |
0ff83799 | 1257 | (set_attr "mode" "SF")]) |
8ef30996 | 1258 | |
71cd5224 | 1259 | (define_expand "subsi3" |
8ef30996 MM |
1260 | [(set (match_operand:SI 0 "register_operand" "=d") |
1261 | (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") | |
1262 | (match_operand:SI 2 "arith_operand" "dI")))] | |
1263 | "" | |
71cd5224 RS |
1264 | " |
1265 | { | |
2bcb2ab3 GK |
1266 | if (GET_CODE (operands[2]) == CONST_INT |
1267 | && (INTVAL (operands[2]) == -32768 | |
1268 | || (TARGET_MIPS16 | |
1269 | && INTVAL (operands[2]) == -0x4000))) | |
71cd5224 RS |
1270 | operands[2] = force_reg (SImode, operands[2]); |
1271 | }") | |
1272 | ||
1273 | (define_insn "subsi3_internal" | |
1274 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1275 | (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") | |
1276 | (match_operand:SI 2 "arith_operand" "dI")))] | |
2bcb2ab3 GK |
1277 | "!TARGET_MIPS16 |
1278 | && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" | |
9b190d1c | 1279 | "subu\\t%0,%z1,%2" |
8ef30996 | 1280 | [(set_attr "type" "arith") |
0ff83799 | 1281 | (set_attr "mode" "SI")]) |
8ef30996 | 1282 | |
2bcb2ab3 GK |
1283 | ;; For the mips16, we need to recognize stack pointer subtractions |
1284 | ;; explicitly, since we don't have a constraint for $sp. These insns | |
1285 | ;; will be generated by the save_restore_insns functions. | |
1286 | ||
1287 | (define_insn "" | |
1288 | [(set (reg:SI 29) | |
1289 | (minus:SI (reg:SI 29) | |
1290 | (match_operand:SI 0 "small_int" "I")))] | |
1291 | "TARGET_MIPS16 | |
1292 | && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" | |
1293 | "addu\\t%$,%$,%n0" | |
1294 | [(set_attr "type" "arith") | |
1295 | (set_attr "mode" "SI") | |
1296 | (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "") | |
0ff83799 MM |
1297 | (const_int 4) |
1298 | (const_int 8)))]) | |
2bcb2ab3 GK |
1299 | |
1300 | (define_insn "" | |
1301 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1302 | (minus:SI (reg:SI 29) | |
1303 | (match_operand:SI 1 "small_int" "I")))] | |
1304 | "TARGET_MIPS16 | |
1305 | && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" | |
1306 | "addu\\t%0,%$,%n1" | |
1307 | [(set_attr "type" "arith") | |
1308 | (set_attr "mode" "SI") | |
1309 | (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "") | |
0ff83799 MM |
1310 | (const_int 4) |
1311 | (const_int 8)))]) | |
2bcb2ab3 GK |
1312 | |
1313 | ||
1314 | (define_insn "" | |
1315 | [(set (match_operand:SI 0 "register_operand" "=d,d,d") | |
1316 | (minus:SI (match_operand:SI 1 "register_operand" "0,d,d") | |
1317 | (match_operand:SI 2 "arith_operand" "I,O,d")))] | |
1318 | "TARGET_MIPS16 | |
1319 | && (GET_CODE (operands[2]) != CONST_INT | |
1320 | || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))" | |
1321 | "* | |
1322 | { | |
1323 | if (REGNO (operands[0]) == REGNO (operands[1])) | |
1324 | return \"subu\\t%0,%2\"; | |
1325 | return \"subu\\t%0,%1,%2\"; | |
1326 | }" | |
1327 | [(set_attr "type" "arith") | |
1328 | (set_attr "mode" "SI") | |
1329 | (set_attr_alternative "length" | |
1330 | [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "") | |
0ff83799 MM |
1331 | (const_int 4) |
1332 | (const_int 8)) | |
2bcb2ab3 | 1333 | (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "") |
0ff83799 MM |
1334 | (const_int 4) |
1335 | (const_int 8)) | |
1336 | (const_int 4)])]) | |
2bcb2ab3 | 1337 | |
5bdc5878 | 1338 | ;; On the mips16, we can sometimes split a subtract of a constant |
2bcb2ab3 GK |
1339 | ;; which is a 4 byte instruction into two adds which are both 2 byte |
1340 | ;; instructions. There are two cases: one where we are setting a | |
1341 | ;; register to a register minus a constant, and one where we are | |
1342 | ;; simply subtracting a constant from a register. | |
1343 | ||
1344 | (define_split | |
1345 | [(set (match_operand:SI 0 "register_operand" "") | |
1346 | (minus:SI (match_dup 0) | |
1347 | (match_operand:SI 1 "const_int_operand" "")))] | |
2ca2d9ee | 1348 | "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
1349 | && GET_CODE (operands[0]) == REG |
1350 | && M16_REG_P (REGNO (operands[0])) | |
1351 | && GET_CODE (operands[1]) == CONST_INT | |
1352 | && ((INTVAL (operands[1]) > 0x80 | |
1353 | && INTVAL (operands[1]) <= 0x80 + 0x80) | |
1354 | || (INTVAL (operands[1]) < - 0x7f | |
1355 | && INTVAL (operands[1]) >= - 0x7f - 0x7f))" | |
1356 | [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1))) | |
1357 | (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))] | |
1358 | " | |
1359 | { | |
1360 | HOST_WIDE_INT val = INTVAL (operands[1]); | |
1361 | ||
1362 | if (val >= 0) | |
1363 | { | |
1364 | operands[1] = GEN_INT (0x80); | |
1365 | operands[2] = GEN_INT (val - 0x80); | |
1366 | } | |
1367 | else | |
1368 | { | |
1369 | operands[1] = GEN_INT (- 0x7f); | |
1370 | operands[2] = GEN_INT (val + 0x7f); | |
1371 | } | |
1372 | }") | |
1373 | ||
1374 | (define_split | |
1375 | [(set (match_operand:SI 0 "register_operand" "") | |
1376 | (minus:SI (match_operand:SI 1 "register_operand" "") | |
1377 | (match_operand:SI 2 "const_int_operand" "")))] | |
2ca2d9ee | 1378 | "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
1379 | && GET_CODE (operands[0]) == REG |
1380 | && M16_REG_P (REGNO (operands[0])) | |
1381 | && GET_CODE (operands[1]) == REG | |
1382 | && M16_REG_P (REGNO (operands[1])) | |
1383 | && REGNO (operands[0]) != REGNO (operands[1]) | |
1384 | && GET_CODE (operands[2]) == CONST_INT | |
1385 | && ((INTVAL (operands[2]) > 0x8 | |
1386 | && INTVAL (operands[2]) <= 0x8 + 0x80) | |
1387 | || (INTVAL (operands[2]) < - 0x7 | |
1388 | && INTVAL (operands[2]) >= - 0x7 - 0x7f))" | |
1389 | [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2))) | |
1390 | (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))] | |
1391 | " | |
1392 | { | |
1393 | HOST_WIDE_INT val = INTVAL (operands[2]); | |
1394 | ||
1395 | if (val >= 0) | |
1396 | { | |
1397 | operands[2] = GEN_INT (0x8); | |
1398 | operands[3] = GEN_INT (val - 0x8); | |
1399 | } | |
1400 | else | |
1401 | { | |
1402 | operands[2] = GEN_INT (- 0x7); | |
1403 | operands[3] = GEN_INT (val + 0x7); | |
1404 | } | |
1405 | }") | |
1406 | ||
8ef30996 MM |
1407 | (define_expand "subdi3" |
1408 | [(parallel [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
1409 | (minus:DI (match_operand:DI 1 "register_operand" "d") |
1410 | (match_operand:DI 2 "register_operand" "d"))) | |
8ef30996 | 1411 | (clobber (match_dup 3))])] |
2bcb2ab3 | 1412 | "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)" |
bb621ad7 JW |
1413 | " |
1414 | { | |
1415 | if (TARGET_64BIT) | |
1416 | { | |
1417 | emit_insn (gen_subdi3_internal_3 (operands[0], operands[1], | |
1418 | operands[2])); | |
1419 | DONE; | |
1420 | } | |
1421 | ||
1422 | operands[3] = gen_reg_rtx (SImode); | |
1423 | }") | |
8ef30996 MM |
1424 | |
1425 | (define_insn "subdi3_internal" | |
1426 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1427 | (minus:DI (match_operand:DI 1 "register_operand" "d") | |
1428 | (match_operand:DI 2 "register_operand" "d"))) | |
1429 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2bcb2ab3 | 1430 | "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16" |
8ef30996 MM |
1431 | "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3" |
1432 | [(set_attr "type" "darith") | |
1433 | (set_attr "mode" "DI") | |
0ff83799 | 1434 | (set_attr "length" "16")]) |
8ef30996 MM |
1435 | |
1436 | (define_split | |
1437 | [(set (match_operand:DI 0 "register_operand" "") | |
1438 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
1439 | (match_operand:DI 2 "register_operand" ""))) | |
1440 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
1441 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT |
1442 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
1443 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
1444 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
1445 | && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" | |
1446 | ||
1447 | [(set (match_dup 3) | |
34b650b3 | 1448 | (ltu:SI (subreg:SI (match_dup 1) 0) |
6d518002 | 1449 | (subreg:SI (match_dup 2) 0))) |
8ef30996 MM |
1450 | |
1451 | (set (subreg:SI (match_dup 0) 0) | |
1452 | (minus:SI (subreg:SI (match_dup 1) 0) | |
1453 | (subreg:SI (match_dup 2) 0))) | |
1454 | ||
ddef6bc7 JJ |
1455 | (set (subreg:SI (match_dup 0) 4) |
1456 | (minus:SI (subreg:SI (match_dup 1) 4) | |
1457 | (subreg:SI (match_dup 2) 4))) | |
8ef30996 | 1458 | |
ddef6bc7 JJ |
1459 | (set (subreg:SI (match_dup 0) 4) |
1460 | (minus:SI (subreg:SI (match_dup 0) 4) | |
8ef30996 MM |
1461 | (match_dup 3)))] |
1462 | "") | |
1463 | ||
1464 | (define_split | |
1465 | [(set (match_operand:DI 0 "register_operand" "") | |
1466 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
1467 | (match_operand:DI 2 "register_operand" ""))) | |
1468 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
1469 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT |
1470 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
1471 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
1472 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
1473 | && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" | |
1474 | ||
1475 | [(set (match_dup 3) | |
ddef6bc7 JJ |
1476 | (ltu:SI (subreg:SI (match_dup 1) 4) |
1477 | (subreg:SI (match_dup 2) 4))) | |
8ef30996 | 1478 | |
ddef6bc7 JJ |
1479 | (set (subreg:SI (match_dup 0) 4) |
1480 | (minus:SI (subreg:SI (match_dup 1) 4) | |
1481 | (subreg:SI (match_dup 2) 4))) | |
8ef30996 MM |
1482 | |
1483 | (set (subreg:SI (match_dup 0) 0) | |
1484 | (minus:SI (subreg:SI (match_dup 1) 0) | |
1485 | (subreg:SI (match_dup 2) 0))) | |
1486 | ||
1487 | (set (subreg:SI (match_dup 0) 0) | |
1488 | (minus:SI (subreg:SI (match_dup 0) 0) | |
1489 | (match_dup 3)))] | |
1490 | "") | |
1491 | ||
1492 | (define_insn "subdi3_internal_2" | |
1493 | [(set (match_operand:DI 0 "register_operand" "=d,d,d") | |
1494 | (minus:DI (match_operand:DI 1 "register_operand" "d,d,d") | |
1495 | (match_operand:DI 2 "small_int" "P,J,N"))) | |
1496 | (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))] | |
2bcb2ab3 GK |
1497 | "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 |
1498 | && INTVAL (operands[2]) != -32768" | |
8ef30996 MM |
1499 | "@ |
1500 | sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3 | |
1501 | move\\t%L0,%L1\;move\\t%M0,%M1 | |
1502 | sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3" | |
92b4cee1 MM |
1503 | [(set_attr "type" "darith") |
1504 | (set_attr "mode" "DI") | |
0ff83799 | 1505 | (set_attr "length" "12,8,16")]) |
8ef30996 MM |
1506 | |
1507 | (define_split | |
1508 | [(set (match_operand:DI 0 "register_operand" "") | |
1509 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
1510 | (match_operand:DI 2 "small_int" ""))) | |
1511 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
1512 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT |
1513 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
1514 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
1515 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
1516 | && INTVAL (operands[2]) > 0" | |
1517 | ||
1518 | [(set (match_dup 3) | |
34b650b3 | 1519 | (ltu:SI (subreg:SI (match_dup 1) 0) |
8ef30996 MM |
1520 | (match_dup 2))) |
1521 | ||
1522 | (set (subreg:SI (match_dup 0) 0) | |
1523 | (minus:SI (subreg:SI (match_dup 1) 0) | |
1524 | (match_dup 2))) | |
1525 | ||
ddef6bc7 JJ |
1526 | (set (subreg:SI (match_dup 0) 4) |
1527 | (minus:SI (subreg:SI (match_dup 1) 4) | |
8ef30996 MM |
1528 | (match_dup 3)))] |
1529 | "") | |
1530 | ||
1531 | (define_split | |
1532 | [(set (match_operand:DI 0 "register_operand" "") | |
1533 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
1534 | (match_operand:DI 2 "small_int" ""))) | |
1535 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
1536 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT |
1537 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
1538 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
1539 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) | |
1540 | && INTVAL (operands[2]) > 0" | |
1541 | ||
1542 | [(set (match_dup 3) | |
ddef6bc7 | 1543 | (ltu:SI (subreg:SI (match_dup 1) 4) |
8ef30996 MM |
1544 | (match_dup 2))) |
1545 | ||
ddef6bc7 JJ |
1546 | (set (subreg:SI (match_dup 0) 4) |
1547 | (minus:SI (subreg:SI (match_dup 1) 4) | |
8ef30996 MM |
1548 | (match_dup 2))) |
1549 | ||
1550 | (set (subreg:SI (match_dup 0) 0) | |
1551 | (minus:SI (subreg:SI (match_dup 1) 0) | |
1552 | (match_dup 3)))] | |
1553 | "") | |
1554 | ||
bb621ad7 JW |
1555 | (define_insn "subdi3_internal_3" |
1556 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
1557 | (minus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ") |
1558 | (match_operand:DI 2 "arith_operand" "dI")))] | |
2bcb2ab3 GK |
1559 | "TARGET_64BIT && !TARGET_MIPS16 |
1560 | && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" | |
bb621ad7 JW |
1561 | "* |
1562 | { | |
1563 | return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) | |
1564 | ? \"daddu\\t%0,%z1,%n2\" | |
1565 | : \"dsubu\\t%0,%z1,%2\"; | |
1566 | }" | |
1567 | [(set_attr "type" "darith") | |
0ff83799 | 1568 | (set_attr "mode" "DI")]) |
bb621ad7 | 1569 | |
2bcb2ab3 GK |
1570 | ;; For the mips16, we need to recognize stack pointer subtractions |
1571 | ;; explicitly, since we don't have a constraint for $sp. These insns | |
1572 | ;; will be generated by the save_restore_insns functions. | |
1573 | ||
1574 | (define_insn "" | |
1575 | [(set (reg:DI 29) | |
1576 | (minus:DI (reg:DI 29) | |
1577 | (match_operand:DI 0 "small_int" "I")))] | |
1578 | "TARGET_MIPS16 | |
1579 | && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" | |
1580 | "daddu\\t%$,%$,%n0" | |
1581 | [(set_attr "type" "arith") | |
1582 | (set_attr "mode" "DI") | |
1583 | (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "") | |
0ff83799 MM |
1584 | (const_int 4) |
1585 | (const_int 8)))]) | |
2bcb2ab3 GK |
1586 | |
1587 | (define_insn "" | |
1588 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1589 | (minus:DI (reg:DI 29) | |
1590 | (match_operand:DI 1 "small_int" "I")))] | |
1591 | "TARGET_MIPS16 | |
1592 | && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" | |
1593 | "daddu\\t%0,%$,%n1" | |
1594 | [(set_attr "type" "arith") | |
1595 | (set_attr "mode" "DI") | |
1596 | (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "") | |
0ff83799 MM |
1597 | (const_int 4) |
1598 | (const_int 8)))]) | |
2bcb2ab3 GK |
1599 | |
1600 | (define_insn "" | |
1601 | [(set (match_operand:DI 0 "register_operand" "=d,d,d") | |
1602 | (minus:DI (match_operand:DI 1 "register_operand" "0,d,d") | |
1603 | (match_operand:DI 2 "arith_operand" "I,O,d")))] | |
1604 | "TARGET_MIPS16 | |
1605 | && (GET_CODE (operands[2]) != CONST_INT | |
1606 | || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))" | |
1607 | "* | |
1608 | { | |
1609 | if (REGNO (operands[0]) == REGNO (operands[1])) | |
1610 | return \"dsubu\\t%0,%2\"; | |
1611 | return \"dsubu\\t%0,%1,%2\"; | |
1612 | }" | |
1613 | [(set_attr "type" "arith") | |
1614 | (set_attr "mode" "DI") | |
1615 | (set_attr_alternative "length" | |
1616 | [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "") | |
0ff83799 MM |
1617 | (const_int 4) |
1618 | (const_int 8)) | |
2bcb2ab3 | 1619 | (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "") |
0ff83799 MM |
1620 | (const_int 4) |
1621 | (const_int 8)) | |
1622 | (const_int 4)])]) | |
2bcb2ab3 GK |
1623 | |
1624 | ;; On the mips16, we can sometimes split an add of a constant which is | |
1625 | ;; a 4 byte instruction into two adds which are both 2 byte | |
1626 | ;; instructions. There are two cases: one where we are adding a | |
1627 | ;; constant plus a register to another register, and one where we are | |
1628 | ;; simply adding a constant to a register. | |
1629 | ||
1630 | (define_split | |
1631 | [(set (match_operand:DI 0 "register_operand" "") | |
1632 | (minus:DI (match_dup 0) | |
1633 | (match_operand:DI 1 "const_int_operand" "")))] | |
2ca2d9ee | 1634 | "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
1635 | && GET_CODE (operands[0]) == REG |
1636 | && M16_REG_P (REGNO (operands[0])) | |
1637 | && GET_CODE (operands[1]) == CONST_INT | |
1638 | && ((INTVAL (operands[1]) > 0x10 | |
1639 | && INTVAL (operands[1]) <= 0x10 + 0x10) | |
1640 | || (INTVAL (operands[1]) < - 0xf | |
1641 | && INTVAL (operands[1]) >= - 0xf - 0xf))" | |
1642 | [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1))) | |
1643 | (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))] | |
1644 | " | |
1645 | { | |
1646 | HOST_WIDE_INT val = INTVAL (operands[1]); | |
1647 | ||
1648 | if (val >= 0) | |
1649 | { | |
1650 | operands[1] = GEN_INT (0xf); | |
1651 | operands[2] = GEN_INT (val - 0xf); | |
1652 | } | |
1653 | else | |
1654 | { | |
1655 | operands[1] = GEN_INT (- 0x10); | |
1656 | operands[2] = GEN_INT (val + 0x10); | |
1657 | } | |
1658 | }") | |
1659 | ||
1660 | (define_split | |
1661 | [(set (match_operand:DI 0 "register_operand" "") | |
1662 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
1663 | (match_operand:DI 2 "const_int_operand" "")))] | |
2ca2d9ee | 1664 | "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
1665 | && GET_CODE (operands[0]) == REG |
1666 | && M16_REG_P (REGNO (operands[0])) | |
1667 | && GET_CODE (operands[1]) == REG | |
1668 | && M16_REG_P (REGNO (operands[1])) | |
1669 | && REGNO (operands[0]) != REGNO (operands[1]) | |
1670 | && GET_CODE (operands[2]) == CONST_INT | |
1671 | && ((INTVAL (operands[2]) > 0x8 | |
1672 | && INTVAL (operands[2]) <= 0x8 + 0x10) | |
1673 | || (INTVAL (operands[2]) < - 0x7 | |
1674 | && INTVAL (operands[2]) >= - 0x7 - 0xf))" | |
1675 | [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2))) | |
1676 | (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))] | |
1677 | " | |
1678 | { | |
1679 | HOST_WIDE_INT val = INTVAL (operands[2]); | |
1680 | ||
1681 | if (val >= 0) | |
1682 | { | |
1683 | operands[2] = GEN_INT (0x8); | |
1684 | operands[3] = GEN_INT (val - 0x8); | |
1685 | } | |
1686 | else | |
1687 | { | |
1688 | operands[2] = GEN_INT (- 0x7); | |
1689 | operands[3] = GEN_INT (val + 0x7); | |
1690 | } | |
1691 | }") | |
bb621ad7 JW |
1692 | |
1693 | (define_insn "subsi3_internal_2" | |
1694 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1695 | (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") | |
1696 | (match_operand:SI 2 "arith_operand" "dI"))))] | |
2bcb2ab3 GK |
1697 | "TARGET_64BIT && !TARGET_MIPS16 |
1698 | && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" | |
bb621ad7 JW |
1699 | "* |
1700 | { | |
1701 | return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) | |
1702 | ? \"addu\\t%0,%z1,%n2\" | |
1703 | : \"subu\\t%0,%z1,%2\"; | |
1704 | }" | |
1705 | [(set_attr "type" "arith") | |
0ff83799 | 1706 | (set_attr "mode" "DI")]) |
bb621ad7 | 1707 | |
2bcb2ab3 GK |
1708 | (define_insn "" |
1709 | [(set (match_operand:DI 0 "register_operand" "=d,d,d") | |
1710 | (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d") | |
1711 | (match_operand:SI 2 "arith_operand" "I,O,d"))))] | |
1712 | "TARGET_64BIT && TARGET_MIPS16 | |
1713 | && (GET_CODE (operands[2]) != CONST_INT | |
1714 | || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))" | |
1715 | "* | |
1716 | { | |
1717 | if (REGNO (operands[0]) == REGNO (operands[1])) | |
1718 | return \"subu\\t%0,%2\"; | |
1719 | return \"subu\\t%0,%1,%2\"; | |
1720 | }" | |
1721 | [(set_attr "type" "arith") | |
1722 | (set_attr "mode" "SI") | |
1723 | (set_attr_alternative "length" | |
1724 | [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "") | |
0ff83799 MM |
1725 | (const_int 4) |
1726 | (const_int 8)) | |
2bcb2ab3 | 1727 | (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "") |
0ff83799 MM |
1728 | (const_int 4) |
1729 | (const_int 8)) | |
1730 | (const_int 4)])]) | |
7a38df19 | 1731 | |
2bcb2ab3 | 1732 | |
8ef30996 MM |
1733 | \f |
1734 | ;; | |
1735 | ;; .................... | |
1736 | ;; | |
1737 | ;; MULTIPLICATION | |
1738 | ;; | |
1739 | ;; .................... | |
1740 | ;; | |
1741 | ||
aa4e54c4 JW |
1742 | ;; Early Vr4300 silicon has a CPU bug where multiplies with certain |
1743 | ;; operands may corrupt immediately following multiplies. This is a | |
1744 | ;; simple fix to insert NOPs. | |
8fbaea49 JW |
1745 | |
1746 | (define_expand "muldf3" | |
8ef30996 MM |
1747 | [(set (match_operand:DF 0 "register_operand" "=f") |
1748 | (mult:DF (match_operand:DF 1 "register_operand" "f") | |
1749 | (match_operand:DF 2 "register_operand" "f")))] | |
46299de9 | 1750 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
8fbaea49 JW |
1751 | " |
1752 | { | |
41f9efba | 1753 | if (!TARGET_MIPS4300) |
8fbaea49 JW |
1754 | emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2])); |
1755 | else | |
1756 | emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2])); | |
1757 | DONE; | |
1758 | }") | |
1759 | ||
1760 | (define_insn "muldf3_internal" | |
1761 | [(set (match_operand:DF 0 "register_operand" "=f") | |
1762 | (mult:DF (match_operand:DF 1 "register_operand" "f") | |
1763 | (match_operand:DF 2 "register_operand" "f")))] | |
41f9efba | 1764 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_MIPS4300" |
8ef30996 MM |
1765 | "mul.d\\t%0,%1,%2" |
1766 | [(set_attr "type" "fmul") | |
0ff83799 | 1767 | (set_attr "mode" "DF")]) |
8ef30996 | 1768 | |
8fbaea49 JW |
1769 | (define_insn "muldf3_r4300" |
1770 | [(set (match_operand:DF 0 "register_operand" "=f") | |
1771 | (mult:DF (match_operand:DF 1 "register_operand" "f") | |
1772 | (match_operand:DF 2 "register_operand" "f")))] | |
41f9efba | 1773 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_MIPS4300" |
8fbaea49 JW |
1774 | "* |
1775 | { | |
1776 | output_asm_insn (\"mul.d\\t%0,%1,%2\", operands); | |
1777 | if (TARGET_4300_MUL_FIX) | |
1778 | output_asm_insn (\"nop\", operands); | |
1779 | return \"\"; | |
1780 | }" | |
1781 | [(set_attr "type" "fmul") | |
1782 | (set_attr "mode" "DF") | |
0ff83799 | 1783 | (set_attr "length" "8")]) ;; mul.d + nop |
8fbaea49 JW |
1784 | |
1785 | (define_expand "mulsf3" | |
8ef30996 MM |
1786 | [(set (match_operand:SF 0 "register_operand" "=f") |
1787 | (mult:SF (match_operand:SF 1 "register_operand" "f") | |
1788 | (match_operand:SF 2 "register_operand" "f")))] | |
1789 | "TARGET_HARD_FLOAT" | |
8fbaea49 JW |
1790 | " |
1791 | { | |
41f9efba | 1792 | if (!TARGET_MIPS4300) |
8fbaea49 JW |
1793 | emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2])); |
1794 | else | |
1795 | emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2])); | |
1796 | DONE; | |
1797 | }") | |
1798 | ||
1799 | (define_insn "mulsf3_internal" | |
1800 | [(set (match_operand:SF 0 "register_operand" "=f") | |
1801 | (mult:SF (match_operand:SF 1 "register_operand" "f") | |
1802 | (match_operand:SF 2 "register_operand" "f")))] | |
41f9efba | 1803 | "TARGET_HARD_FLOAT && !TARGET_MIPS4300" |
8ef30996 MM |
1804 | "mul.s\\t%0,%1,%2" |
1805 | [(set_attr "type" "fmul") | |
0ff83799 | 1806 | (set_attr "mode" "SF")]) |
8ef30996 | 1807 | |
8fbaea49 JW |
1808 | (define_insn "mulsf3_r4300" |
1809 | [(set (match_operand:SF 0 "register_operand" "=f") | |
1810 | (mult:SF (match_operand:SF 1 "register_operand" "f") | |
1811 | (match_operand:SF 2 "register_operand" "f")))] | |
41f9efba | 1812 | "TARGET_HARD_FLOAT && TARGET_MIPS4300" |
8fbaea49 JW |
1813 | "* |
1814 | { | |
1815 | output_asm_insn (\"mul.s\\t%0,%1,%2\", operands); | |
1816 | if (TARGET_4300_MUL_FIX) | |
1817 | output_asm_insn (\"nop\", operands); | |
1818 | return \"\"; | |
1819 | }" | |
1820 | [(set_attr "type" "fmul") | |
1821 | (set_attr "mode" "SF") | |
0ff83799 | 1822 | (set_attr "length" "8")]) ;; mul.s + nop |
8fbaea49 | 1823 | |
cb923660 | 1824 | |
46299de9 ILT |
1825 | ;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while |
1826 | ;; a multiply is in progress, it may give an incorrect result. Avoid | |
1827 | ;; this by keeping the mflo with the mult on the R4000. | |
1828 | ||
1829 | (define_expand "mulsi3" | |
1830 | [(set (match_operand:SI 0 "register_operand" "=l") | |
8ef30996 MM |
1831 | (mult:SI (match_operand:SI 1 "register_operand" "d") |
1832 | (match_operand:SI 2 "register_operand" "d"))) | |
225b8835 ILT |
1833 | (clobber (match_scratch:SI 3 "=h")) |
1834 | (clobber (match_scratch:SI 4 "=a"))] | |
8ef30996 | 1835 | "" |
46299de9 ILT |
1836 | " |
1837 | { | |
0e5a4ad8 | 1838 | if (GENERATE_MULT3_SI || TARGET_MAD) |
e9a25f70 | 1839 | emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2])); |
7dac2f89 | 1840 | else if (!TARGET_MIPS4000 || TARGET_MIPS16) |
46299de9 ILT |
1841 | emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2])); |
1842 | else | |
1843 | emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2])); | |
1844 | DONE; | |
1845 | }") | |
1846 | ||
e9a25f70 | 1847 | (define_insn "mulsi3_mult3" |
e4f5c5d6 | 1848 | [(set (match_operand:SI 0 "register_operand" "=d,l") |
cb923660 KR |
1849 | (mult:SI (match_operand:SI 1 "register_operand" "d,d") |
1850 | (match_operand:SI 2 "register_operand" "d,d"))) | |
1851 | (clobber (match_scratch:SI 3 "=h,h")) | |
1852 | (clobber (match_scratch:SI 4 "=l,X")) | |
1853 | (clobber (match_scratch:SI 5 "=a,a"))] | |
0e5a4ad8 | 1854 | "GENERATE_MULT3_SI |
e4f5c5d6 | 1855 | || TARGET_MAD" |
cb923660 KR |
1856 | "* |
1857 | { | |
1858 | if (which_alternative == 1) | |
1859 | return \"mult\\t%1,%2\"; | |
0e5a4ad8 | 1860 | if (TARGET_MAD |
5ce6f47b EC |
1861 | || TARGET_MIPS5400 |
1862 | || TARGET_MIPS5500 | |
ce3649d2 | 1863 | || ISA_MIPS32 |
2d2a50c3 | 1864 | || ISA_MIPS32R2 |
ce3649d2 | 1865 | || ISA_MIPS64) |
cb923660 KR |
1866 | return \"mul\\t%0,%1,%2\"; |
1867 | return \"mult\\t%0,%1,%2\"; | |
1868 | }" | |
e9a25f70 | 1869 | [(set_attr "type" "imul") |
0ff83799 | 1870 | (set_attr "mode" "SI")]) |
e9a25f70 | 1871 | |
cafe096b EC |
1872 | ;; If a register gets allocated to LO, and we spill to memory, the reload |
1873 | ;; will include a move from LO to a GPR. Merge it into the multiplication | |
1874 | ;; if it can set the GPR directly. | |
1875 | ;; | |
1876 | ;; Operand 0: LO | |
1877 | ;; Operand 1: GPR (1st multiplication operand) | |
1878 | ;; Operand 2: GPR (2nd multiplication operand) | |
1879 | ;; Operand 3: HI | |
1880 | ;; Operand 4: HILO | |
1881 | ;; Operand 5: GPR (destination) | |
1882 | (define_peephole2 | |
1883 | [(parallel | |
1884 | [(set (match_operand:SI 0 "register_operand" "") | |
1885 | (mult:SI (match_operand:SI 1 "register_operand" "") | |
1886 | (match_operand:SI 2 "register_operand" ""))) | |
1887 | (clobber (match_operand:SI 3 "register_operand" "")) | |
1888 | (clobber (scratch:SI)) | |
1889 | (clobber (match_operand:SI 4 "register_operand" ""))]) | |
1890 | (set (match_operand:SI 5 "register_operand" "") | |
1891 | (match_dup 0))] | |
1892 | "GENERATE_MULT3_SI | |
1893 | && true_regnum (operands[0]) == LO_REGNUM | |
1894 | && GP_REG_P (true_regnum (operands[5])) | |
1895 | && peep2_reg_dead_p (2, operands[0])" | |
1896 | [(parallel | |
1897 | [(set (match_dup 5) | |
1898 | (mult:SI (match_dup 1) | |
1899 | (match_dup 2))) | |
1900 | (clobber (match_dup 3)) | |
1901 | (clobber (match_dup 0)) | |
1902 | (clobber (match_dup 4))])]) | |
1903 | ||
46299de9 ILT |
1904 | (define_insn "mulsi3_internal" |
1905 | [(set (match_operand:SI 0 "register_operand" "=l") | |
1906 | (mult:SI (match_operand:SI 1 "register_operand" "d") | |
1907 | (match_operand:SI 2 "register_operand" "d"))) | |
225b8835 ILT |
1908 | (clobber (match_scratch:SI 3 "=h")) |
1909 | (clobber (match_scratch:SI 4 "=a"))] | |
7dac2f89 | 1910 | "!TARGET_MIPS4000 || TARGET_MIPS16" |
46299de9 ILT |
1911 | "mult\\t%1,%2" |
1912 | [(set_attr "type" "imul") | |
0ff83799 | 1913 | (set_attr "mode" "SI")]) |
46299de9 ILT |
1914 | |
1915 | (define_insn "mulsi3_r4000" | |
1916 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1917 | (mult:SI (match_operand:SI 1 "register_operand" "d") | |
1918 | (match_operand:SI 2 "register_operand" "d"))) | |
1919 | (clobber (match_scratch:SI 3 "=h")) | |
225b8835 ILT |
1920 | (clobber (match_scratch:SI 4 "=l")) |
1921 | (clobber (match_scratch:SI 5 "=a"))] | |
7dac2f89 | 1922 | "TARGET_MIPS4000 && !TARGET_MIPS16" |
8ef30996 MM |
1923 | "* |
1924 | { | |
1925 | rtx xoperands[10]; | |
1926 | ||
1927 | xoperands[0] = operands[0]; | |
c5c76735 | 1928 | xoperands[1] = gen_rtx_REG (SImode, LO_REGNUM); |
8ef30996 MM |
1929 | |
1930 | output_asm_insn (\"mult\\t%1,%2\", operands); | |
bb621ad7 | 1931 | output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands); |
8ef30996 MM |
1932 | return \"\"; |
1933 | }" | |
1934 | [(set_attr "type" "imul") | |
1935 | (set_attr "mode" "SI") | |
0ff83799 | 1936 | (set_attr "length" "12")]) ;; mult + mflo + delay |
8ef30996 | 1937 | |
e4f5c5d6 KR |
1938 | ;; Multiply-accumulate patterns |
1939 | ||
1940 | ;; For processors that can copy the output to a general register: | |
1941 | ;; | |
cb923660 KR |
1942 | ;; The all-d alternative is needed because the combiner will find this |
1943 | ;; pattern and then register alloc/reload will move registers around to | |
1944 | ;; make them fit, and we don't want to trigger unnecessary loads to LO. | |
e4f5c5d6 KR |
1945 | ;; |
1946 | ;; The last alternative should be made slightly less desirable, but adding | |
1947 | ;; "?" to the constraint is too strong, and causes values to be loaded into | |
1948 | ;; LO even when that's more costly. For now, using "*d" mostly does the | |
1949 | ;; trick. | |
cb923660 | 1950 | (define_insn "*mul_acc_si" |
e4f5c5d6 | 1951 | [(set (match_operand:SI 0 "register_operand" "=l,*d,*d") |
cb923660 KR |
1952 | (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d") |
1953 | (match_operand:SI 2 "register_operand" "d,d,d")) | |
e4f5c5d6 | 1954 | (match_operand:SI 3 "register_operand" "0,l,*d"))) |
cb923660 KR |
1955 | (clobber (match_scratch:SI 4 "=h,h,h")) |
1956 | (clobber (match_scratch:SI 5 "=X,3,l")) | |
1957 | (clobber (match_scratch:SI 6 "=a,a,a")) | |
1958 | (clobber (match_scratch:SI 7 "=X,X,d"))] | |
bbea0391 NC |
1959 | "(TARGET_MIPS3900 |
1960 | || ISA_HAS_MADD_MSUB) | |
e4f5c5d6 | 1961 | && !TARGET_MIPS16" |
cb923660 KR |
1962 | "* |
1963 | { | |
e2fe6aba | 1964 | static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" }; |
cb923660 KR |
1965 | if (which_alternative == 2) |
1966 | return \"#\"; | |
0e5a4ad8 EC |
1967 | if (ISA_HAS_MADD_MSUB && which_alternative != 0) |
1968 | return \"#\"; | |
cb923660 KR |
1969 | return madd[which_alternative]; |
1970 | }" | |
1d4047e0 | 1971 | [(set_attr "type" "imadd,imadd,multi") |
053665d7 | 1972 | (set_attr "mode" "SI") |
0ff83799 | 1973 | (set_attr "length" "4,4,8")]) |
cb923660 | 1974 | |
e4f5c5d6 | 1975 | ;; Split the above insn if we failed to get LO allocated. |
cb923660 KR |
1976 | (define_split |
1977 | [(set (match_operand:SI 0 "register_operand" "") | |
1978 | (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "") | |
1979 | (match_operand:SI 2 "register_operand" "")) | |
1980 | (match_operand:SI 3 "register_operand" ""))) | |
1981 | (clobber (match_scratch:SI 4 "")) | |
1982 | (clobber (match_scratch:SI 5 "")) | |
1983 | (clobber (match_scratch:SI 6 "")) | |
1984 | (clobber (match_scratch:SI 7 ""))] | |
2ca2d9ee EC |
1985 | "reload_completed && !TARGET_DEBUG_D_MODE |
1986 | && GP_REG_P (true_regnum (operands[0])) | |
1987 | && GP_REG_P (true_regnum (operands[3]))" | |
cb923660 KR |
1988 | [(parallel [(set (match_dup 7) |
1989 | (mult:SI (match_dup 1) (match_dup 2))) | |
1990 | (clobber (match_dup 4)) | |
1991 | (clobber (match_dup 5)) | |
1992 | (clobber (match_dup 6))]) | |
1993 | (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))] | |
1994 | "") | |
1995 | ||
0e5a4ad8 EC |
1996 | ;; Splitter to copy result of MADD to a general register |
1997 | (define_split | |
1998 | [(set (match_operand:SI 0 "register_operand" "") | |
1999 | (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "") | |
2000 | (match_operand:SI 2 "register_operand" "")) | |
2001 | (match_operand:SI 3 "register_operand" ""))) | |
2002 | (clobber (match_scratch:SI 4 "")) | |
2003 | (clobber (match_scratch:SI 5 "")) | |
2004 | (clobber (match_scratch:SI 6 "")) | |
2005 | (clobber (match_scratch:SI 7 ""))] | |
2ca2d9ee EC |
2006 | "reload_completed && !TARGET_DEBUG_D_MODE |
2007 | && GP_REG_P (true_regnum (operands[0])) | |
0e5a4ad8 EC |
2008 | && true_regnum (operands[3]) == LO_REGNUM" |
2009 | [(parallel [(set (match_dup 3) | |
2010 | (plus:SI (mult:SI (match_dup 1) (match_dup 2)) | |
2011 | (match_dup 3))) | |
2012 | (clobber (match_dup 4)) | |
2013 | (clobber (match_dup 5)) | |
2014 | (clobber (match_dup 6)) | |
2015 | (clobber (match_dup 7))]) | |
2016 | (set (match_dup 0) (match_dup 3))] | |
2017 | "") | |
2018 | ||
cafe096b EC |
2019 | (define_insn "*macc" |
2020 | [(set (match_operand:SI 0 "register_operand" "=l,d") | |
2021 | (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") | |
2022 | (match_operand:SI 2 "register_operand" "d,d")) | |
2023 | (match_operand:SI 3 "register_operand" "0,l"))) | |
2024 | (clobber (match_scratch:SI 4 "=h,h")) | |
2025 | (clobber (match_scratch:SI 5 "=X,3")) | |
2026 | (clobber (match_scratch:SI 6 "=a,a"))] | |
2027 | "ISA_HAS_MACC" | |
2028 | "* | |
2029 | { | |
2030 | if (which_alternative == 1) | |
2031 | return \"macc\\t%0,%1,%2\"; | |
2032 | else if (TARGET_MIPS5500) | |
2033 | return \"madd\\t%1,%2\"; | |
2034 | else | |
2035 | return \"macc\\t%.,%1,%2\"; | |
2036 | }" | |
2037 | [(set_attr "type" "imadd") | |
2038 | (set_attr "mode" "SI")]) | |
2039 | ||
2040 | ;; Pattern generated by define_peephole2 below | |
2041 | (define_insn "*macc2" | |
2042 | [(set (match_operand:SI 0 "register_operand" "=l") | |
2043 | (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d") | |
2044 | (match_operand:SI 2 "register_operand" "d")) | |
2045 | (match_dup 0))) | |
2046 | (set (match_operand:SI 3 "register_operand" "=d") | |
2047 | (plus:SI (mult:SI (match_dup 1) | |
2048 | (match_dup 2)) | |
2049 | (match_dup 0))) | |
2050 | (clobber (match_scratch:SI 4 "=h")) | |
2051 | (clobber (match_scratch:SI 5 "=a"))] | |
2052 | "ISA_HAS_MACC && reload_completed" | |
2053 | "macc\\t%3,%1,%2" | |
2054 | [(set_attr "type" "imadd") | |
2055 | (set_attr "mode" "SI")]) | |
2056 | ||
2057 | ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2> | |
2058 | ;; | |
2059 | ;; Operand 0: LO | |
2060 | ;; Operand 1: GPR (1st multiplication operand) | |
2061 | ;; Operand 2: GPR (2nd multiplication operand) | |
2062 | ;; Operand 3: HI | |
2063 | ;; Operand 4: HILO | |
2064 | ;; Operand 5: GPR (destination) | |
2065 | (define_peephole2 | |
2066 | [(parallel | |
2067 | [(set (match_operand:SI 0 "register_operand" "") | |
2068 | (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "") | |
2069 | (match_operand:SI 2 "register_operand" "")) | |
2070 | (match_dup 0))) | |
2071 | (clobber (match_operand:SI 3 "register_operand" "")) | |
2072 | (clobber (scratch:SI)) | |
2073 | (clobber (match_operand:SI 4 "register_operand" ""))]) | |
2074 | (set (match_operand:SI 5 "register_operand" "") | |
2075 | (match_dup 0))] | |
2076 | "ISA_HAS_MACC | |
2077 | && true_regnum (operands[0]) == LO_REGNUM | |
2078 | && GP_REG_P (true_regnum (operands[5]))" | |
2079 | [(parallel [(set (match_dup 0) | |
2080 | (plus:SI (mult:SI (match_dup 1) | |
2081 | (match_dup 2)) | |
2082 | (match_dup 0))) | |
2083 | (set (match_dup 5) | |
2084 | (plus:SI (mult:SI (match_dup 1) | |
2085 | (match_dup 2)) | |
2086 | (match_dup 0))) | |
2087 | (clobber (match_dup 3)) | |
2088 | (clobber (match_dup 4))])] | |
2089 | "") | |
2090 | ||
2091 | ;; When we have a three-address multiplication instruction, it should | |
2092 | ;; be faster to do a separate multiply and add, rather than moving | |
2093 | ;; something into LO in order to use a macc instruction. | |
2094 | ;; | |
2095 | ;; This peephole needs a scratch register to cater for the case when one | |
2096 | ;; of the multiplication operands is the same as the destination. | |
2097 | ;; | |
2098 | ;; Operand 0: GPR (scratch) | |
2099 | ;; Operand 1: LO | |
2100 | ;; Operand 2: GPR (addend) | |
2101 | ;; Operand 3: GPR (destination) | |
2102 | ;; Operand 4: GPR (1st multiplication operand) | |
2103 | ;; Operand 5: GPR (2nd multiplication operand) | |
2104 | ;; Operand 6: HI | |
2105 | ;; Operand 7: HILO | |
2106 | (define_peephole2 | |
2107 | [(match_scratch:SI 0 "d") | |
2108 | (set (match_operand:SI 1 "register_operand" "") | |
2109 | (match_operand:SI 2 "register_operand" "")) | |
2110 | (match_dup 0) | |
2111 | (parallel | |
2112 | [(set (match_operand:SI 3 "register_operand" "") | |
2113 | (plus:SI (mult:SI (match_operand:SI 4 "register_operand" "") | |
2114 | (match_operand:SI 5 "register_operand" "")) | |
2115 | (match_dup 1))) | |
2116 | (clobber (match_operand:SI 6 "register_operand" "")) | |
2117 | (clobber (match_dup 1)) | |
2118 | (clobber (match_operand:SI 7 "register_operand" ""))])] | |
2119 | "ISA_HAS_MACC && GENERATE_MULT3_SI | |
2120 | && true_regnum (operands[1]) == LO_REGNUM | |
2121 | && peep2_reg_dead_p (2, operands[1]) | |
2122 | && GP_REG_P (true_regnum (operands[3]))" | |
2123 | [(parallel [(set (match_dup 0) | |
2124 | (mult:SI (match_dup 4) | |
2125 | (match_dup 5))) | |
2126 | (clobber (match_dup 6)) | |
2127 | (clobber (match_dup 1)) | |
2128 | (clobber (match_dup 7))]) | |
2129 | (set (match_dup 3) | |
2130 | (plus:SI (match_dup 0) | |
2131 | (match_dup 2)))] | |
2132 | "") | |
2133 | ||
2134 | ;; Same as above, except LO is the initial target of the macc. | |
2135 | ;; | |
2136 | ;; Operand 0: GPR (scratch) | |
2137 | ;; Operand 1: LO | |
2138 | ;; Operand 2: GPR (addend) | |
2139 | ;; Operand 3: GPR (1st multiplication operand) | |
2140 | ;; Operand 4: GPR (2nd multiplication operand) | |
2141 | ;; Operand 5: HI | |
2142 | ;; Operand 6: HILO | |
2143 | ;; Operand 7: GPR (destination) | |
2144 | (define_peephole2 | |
2145 | [(match_scratch:SI 0 "d") | |
2146 | (set (match_operand:SI 1 "register_operand" "") | |
2147 | (match_operand:SI 2 "register_operand" "")) | |
2148 | (match_dup 0) | |
2149 | (parallel | |
2150 | [(set (match_dup 1) | |
2151 | (plus:SI (mult:SI (match_operand:SI 3 "register_operand" "") | |
2152 | (match_operand:SI 4 "register_operand" "")) | |
2153 | (match_dup 1))) | |
2154 | (clobber (match_operand:SI 5 "register_operand" "")) | |
2155 | (clobber (scratch:SI)) | |
2156 | (clobber (match_operand:SI 6 "register_operand" ""))]) | |
2157 | (match_dup 0) | |
2158 | (set (match_operand:SI 7 "register_operand" "") | |
2159 | (match_dup 1))] | |
2160 | "ISA_HAS_MACC && GENERATE_MULT3_SI | |
2161 | && true_regnum (operands[1]) == LO_REGNUM | |
2162 | && peep2_reg_dead_p (3, operands[1]) | |
2163 | && GP_REG_P (true_regnum (operands[7]))" | |
2164 | [(parallel [(set (match_dup 0) | |
2165 | (mult:SI (match_dup 3) | |
2166 | (match_dup 4))) | |
2167 | (clobber (match_dup 5)) | |
2168 | (clobber (match_dup 1)) | |
2169 | (clobber (match_dup 6))]) | |
2170 | (set (match_dup 7) | |
2171 | (plus:SI (match_dup 0) | |
2172 | (match_dup 2)))] | |
2173 | "") | |
2174 | ||
0e5a4ad8 EC |
2175 | (define_insn "*mul_sub_si" |
2176 | [(set (match_operand:SI 0 "register_operand" "=l,*d,*d") | |
2177 | (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d") | |
2178 | (mult:SI (match_operand:SI 2 "register_operand" "d,d,d") | |
2179 | (match_operand:SI 3 "register_operand" "d,d,d")))) | |
2180 | (clobber (match_scratch:SI 4 "=h,h,h")) | |
cafe096b | 2181 | (clobber (match_scratch:SI 5 "=X,1,l")) |
0e5a4ad8 EC |
2182 | (clobber (match_scratch:SI 6 "=a,a,a")) |
2183 | (clobber (match_scratch:SI 7 "=X,X,d"))] | |
2184 | "ISA_HAS_MADD_MSUB" | |
2185 | "* | |
2186 | { | |
2187 | if (which_alternative != 0) | |
2188 | return \"#\"; | |
2189 | return \"msub\\t%2,%3\"; | |
2190 | }" | |
1d4047e0 | 2191 | [(set_attr "type" "imadd,multi,multi") |
0e5a4ad8 EC |
2192 | (set_attr "mode" "SI") |
2193 | (set_attr "length" "4,8,8")]) | |
2194 | ||
2195 | ;; Split the above insn if we failed to get LO allocated. | |
2196 | (define_split | |
2197 | [(set (match_operand:SI 0 "register_operand" "") | |
2198 | (minus:SI (match_operand:SI 1 "register_operand" "") | |
2199 | (mult:SI (match_operand:SI 2 "register_operand" "") | |
2200 | (match_operand:SI 3 "register_operand" "")))) | |
2201 | (clobber (match_scratch:SI 4 "")) | |
2202 | (clobber (match_scratch:SI 5 "")) | |
2203 | (clobber (match_scratch:SI 6 "")) | |
2204 | (clobber (match_scratch:SI 7 ""))] | |
2ca2d9ee EC |
2205 | "reload_completed && !TARGET_DEBUG_D_MODE |
2206 | && GP_REG_P (true_regnum (operands[0])) | |
2207 | && GP_REG_P (true_regnum (operands[1]))" | |
0e5a4ad8 EC |
2208 | [(parallel [(set (match_dup 7) |
2209 | (mult:SI (match_dup 2) (match_dup 3))) | |
2210 | (clobber (match_dup 4)) | |
2211 | (clobber (match_dup 5)) | |
2212 | (clobber (match_dup 6))]) | |
2213 | (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))] | |
2214 | "") | |
2215 | ||
2216 | ;; Splitter to copy result of MSUB to a general register | |
2217 | (define_split | |
2218 | [(set (match_operand:SI 0 "register_operand" "") | |
2219 | (minus:SI (match_operand:SI 1 "register_operand" "") | |
2220 | (mult:SI (match_operand:SI 2 "register_operand" "") | |
2221 | (match_operand:SI 3 "register_operand" "")))) | |
2222 | (clobber (match_scratch:SI 4 "")) | |
2223 | (clobber (match_scratch:SI 5 "")) | |
2224 | (clobber (match_scratch:SI 6 "")) | |
2225 | (clobber (match_scratch:SI 7 ""))] | |
2ca2d9ee EC |
2226 | "reload_completed && !TARGET_DEBUG_D_MODE |
2227 | && GP_REG_P (true_regnum (operands[0])) | |
0e5a4ad8 EC |
2228 | && true_regnum (operands[1]) == LO_REGNUM" |
2229 | [(parallel [(set (match_dup 1) | |
2230 | (minus:SI (match_dup 1) | |
2231 | (mult:SI (match_dup 2) (match_dup 3)))) | |
2232 | (clobber (match_dup 4)) | |
2233 | (clobber (match_dup 5)) | |
2234 | (clobber (match_dup 6)) | |
2235 | (clobber (match_dup 7))]) | |
2236 | (set (match_dup 0) (match_dup 1))] | |
2237 | "") | |
2238 | ||
5ce6f47b EC |
2239 | (define_insn "*muls" |
2240 | [(set (match_operand:SI 0 "register_operand" "=l,d") | |
2241 | (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") | |
2242 | (match_operand:SI 2 "register_operand" "d,d")))) | |
2243 | (clobber (match_scratch:SI 3 "=h,h")) | |
2244 | (clobber (match_scratch:SI 4 "=a,a")) | |
2245 | (clobber (match_scratch:SI 5 "=X,l"))] | |
cafe096b | 2246 | "ISA_HAS_MULS" |
5ce6f47b EC |
2247 | "@ |
2248 | muls\\t$0,%1,%2 | |
2249 | muls\\t%0,%1,%2" | |
2250 | [(set_attr "type" "imul") | |
2251 | (set_attr "mode" "SI")]) | |
2252 | ||
5ce6f47b | 2253 | (define_insn "*msac" |
cafe096b EC |
2254 | [(set (match_operand:SI 0 "register_operand" "=l,d") |
2255 | (minus:SI (match_operand:SI 1 "register_operand" "0,l") | |
2256 | (mult:SI (match_operand:SI 2 "register_operand" "d,d") | |
2257 | (match_operand:SI 3 "register_operand" "d,d")))) | |
2258 | (clobber (match_scratch:SI 4 "=h,h")) | |
2259 | (clobber (match_scratch:SI 5 "=X,1")) | |
2260 | (clobber (match_scratch:SI 6 "=a,a"))] | |
2261 | "ISA_HAS_MSAC" | |
2262 | "* | |
2263 | { | |
2264 | if (which_alternative == 1) | |
2265 | return \"msac\\t%0,%2,%3\"; | |
2266 | else if (TARGET_MIPS5500) | |
2267 | return \"msub\\t%2,%3\"; | |
2268 | else | |
2269 | return \"msac\\t$0,%2,%3\"; | |
2270 | }" | |
2271 | [(set_attr "type" "imadd") | |
2272 | (set_attr "mode" "SI")]) | |
053665d7 | 2273 | |
46299de9 ILT |
2274 | (define_expand "muldi3" |
2275 | [(set (match_operand:DI 0 "register_operand" "=l") | |
cafe096b | 2276 | (mult:DI (match_operand:DI 1 "register_operand" "d") |
46299de9 | 2277 | (match_operand:DI 2 "register_operand" "d"))) |
225b8835 ILT |
2278 | (clobber (match_scratch:DI 3 "=h")) |
2279 | (clobber (match_scratch:DI 4 "=a"))] | |
46299de9 | 2280 | "TARGET_64BIT" |
cb923660 | 2281 | |
46299de9 ILT |
2282 | " |
2283 | { | |
0e5a4ad8 | 2284 | if (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16) |
868e82ab | 2285 | emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2])); |
46299de9 | 2286 | else |
868e82ab | 2287 | emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2])); |
46299de9 ILT |
2288 | DONE; |
2289 | }") | |
8ef30996 | 2290 | |
46299de9 ILT |
2291 | (define_insn "muldi3_internal" |
2292 | [(set (match_operand:DI 0 "register_operand" "=l") | |
cafe096b | 2293 | (mult:DI (match_operand:DI 1 "register_operand" "d") |
46299de9 | 2294 | (match_operand:DI 2 "register_operand" "d"))) |
225b8835 ILT |
2295 | (clobber (match_scratch:DI 3 "=h")) |
2296 | (clobber (match_scratch:DI 4 "=a"))] | |
7dac2f89 | 2297 | "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16" |
e7faa2f6 | 2298 | "dmult\\t%1,%2" |
8ef30996 | 2299 | [(set_attr "type" "imul") |
0ff83799 | 2300 | (set_attr "mode" "DI")]) |
8ef30996 | 2301 | |
868e82ab | 2302 | (define_insn "muldi3_internal2" |
bb621ad7 | 2303 | [(set (match_operand:DI 0 "register_operand" "=d") |
cafe096b | 2304 | (mult:DI (match_operand:DI 1 "register_operand" "d") |
bb621ad7 | 2305 | (match_operand:DI 2 "register_operand" "d"))) |
46299de9 | 2306 | (clobber (match_scratch:DI 3 "=h")) |
225b8835 ILT |
2307 | (clobber (match_scratch:DI 4 "=l")) |
2308 | (clobber (match_scratch:DI 5 "=a"))] | |
0e5a4ad8 | 2309 | "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)" |
bb621ad7 JW |
2310 | "* |
2311 | { | |
0e5a4ad8 | 2312 | if (GENERATE_MULT3_DI) |
868e82ab | 2313 | output_asm_insn (\"dmult\\t%0,%1,%2\", operands); |
7a38df19 | 2314 | else |
868e82ab | 2315 | { |
c5c76735 | 2316 | rtx xoperands[10]; |
bb621ad7 | 2317 | |
c5c76735 JL |
2318 | xoperands[0] = operands[0]; |
2319 | xoperands[1] = gen_rtx_REG (DImode, LO_REGNUM); | |
bb621ad7 | 2320 | |
c5c76735 JL |
2321 | output_asm_insn (\"dmult\\t%1,%2\", operands); |
2322 | output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands); | |
868e82ab | 2323 | } |
bb621ad7 JW |
2324 | return \"\"; |
2325 | }" | |
2326 | [(set_attr "type" "imul") | |
2327 | (set_attr "mode" "DI") | |
868e82ab | 2328 | (set (attr "length") |
0e5a4ad8 | 2329 | (if_then_else (ne (symbol_ref "GENERATE_MULT3_DI") (const_int 0)) |
0ff83799 MM |
2330 | (const_int 4) |
2331 | (const_int 12)))]) ;; mult + mflo + delay | |
bb621ad7 | 2332 | |
bb621ad7 JW |
2333 | ;; ??? We could define a mulditi3 pattern when TARGET_64BIT. |
2334 | ||
225b8835 | 2335 | (define_expand "mulsidi3" |
46299de9 | 2336 | [(set (match_operand:DI 0 "register_operand" "=x") |
8ef30996 | 2337 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) |
46299de9 | 2338 | (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))] |
225b8835 ILT |
2339 | "" |
2340 | " | |
2341 | { | |
2342 | if (TARGET_64BIT) | |
cafe096b | 2343 | emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2])); |
225b8835 | 2344 | else |
cafe096b | 2345 | emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2])); |
225b8835 ILT |
2346 | DONE; |
2347 | }") | |
2348 | ||
cafe096b EC |
2349 | (define_insn "mulsidi3_internal" |
2350 | [(set (match_operand:DI 0 "register_operand" "=x") | |
2351 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
2352 | (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))) | |
2353 | (clobber (match_scratch:SI 3 "=a"))] | |
2354 | "!TARGET_64BIT" | |
2355 | "mult\\t%1,%2" | |
2356 | [(set_attr "type" "imul") | |
2357 | (set_attr "mode" "SI")]) | |
2358 | ||
2359 | (define_insn "mulsidi3_64bit" | |
2360 | [(set (match_operand:DI 0 "register_operand" "=a") | |
2361 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
2362 | (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))) | |
2363 | (clobber (match_scratch:DI 3 "=l")) | |
2364 | (clobber (match_scratch:DI 4 "=h"))] | |
2365 | "TARGET_64BIT" | |
2366 | "mult\\t%1,%2" | |
2367 | [(set_attr "type" "imul") | |
2368 | (set_attr "mode" "SI")]) | |
2369 | ||
225b8835 | 2370 | (define_expand "umulsidi3" |
46299de9 | 2371 | [(set (match_operand:DI 0 "register_operand" "=x") |
8ef30996 | 2372 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) |
46299de9 | 2373 | (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))] |
225b8835 ILT |
2374 | "" |
2375 | " | |
2376 | { | |
2377 | if (TARGET_64BIT) | |
cafe096b | 2378 | emit_insn (gen_umulsidi3_64bit (operands[0], operands[1], operands[2])); |
225b8835 | 2379 | else |
cafe096b EC |
2380 | emit_insn (gen_umulsidi3_internal (operands[0], operands[1], operands[2])); |
2381 | ||
225b8835 ILT |
2382 | DONE; |
2383 | }") | |
2384 | ||
cafe096b EC |
2385 | |
2386 | (define_insn "umulsidi3_internal" | |
225b8835 | 2387 | [(set (match_operand:DI 0 "register_operand" "=x") |
cafe096b EC |
2388 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) |
2389 | (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))) | |
2390 | (clobber (match_scratch:SI 3 "=a"))] | |
2391 | "!TARGET_64BIT" | |
2392 | "multu\\t%1,%2" | |
8ef30996 | 2393 | [(set_attr "type" "imul") |
0ff83799 | 2394 | (set_attr "mode" "SI")]) |
8ef30996 | 2395 | |
cafe096b | 2396 | (define_insn "umulsidi3_64bit" |
225b8835 | 2397 | [(set (match_operand:DI 0 "register_operand" "=a") |
cafe096b EC |
2398 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) |
2399 | (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))) | |
2400 | (clobber (match_scratch:DI 3 "=l")) | |
2401 | (clobber (match_scratch:DI 4 "=h"))] | |
2402 | "TARGET_64BIT" | |
2403 | "multu\\t%1,%2" | |
225b8835 | 2404 | [(set_attr "type" "imul") |
0ff83799 | 2405 | (set_attr "mode" "SI")]) |
225b8835 | 2406 | |
cafe096b EC |
2407 | ;; Widening multiply with negation. It isn't worth using this pattern |
2408 | ;; for 64-bit code since the reload sequence for HILO_REGNUM is so long. | |
5ce6f47b | 2409 | (define_insn "*muls_di" |
cafe096b | 2410 | [(set (match_operand:DI 0 "register_operand" "=x") |
5ce6f47b | 2411 | (neg:DI |
cafe096b EC |
2412 | (mult:DI |
2413 | (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
2414 | (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))) | |
2415 | (clobber (match_scratch:SI 3 "=a"))] | |
2416 | "!TARGET_64BIT && ISA_HAS_MULS" | |
2417 | "muls\\t$0,%1,%2" | |
2418 | [(set_attr "type" "imul") | |
2419 | (set_attr "length" "4") | |
2420 | (set_attr "mode" "SI")]) | |
2421 | ||
2422 | (define_insn "*umuls_di" | |
2423 | [(set (match_operand:DI 0 "register_operand" "=x") | |
2424 | (neg:DI | |
2425 | (mult:DI | |
2426 | (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
2427 | (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))) | |
2428 | (clobber (match_scratch:SI 3 "=a"))] | |
2429 | "!TARGET_64BIT && ISA_HAS_MULS" | |
2430 | "mulsu\\t$0,%1,%2" | |
2431 | [(set_attr "type" "imul") | |
2432 | (set_attr "length" "4") | |
2433 | (set_attr "mode" "SI")]) | |
2434 | ||
2435 | ;; Not used for 64-bit code: see comment for *muls_di. | |
2436 | (define_insn "*smsac_di" | |
2437 | [(set (match_operand:DI 0 "register_operand" "=x") | |
2438 | (minus:DI (match_operand:DI 3 "register_operand" "0") | |
2439 | (mult:DI | |
2440 | (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
2441 | (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))) | |
2442 | (clobber (match_scratch:SI 4 "=a"))] | |
2443 | "!TARGET_64BIT && ISA_HAS_MSAC" | |
5ce6f47b EC |
2444 | "* |
2445 | { | |
cafe096b EC |
2446 | if (TARGET_MIPS5500) |
2447 | return \"msub\\t%1,%2\"; | |
5ce6f47b | 2448 | else |
cafe096b | 2449 | return \"msac\\t$0,%1,%2\"; |
5ce6f47b | 2450 | }" |
cafe096b | 2451 | [(set_attr "type" "imadd") |
5ce6f47b EC |
2452 | (set_attr "length" "4") |
2453 | (set_attr "mode" "SI")]) | |
2454 | ||
cafe096b EC |
2455 | (define_insn "*umsac_di" |
2456 | [(set (match_operand:DI 0 "register_operand" "=x") | |
2457 | (minus:DI (match_operand:DI 3 "register_operand" "0") | |
2458 | (mult:DI | |
2459 | (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
2460 | (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))) | |
2461 | (clobber (match_scratch:SI 4 "=a"))] | |
2462 | "!TARGET_64BIT && ISA_HAS_MSAC" | |
5ce6f47b EC |
2463 | "* |
2464 | { | |
cafe096b EC |
2465 | if (TARGET_MIPS5500) |
2466 | return \"msubu\\t%1,%2\"; | |
5ce6f47b | 2467 | else |
5ce6f47b | 2468 | return \"msacu\\t$0,%1,%2\"; |
5ce6f47b EC |
2469 | }" |
2470 | [(set_attr "type" "imadd") | |
2471 | (set_attr "length" "4") | |
2472 | (set_attr "mode" "SI")]) | |
2473 | ||
cb923660 | 2474 | ;; _highpart patterns |
cafe096b | 2475 | (define_expand "umulsi3_highpart" |
cb923660 KR |
2476 | [(set (match_operand:SI 0 "register_operand" "=h") |
2477 | (truncate:SI | |
cafe096b EC |
2478 | (lshiftrt:DI |
2479 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
2480 | (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))) | |
2481 | (const_int 32))))] | |
cb923660 KR |
2482 | "" |
2483 | " | |
2484 | { | |
cafe096b EC |
2485 | if (ISA_HAS_MULHI) |
2486 | emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1], | |
2487 | operands[2])); | |
2488 | else | |
2489 | emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1], | |
2490 | operands[2])); | |
cb923660 KR |
2491 | DONE; |
2492 | }") | |
2493 | ||
cafe096b | 2494 | (define_insn "umulsi3_highpart_internal" |
46299de9 | 2495 | [(set (match_operand:SI 0 "register_operand" "=h") |
903df3fe | 2496 | (truncate:SI |
cafe096b EC |
2497 | (lshiftrt:DI |
2498 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
2499 | (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))) | |
2500 | (const_int 32)))) | |
2501 | (clobber (match_scratch:SI 3 "=l")) | |
2502 | (clobber (match_scratch:SI 4 "=a"))] | |
2503 | "!ISA_HAS_MULHI" | |
2504 | "multu\\t%1,%2" | |
2505 | [(set_attr "type" "imul") | |
2506 | (set_attr "mode" "SI") | |
2507 | (set_attr "length" "4")]) | |
2508 | ||
2509 | (define_insn "umulsi3_highpart_mulhi_internal" | |
2510 | [(set (match_operand:SI 0 "register_operand" "=h,d") | |
2511 | (truncate:SI | |
2512 | (lshiftrt:DI | |
2513 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d")) | |
2514 | (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))) | |
2515 | (const_int 32)))) | |
2516 | (clobber (match_scratch:SI 3 "=l,l")) | |
2517 | (clobber (match_scratch:SI 4 "=a,a")) | |
2518 | (clobber (match_scratch:SI 5 "=X,h"))] | |
2519 | "ISA_HAS_MULHI" | |
2520 | "@ | |
2521 | multu\\t%1,%2 | |
2522 | mulhiu\\t%0,%1,%2" | |
2523 | [(set_attr "type" "imul") | |
2524 | (set_attr "mode" "SI") | |
2525 | (set_attr "length" "4")]) | |
2526 | ||
2527 | (define_insn "umulsi3_highpart_neg_mulhi_internal" | |
2528 | [(set (match_operand:SI 0 "register_operand" "=h,d") | |
2529 | (truncate:SI | |
2530 | (lshiftrt:DI | |
2531 | (neg:DI | |
2532 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d")) | |
2533 | (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))) | |
2534 | (const_int 32)))) | |
2535 | (clobber (match_scratch:SI 3 "=l,l")) | |
2536 | (clobber (match_scratch:SI 4 "=a,a")) | |
2537 | (clobber (match_scratch:SI 5 "=X,h"))] | |
2538 | "ISA_HAS_MULHI" | |
2539 | "@ | |
2540 | mulshiu\\t%.,%1,%2 | |
2541 | mulshiu\\t%0,%1,%2" | |
2542 | [(set_attr "type" "imul") | |
2543 | (set_attr "mode" "SI") | |
2544 | (set_attr "length" "4")]) | |
2545 | ||
2546 | (define_expand "smulsi3_highpart" | |
2547 | [(set (match_operand:SI 0 "register_operand" "=h") | |
2548 | (truncate:SI | |
2549 | (lshiftrt:DI | |
2550 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
2551 | (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))) | |
2552 | (const_int 32))))] | |
903df3fe | 2553 | "" |
cb923660 KR |
2554 | " |
2555 | { | |
cafe096b EC |
2556 | if (ISA_HAS_MULHI) |
2557 | emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1], | |
2558 | operands[2])); | |
5ce6f47b | 2559 | else |
cafe096b EC |
2560 | emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1], |
2561 | operands[2])); | |
cb923660 KR |
2562 | DONE; |
2563 | }") | |
2564 | ||
cafe096b | 2565 | (define_insn "smulsi3_highpart_internal" |
cb923660 KR |
2566 | [(set (match_operand:SI 0 "register_operand" "=h") |
2567 | (truncate:SI | |
cafe096b EC |
2568 | (lshiftrt:DI |
2569 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
2570 | (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))) | |
2571 | (const_int 32)))) | |
2572 | (clobber (match_scratch:SI 3 "=l")) | |
2573 | (clobber (match_scratch:SI 4 "=a"))] | |
2574 | "!ISA_HAS_MULHI" | |
2575 | "mult\\t%1,%2" | |
903df3fe | 2576 | [(set_attr "type" "imul") |
cafe096b EC |
2577 | (set_attr "mode" "SI") |
2578 | (set_attr "length" "4")]) | |
48199e32 | 2579 | |
cafe096b | 2580 | (define_insn "smulsi3_highpart_mulhi_internal" |
5ce6f47b EC |
2581 | [(set (match_operand:SI 0 "register_operand" "=h,d") |
2582 | (truncate:SI | |
cafe096b EC |
2583 | (lshiftrt:DI |
2584 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d")) | |
2585 | (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))) | |
2586 | (const_int 32)))) | |
2587 | (clobber (match_scratch:SI 3 "=l,l")) | |
2588 | (clobber (match_scratch:SI 4 "=a,a")) | |
2589 | (clobber (match_scratch:SI 5 "=X,h"))] | |
2590 | "ISA_HAS_MULHI" | |
2591 | "@ | |
2592 | mult\\t%1,%2 | |
2593 | mulhi\\t%0,%1,%2" | |
2594 | [(set_attr "type" "imul") | |
2595 | (set_attr "mode" "SI") | |
2596 | (set_attr "length" "4")]) | |
5ce6f47b | 2597 | |
cafe096b | 2598 | (define_insn "smulsi3_highpart_neg_mulhi_internal" |
5ce6f47b EC |
2599 | [(set (match_operand:SI 0 "register_operand" "=h,d") |
2600 | (truncate:SI | |
cafe096b EC |
2601 | (lshiftrt:DI |
2602 | (neg:DI | |
2603 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d")) | |
2604 | (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))) | |
2605 | (const_int 32)))) | |
2606 | (clobber (match_scratch:SI 3 "=l,l")) | |
2607 | (clobber (match_scratch:SI 4 "=a,a")) | |
2608 | (clobber (match_scratch:SI 5 "=X,h"))] | |
2609 | "ISA_HAS_MULHI" | |
2610 | "@ | |
2611 | mulshi\\t%.,%1,%2 | |
2612 | mulshi\\t%0,%1,%2" | |
2613 | [(set_attr "type" "imul") | |
2614 | (set_attr "mode" "SI")]) | |
5ce6f47b | 2615 | |
48199e32 | 2616 | (define_insn "smuldi3_highpart" |
46299de9 | 2617 | [(set (match_operand:DI 0 "register_operand" "=h") |
48199e32 | 2618 | (truncate:DI |
cafe096b EC |
2619 | (lshiftrt:TI |
2620 | (mult:TI | |
2621 | (sign_extend:TI (match_operand:DI 1 "register_operand" "d")) | |
2622 | (sign_extend:TI (match_operand:DI 2 "register_operand" "d"))) | |
2623 | (const_int 64)))) | |
225b8835 ILT |
2624 | (clobber (match_scratch:DI 3 "=l")) |
2625 | (clobber (match_scratch:DI 4 "=a"))] | |
48199e32 | 2626 | "TARGET_64BIT" |
46299de9 | 2627 | "dmult\\t%1,%2" |
48199e32 | 2628 | [(set_attr "type" "imul") |
0ff83799 | 2629 | (set_attr "mode" "DI")]) |
48199e32 JW |
2630 | |
2631 | (define_insn "umuldi3_highpart" | |
46299de9 | 2632 | [(set (match_operand:DI 0 "register_operand" "=h") |
48199e32 | 2633 | (truncate:DI |
cafe096b EC |
2634 | (lshiftrt:TI |
2635 | (mult:TI | |
2636 | (zero_extend:TI (match_operand:DI 1 "register_operand" "d")) | |
2637 | (zero_extend:TI (match_operand:DI 2 "register_operand" "d"))) | |
2638 | (const_int 64)))) | |
225b8835 ILT |
2639 | (clobber (match_scratch:DI 3 "=l")) |
2640 | (clobber (match_scratch:DI 4 "=a"))] | |
48199e32 | 2641 | "TARGET_64BIT" |
46299de9 | 2642 | "dmultu\\t%1,%2" |
48199e32 | 2643 | [(set_attr "type" "imul") |
0ff83799 | 2644 | (set_attr "mode" "DI")]) |
48199e32 | 2645 | |
cafe096b | 2646 | |
46299de9 ILT |
2647 | ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate |
2648 | ;; instruction. The HI/LO registers are used as a 64 bit accumulator. | |
2649 | ||
2650 | (define_insn "madsi" | |
2651 | [(set (match_operand:SI 0 "register_operand" "+l") | |
2652 | (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d") | |
2653 | (match_operand:SI 2 "register_operand" "d")) | |
2654 | (match_dup 0))) | |
225b8835 ILT |
2655 | (clobber (match_scratch:SI 3 "=h")) |
2656 | (clobber (match_scratch:SI 4 "=a"))] | |
cb923660 | 2657 | "TARGET_MAD" |
225b8835 | 2658 | "mad\\t%1,%2" |
1d4047e0 | 2659 | [(set_attr "type" "imadd") |
0ff83799 | 2660 | (set_attr "mode" "SI")]) |
225b8835 | 2661 | |
cafe096b EC |
2662 | ;; Only use this pattern in 32-bit code: see *muls_di. |
2663 | (define_insn "*umul_acc_di" | |
2664 | [(set (match_operand:DI 0 "register_operand" "=x") | |
2665 | (plus:DI | |
2666 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
2667 | (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))) | |
2668 | (match_operand:DI 3 "register_operand" "0"))) | |
2669 | (clobber (match_scratch:SI 4 "=a"))] | |
2670 | "(TARGET_MAD || ISA_HAS_MACC) | |
2671 | && !TARGET_64BIT" | |
cb923660 KR |
2672 | "* |
2673 | { | |
cafe096b | 2674 | if (TARGET_MAD) |
cb923660 | 2675 | return \"madu\\t%1,%2\"; |
cafe096b EC |
2676 | else if (TARGET_MIPS5500) |
2677 | return \"maddu\\t%1,%2\"; | |
2678 | else | |
2679 | return \"maccu\\t%.,%1,%2\"; | |
cb923660 | 2680 | }" |
cafe096b EC |
2681 | [(set_attr "type" "imadd") |
2682 | (set_attr "mode" "SI")]) | |
e19ff60f | 2683 | |
cafe096b EC |
2684 | |
2685 | (define_insn "*smul_acc_di" | |
2686 | [(set (match_operand:DI 0 "register_operand" "=x") | |
2687 | (plus:DI | |
2688 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) | |
2689 | (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))) | |
2690 | (match_operand:DI 3 "register_operand" "0"))) | |
2691 | (clobber (match_scratch:SI 4 "=a"))] | |
2692 | "(TARGET_MAD || ISA_HAS_MACC) | |
2693 | && !TARGET_64BIT" | |
cb923660 KR |
2694 | "* |
2695 | { | |
5ce6f47b | 2696 | if (TARGET_MAD) |
cafe096b EC |
2697 | return \"mad\\t%1,%2\"; |
2698 | else if (TARGET_MIPS5500) | |
2699 | return \"madd\\t%1,%2\"; | |
cb923660 | 2700 | else |
cafe096b | 2701 | return \"macc\\t%.,%1,%2\"; |
cb923660 | 2702 | }" |
cafe096b EC |
2703 | [(set_attr "type" "imadd") |
2704 | (set_attr "mode" "SI")]) | |
e9a25f70 | 2705 | |
e19ff60f JW |
2706 | ;; Floating point multiply accumulate instructions. |
2707 | ||
2708 | (define_insn "" | |
2709 | [(set (match_operand:DF 0 "register_operand" "=f") | |
2710 | (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f") | |
2711 | (match_operand:DF 2 "register_operand" "f")) | |
2712 | (match_operand:DF 3 "register_operand" "f")))] | |
13fac94a | 2713 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD" |
e19ff60f JW |
2714 | "madd.d\\t%0,%3,%1,%2" |
2715 | [(set_attr "type" "fmadd") | |
0ff83799 | 2716 | (set_attr "mode" "DF")]) |
e19ff60f JW |
2717 | |
2718 | (define_insn "" | |
2719 | [(set (match_operand:SF 0 "register_operand" "=f") | |
2720 | (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f") | |
2721 | (match_operand:SF 2 "register_operand" "f")) | |
2722 | (match_operand:SF 3 "register_operand" "f")))] | |
13fac94a | 2723 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD" |
e19ff60f JW |
2724 | "madd.s\\t%0,%3,%1,%2" |
2725 | [(set_attr "type" "fmadd") | |
0ff83799 | 2726 | (set_attr "mode" "SF")]) |
e19ff60f JW |
2727 | |
2728 | (define_insn "" | |
2729 | [(set (match_operand:DF 0 "register_operand" "=f") | |
2730 | (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f") | |
2731 | (match_operand:DF 2 "register_operand" "f")) | |
2732 | (match_operand:DF 3 "register_operand" "f")))] | |
13fac94a | 2733 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD" |
e19ff60f JW |
2734 | "msub.d\\t%0,%3,%1,%2" |
2735 | [(set_attr "type" "fmadd") | |
0ff83799 | 2736 | (set_attr "mode" "DF")]) |
e19ff60f JW |
2737 | |
2738 | (define_insn "" | |
2739 | [(set (match_operand:SF 0 "register_operand" "=f") | |
2740 | (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f") | |
2741 | (match_operand:SF 2 "register_operand" "f")) | |
2742 | (match_operand:SF 3 "register_operand" "f")))] | |
7a38df19 | 2743 | |
13fac94a | 2744 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD" |
e19ff60f JW |
2745 | "msub.s\\t%0,%3,%1,%2" |
2746 | [(set_attr "type" "fmadd") | |
0ff83799 | 2747 | (set_attr "mode" "SF")]) |
e19ff60f JW |
2748 | |
2749 | (define_insn "" | |
2750 | [(set (match_operand:DF 0 "register_operand" "=f") | |
2751 | (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f") | |
2752 | (match_operand:DF 2 "register_operand" "f")) | |
2753 | (match_operand:DF 3 "register_operand" "f"))))] | |
13fac94a | 2754 | "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD" |
e19ff60f JW |
2755 | "nmadd.d\\t%0,%3,%1,%2" |
2756 | [(set_attr "type" "fmadd") | |
0ff83799 | 2757 | (set_attr "mode" "DF")]) |
e19ff60f JW |
2758 | |
2759 | (define_insn "" | |
2760 | [(set (match_operand:SF 0 "register_operand" "=f") | |
2761 | (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f") | |
2762 | (match_operand:SF 2 "register_operand" "f")) | |
2763 | (match_operand:SF 3 "register_operand" "f"))))] | |
13fac94a | 2764 | "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD" |
e19ff60f JW |
2765 | "nmadd.s\\t%0,%3,%1,%2" |
2766 | [(set_attr "type" "fmadd") | |
0ff83799 | 2767 | (set_attr "mode" "SF")]) |
e19ff60f JW |
2768 | |
2769 | (define_insn "" | |
2770 | [(set (match_operand:DF 0 "register_operand" "=f") | |
2771 | (minus:DF (match_operand:DF 1 "register_operand" "f") | |
2772 | (mult:DF (match_operand:DF 2 "register_operand" "f") | |
2773 | (match_operand:DF 3 "register_operand" "f"))))] | |
13fac94a | 2774 | "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD" |
e19ff60f JW |
2775 | "nmsub.d\\t%0,%1,%2,%3" |
2776 | [(set_attr "type" "fmadd") | |
0ff83799 | 2777 | (set_attr "mode" "DF")]) |
e19ff60f JW |
2778 | |
2779 | (define_insn "" | |
2780 | [(set (match_operand:SF 0 "register_operand" "=f") | |
2781 | (minus:SF (match_operand:SF 1 "register_operand" "f") | |
2782 | (mult:SF (match_operand:SF 2 "register_operand" "f") | |
2783 | (match_operand:SF 3 "register_operand" "f"))))] | |
13fac94a | 2784 | "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD" |
e19ff60f JW |
2785 | "nmsub.s\\t%0,%1,%2,%3" |
2786 | [(set_attr "type" "fmadd") | |
0ff83799 | 2787 | (set_attr "mode" "SF")]) |
8ef30996 MM |
2788 | \f |
2789 | ;; | |
2790 | ;; .................... | |
2791 | ;; | |
2792 | ;; DIVISION and REMAINDER | |
2793 | ;; | |
2794 | ;; .................... | |
2795 | ;; | |
2796 | ||
2797 | (define_insn "divdf3" | |
2798 | [(set (match_operand:DF 0 "register_operand" "=f") | |
2799 | (div:DF (match_operand:DF 1 "register_operand" "f") | |
2800 | (match_operand:DF 2 "register_operand" "f")))] | |
46299de9 | 2801 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
8ef30996 MM |
2802 | "div.d\\t%0,%1,%2" |
2803 | [(set_attr "type" "fdiv") | |
0ff83799 | 2804 | (set_attr "mode" "DF")]) |
8ef30996 MM |
2805 | |
2806 | (define_insn "divsf3" | |
2807 | [(set (match_operand:SF 0 "register_operand" "=f") | |
2808 | (div:SF (match_operand:SF 1 "register_operand" "f") | |
2809 | (match_operand:SF 2 "register_operand" "f")))] | |
2810 | "TARGET_HARD_FLOAT" | |
2811 | "div.s\\t%0,%1,%2" | |
2812 | [(set_attr "type" "fdiv") | |
0ff83799 | 2813 | (set_attr "mode" "SF")]) |
8ef30996 | 2814 | |
b8eb88d0 ILT |
2815 | (define_insn "" |
2816 | [(set (match_operand:DF 0 "register_operand" "=f") | |
2817 | (div:DF (match_operand:DF 1 "const_float_1_operand" "") | |
2818 | (match_operand:DF 2 "register_operand" "f")))] | |
de6c5979 | 2819 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations" |
b8eb88d0 ILT |
2820 | "recip.d\\t%0,%2" |
2821 | [(set_attr "type" "fdiv") | |
0ff83799 | 2822 | (set_attr "mode" "DF")]) |
b8eb88d0 ILT |
2823 | |
2824 | (define_insn "" | |
2825 | [(set (match_operand:SF 0 "register_operand" "=f") | |
2826 | (div:SF (match_operand:SF 1 "const_float_1_operand" "") | |
2827 | (match_operand:SF 2 "register_operand" "f")))] | |
de6c5979 | 2828 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations" |
b8eb88d0 ILT |
2829 | "recip.s\\t%0,%2" |
2830 | [(set_attr "type" "fdiv") | |
0ff83799 | 2831 | (set_attr "mode" "SF")]) |
b8eb88d0 | 2832 | |
8ef30996 MM |
2833 | ;; If optimizing, prefer the divmod functions over separate div and |
2834 | ;; mod functions, since this will allow using one instruction for both | |
2835 | ;; the quotient and remainder. At present, the divmod is not moved out | |
2836 | ;; of loops if it is constant within the loop, so allow -mdebugc to | |
2837 | ;; use the old method of doing things. | |
2838 | ||
2839 | ;; 64 is the multiply/divide hi register | |
2840 | ;; 65 is the multiply/divide lo register | |
2841 | ||
bb621ad7 JW |
2842 | ;; ??? We can't accept constants here, because the MIPS assembler will replace |
2843 | ;; a divide by power of 2 with a shift, and then the remainder is no longer | |
2844 | ;; available. | |
2845 | ||
08c2951c | 2846 | (define_expand "divmodsi4" |
70252580 MM |
2847 | [(set (match_operand:SI 0 "register_operand" "=d") |
2848 | (div:SI (match_operand:SI 1 "register_operand" "d") | |
2849 | (match_operand:SI 2 "register_operand" "d"))) | |
2850 | (set (match_operand:SI 3 "register_operand" "=d") | |
2851 | (mod:SI (match_dup 1) | |
2852 | (match_dup 2))) | |
46299de9 | 2853 | (clobber (match_scratch:SI 4 "=l")) |
225b8835 ILT |
2854 | (clobber (match_scratch:SI 5 "=h")) |
2855 | (clobber (match_scratch:SI 6 "=a"))] | |
34b650b3 | 2856 | "optimize" |
08c2951c | 2857 | " |
8ef30996 | 2858 | { |
08c2951c SC |
2859 | emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2], |
2860 | operands[3])); | |
2861 | if (!TARGET_NO_CHECK_ZERO_DIV) | |
2862 | { | |
2863 | emit_insn (gen_div_trap (operands[2], | |
1feed51c | 2864 | GEN_INT (0), |
08c2951c SC |
2865 | GEN_INT (0x7))); |
2866 | } | |
2867 | if (TARGET_CHECK_RANGE_DIV) | |
2868 | { | |
2869 | emit_insn (gen_div_trap (operands[2], | |
2870 | copy_to_mode_reg (SImode, GEN_INT (-1)), | |
2871 | GEN_INT (0x6))); | |
2872 | emit_insn (gen_div_trap (operands[2], | |
024c02b1 AO |
2873 | copy_to_mode_reg (SImode, |
2874 | GEN_INT | |
2875 | (trunc_int_for_mode | |
2876 | (BITMASK_HIGH, SImode))), | |
08c2951c SC |
2877 | GEN_INT (0x6))); |
2878 | } | |
7a38df19 | 2879 | |
08c2951c SC |
2880 | DONE; |
2881 | }") | |
8ef30996 | 2882 | |
08c2951c SC |
2883 | (define_insn "divmodsi4_internal" |
2884 | [(set (match_operand:SI 0 "register_operand" "=l") | |
2885 | (div:SI (match_operand:SI 1 "register_operand" "d") | |
2886 | (match_operand:SI 2 "register_operand" "d"))) | |
2887 | (set (match_operand:SI 3 "register_operand" "=h") | |
2888 | (mod:SI (match_dup 1) | |
2889 | (match_dup 2))) | |
c77e04ae | 2890 | (clobber (match_scratch:SI 4 "=a"))] |
08c2951c SC |
2891 | "optimize" |
2892 | "div\\t$0,%1,%2" | |
8ef30996 | 2893 | [(set_attr "type" "idiv") |
0ff83799 | 2894 | (set_attr "mode" "SI")]) |
bb621ad7 | 2895 | |
08c2951c | 2896 | (define_expand "divmoddi4" |
bb621ad7 | 2897 | [(set (match_operand:DI 0 "register_operand" "=d") |
cafe096b EC |
2898 | (div:DI (match_operand:DI 1 "register_operand" "d") |
2899 | (match_operand:DI 2 "register_operand" "d"))) | |
bb621ad7 JW |
2900 | (set (match_operand:DI 3 "register_operand" "=d") |
2901 | (mod:DI (match_dup 1) | |
2902 | (match_dup 2))) | |
46299de9 | 2903 | (clobber (match_scratch:DI 4 "=l")) |
225b8835 ILT |
2904 | (clobber (match_scratch:DI 5 "=h")) |
2905 | (clobber (match_scratch:DI 6 "=a"))] | |
bb621ad7 | 2906 | "TARGET_64BIT && optimize" |
08c2951c | 2907 | " |
bb621ad7 | 2908 | { |
08c2951c SC |
2909 | emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2], |
2910 | operands[3])); | |
2911 | if (!TARGET_NO_CHECK_ZERO_DIV) | |
2912 | { | |
2913 | emit_insn (gen_div_trap (operands[2], | |
1feed51c | 2914 | GEN_INT (0), |
08c2951c SC |
2915 | GEN_INT (0x7))); |
2916 | } | |
2917 | if (TARGET_CHECK_RANGE_DIV) | |
2918 | { | |
2919 | emit_insn (gen_div_trap (operands[2], | |
2920 | copy_to_mode_reg (DImode, GEN_INT (-1)), | |
2921 | GEN_INT (0x6))); | |
2922 | emit_insn (gen_div_trap (operands[2], | |
024c02b1 AO |
2923 | copy_to_mode_reg (DImode, |
2924 | GEN_INT (BITMASK_HIGH)), | |
08c2951c SC |
2925 | GEN_INT (0x6))); |
2926 | } | |
7a38df19 | 2927 | |
08c2951c SC |
2928 | DONE; |
2929 | }") | |
bb621ad7 | 2930 | |
08c2951c SC |
2931 | (define_insn "divmoddi4_internal" |
2932 | [(set (match_operand:DI 0 "register_operand" "=l") | |
cafe096b EC |
2933 | (div:DI (match_operand:DI 1 "register_operand" "d") |
2934 | (match_operand:DI 2 "register_operand" "d"))) | |
08c2951c SC |
2935 | (set (match_operand:DI 3 "register_operand" "=h") |
2936 | (mod:DI (match_dup 1) | |
2937 | (match_dup 2))) | |
c77e04ae | 2938 | (clobber (match_scratch:DI 4 "=a"))] |
08c2951c SC |
2939 | "TARGET_64BIT && optimize" |
2940 | "ddiv\\t$0,%1,%2" | |
bb621ad7 | 2941 | [(set_attr "type" "idiv") |
0ff83799 | 2942 | (set_attr "mode" "SI")]) |
8ef30996 | 2943 | |
08c2951c | 2944 | (define_expand "udivmodsi4" |
70252580 MM |
2945 | [(set (match_operand:SI 0 "register_operand" "=d") |
2946 | (udiv:SI (match_operand:SI 1 "register_operand" "d") | |
2947 | (match_operand:SI 2 "register_operand" "d"))) | |
2948 | (set (match_operand:SI 3 "register_operand" "=d") | |
2949 | (umod:SI (match_dup 1) | |
2950 | (match_dup 2))) | |
46299de9 | 2951 | (clobber (match_scratch:SI 4 "=l")) |
225b8835 ILT |
2952 | (clobber (match_scratch:SI 5 "=h")) |
2953 | (clobber (match_scratch:SI 6 "=a"))] | |
34b650b3 | 2954 | "optimize" |
08c2951c | 2955 | " |
8ef30996 | 2956 | { |
08c2951c SC |
2957 | emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2], |
2958 | operands[3])); | |
2959 | if (!TARGET_NO_CHECK_ZERO_DIV) | |
2960 | { | |
2961 | emit_insn (gen_div_trap (operands[2], | |
1feed51c | 2962 | GEN_INT (0), |
08c2951c SC |
2963 | GEN_INT (0x7))); |
2964 | } | |
7a38df19 | 2965 | |
08c2951c SC |
2966 | DONE; |
2967 | }") | |
8ef30996 | 2968 | |
08c2951c SC |
2969 | (define_insn "udivmodsi4_internal" |
2970 | [(set (match_operand:SI 0 "register_operand" "=l") | |
2971 | (udiv:SI (match_operand:SI 1 "register_operand" "d") | |
2972 | (match_operand:SI 2 "register_operand" "d"))) | |
2973 | (set (match_operand:SI 3 "register_operand" "=h") | |
2974 | (umod:SI (match_dup 1) | |
2975 | (match_dup 2))) | |
c77e04ae | 2976 | (clobber (match_scratch:SI 4 "=a"))] |
08c2951c SC |
2977 | "optimize" |
2978 | "divu\\t$0,%1,%2" | |
8ef30996 | 2979 | [(set_attr "type" "idiv") |
0ff83799 | 2980 | (set_attr "mode" "SI")]) |
bb621ad7 | 2981 | |
08c2951c | 2982 | (define_expand "udivmoddi4" |
bb621ad7 | 2983 | [(set (match_operand:DI 0 "register_operand" "=d") |
cafe096b EC |
2984 | (udiv:DI (match_operand:DI 1 "register_operand" "d") |
2985 | (match_operand:DI 2 "register_operand" "d"))) | |
bb621ad7 JW |
2986 | (set (match_operand:DI 3 "register_operand" "=d") |
2987 | (umod:DI (match_dup 1) | |
2988 | (match_dup 2))) | |
46299de9 | 2989 | (clobber (match_scratch:DI 4 "=l")) |
225b8835 ILT |
2990 | (clobber (match_scratch:DI 5 "=h")) |
2991 | (clobber (match_scratch:DI 6 "=a"))] | |
bb621ad7 | 2992 | "TARGET_64BIT && optimize" |
08c2951c | 2993 | " |
bb621ad7 | 2994 | { |
08c2951c SC |
2995 | emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2], |
2996 | operands[3])); | |
2997 | if (!TARGET_NO_CHECK_ZERO_DIV) | |
2998 | { | |
2999 | emit_insn (gen_div_trap (operands[2], | |
1feed51c | 3000 | GEN_INT (0), |
08c2951c SC |
3001 | GEN_INT (0x7))); |
3002 | } | |
7a38df19 | 3003 | |
08c2951c SC |
3004 | DONE; |
3005 | }") | |
bb621ad7 | 3006 | |
08c2951c SC |
3007 | (define_insn "udivmoddi4_internal" |
3008 | [(set (match_operand:DI 0 "register_operand" "=l") | |
cafe096b EC |
3009 | (udiv:DI (match_operand:DI 1 "register_operand" "d") |
3010 | (match_operand:DI 2 "register_operand" "d"))) | |
08c2951c SC |
3011 | (set (match_operand:DI 3 "register_operand" "=h") |
3012 | (umod:DI (match_dup 1) | |
3013 | (match_dup 2))) | |
c77e04ae | 3014 | (clobber (match_scratch:DI 4 "=a"))] |
08c2951c SC |
3015 | "TARGET_64BIT && optimize" |
3016 | "ddivu\\t$0,%1,%2" | |
3017 | [(set_attr "type" "idiv") | |
0ff83799 | 3018 | (set_attr "mode" "SI")]) |
08c2951c SC |
3019 | |
3020 | ;; Division trap | |
bb621ad7 | 3021 | |
aa7ecb4a | 3022 | (define_expand "div_trap" |
08c2951c | 3023 | [(trap_if (eq (match_operand 0 "register_operand" "d") |
def72bd2 | 3024 | (match_operand 1 "true_reg_or_0_operand" "dJ")) |
08c2951c SC |
3025 | (match_operand 2 "immediate_operand" ""))] |
3026 | "" | |
aa7ecb4a GRK |
3027 | " |
3028 | { | |
3029 | if (TARGET_MIPS16) | |
3030 | emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2])); | |
3031 | else | |
3032 | emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2])); | |
3033 | DONE; | |
3034 | }") | |
3035 | ||
3036 | (define_insn "div_trap_normal" | |
8f8b5612 GK |
3037 | [(trap_if (eq (match_operand 0 "register_operand" "d,d") |
3038 | (match_operand 1 "true_reg_or_0_operand" "d,J")) | |
aa7ecb4a GRK |
3039 | (match_operand 2 "immediate_operand" ""))] |
3040 | "!TARGET_MIPS16" | |
08c2951c SC |
3041 | "* |
3042 | { | |
3043 | rtx link; | |
3044 | int have_dep_anti = 0; | |
3045 | ||
3046 | /* For divmod if one division is not needed then we don't need an extra | |
3047 | divide by zero trap, which is anti dependent on previous trap */ | |
3048 | for (link = LOG_LINKS (insn); link; link = XEXP (link, 1)) | |
3049 | ||
3050 | if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link) | |
487f99d2 | 3051 | && GET_CODE (XEXP (link, 0)) == INSN |
08c2951c | 3052 | && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF |
8f8b5612 | 3053 | && which_alternative == 1) |
08c2951c SC |
3054 | have_dep_anti = 1; |
3055 | if (! have_dep_anti) | |
b151501e JL |
3056 | { |
3057 | if (GENERATE_BRANCHLIKELY) | |
3058 | { | |
8f8b5612 | 3059 | if (which_alternative == 1) |
efa3896a | 3060 | return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\"; |
b151501e | 3061 | else |
efa3896a | 3062 | return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\"; |
b151501e JL |
3063 | } |
3064 | else | |
3065 | { | |
8f8b5612 | 3066 | if (which_alternative == 1) |
efa3896a | 3067 | return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\"; |
b151501e | 3068 | else |
efa3896a | 3069 | return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\"; |
b151501e JL |
3070 | } |
3071 | } | |
8da31fc1 | 3072 | return \"\"; |
bb621ad7 | 3073 | }" |
08c2951c | 3074 | [(set_attr "type" "unknown") |
0ff83799 | 3075 | (set_attr "length" "12")]) |
aa7ecb4a GRK |
3076 | |
3077 | ||
3078 | ;; The mips16 bne insns is a macro which uses reg 24 as an intermediate. | |
3079 | ||
3080 | (define_insn "div_trap_mips16" | |
8f8b5612 GK |
3081 | [(trap_if (eq (match_operand 0 "register_operand" "d,d") |
3082 | (match_operand 1 "true_reg_or_0_operand" "d,J")) | |
aa7ecb4a GRK |
3083 | (match_operand 2 "immediate_operand" "")) |
3084 | (clobber (reg:SI 24))] | |
3085 | "TARGET_MIPS16" | |
3086 | "* | |
3087 | { | |
3088 | rtx link; | |
3089 | int have_dep_anti = 0; | |
3090 | ||
3091 | /* For divmod if one division is not needed then we don't need an extra | |
3092 | divide by zero trap, which is anti dependent on previous trap */ | |
3093 | for (link = LOG_LINKS (insn); link; link = XEXP (link, 1)) | |
3094 | ||
3095 | if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link) | |
487f99d2 | 3096 | && GET_CODE (XEXP (link, 0)) == INSN |
aa7ecb4a | 3097 | && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF |
8f8b5612 | 3098 | && which_alternative == 1) |
aa7ecb4a GRK |
3099 | have_dep_anti = 1; |
3100 | if (! have_dep_anti) | |
3101 | { | |
987ba558 | 3102 | /* No branch delay slots on mips16. */ |
8f8b5612 | 3103 | if (which_alternative == 1) |
efa3896a | 3104 | return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\"; |
aa7ecb4a | 3105 | else |
efa3896a | 3106 | return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\"; |
aa7ecb4a GRK |
3107 | } |
3108 | return \"\"; | |
3109 | }" | |
3110 | [(set_attr "type" "unknown") | |
0ff83799 | 3111 | (set_attr "length" "12")]) |
8ef30996 | 3112 | |
7e07e3ba | 3113 | (define_expand "divsi3" |
08c2951c | 3114 | [(set (match_operand:SI 0 "register_operand" "=l") |
8ef30996 | 3115 | (div:SI (match_operand:SI 1 "register_operand" "d") |
08c2951c SC |
3116 | (match_operand:SI 2 "register_operand" "d"))) |
3117 | (clobber (match_scratch:SI 3 "=h")) | |
3118 | (clobber (match_scratch:SI 4 "=a"))] | |
34b650b3 | 3119 | "!optimize" |
7e07e3ba GK |
3120 | " |
3121 | { | |
08c2951c | 3122 | emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2])); |
cafe096b | 3123 | |
08c2951c SC |
3124 | if (!TARGET_NO_CHECK_ZERO_DIV) |
3125 | { | |
3126 | emit_insn (gen_div_trap (operands[2], | |
1feed51c | 3127 | GEN_INT (0), |
08c2951c SC |
3128 | GEN_INT (0x7))); |
3129 | } | |
3130 | if (TARGET_CHECK_RANGE_DIV) | |
3131 | { | |
3132 | emit_insn (gen_div_trap (operands[2], | |
3133 | copy_to_mode_reg (SImode, GEN_INT (-1)), | |
3134 | GEN_INT (0x6))); | |
3135 | emit_insn (gen_div_trap (operands[2], | |
024c02b1 AO |
3136 | copy_to_mode_reg (SImode, |
3137 | GEN_INT | |
3138 | (trunc_int_for_mode | |
3139 | (BITMASK_HIGH, SImode))), | |
08c2951c SC |
3140 | GEN_INT (0x6))); |
3141 | } | |
7a38df19 | 3142 | |
08c2951c | 3143 | DONE; |
7e07e3ba GK |
3144 | }") |
3145 | ||
3146 | (define_insn "divsi3_internal" | |
08c2951c | 3147 | [(set (match_operand:SI 0 "register_operand" "=l") |
7e07e3ba | 3148 | (div:SI (match_operand:SI 1 "register_operand" "d") |
08c2951c SC |
3149 | (match_operand:SI 2 "nonmemory_operand" "di"))) |
3150 | (clobber (match_scratch:SI 3 "=h")) | |
3151 | (clobber (match_scratch:SI 4 "=a"))] | |
7e07e3ba | 3152 | "!optimize" |
08c2951c | 3153 | "div\\t$0,%1,%2" |
8ef30996 | 3154 | [(set_attr "type" "idiv") |
0ff83799 | 3155 | (set_attr "mode" "SI")]) |
8ef30996 | 3156 | |
7e07e3ba | 3157 | (define_expand "divdi3" |
08c2951c | 3158 | [(set (match_operand:DI 0 "register_operand" "=l") |
cafe096b EC |
3159 | (div:DI (match_operand:DI 1 "register_operand" "d") |
3160 | (match_operand:DI 2 "register_operand" "d"))) | |
08c2951c SC |
3161 | (clobber (match_scratch:DI 3 "=h")) |
3162 | (clobber (match_scratch:DI 4 "=a"))] | |
bb621ad7 | 3163 | "TARGET_64BIT && !optimize" |
7e07e3ba GK |
3164 | " |
3165 | { | |
08c2951c SC |
3166 | emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2])); |
3167 | if (!TARGET_NO_CHECK_ZERO_DIV) | |
3168 | { | |
3169 | emit_insn (gen_div_trap (operands[2], | |
1feed51c | 3170 | GEN_INT (0), |
08c2951c SC |
3171 | GEN_INT (0x7))); |
3172 | } | |
3173 | if (TARGET_CHECK_RANGE_DIV) | |
3174 | { | |
3175 | emit_insn (gen_div_trap (operands[2], | |
3176 | copy_to_mode_reg (DImode, GEN_INT (-1)), | |
3177 | GEN_INT (0x6))); | |
3178 | emit_insn (gen_div_trap (operands[2], | |
024c02b1 AO |
3179 | copy_to_mode_reg (DImode, |
3180 | GEN_INT (BITMASK_HIGH)), | |
08c2951c SC |
3181 | GEN_INT (0x6))); |
3182 | } | |
7a38df19 | 3183 | |
08c2951c | 3184 | DONE; |
7e07e3ba GK |
3185 | }") |
3186 | ||
3187 | (define_insn "divdi3_internal" | |
08c2951c | 3188 | [(set (match_operand:DI 0 "register_operand" "=l") |
cafe096b EC |
3189 | (div:DI (match_operand:DI 1 "register_operand" "d") |
3190 | (match_operand:DI 2 "nonmemory_operand" "di"))) | |
08c2951c SC |
3191 | (clobber (match_scratch:SI 3 "=h")) |
3192 | (clobber (match_scratch:SI 4 "=a"))] | |
7e07e3ba | 3193 | "TARGET_64BIT && !optimize" |
08c2951c | 3194 | "ddiv\\t$0,%1,%2" |
bb621ad7 | 3195 | [(set_attr "type" "idiv") |
0ff83799 | 3196 | (set_attr "mode" "DI")]) |
bb621ad7 | 3197 | |
7e07e3ba | 3198 | (define_expand "modsi3" |
08c2951c | 3199 | [(set (match_operand:SI 0 "register_operand" "=h") |
8ef30996 | 3200 | (mod:SI (match_operand:SI 1 "register_operand" "d") |
08c2951c | 3201 | (match_operand:SI 2 "register_operand" "d"))) |
46299de9 | 3202 | (clobber (match_scratch:SI 3 "=l")) |
08c2951c | 3203 | (clobber (match_scratch:SI 4 "=a"))] |
34b650b3 | 3204 | "!optimize" |
7e07e3ba GK |
3205 | " |
3206 | { | |
08c2951c SC |
3207 | emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2])); |
3208 | if (!TARGET_NO_CHECK_ZERO_DIV) | |
3209 | { | |
3210 | emit_insn (gen_div_trap (operands[2], | |
1feed51c | 3211 | GEN_INT (0), |
08c2951c SC |
3212 | GEN_INT (0x7))); |
3213 | } | |
3214 | if (TARGET_CHECK_RANGE_DIV) | |
3215 | { | |
3216 | emit_insn (gen_div_trap (operands[2], | |
3217 | copy_to_mode_reg (SImode, GEN_INT (-1)), | |
3218 | GEN_INT (0x6))); | |
3219 | emit_insn (gen_div_trap (operands[2], | |
024c02b1 AO |
3220 | copy_to_mode_reg (SImode, |
3221 | GEN_INT | |
3222 | (trunc_int_for_mode | |
3223 | (BITMASK_HIGH, SImode))), | |
08c2951c SC |
3224 | GEN_INT (0x6))); |
3225 | } | |
7a38df19 | 3226 | |
08c2951c | 3227 | DONE; |
7e07e3ba GK |
3228 | }") |
3229 | ||
3230 | (define_insn "modsi3_internal" | |
08c2951c | 3231 | [(set (match_operand:SI 0 "register_operand" "=h") |
7e07e3ba | 3232 | (mod:SI (match_operand:SI 1 "register_operand" "d") |
08c2951c SC |
3233 | (match_operand:SI 2 "nonmemory_operand" "di"))) |
3234 | (clobber (match_scratch:SI 3 "=l")) | |
3235 | (clobber (match_scratch:SI 4 "=a"))] | |
7e07e3ba | 3236 | "!optimize" |
08c2951c | 3237 | "div\\t$0,%1,%2" |
8ef30996 | 3238 | [(set_attr "type" "idiv") |
0ff83799 | 3239 | (set_attr "mode" "SI")]) |
bb621ad7 | 3240 | |
7e07e3ba | 3241 | (define_expand "moddi3" |
08c2951c | 3242 | [(set (match_operand:DI 0 "register_operand" "=h") |
cafe096b EC |
3243 | (mod:DI (match_operand:DI 1 "register_operand" "d") |
3244 | (match_operand:DI 2 "register_operand" "d"))) | |
46299de9 | 3245 | (clobber (match_scratch:DI 3 "=l")) |
08c2951c | 3246 | (clobber (match_scratch:DI 4 "=a"))] |
bb621ad7 | 3247 | "TARGET_64BIT && !optimize" |
7e07e3ba GK |
3248 | " |
3249 | { | |
08c2951c SC |
3250 | emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2])); |
3251 | if (!TARGET_NO_CHECK_ZERO_DIV) | |
3252 | { | |
3253 | emit_insn (gen_div_trap (operands[2], | |
1feed51c | 3254 | GEN_INT (0), |
08c2951c SC |
3255 | GEN_INT (0x7))); |
3256 | } | |
3257 | if (TARGET_CHECK_RANGE_DIV) | |
3258 | { | |
3259 | emit_insn (gen_div_trap (operands[2], | |
3260 | copy_to_mode_reg (DImode, GEN_INT (-1)), | |
3261 | GEN_INT (0x6))); | |
3262 | emit_insn (gen_div_trap (operands[2], | |
024c02b1 AO |
3263 | copy_to_mode_reg (DImode, |
3264 | GEN_INT (BITMASK_HIGH)), | |
08c2951c SC |
3265 | GEN_INT (0x6))); |
3266 | } | |
7a38df19 | 3267 | |
08c2951c | 3268 | DONE; |
7e07e3ba GK |
3269 | }") |
3270 | ||
3271 | (define_insn "moddi3_internal" | |
08c2951c | 3272 | [(set (match_operand:DI 0 "register_operand" "=h") |
cafe096b EC |
3273 | (mod:DI (match_operand:DI 1 "register_operand" "d") |
3274 | (match_operand:DI 2 "nonmemory_operand" "di"))) | |
08c2951c SC |
3275 | (clobber (match_scratch:SI 3 "=l")) |
3276 | (clobber (match_scratch:SI 4 "=a"))] | |
7e07e3ba | 3277 | "TARGET_64BIT && !optimize" |
08c2951c | 3278 | "ddiv\\t$0,%1,%2" |
bb621ad7 | 3279 | [(set_attr "type" "idiv") |
0ff83799 | 3280 | (set_attr "mode" "DI")]) |
8ef30996 | 3281 | |
7e07e3ba | 3282 | (define_expand "udivsi3" |
08c2951c | 3283 | [(set (match_operand:SI 0 "register_operand" "=l") |
8ef30996 | 3284 | (udiv:SI (match_operand:SI 1 "register_operand" "d") |
08c2951c SC |
3285 | (match_operand:SI 2 "register_operand" "d"))) |
3286 | (clobber (match_scratch:SI 3 "=h")) | |
3287 | (clobber (match_scratch:SI 4 "=a"))] | |
34b650b3 | 3288 | "!optimize" |
7e07e3ba GK |
3289 | " |
3290 | { | |
08c2951c SC |
3291 | emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2])); |
3292 | if (!TARGET_NO_CHECK_ZERO_DIV) | |
3293 | { | |
3294 | emit_insn (gen_div_trap (operands[2], | |
1feed51c | 3295 | GEN_INT (0), |
08c2951c SC |
3296 | GEN_INT (0x7))); |
3297 | } | |
7a38df19 | 3298 | |
08c2951c | 3299 | DONE; |
7e07e3ba GK |
3300 | }") |
3301 | ||
3302 | (define_insn "udivsi3_internal" | |
08c2951c | 3303 | [(set (match_operand:SI 0 "register_operand" "=l") |
7e07e3ba | 3304 | (udiv:SI (match_operand:SI 1 "register_operand" "d") |
08c2951c SC |
3305 | (match_operand:SI 2 "nonmemory_operand" "di"))) |
3306 | (clobber (match_scratch:SI 3 "=h")) | |
3307 | (clobber (match_scratch:SI 4 "=a"))] | |
7e07e3ba | 3308 | "!optimize" |
08c2951c | 3309 | "divu\\t$0,%1,%2" |
8ef30996 | 3310 | [(set_attr "type" "idiv") |
0ff83799 | 3311 | (set_attr "mode" "SI")]) |
bb621ad7 | 3312 | |
7e07e3ba | 3313 | (define_expand "udivdi3" |
08c2951c | 3314 | [(set (match_operand:DI 0 "register_operand" "=l") |
cafe096b EC |
3315 | (udiv:DI (match_operand:DI 1 "register_operand" "d") |
3316 | (match_operand:DI 2 "register_operand" "di"))) | |
08c2951c SC |
3317 | (clobber (match_scratch:DI 3 "=h")) |
3318 | (clobber (match_scratch:DI 4 "=a"))] | |
bb621ad7 | 3319 | "TARGET_64BIT && !optimize" |
7e07e3ba GK |
3320 | " |
3321 | { | |
08c2951c SC |
3322 | emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2])); |
3323 | if (!TARGET_NO_CHECK_ZERO_DIV) | |
3324 | { | |
3325 | emit_insn (gen_div_trap (operands[2], | |
1feed51c | 3326 | GEN_INT (0), |
08c2951c SC |
3327 | GEN_INT (0x7))); |
3328 | } | |
7a38df19 | 3329 | |
08c2951c | 3330 | DONE; |
7e07e3ba GK |
3331 | }") |
3332 | ||
3333 | (define_insn "udivdi3_internal" | |
08c2951c | 3334 | [(set (match_operand:DI 0 "register_operand" "=l") |
cafe096b EC |
3335 | (udiv:DI (match_operand:DI 1 "register_operand" "d") |
3336 | (match_operand:DI 2 "nonmemory_operand" "di"))) | |
08c2951c SC |
3337 | (clobber (match_scratch:SI 3 "=h")) |
3338 | (clobber (match_scratch:SI 4 "=a"))] | |
7e07e3ba | 3339 | "TARGET_64BIT && !optimize" |
08c2951c | 3340 | "ddivu\\t$0,%1,%2" |
bb621ad7 | 3341 | [(set_attr "type" "idiv") |
0ff83799 | 3342 | (set_attr "mode" "DI")]) |
8ef30996 | 3343 | |
7e07e3ba | 3344 | (define_expand "umodsi3" |
08c2951c | 3345 | [(set (match_operand:SI 0 "register_operand" "=h") |
8ef30996 | 3346 | (umod:SI (match_operand:SI 1 "register_operand" "d") |
08c2951c | 3347 | (match_operand:SI 2 "register_operand" "d"))) |
46299de9 | 3348 | (clobber (match_scratch:SI 3 "=l")) |
08c2951c | 3349 | (clobber (match_scratch:SI 4 "=a"))] |
34b650b3 | 3350 | "!optimize" |
7e07e3ba GK |
3351 | " |
3352 | { | |
08c2951c SC |
3353 | emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2])); |
3354 | if (!TARGET_NO_CHECK_ZERO_DIV) | |
3355 | { | |
3356 | emit_insn (gen_div_trap (operands[2], | |
1feed51c | 3357 | GEN_INT (0), |
08c2951c SC |
3358 | GEN_INT (0x7))); |
3359 | } | |
7a38df19 | 3360 | |
08c2951c | 3361 | DONE; |
7e07e3ba GK |
3362 | }") |
3363 | ||
3364 | (define_insn "umodsi3_internal" | |
08c2951c | 3365 | [(set (match_operand:SI 0 "register_operand" "=h") |
7e07e3ba | 3366 | (umod:SI (match_operand:SI 1 "register_operand" "d") |
08c2951c SC |
3367 | (match_operand:SI 2 "nonmemory_operand" "di"))) |
3368 | (clobber (match_scratch:SI 3 "=l")) | |
3369 | (clobber (match_scratch:SI 4 "=a"))] | |
7e07e3ba | 3370 | "!optimize" |
08c2951c | 3371 | "divu\\t$0,%1,%2" |
8ef30996 | 3372 | [(set_attr "type" "idiv") |
0ff83799 | 3373 | (set_attr "mode" "SI")]) |
bb621ad7 | 3374 | |
7e07e3ba | 3375 | (define_expand "umoddi3" |
08c2951c | 3376 | [(set (match_operand:DI 0 "register_operand" "=h") |
cafe096b EC |
3377 | (umod:DI (match_operand:DI 1 "register_operand" "d") |
3378 | (match_operand:DI 2 "register_operand" "di"))) | |
46299de9 | 3379 | (clobber (match_scratch:DI 3 "=l")) |
08c2951c | 3380 | (clobber (match_scratch:DI 4 "=a"))] |
bb621ad7 | 3381 | "TARGET_64BIT && !optimize" |
7e07e3ba GK |
3382 | " |
3383 | { | |
08c2951c SC |
3384 | emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2])); |
3385 | if (!TARGET_NO_CHECK_ZERO_DIV) | |
3386 | { | |
3387 | emit_insn (gen_div_trap (operands[2], | |
1feed51c | 3388 | GEN_INT (0), |
08c2951c SC |
3389 | GEN_INT (0x7))); |
3390 | } | |
7a38df19 | 3391 | |
08c2951c | 3392 | DONE; |
7e07e3ba GK |
3393 | }") |
3394 | ||
3395 | (define_insn "umoddi3_internal" | |
08c2951c | 3396 | [(set (match_operand:DI 0 "register_operand" "=h") |
cafe096b EC |
3397 | (umod:DI (match_operand:DI 1 "register_operand" "d") |
3398 | (match_operand:DI 2 "nonmemory_operand" "di"))) | |
08c2951c SC |
3399 | (clobber (match_scratch:SI 3 "=l")) |
3400 | (clobber (match_scratch:SI 4 "=a"))] | |
7e07e3ba | 3401 | "TARGET_64BIT && !optimize" |
08c2951c | 3402 | "ddivu\\t$0,%1,%2" |
bb621ad7 | 3403 | [(set_attr "type" "idiv") |
0ff83799 | 3404 | (set_attr "mode" "DI")]) |
8ef30996 MM |
3405 | \f |
3406 | ;; | |
3407 | ;; .................... | |
3408 | ;; | |
3409 | ;; SQUARE ROOT | |
3410 | ;; | |
3411 | ;; .................... | |
3412 | ||
3413 | (define_insn "sqrtdf2" | |
3414 | [(set (match_operand:DF 0 "register_operand" "=f") | |
3415 | (sqrt:DF (match_operand:DF 1 "register_operand" "f")))] | |
46299de9 | 3416 | "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT" |
8ef30996 | 3417 | "sqrt.d\\t%0,%1" |
bb621ad7 | 3418 | [(set_attr "type" "fsqrt") |
0ff83799 | 3419 | (set_attr "mode" "DF")]) |
8ef30996 MM |
3420 | |
3421 | (define_insn "sqrtsf2" | |
3422 | [(set (match_operand:SF 0 "register_operand" "=f") | |
3423 | (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] | |
3424 | "TARGET_HARD_FLOAT && HAVE_SQRT_P()" | |
3425 | "sqrt.s\\t%0,%1" | |
bb621ad7 | 3426 | [(set_attr "type" "fsqrt") |
0ff83799 | 3427 | (set_attr "mode" "SF")]) |
8ef30996 | 3428 | |
b8eb88d0 ILT |
3429 | (define_insn "" |
3430 | [(set (match_operand:DF 0 "register_operand" "=f") | |
3431 | (div:DF (match_operand:DF 1 "const_float_1_operand" "") | |
3432 | (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))] | |
de6c5979 | 3433 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations" |
b8eb88d0 | 3434 | "rsqrt.d\\t%0,%2" |
5ce6f47b | 3435 | [(set_attr "type" "frsqrt") |
0ff83799 | 3436 | (set_attr "mode" "DF")]) |
b8eb88d0 ILT |
3437 | |
3438 | (define_insn "" | |
3439 | [(set (match_operand:SF 0 "register_operand" "=f") | |
3440 | (div:SF (match_operand:SF 1 "const_float_1_operand" "") | |
3441 | (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))] | |
de6c5979 | 3442 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations" |
b8eb88d0 | 3443 | "rsqrt.s\\t%0,%2" |
5ce6f47b | 3444 | [(set_attr "type" "frsqrt") |
0ff83799 | 3445 | (set_attr "mode" "SF")]) |
b8eb88d0 | 3446 | |
8ef30996 MM |
3447 | \f |
3448 | ;; | |
3449 | ;; .................... | |
3450 | ;; | |
3451 | ;; ABSOLUTE VALUE | |
3452 | ;; | |
3453 | ;; .................... | |
3454 | ||
3455 | ;; Do not use the integer abs macro instruction, since that signals an | |
3456 | ;; exception on -2147483648 (sigh). | |
3457 | ||
3458 | (define_insn "abssi2" | |
3459 | [(set (match_operand:SI 0 "register_operand" "=d") | |
3460 | (abs:SI (match_operand:SI 1 "register_operand" "d")))] | |
2bcb2ab3 | 3461 | "!TARGET_MIPS16" |
8ef30996 MM |
3462 | "* |
3463 | { | |
3464 | dslots_jump_total++; | |
3465 | dslots_jump_filled++; | |
3466 | operands[2] = const0_rtx; | |
3467 | ||
bb621ad7 JW |
3468 | if (REGNO (operands[0]) == REGNO (operands[1])) |
3469 | { | |
e9a25f70 | 3470 | if (GENERATE_BRANCHLIKELY) |
efa3896a | 3471 | return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\"; |
bb621ad7 | 3472 | else |
efa3896a | 3473 | return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\"; |
7a38df19 | 3474 | } |
bb621ad7 | 3475 | else |
efa3896a | 3476 | return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\"; |
8ef30996 MM |
3477 | }" |
3478 | [(set_attr "type" "multi") | |
3479 | (set_attr "mode" "SI") | |
0ff83799 | 3480 | (set_attr "length" "12")]) |
8ef30996 | 3481 | |
bb621ad7 JW |
3482 | (define_insn "absdi2" |
3483 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b | 3484 | (abs:DI (match_operand:DI 1 "register_operand" "d")))] |
2bcb2ab3 | 3485 | "TARGET_64BIT && !TARGET_MIPS16" |
bb621ad7 JW |
3486 | "* |
3487 | { | |
404e4854 | 3488 | unsigned int regno1; |
bb621ad7 JW |
3489 | dslots_jump_total++; |
3490 | dslots_jump_filled++; | |
3491 | operands[2] = const0_rtx; | |
7a38df19 | 3492 | |
12a345cd CP |
3493 | if (GET_CODE (operands[1]) == REG) |
3494 | regno1 = REGNO (operands[1]); | |
7a38df19 | 3495 | else |
12a345cd | 3496 | regno1 = REGNO (XEXP (operands[1], 0)); |
bb621ad7 | 3497 | |
12a345cd | 3498 | if (REGNO (operands[0]) == regno1) |
efa3896a | 3499 | return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\"; |
bb621ad7 | 3500 | else |
efa3896a | 3501 | return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\"; |
bb621ad7 JW |
3502 | }" |
3503 | [(set_attr "type" "multi") | |
3504 | (set_attr "mode" "DI") | |
0ff83799 | 3505 | (set_attr "length" "12")]) |
bb621ad7 | 3506 | |
8ef30996 MM |
3507 | (define_insn "absdf2" |
3508 | [(set (match_operand:DF 0 "register_operand" "=f") | |
3509 | (abs:DF (match_operand:DF 1 "register_operand" "f")))] | |
46299de9 | 3510 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
8ef30996 MM |
3511 | "abs.d\\t%0,%1" |
3512 | [(set_attr "type" "fabs") | |
0ff83799 | 3513 | (set_attr "mode" "DF")]) |
8ef30996 MM |
3514 | |
3515 | (define_insn "abssf2" | |
3516 | [(set (match_operand:SF 0 "register_operand" "=f") | |
3517 | (abs:SF (match_operand:SF 1 "register_operand" "f")))] | |
3518 | "TARGET_HARD_FLOAT" | |
3519 | "abs.s\\t%0,%1" | |
3520 | [(set_attr "type" "fabs") | |
0ff83799 | 3521 | (set_attr "mode" "SF")]) |
8ef30996 MM |
3522 | |
3523 | \f | |
3524 | ;; | |
3525 | ;; .................... | |
3526 | ;; | |
3527 | ;; FIND FIRST BIT INSTRUCTION | |
3528 | ;; | |
3529 | ;; .................... | |
3530 | ;; | |
3531 | ||
3532 | (define_insn "ffssi2" | |
3533 | [(set (match_operand:SI 0 "register_operand" "=&d") | |
3534 | (ffs:SI (match_operand:SI 1 "register_operand" "d"))) | |
7d87c851 MM |
3535 | (clobber (match_scratch:SI 2 "=&d")) |
3536 | (clobber (match_scratch:SI 3 "=&d"))] | |
2bcb2ab3 | 3537 | "!TARGET_MIPS16" |
8ef30996 MM |
3538 | "* |
3539 | { | |
3540 | dslots_jump_total += 2; | |
3541 | dslots_jump_filled += 2; | |
3542 | operands[4] = const0_rtx; | |
3543 | ||
3544 | if (optimize && find_reg_note (insn, REG_DEAD, operands[1])) | |
3545 | return \"%(\\ | |
3546 | move\\t%0,%z4\\n\\ | |
3547 | \\tbeq\\t%1,%z4,2f\\n\\ | |
efa3896a | 3548 | %~1:\\tand\\t%2,%1,0x0001\\n\\ |
8ef30996 MM |
3549 | \\taddu\\t%0,%0,1\\n\\ |
3550 | \\tbeq\\t%2,%z4,1b\\n\\ | |
3551 | \\tsrl\\t%1,%1,1\\n\\ | |
efa3896a | 3552 | %~2:%)\"; |
8ef30996 MM |
3553 | |
3554 | return \"%(\\ | |
3555 | move\\t%0,%z4\\n\\ | |
3556 | \\tmove\\t%3,%1\\n\\ | |
3557 | \\tbeq\\t%3,%z4,2f\\n\\ | |
efa3896a | 3558 | %~1:\\tand\\t%2,%3,0x0001\\n\\ |
8ef30996 MM |
3559 | \\taddu\\t%0,%0,1\\n\\ |
3560 | \\tbeq\\t%2,%z4,1b\\n\\ | |
3561 | \\tsrl\\t%3,%3,1\\n\\ | |
efa3896a | 3562 | %~2:%)\"; |
8ef30996 MM |
3563 | }" |
3564 | [(set_attr "type" "multi") | |
3565 | (set_attr "mode" "SI") | |
0ff83799 | 3566 | (set_attr "length" "12")]) |
8ef30996 | 3567 | |
bb621ad7 JW |
3568 | (define_insn "ffsdi2" |
3569 | [(set (match_operand:DI 0 "register_operand" "=&d") | |
cafe096b | 3570 | (ffs:DI (match_operand:DI 1 "register_operand" "d"))) |
bb621ad7 JW |
3571 | (clobber (match_scratch:DI 2 "=&d")) |
3572 | (clobber (match_scratch:DI 3 "=&d"))] | |
2bcb2ab3 | 3573 | "TARGET_64BIT && !TARGET_MIPS16" |
bb621ad7 JW |
3574 | "* |
3575 | { | |
3576 | dslots_jump_total += 2; | |
3577 | dslots_jump_filled += 2; | |
3578 | operands[4] = const0_rtx; | |
3579 | ||
3580 | if (optimize && find_reg_note (insn, REG_DEAD, operands[1])) | |
3581 | return \"%(\\ | |
3582 | move\\t%0,%z4\\n\\ | |
3583 | \\tbeq\\t%1,%z4,2f\\n\\ | |
efa3896a | 3584 | %~1:\\tand\\t%2,%1,0x0001\\n\\ |
bb621ad7 JW |
3585 | \\tdaddu\\t%0,%0,1\\n\\ |
3586 | \\tbeq\\t%2,%z4,1b\\n\\ | |
3587 | \\tdsrl\\t%1,%1,1\\n\\ | |
efa3896a | 3588 | %~2:%)\"; |
bb621ad7 JW |
3589 | |
3590 | return \"%(\\ | |
3591 | move\\t%0,%z4\\n\\ | |
3592 | \\tmove\\t%3,%1\\n\\ | |
3593 | \\tbeq\\t%3,%z4,2f\\n\\ | |
efa3896a | 3594 | %~1:\\tand\\t%2,%3,0x0001\\n\\ |
bb621ad7 JW |
3595 | \\tdaddu\\t%0,%0,1\\n\\ |
3596 | \\tbeq\\t%2,%z4,1b\\n\\ | |
3597 | \\tdsrl\\t%3,%3,1\\n\\ | |
efa3896a | 3598 | %~2:%)\"; |
bb621ad7 JW |
3599 | }" |
3600 | [(set_attr "type" "multi") | |
3601 | (set_attr "mode" "DI") | |
0ff83799 | 3602 | (set_attr "length" "24")]) |
bb621ad7 | 3603 | |
8ef30996 MM |
3604 | \f |
3605 | ;; | |
3606 | ;; .................... | |
3607 | ;; | |
3608 | ;; NEGATION and ONE'S COMPLEMENT | |
3609 | ;; | |
3610 | ;; .................... | |
3611 | ||
3612 | (define_insn "negsi2" | |
3613 | [(set (match_operand:SI 0 "register_operand" "=d") | |
3614 | (neg:SI (match_operand:SI 1 "register_operand" "d")))] | |
3615 | "" | |
3616 | "* | |
3617 | { | |
2bcb2ab3 GK |
3618 | if (TARGET_MIPS16) |
3619 | return \"neg\\t%0,%1\"; | |
8ef30996 MM |
3620 | operands[2] = const0_rtx; |
3621 | return \"subu\\t%0,%z2,%1\"; | |
3622 | }" | |
3623 | [(set_attr "type" "arith") | |
0ff83799 | 3624 | (set_attr "mode" "SI")]) |
8ef30996 | 3625 | |
e7d7b3dc | 3626 | (define_expand "negdi2" |
8ef30996 | 3627 | [(parallel [(set (match_operand:DI 0 "register_operand" "=d") |
cafe096b | 3628 | (neg:DI (match_operand:DI 1 "register_operand" "d"))) |
8ef30996 | 3629 | (clobber (match_dup 2))])] |
2bcb2ab3 | 3630 | "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16" |
bb621ad7 JW |
3631 | " |
3632 | { | |
3633 | if (TARGET_64BIT) | |
3634 | { | |
3635 | emit_insn (gen_negdi2_internal_2 (operands[0], operands[1])); | |
3636 | DONE; | |
3637 | } | |
3638 | ||
3639 | operands[2] = gen_reg_rtx (SImode); | |
3640 | }") | |
8ef30996 | 3641 | |
e7d7b3dc | 3642 | (define_insn "negdi2_internal" |
8ef30996 MM |
3643 | [(set (match_operand:DI 0 "register_operand" "=d") |
3644 | (neg:DI (match_operand:DI 1 "register_operand" "d"))) | |
3645 | (clobber (match_operand:SI 2 "register_operand" "=d"))] | |
2bcb2ab3 | 3646 | "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16" |
8ef30996 MM |
3647 | "* |
3648 | { | |
3649 | operands[3] = const0_rtx; | |
3650 | return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\"; | |
3651 | }" | |
3652 | [(set_attr "type" "darith") | |
3653 | (set_attr "mode" "DI") | |
0ff83799 | 3654 | (set_attr "length" "16")]) |
8ef30996 | 3655 | |
bb621ad7 JW |
3656 | (define_insn "negdi2_internal_2" |
3657 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b | 3658 | (neg:DI (match_operand:DI 1 "register_operand" "d")))] |
2bcb2ab3 | 3659 | "TARGET_64BIT && !TARGET_MIPS16" |
bb621ad7 JW |
3660 | "* |
3661 | { | |
3662 | operands[2] = const0_rtx; | |
3663 | return \"dsubu\\t%0,%z2,%1\"; | |
3664 | }" | |
3665 | [(set_attr "type" "arith") | |
0ff83799 | 3666 | (set_attr "mode" "DI")]) |
bb621ad7 | 3667 | |
8ef30996 MM |
3668 | (define_insn "negdf2" |
3669 | [(set (match_operand:DF 0 "register_operand" "=f") | |
3670 | (neg:DF (match_operand:DF 1 "register_operand" "f")))] | |
46299de9 | 3671 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
8ef30996 MM |
3672 | "neg.d\\t%0,%1" |
3673 | [(set_attr "type" "fneg") | |
0ff83799 | 3674 | (set_attr "mode" "DF")]) |
8ef30996 MM |
3675 | |
3676 | (define_insn "negsf2" | |
3677 | [(set (match_operand:SF 0 "register_operand" "=f") | |
3678 | (neg:SF (match_operand:SF 1 "register_operand" "f")))] | |
3679 | "TARGET_HARD_FLOAT" | |
3680 | "neg.s\\t%0,%1" | |
3681 | [(set_attr "type" "fneg") | |
0ff83799 | 3682 | (set_attr "mode" "SF")]) |
8ef30996 MM |
3683 | |
3684 | (define_insn "one_cmplsi2" | |
3685 | [(set (match_operand:SI 0 "register_operand" "=d") | |
3686 | (not:SI (match_operand:SI 1 "register_operand" "d")))] | |
3687 | "" | |
3688 | "* | |
3689 | { | |
2bcb2ab3 GK |
3690 | if (TARGET_MIPS16) |
3691 | return \"not\\t%0,%1\"; | |
8ef30996 MM |
3692 | operands[2] = const0_rtx; |
3693 | return \"nor\\t%0,%z2,%1\"; | |
3694 | }" | |
3695 | [(set_attr "type" "arith") | |
0ff83799 | 3696 | (set_attr "mode" "SI")]) |
8ef30996 MM |
3697 | |
3698 | (define_insn "one_cmpldi2" | |
3699 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
3700 | (not:DI (match_operand:DI 1 "register_operand" "d")))] |
3701 | "TARGET_64BIT" | |
8ef30996 MM |
3702 | "* |
3703 | { | |
2bcb2ab3 | 3704 | if (TARGET_MIPS16) |
cafe096b EC |
3705 | return \"not\\t%0,%1\"; |
3706 | return \"nor\\t%0,%.,%1\"; | |
8ef30996 MM |
3707 | }" |
3708 | [(set_attr "type" "darith") | |
cafe096b | 3709 | (set_attr "mode" "DI")]) |
8ef30996 MM |
3710 | \f |
3711 | ;; | |
3712 | ;; .................... | |
3713 | ;; | |
3714 | ;; LOGICAL | |
3715 | ;; | |
3716 | ;; .................... | |
3717 | ;; | |
3718 | ||
2bcb2ab3 GK |
3719 | ;; Many of these instructions uses trivial define_expands, because we |
3720 | ;; want to use a different set of constraints when TARGET_MIPS16. | |
3721 | ||
3722 | (define_expand "andsi3" | |
65437fe8 | 3723 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
e2f2127c MM |
3724 | (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d") |
3725 | (match_operand:SI 2 "uns_arith_operand" "d,K")))] | |
65437fe8 | 3726 | "" |
2bcb2ab3 GK |
3727 | " |
3728 | { | |
3729 | if (TARGET_MIPS16) | |
1bfbbbcf AO |
3730 | { |
3731 | operands[1] = force_reg (SImode, operands[1]); | |
3732 | operands[2] = force_reg (SImode, operands[2]); | |
3733 | } | |
2bcb2ab3 GK |
3734 | }") |
3735 | ||
3736 | (define_insn "" | |
3737 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
3738 | (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d") | |
3739 | (match_operand:SI 2 "uns_arith_operand" "d,K")))] | |
3740 | "!TARGET_MIPS16" | |
65437fe8 MM |
3741 | "@ |
3742 | and\\t%0,%1,%2 | |
3743 | andi\\t%0,%1,%x2" | |
3744 | [(set_attr "type" "arith") | |
0ff83799 | 3745 | (set_attr "mode" "SI")]) |
65437fe8 | 3746 | |
2bcb2ab3 GK |
3747 | (define_insn "" |
3748 | [(set (match_operand:SI 0 "register_operand" "=d") | |
3749 | (and:SI (match_operand:SI 1 "register_operand" "%0") | |
3750 | (match_operand:SI 2 "register_operand" "d")))] | |
3751 | "TARGET_MIPS16" | |
3752 | "and\\t%0,%2" | |
3753 | [(set_attr "type" "arith") | |
0ff83799 | 3754 | (set_attr "mode" "SI")]) |
2bcb2ab3 GK |
3755 | |
3756 | (define_expand "anddi3" | |
cafe096b EC |
3757 | [(set (match_operand:DI 0 "register_operand" "") |
3758 | (and:DI (match_operand:DI 1 "register_operand" "") | |
3759 | (match_operand:DI 2 "uns_arith_operand" "")))] | |
3760 | "TARGET_64BIT" | |
2bcb2ab3 GK |
3761 | " |
3762 | { | |
3763 | if (TARGET_MIPS16) | |
1bfbbbcf AO |
3764 | { |
3765 | operands[1] = force_reg (DImode, operands[1]); | |
3766 | operands[2] = force_reg (DImode, operands[2]); | |
3767 | } | |
2bcb2ab3 GK |
3768 | }") |
3769 | ||
3770 | (define_insn "" | |
bb621ad7 | 3771 | [(set (match_operand:DI 0 "register_operand" "=d,d") |
cafe096b EC |
3772 | (and:DI (match_operand:DI 1 "register_operand" "d,d") |
3773 | (match_operand:DI 2 "uns_arith_operand" "d,K")))] | |
2bcb2ab3 | 3774 | "TARGET_64BIT && !TARGET_MIPS16" |
bb621ad7 JW |
3775 | "@ |
3776 | and\\t%0,%1,%2 | |
3777 | andi\\t%0,%1,%x2" | |
cafe096b EC |
3778 | [(set_attr "type" "darith") |
3779 | (set_attr "mode" "DI")]) | |
3780 | ||
3781 | (define_insn "" | |
3782 | [(set (match_operand:DI 0 "register_operand" "=d") | |
3783 | (and:DI (match_operand:DI 1 "register_operand" "0") | |
3784 | (match_operand:DI 2 "register_operand" "d")))] | |
3785 | "TARGET_64BIT && TARGET_MIPS16" | |
3786 | "and\\t%0,%2" | |
3787 | [(set_attr "type" "darith") | |
0ff83799 | 3788 | (set_attr "mode" "DI")]) |
bb621ad7 | 3789 | |
2bcb2ab3 | 3790 | (define_expand "iorsi3" |
65437fe8 | 3791 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
e2f2127c MM |
3792 | (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d") |
3793 | (match_operand:SI 2 "uns_arith_operand" "d,K")))] | |
65437fe8 | 3794 | "" |
2bcb2ab3 GK |
3795 | " |
3796 | { | |
3797 | if (TARGET_MIPS16) | |
1bfbbbcf AO |
3798 | { |
3799 | operands[1] = force_reg (SImode, operands[1]); | |
3800 | operands[2] = force_reg (SImode, operands[2]); | |
3801 | } | |
2bcb2ab3 GK |
3802 | }") |
3803 | ||
3804 | (define_insn "" | |
3805 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
3806 | (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d") | |
3807 | (match_operand:SI 2 "uns_arith_operand" "d,K")))] | |
3808 | "!TARGET_MIPS16" | |
65437fe8 MM |
3809 | "@ |
3810 | or\\t%0,%1,%2 | |
3811 | ori\\t%0,%1,%x2" | |
3812 | [(set_attr "type" "arith") | |
0ff83799 | 3813 | (set_attr "mode" "SI")]) |
65437fe8 | 3814 | |
2bcb2ab3 GK |
3815 | (define_insn "" |
3816 | [(set (match_operand:SI 0 "register_operand" "=d") | |
3817 | (ior:SI (match_operand:SI 1 "register_operand" "%0") | |
3818 | (match_operand:SI 2 "register_operand" "d")))] | |
3819 | "TARGET_MIPS16" | |
3820 | "or\\t%0,%2" | |
3821 | [(set_attr "type" "arith") | |
0ff83799 | 3822 | (set_attr "mode" "SI")]) |
2bcb2ab3 | 3823 | |
2bcb2ab3 | 3824 | (define_expand "iordi3" |
cafe096b EC |
3825 | [(set (match_operand:DI 0 "register_operand" "") |
3826 | (ior:DI (match_operand:DI 1 "register_operand" "") | |
3827 | (match_operand:DI 2 "uns_arith_operand" "")))] | |
3828 | "TARGET_64BIT" | |
3829 | " | |
3830 | { | |
3831 | if (TARGET_MIPS16) | |
3832 | { | |
3833 | operands[1] = force_reg (DImode, operands[1]); | |
3834 | operands[2] = force_reg (DImode, operands[2]); | |
3835 | } | |
3836 | }") | |
2bcb2ab3 GK |
3837 | |
3838 | (define_insn "" | |
cafe096b EC |
3839 | [(set (match_operand:DI 0 "register_operand" "=d,d") |
3840 | (ior:DI (match_operand:DI 1 "register_operand" "d,d") | |
3841 | (match_operand:DI 2 "uns_arith_operand" "d,K")))] | |
3842 | "TARGET_64BIT && !TARGET_MIPS16" | |
3843 | "@ | |
3844 | or\t%0,%1,%2 | |
3845 | ori\t%0,%1,%x2" | |
8ef30996 | 3846 | [(set_attr "type" "darith") |
cafe096b | 3847 | (set_attr "mode" "DI")]) |
8ef30996 | 3848 | |
2bcb2ab3 GK |
3849 | (define_insn "" |
3850 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
3851 | (ior:DI (match_operand:DI 1 "register_operand" "0") |
3852 | (match_operand:DI 2 "register_operand" "d")))] | |
3853 | "TARGET_64BIT && TARGET_MIPS16" | |
3854 | "or\t%0,%2" | |
2bcb2ab3 | 3855 | [(set_attr "type" "darith") |
cafe096b | 3856 | (set_attr "mode" "DI")]) |
8ef30996 | 3857 | |
2bcb2ab3 | 3858 | (define_expand "xorsi3" |
65437fe8 | 3859 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
e2f2127c MM |
3860 | (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d") |
3861 | (match_operand:SI 2 "uns_arith_operand" "d,K")))] | |
65437fe8 | 3862 | "" |
2bcb2ab3 GK |
3863 | "") |
3864 | ||
3865 | (define_insn "" | |
3866 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
3867 | (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d") | |
3868 | (match_operand:SI 2 "uns_arith_operand" "d,K")))] | |
3869 | "!TARGET_MIPS16" | |
65437fe8 MM |
3870 | "@ |
3871 | xor\\t%0,%1,%2 | |
3872 | xori\\t%0,%1,%x2" | |
3873 | [(set_attr "type" "arith") | |
0ff83799 | 3874 | (set_attr "mode" "SI")]) |
65437fe8 | 3875 | |
2bcb2ab3 GK |
3876 | (define_insn "" |
3877 | [(set (match_operand:SI 0 "register_operand" "=d,t,t") | |
3878 | (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d") | |
3879 | (match_operand:SI 2 "uns_arith_operand" "d,K,d")))] | |
3880 | "TARGET_MIPS16" | |
3881 | "@ | |
3882 | xor\\t%0,%2 | |
3883 | cmpi\\t%1,%2 | |
3884 | cmp\\t%1,%2" | |
3885 | [(set_attr "type" "arith") | |
3886 | (set_attr "mode" "SI") | |
3887 | (set_attr_alternative "length" | |
0ff83799 | 3888 | [(const_int 4) |
2bcb2ab3 | 3889 | (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "") |
0ff83799 MM |
3890 | (const_int 4) |
3891 | (const_int 8)) | |
3892 | (const_int 4)])]) | |
2bcb2ab3 | 3893 | |
2bcb2ab3 | 3894 | (define_expand "xordi3" |
cafe096b EC |
3895 | [(set (match_operand:DI 0 "register_operand" "") |
3896 | (xor:DI (match_operand:DI 1 "register_operand" "") | |
3897 | (match_operand:DI 2 "uns_arith_operand" "")))] | |
3898 | "TARGET_64BIT" | |
3899 | " | |
bb621ad7 | 3900 | { |
cafe096b EC |
3901 | if (TARGET_MIPS16) |
3902 | { | |
3903 | operands[1] = force_reg (DImode, operands[1]); | |
3904 | operands[2] = force_reg (DImode, operands[2]); | |
3905 | } | |
3906 | }") | |
8ef30996 | 3907 | |
2bcb2ab3 | 3908 | (define_insn "" |
cafe096b EC |
3909 | [(set (match_operand:DI 0 "register_operand" "=d,d") |
3910 | (xor:DI (match_operand:DI 1 "register_operand" "d,d") | |
3911 | (match_operand:DI 2 "uns_arith_operand" "d,K")))] | |
3912 | "TARGET_64BIT && !TARGET_MIPS16" | |
3913 | "@ | |
3914 | xor\t%0,%1,%2 | |
3915 | xori\t%0,%1,%x2" | |
2bcb2ab3 | 3916 | [(set_attr "type" "darith") |
cafe096b | 3917 | (set_attr "mode" "DI")]) |
2bcb2ab3 GK |
3918 | |
3919 | (define_insn "" | |
3920 | [(set (match_operand:DI 0 "register_operand" "=d,t,t") | |
cafe096b EC |
3921 | (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d") |
3922 | (match_operand:DI 2 "uns_arith_operand" "d,K,d")))] | |
2bcb2ab3 GK |
3923 | "TARGET_64BIT && TARGET_MIPS16" |
3924 | "@ | |
3925 | xor\\t%0,%2 | |
3926 | cmpi\\t%1,%2 | |
3927 | cmp\\t%1,%2" | |
3928 | [(set_attr "type" "arith") | |
3929 | (set_attr "mode" "DI") | |
3930 | (set_attr_alternative "length" | |
0ff83799 | 3931 | [(const_int 4) |
2bcb2ab3 | 3932 | (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "") |
0ff83799 MM |
3933 | (const_int 4) |
3934 | (const_int 8)) | |
3935 | (const_int 4)])]) | |
2bcb2ab3 | 3936 | |
77a8368e JW |
3937 | (define_insn "*norsi3" |
3938 | [(set (match_operand:SI 0 "register_operand" "=d") | |
3939 | (and:SI (not:SI (match_operand:SI 1 "register_operand" "d")) | |
3940 | (not:SI (match_operand:SI 2 "register_operand" "d"))))] | |
2bcb2ab3 | 3941 | "!TARGET_MIPS16" |
77a8368e JW |
3942 | "nor\\t%0,%z1,%z2" |
3943 | [(set_attr "type" "arith") | |
0ff83799 | 3944 | (set_attr "mode" "SI")]) |
77a8368e JW |
3945 | |
3946 | (define_insn "*nordi3" | |
3947 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
3948 | (and:DI (not:DI (match_operand:DI 1 "register_operand" "d")) |
3949 | (not:DI (match_operand:DI 2 "register_operand" "d"))))] | |
3950 | "TARGET_64BIT && !TARGET_MIPS16" | |
3951 | "nor\\t%0,%z1,%z2" | |
77a8368e | 3952 | [(set_attr "type" "darith") |
cafe096b | 3953 | (set_attr "mode" "DI")]) |
8ef30996 MM |
3954 | \f |
3955 | ;; | |
3956 | ;; .................... | |
3957 | ;; | |
3958 | ;; TRUNCATION | |
3959 | ;; | |
3960 | ;; .................... | |
3961 | ||
cafe096b EC |
3962 | |
3963 | ||
8ef30996 MM |
3964 | (define_insn "truncdfsf2" |
3965 | [(set (match_operand:SF 0 "register_operand" "=f") | |
3966 | (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] | |
46299de9 | 3967 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
8ef30996 MM |
3968 | "cvt.s.d\\t%0,%1" |
3969 | [(set_attr "type" "fcvt") | |
0ff83799 | 3970 | (set_attr "mode" "SF")]) |
8ef30996 | 3971 | |
cafe096b EC |
3972 | ;; Integer truncation patterns. Truncating SImode values to smaller |
3973 | ;; modes is a no-op, as it is for most other GCC ports. Truncating | |
3974 | ;; DImode values to SImode is not a no-op for TARGET_64BIT since we | |
3975 | ;; need to make sure that the lower 32 bits are properly sign-extended | |
3976 | ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes | |
3977 | ;; smaller than SImode is equivalent to two separate truncations: | |
3978 | ;; | |
3979 | ;; A B | |
3980 | ;; DI ---> HI == DI ---> SI ---> HI | |
3981 | ;; DI ---> QI == DI ---> SI ---> QI | |
3982 | ;; | |
3983 | ;; Step A needs a real instruction but step B does not. | |
3984 | ||
8894cf34 | 3985 | (define_insn "truncdisi2" |
cafe096b EC |
3986 | [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m") |
3987 | (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))] | |
bb621ad7 | 3988 | "TARGET_64BIT" |
cafe096b EC |
3989 | "@ |
3990 | sll\t%0,%1,0 | |
3991 | sw\t%1,%0" | |
3992 | [(set_attr "type" "darith") | |
3993 | (set_attr "mode" "SI") | |
3994 | (set_attr "extended_mips16" "yes,*")]) | |
bb621ad7 | 3995 | |
8894cf34 | 3996 | (define_insn "truncdihi2" |
cafe096b EC |
3997 | [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m") |
3998 | (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))] | |
00bb4b62 | 3999 | "TARGET_64BIT" |
cafe096b EC |
4000 | "@ |
4001 | sll\t%0,%1,0 | |
4002 | sh\t%1,%0" | |
4003 | [(set_attr "type" "darith") | |
4004 | (set_attr "mode" "SI") | |
4005 | (set_attr "extended_mips16" "yes,*")]) | |
4006 | ||
8894cf34 | 4007 | (define_insn "truncdiqi2" |
cafe096b EC |
4008 | [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m") |
4009 | (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))] | |
00bb4b62 | 4010 | "TARGET_64BIT" |
cafe096b EC |
4011 | "@ |
4012 | sll\t%0,%1,0 | |
4013 | sb\t%1,%0" | |
4014 | [(set_attr "type" "darith") | |
4015 | (set_attr "mode" "SI") | |
4016 | (set_attr "extended_mips16" "yes,*")]) | |
a67f7692 JW |
4017 | |
4018 | ;; Combiner patterns to optimize shift/truncate combinations. | |
cafe096b | 4019 | |
a67f7692 JW |
4020 | (define_insn "" |
4021 | [(set (match_operand:SI 0 "register_operand" "=d") | |
cafe096b EC |
4022 | (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") |
4023 | (match_operand:DI 2 "small_int" "I"))))] | |
4024 | "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32" | |
4025 | "dsra\\t%0,%1,%2" | |
4026 | [(set_attr "type" "darith") | |
4027 | (set_attr "mode" "SI")]) | |
7a38df19 | 4028 | |
a67f7692 JW |
4029 | (define_insn "" |
4030 | [(set (match_operand:SI 0 "register_operand" "=d") | |
cafe096b EC |
4031 | (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") |
4032 | (const_int 32))))] | |
2bcb2ab3 | 4033 | "TARGET_64BIT && !TARGET_MIPS16" |
cafe096b EC |
4034 | "dsra\\t%0,%1,32" |
4035 | [(set_attr "type" "darith") | |
4036 | (set_attr "mode" "SI")]) | |
a67f7692 | 4037 | |
a67f7692 | 4038 | |
cafe096b EC |
4039 | ;; Combiner patterns for truncate/sign_extend combinations. They use |
4040 | ;; the shift/truncate patterns above. | |
4041 | ||
4042 | (define_insn_and_split "" | |
a67f7692 | 4043 | [(set (match_operand:SI 0 "register_operand" "=d") |
cafe096b EC |
4044 | (sign_extend:SI |
4045 | (truncate:HI (match_operand:DI 1 "register_operand" "d"))))] | |
4046 | "TARGET_64BIT && !TARGET_MIPS16" | |
4047 | "#" | |
4048 | "&& reload_completed" | |
4049 | [(set (match_dup 2) | |
4050 | (ashift:DI (match_dup 1) | |
4051 | (const_int 48))) | |
4052 | (set (match_dup 0) | |
4053 | (truncate:SI (ashiftrt:DI (match_dup 2) | |
4054 | (const_int 48))))] | |
4055 | { operands[2] = gen_lowpart (DImode, operands[0]); }) | |
4056 | ||
4057 | (define_insn_and_split "" | |
4058 | [(set (match_operand:SI 0 "register_operand" "=d") | |
4059 | (sign_extend:SI | |
4060 | (truncate:QI (match_operand:DI 1 "register_operand" "d"))))] | |
4061 | "TARGET_64BIT && !TARGET_MIPS16" | |
4062 | "#" | |
4063 | "&& reload_completed" | |
4064 | [(set (match_dup 2) | |
4065 | (ashift:DI (match_dup 1) | |
4066 | (const_int 56))) | |
4067 | (set (match_dup 0) | |
4068 | (truncate:SI (ashiftrt:DI (match_dup 2) | |
4069 | (const_int 56))))] | |
4070 | { operands[2] = gen_lowpart (DImode, operands[0]); }) | |
a67f7692 | 4071 | |
99f762bf JW |
4072 | |
4073 | ;; Combiner patterns to optimize truncate/zero_extend combinations. | |
4074 | ||
4075 | (define_insn "" | |
4076 | [(set (match_operand:SI 0 "register_operand" "=d") | |
cafe096b EC |
4077 | (zero_extend:SI (truncate:HI |
4078 | (match_operand:DI 1 "register_operand" "d"))))] | |
2bcb2ab3 | 4079 | "TARGET_64BIT && !TARGET_MIPS16" |
99f762bf | 4080 | "andi\\t%0,%1,0xffff" |
cafe096b EC |
4081 | [(set_attr "type" "darith") |
4082 | (set_attr "mode" "SI")]) | |
99f762bf JW |
4083 | |
4084 | (define_insn "" | |
4085 | [(set (match_operand:SI 0 "register_operand" "=d") | |
cafe096b EC |
4086 | (zero_extend:SI (truncate:QI |
4087 | (match_operand:DI 1 "register_operand" "d"))))] | |
2bcb2ab3 | 4088 | "TARGET_64BIT && !TARGET_MIPS16" |
99f762bf | 4089 | "andi\\t%0,%1,0xff" |
cafe096b EC |
4090 | [(set_attr "type" "darith") |
4091 | (set_attr "mode" "SI")]) | |
99f762bf JW |
4092 | |
4093 | (define_insn "" | |
4094 | [(set (match_operand:HI 0 "register_operand" "=d") | |
cafe096b EC |
4095 | (zero_extend:HI (truncate:QI |
4096 | (match_operand:DI 1 "register_operand" "d"))))] | |
2bcb2ab3 | 4097 | "TARGET_64BIT && !TARGET_MIPS16" |
99f762bf | 4098 | "andi\\t%0,%1,0xff" |
cafe096b EC |
4099 | [(set_attr "type" "darith") |
4100 | (set_attr "mode" "HI")]) | |
4101 | ||
8ef30996 MM |
4102 | \f |
4103 | ;; | |
4104 | ;; .................... | |
4105 | ;; | |
4106 | ;; ZERO EXTENSION | |
4107 | ;; | |
4108 | ;; .................... | |
4109 | ||
4110 | ;; Extension insns. | |
abdf3eea | 4111 | ;; Those for integer source operand are ordered widest source type first. |
8ef30996 | 4112 | |
cafe096b EC |
4113 | (define_insn_and_split "zero_extendsidi2" |
4114 | [(set (match_operand:DI 0 "register_operand" "=d") | |
4115 | (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))] | |
bb621ad7 | 4116 | "TARGET_64BIT" |
cafe096b EC |
4117 | "#" |
4118 | "&& reload_completed" | |
4119 | [(set (match_dup 0) | |
4120 | (ashift:DI (match_dup 1) (const_int 32))) | |
4121 | (set (match_dup 0) | |
4122 | (lshiftrt:DI (match_dup 0) (const_int 32)))] | |
4123 | "operands[1] = gen_lowpart (DImode, operands[1]);" | |
4124 | [(set_attr "type" "arith") | |
4125 | (set_attr "mode" "DI")]) | |
bb621ad7 | 4126 | |
cafe096b EC |
4127 | (define_insn "*zero_extendsidi2_mem" |
4128 | [(set (match_operand:DI 0 "register_operand" "=d") | |
4129 | (zero_extend:DI (match_operand:SI 1 "memory_operand" "m")))] | |
b5031ab7 | 4130 | "TARGET_64BIT && !TARGET_MIPS16" |
cafe096b EC |
4131 | "lwu\t%0,%1" |
4132 | [(set_attr "type" "load") | |
4133 | (set_attr "mode" "DI")]) | |
bb621ad7 | 4134 | |
2bcb2ab3 GK |
4135 | (define_expand "zero_extendhisi2" |
4136 | [(set (match_operand:SI 0 "register_operand" "") | |
cafe096b | 4137 | (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] |
2bcb2ab3 GK |
4138 | "" |
4139 | " | |
4140 | { | |
4141 | if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM) | |
4142 | { | |
4143 | rtx op = gen_lowpart (SImode, operands[1]); | |
4144 | rtx temp = force_reg (SImode, GEN_INT (0xffff)); | |
4145 | ||
4146 | emit_insn (gen_andsi3 (operands[0], op, temp)); | |
4147 | DONE; | |
4148 | } | |
4149 | }") | |
4150 | ||
4151 | (define_insn "" | |
cafe096b EC |
4152 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
4153 | (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))] | |
2bcb2ab3 | 4154 | "!TARGET_MIPS16" |
cafe096b EC |
4155 | "@ |
4156 | andi\t%0,%1,0xffff | |
4157 | lhu\t%0,%1" | |
4158 | [(set_attr "type" "arith,load") | |
4159 | (set_attr "mode" "SI") | |
4160 | (set_attr "length" "4,*")]) | |
8ef30996 | 4161 | |
2bcb2ab3 | 4162 | (define_insn "" |
cafe096b EC |
4163 | [(set (match_operand:SI 0 "register_operand" "=d") |
4164 | (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] | |
2bcb2ab3 | 4165 | "TARGET_MIPS16" |
cafe096b EC |
4166 | "lhu\t%0,%1" |
4167 | [(set_attr "type" "load") | |
4168 | (set_attr "mode" "SI")]) | |
2bcb2ab3 GK |
4169 | |
4170 | (define_expand "zero_extendhidi2" | |
4171 | [(set (match_operand:DI 0 "register_operand" "") | |
cafe096b | 4172 | (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))] |
2bcb2ab3 GK |
4173 | "TARGET_64BIT" |
4174 | " | |
4175 | { | |
4176 | if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM) | |
4177 | { | |
4178 | rtx op = gen_lowpart (DImode, operands[1]); | |
4179 | rtx temp = force_reg (DImode, GEN_INT (0xffff)); | |
4180 | ||
4181 | emit_insn (gen_anddi3 (operands[0], op, temp)); | |
4182 | DONE; | |
4183 | } | |
4184 | }") | |
4185 | ||
4186 | (define_insn "" | |
cafe096b EC |
4187 | [(set (match_operand:DI 0 "register_operand" "=d,d") |
4188 | (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))] | |
2bcb2ab3 | 4189 | "TARGET_64BIT && !TARGET_MIPS16" |
cafe096b EC |
4190 | "@ |
4191 | andi\t%0,%1,0xffff | |
4192 | lhu\t%0,%1" | |
4193 | [(set_attr "type" "arith,load") | |
4194 | (set_attr "mode" "DI") | |
4195 | (set_attr "length" "4,*")]) | |
bb621ad7 | 4196 | |
2bcb2ab3 | 4197 | (define_insn "" |
cafe096b EC |
4198 | [(set (match_operand:DI 0 "register_operand" "=d") |
4199 | (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))] | |
2bcb2ab3 | 4200 | "TARGET_64BIT && TARGET_MIPS16" |
cafe096b EC |
4201 | "lhu\t%0,%1" |
4202 | [(set_attr "type" "load") | |
4203 | (set_attr "mode" "DI")]) | |
2bcb2ab3 GK |
4204 | |
4205 | (define_expand "zero_extendqihi2" | |
4206 | [(set (match_operand:HI 0 "register_operand" "") | |
4207 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] | |
4208 | "" | |
4209 | " | |
4210 | { | |
4211 | if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM) | |
4212 | { | |
4213 | rtx op0 = gen_lowpart (SImode, operands[0]); | |
4214 | rtx op1 = gen_lowpart (SImode, operands[1]); | |
4215 | rtx temp = force_reg (SImode, GEN_INT (0xff)); | |
4216 | ||
4217 | emit_insn (gen_andsi3 (op0, op1, temp)); | |
4218 | DONE; | |
4219 | } | |
4220 | }") | |
4221 | ||
2bcb2ab3 GK |
4222 | (define_insn "" |
4223 | [(set (match_operand:HI 0 "register_operand" "=d,d") | |
cafe096b EC |
4224 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] |
4225 | "!TARGET_MIPS16" | |
4226 | "@ | |
4227 | andi\t%0,%1,0x00ff | |
4228 | lbu\t%0,%1" | |
4229 | [(set_attr "type" "arith,load") | |
4230 | (set_attr "mode" "HI") | |
4231 | (set_attr "length" "4,*")]) | |
4232 | ||
4233 | (define_insn "" | |
4234 | [(set (match_operand:HI 0 "register_operand" "=d") | |
4235 | (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] | |
2bcb2ab3 | 4236 | "TARGET_MIPS16" |
cafe096b EC |
4237 | "lbu\t%0,%1" |
4238 | [(set_attr "type" "load") | |
4239 | (set_attr "mode" "HI")]) | |
2bcb2ab3 GK |
4240 | |
4241 | (define_expand "zero_extendqisi2" | |
4242 | [(set (match_operand:SI 0 "register_operand" "") | |
4243 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] | |
4244 | "" | |
4245 | " | |
4246 | { | |
4247 | if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM) | |
4248 | { | |
4249 | rtx op = gen_lowpart (SImode, operands[1]); | |
4250 | rtx temp = force_reg (SImode, GEN_INT (0xff)); | |
4251 | ||
4252 | emit_insn (gen_andsi3 (operands[0], op, temp)); | |
4253 | DONE; | |
4254 | } | |
4255 | }") | |
4256 | ||
4257 | (define_insn "" | |
cafe096b EC |
4258 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
4259 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] | |
2bcb2ab3 | 4260 | "!TARGET_MIPS16" |
cafe096b EC |
4261 | "@ |
4262 | andi\t%0,%1,0x00ff | |
4263 | lbu\t%0,%1" | |
4264 | [(set_attr "type" "arith,load") | |
4265 | (set_attr "mode" "SI") | |
4266 | (set_attr "length" "4,*")]) | |
8ef30996 | 4267 | |
2bcb2ab3 | 4268 | (define_insn "" |
cafe096b EC |
4269 | [(set (match_operand:SI 0 "register_operand" "=d") |
4270 | (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))] | |
2bcb2ab3 | 4271 | "TARGET_MIPS16" |
cafe096b EC |
4272 | "lbu\t%0,%1" |
4273 | [(set_attr "type" "load") | |
4274 | (set_attr "mode" "SI")]) | |
2bcb2ab3 GK |
4275 | |
4276 | (define_expand "zero_extendqidi2" | |
4277 | [(set (match_operand:DI 0 "register_operand" "") | |
4278 | (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))] | |
4279 | "TARGET_64BIT" | |
4280 | " | |
4281 | { | |
4282 | if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM) | |
4283 | { | |
4284 | rtx op = gen_lowpart (DImode, operands[1]); | |
4285 | rtx temp = force_reg (DImode, GEN_INT (0xff)); | |
4286 | ||
4287 | emit_insn (gen_anddi3 (operands[0], op, temp)); | |
4288 | DONE; | |
4289 | } | |
4290 | }") | |
4291 | ||
4292 | (define_insn "" | |
cafe096b EC |
4293 | [(set (match_operand:DI 0 "register_operand" "=d,d") |
4294 | (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] | |
2bcb2ab3 | 4295 | "TARGET_64BIT && !TARGET_MIPS16" |
cafe096b EC |
4296 | "@ |
4297 | andi\t%0,%1,0x00ff | |
4298 | lbu\t%0,%1" | |
4299 | [(set_attr "type" "arith,load") | |
4300 | (set_attr "mode" "DI") | |
4301 | (set_attr "length" "4,*")]) | |
bb621ad7 | 4302 | |
3cce8bc6 JW |
4303 | ;; These can be created when a paradoxical subreg operand with an implicit |
4304 | ;; sign_extend operator is reloaded. Because of the subreg, this is really | |
4305 | ;; a zero extend. | |
4306 | ;; ??? It might be possible to eliminate the need for these patterns by adding | |
4307 | ;; more support to reload for implicit sign_extend operators. | |
4308 | (define_insn "*paradoxical_extendhidi2" | |
cafe096b | 4309 | [(set (match_operand:DI 0 "register_operand" "=d") |
3cce8bc6 | 4310 | (sign_extend:DI |
cafe096b | 4311 | (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)))] |
3cce8bc6 JW |
4312 | "TARGET_64BIT" |
4313 | "* | |
4314 | { | |
4315 | return mips_move_1word (operands, insn, TRUE); | |
4316 | }" | |
cafe096b EC |
4317 | [(set_attr "type" "load") |
4318 | (set_attr "mode" "DI")]) | |
3cce8bc6 | 4319 | |
2bcb2ab3 | 4320 | (define_insn "" |
cafe096b EC |
4321 | [(set (match_operand:DI 0 "register_operand" "=d") |
4322 | (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))] | |
2bcb2ab3 | 4323 | "TARGET_64BIT && TARGET_MIPS16" |
cafe096b EC |
4324 | "lbu\t%0,%1" |
4325 | [(set_attr "type" "load") | |
4326 | (set_attr "mode" "DI")]) | |
8ef30996 MM |
4327 | \f |
4328 | ;; | |
4329 | ;; .................... | |
4330 | ;; | |
4331 | ;; SIGN EXTENSION | |
4332 | ;; | |
4333 | ;; .................... | |
4334 | ||
4335 | ;; Extension insns. | |
abdf3eea | 4336 | ;; Those for integer source operand are ordered widest source type first. |
8ef30996 | 4337 | |
8214bf98 RS |
4338 | (define_expand "extendsidi2" |
4339 | [(set (match_operand:DI 0 "register_operand" "") | |
cafe096b | 4340 | (sign_extend:DI (match_operand:SI 1 "move_operand" "")))] |
abdf3eea | 4341 | "TARGET_64BIT" |
cafe096b EC |
4342 | " |
4343 | { | |
4344 | if (symbolic_operand (operands[1], SImode)) | |
4345 | { | |
4346 | emit_move_insn (operands[0], convert_memory_address (DImode, operands[1])); | |
4347 | DONE; | |
4348 | } | |
4349 | ||
4350 | }") | |
4351 | ||
4352 | (define_insn "*extendsidi2" | |
4353 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
4354 | (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))] | |
4355 | "TARGET_64BIT" | |
4356 | "@ | |
4357 | sll\t%0,%1,0 | |
4358 | lw\t%0,%1" | |
4359 | [(set_attr "type" "arith,load") | |
4360 | (set_attr "mode" "DI") | |
4361 | (set_attr "extended_mips16" "yes,*")]) | |
bb621ad7 | 4362 | |
8ef30996 MM |
4363 | ;; These patterns originally accepted general_operands, however, slightly |
4364 | ;; better code is generated by only accepting register_operands, and then | |
4365 | ;; letting combine generate the lh and lb insns. | |
4366 | ||
cafe096b EC |
4367 | ;; These expanders originally put values in registers first. We split |
4368 | ;; all non-mem patterns after reload. | |
4369 | ||
bb621ad7 JW |
4370 | (define_expand "extendhidi2" |
4371 | [(set (match_operand:DI 0 "register_operand" "") | |
cafe096b | 4372 | (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))] |
bb621ad7 | 4373 | "TARGET_64BIT" |
cafe096b | 4374 | "") |
bb621ad7 | 4375 | |
cafe096b EC |
4376 | (define_insn "*extendhidi2" |
4377 | [(set (match_operand:DI 0 "register_operand" "=d") | |
4378 | (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))] | |
4379 | "TARGET_64BIT" | |
4380 | "#") | |
bb621ad7 | 4381 | |
cafe096b EC |
4382 | (define_split |
4383 | [(set (match_operand:DI 0 "register_operand" "") | |
4384 | (sign_extend:DI (match_operand:HI 1 "register_operand" "")))] | |
4385 | "TARGET_64BIT && reload_completed" | |
4386 | [(set (match_dup 0) | |
4387 | (ashift:DI (match_dup 1) (const_int 48))) | |
4388 | (set (match_dup 0) | |
4389 | (ashiftrt:DI (match_dup 0) (const_int 48)))] | |
4390 | "operands[1] = gen_lowpart (DImode, operands[1]);") | |
bb621ad7 | 4391 | |
cafe096b EC |
4392 | (define_insn "*extendhidi2_mem" |
4393 | [(set (match_operand:DI 0 "register_operand" "=d") | |
4394 | (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))] | |
bb621ad7 | 4395 | "TARGET_64BIT" |
cafe096b EC |
4396 | "lh\t%0,%1" |
4397 | [(set_attr "type" "load") | |
4398 | (set_attr "mode" "DI")]) | |
bb621ad7 | 4399 | |
8ef30996 MM |
4400 | (define_expand "extendhisi2" |
4401 | [(set (match_operand:SI 0 "register_operand" "") | |
cafe096b | 4402 | (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] |
8ef30996 MM |
4403 | "" |
4404 | " | |
cafe096b EC |
4405 | if (ISA_HAS_SEB_SEH) |
4406 | { | |
4407 | emit_insn (gen_extendhisi2_hw (operands[0], | |
4408 | force_reg (HImode, operands[1]))); | |
4409 | DONE; | |
4410 | } | |
4411 | ") | |
2d2a50c3 | 4412 | |
cafe096b EC |
4413 | (define_insn "*extendhisi2" |
4414 | [(set (match_operand:SI 0 "register_operand" "=d") | |
4415 | (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))] | |
4416 | "" | |
4417 | "#") | |
8ef30996 | 4418 | |
cafe096b EC |
4419 | (define_split |
4420 | [(set (match_operand:SI 0 "register_operand" "") | |
4421 | (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] | |
4422 | "reload_completed" | |
4423 | [(set (match_dup 0) | |
4424 | (ashift:SI (match_dup 1) (const_int 16))) | |
4425 | (set (match_dup 0) | |
4426 | (ashiftrt:SI (match_dup 0) (const_int 16)))] | |
4427 | "operands[1] = gen_lowpart (SImode, operands[1]);") | |
8ef30996 | 4428 | |
cafe096b EC |
4429 | (define_insn "extendhisi2_mem" |
4430 | [(set (match_operand:SI 0 "register_operand" "=d") | |
4431 | (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] | |
4432 | "" | |
4433 | "lh\t%0,%1" | |
4434 | [(set_attr "type" "load") | |
4435 | (set_attr "mode" "SI")]) | |
8ef30996 | 4436 | |
cafe096b | 4437 | (define_insn "extendhisi2_hw" |
2d2a50c3 | 4438 | [(set (match_operand:SI 0 "register_operand" "=r") |
cafe096b EC |
4439 | (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))] |
4440 | "ISA_HAS_SEB_SEH" | |
2d2a50c3 CD |
4441 | "seh\\t%0,%1" |
4442 | [(set_attr "type" "arith") | |
4443 | (set_attr "mode" "SI")]) | |
4444 | ||
8ef30996 MM |
4445 | (define_expand "extendqihi2" |
4446 | [(set (match_operand:HI 0 "register_operand" "") | |
cafe096b | 4447 | (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] |
8ef30996 | 4448 | "" |
cafe096b | 4449 | "") |
8ef30996 | 4450 | |
cafe096b EC |
4451 | (define_insn "*extendqihi2" |
4452 | [(set (match_operand:HI 0 "register_operand" "=d") | |
4453 | (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))] | |
4454 | "" | |
4455 | "#") | |
8ef30996 | 4456 | |
cafe096b EC |
4457 | (define_split |
4458 | [(set (match_operand:HI 0 "register_operand" "") | |
4459 | (sign_extend:HI (match_operand:QI 1 "register_operand" "")))] | |
4460 | "reload_completed" | |
4461 | [(set (match_dup 0) | |
4462 | (ashift:SI (match_dup 1) (const_int 24))) | |
4463 | (set (match_dup 0) | |
4464 | (ashiftrt:SI (match_dup 0) (const_int 24)))] | |
4465 | "operands[0] = gen_lowpart (SImode, operands[0]); | |
4466 | operands[1] = gen_lowpart (SImode, operands[1]);") | |
8ef30996 | 4467 | |
cafe096b EC |
4468 | (define_insn "*extendqihi2_internal_mem" |
4469 | [(set (match_operand:HI 0 "register_operand" "=d") | |
4470 | (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] | |
8ef30996 | 4471 | "" |
cafe096b EC |
4472 | "lb\t%0,%1" |
4473 | [(set_attr "type" "load") | |
4474 | (set_attr "mode" "SI")]) | |
8ef30996 MM |
4475 | |
4476 | ||
4477 | (define_expand "extendqisi2" | |
4478 | [(set (match_operand:SI 0 "register_operand" "") | |
cafe096b | 4479 | (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] |
8ef30996 MM |
4480 | "" |
4481 | " | |
cafe096b EC |
4482 | if (ISA_HAS_SEB_SEH) |
4483 | { | |
4484 | emit_insn (gen_extendqisi2_hw (operands[0], | |
4485 | force_reg (QImode, operands[1]))); | |
4486 | DONE; | |
4487 | } | |
4488 | ") | |
8ef30996 | 4489 | |
cafe096b EC |
4490 | (define_insn "*extendqisi2" |
4491 | [(set (match_operand:SI 0 "register_operand" "=d") | |
4492 | (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))] | |
4493 | "" | |
4494 | "#") | |
8ef30996 | 4495 | |
cafe096b EC |
4496 | (define_split |
4497 | [(set (match_operand:SI 0 "register_operand" "") | |
4498 | (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] | |
4499 | "reload_completed" | |
4500 | [(set (match_dup 0) | |
4501 | (ashift:SI (match_dup 1) (const_int 24))) | |
4502 | (set (match_dup 0) | |
4503 | (ashiftrt:SI (match_dup 0) (const_int 24)))] | |
4504 | "operands[1] = gen_lowpart (SImode, operands[1]);") | |
4505 | ||
4506 | (define_insn "*extendqisi2_mem" | |
4507 | [(set (match_operand:SI 0 "register_operand" "=d") | |
4508 | (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] | |
4509 | "" | |
4510 | "lb\t%0,%1" | |
4511 | [(set_attr "type" "load") | |
4512 | (set_attr "mode" "SI")]) | |
8ef30996 | 4513 | |
cafe096b | 4514 | (define_insn "extendqisi2_hw" |
2d2a50c3 | 4515 | [(set (match_operand:SI 0 "register_operand" "=r") |
cafe096b EC |
4516 | (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))] |
4517 | "ISA_HAS_SEB_SEH" | |
2d2a50c3 CD |
4518 | "seb\\t%0,%1" |
4519 | [(set_attr "type" "arith") | |
4520 | (set_attr "mode" "SI")]) | |
4521 | ||
bb621ad7 JW |
4522 | (define_expand "extendqidi2" |
4523 | [(set (match_operand:DI 0 "register_operand" "") | |
cafe096b | 4524 | (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))] |
bb621ad7 | 4525 | "TARGET_64BIT" |
cafe096b | 4526 | "") |
bb621ad7 | 4527 | |
cafe096b EC |
4528 | (define_insn "*extendqidi2" |
4529 | [(set (match_operand:DI 0 "register_operand" "=d") | |
4530 | (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))] | |
4531 | "TARGET_64BIT" | |
4532 | "#") | |
bb621ad7 | 4533 | |
cafe096b EC |
4534 | (define_split |
4535 | [(set (match_operand:DI 0 "register_operand" "") | |
4536 | (sign_extend:DI (match_operand:QI 1 "register_operand" "")))] | |
4537 | "TARGET_64BIT && reload_completed" | |
4538 | [(set (match_dup 0) | |
4539 | (ashift:DI (match_dup 1) (const_int 56))) | |
4540 | (set (match_dup 0) | |
4541 | (ashiftrt:DI (match_dup 0) (const_int 56)))] | |
4542 | "operands[1] = gen_lowpart (DImode, operands[1]);") | |
bb621ad7 | 4543 | |
cafe096b EC |
4544 | (define_insn "*extendqidi2_mem" |
4545 | [(set (match_operand:DI 0 "register_operand" "=d") | |
4546 | (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))] | |
bb621ad7 | 4547 | "TARGET_64BIT" |
cafe096b EC |
4548 | "lb\t%0,%1" |
4549 | [(set_attr "type" "load") | |
4550 | (set_attr "mode" "DI")]) | |
8ef30996 MM |
4551 | |
4552 | (define_insn "extendsfdf2" | |
4553 | [(set (match_operand:DF 0 "register_operand" "=f") | |
4554 | (float_extend:DF (match_operand:SF 1 "register_operand" "f")))] | |
46299de9 | 4555 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
8ef30996 MM |
4556 | "cvt.d.s\\t%0,%1" |
4557 | [(set_attr "type" "fcvt") | |
0ff83799 | 4558 | (set_attr "mode" "DF")]) |
8ef30996 MM |
4559 | |
4560 | \f | |
4561 | ||
4562 | ;; | |
4563 | ;; .................... | |
4564 | ;; | |
4565 | ;; CONVERSIONS | |
4566 | ;; | |
4567 | ;; .................... | |
4568 | ||
8214bf98 RS |
4569 | (define_expand "fix_truncdfsi2" |
4570 | [(set (match_operand:SI 0 "register_operand" "=f") | |
4571 | (fix:SI (match_operand:DF 1 "register_operand" "f")))] | |
46299de9 | 4572 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
8ef30996 | 4573 | { |
8214bf98 RS |
4574 | if (!ISA_HAS_TRUNC_W) |
4575 | { | |
4576 | emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1])); | |
4577 | DONE; | |
4578 | } | |
4579 | }) | |
8ef30996 | 4580 | |
8214bf98 RS |
4581 | (define_insn "fix_truncdfsi2_insn" |
4582 | [(set (match_operand:SI 0 "register_operand" "=f") | |
4583 | (fix:SI (match_operand:DF 1 "register_operand" "f")))] | |
4584 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W" | |
4585 | "trunc.w.d %0,%1" | |
92b4cee1 MM |
4586 | [(set_attr "type" "fcvt") |
4587 | (set_attr "mode" "DF") | |
8214bf98 RS |
4588 | (set_attr "length" "4")]) |
4589 | ||
4590 | (define_insn "fix_truncdfsi2_macro" | |
4591 | [(set (match_operand:SI 0 "register_operand" "=f") | |
4592 | (fix:SI (match_operand:DF 1 "register_operand" "f"))) | |
4593 | (clobber (match_scratch:DF 2 "=d"))] | |
4594 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W" | |
4595 | "trunc.w.d %0,%1,%2" | |
4596 | [(set_attr "type" "fcvt") | |
4597 | (set_attr "mode" "DF") | |
4598 | (set_attr "length" "36")]) | |
8ef30996 | 4599 | |
8214bf98 RS |
4600 | (define_expand "fix_truncsfsi2" |
4601 | [(set (match_operand:SI 0 "register_operand" "=f") | |
4602 | (fix:SI (match_operand:SF 1 "register_operand" "f")))] | |
8ef30996 | 4603 | "TARGET_HARD_FLOAT" |
8ef30996 | 4604 | { |
8214bf98 RS |
4605 | if (!ISA_HAS_TRUNC_W) |
4606 | { | |
4607 | emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1])); | |
4608 | DONE; | |
4609 | } | |
4610 | }) | |
8ef30996 | 4611 | |
8214bf98 RS |
4612 | (define_insn "fix_truncsfsi2_insn" |
4613 | [(set (match_operand:SI 0 "register_operand" "=f") | |
4614 | (fix:SI (match_operand:SF 1 "register_operand" "f")))] | |
4615 | "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W" | |
4616 | "trunc.w.s %0,%1" | |
92b4cee1 | 4617 | [(set_attr "type" "fcvt") |
8214bf98 RS |
4618 | (set_attr "mode" "DF") |
4619 | (set_attr "length" "4")]) | |
4620 | ||
4621 | (define_insn "fix_truncsfsi2_macro" | |
4622 | [(set (match_operand:SI 0 "register_operand" "=f") | |
4623 | (fix:SI (match_operand:SF 1 "register_operand" "f"))) | |
4624 | (clobber (match_scratch:SF 2 "=d"))] | |
4625 | "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W" | |
4626 | "trunc.w.s %0,%1,%2" | |
4627 | [(set_attr "type" "fcvt") | |
4628 | (set_attr "mode" "DF") | |
4629 | (set_attr "length" "36")]) | |
8ef30996 | 4630 | |
bb621ad7 JW |
4631 | ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals |
4632 | ;;; but not in the chapter that describes the FPU. It is not mentioned at all | |
4633 | ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction. | |
4634 | ||
4635 | ;;; Deleting this means that we now need two libgcc2.a libraries. One for | |
4636 | ;;; the 32 bit calling convention and one for the 64 bit calling convention. | |
4637 | ||
4638 | ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also. | |
4639 | ||
4640 | (define_insn "fix_truncdfdi2" | |
8214bf98 RS |
4641 | [(set (match_operand:DI 0 "register_operand" "=f") |
4642 | (fix:DI (match_operand:DF 1 "register_operand" "f")))] | |
4643 | "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT" | |
4644 | "trunc.l.d %0,%1" | |
bb621ad7 JW |
4645 | [(set_attr "type" "fcvt") |
4646 | (set_attr "mode" "DF") | |
8214bf98 | 4647 | (set_attr "length" "4")]) |
bb621ad7 JW |
4648 | |
4649 | ||
4650 | ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals | |
4651 | ;;; but not in the chapter that describes the FPU. It is not mentioned at all | |
4652 | ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction. | |
4653 | (define_insn "fix_truncsfdi2" | |
8214bf98 RS |
4654 | [(set (match_operand:DI 0 "register_operand" "=f") |
4655 | (fix:DI (match_operand:SF 1 "register_operand" "f")))] | |
4656 | "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT" | |
4657 | "trunc.l.s %0,%1" | |
bb621ad7 JW |
4658 | [(set_attr "type" "fcvt") |
4659 | (set_attr "mode" "SF") | |
8214bf98 | 4660 | (set_attr "length" "4")]) |
bb621ad7 JW |
4661 | |
4662 | ||
8ef30996 | 4663 | (define_insn "floatsidf2" |
8214bf98 RS |
4664 | [(set (match_operand:DF 0 "register_operand" "=f") |
4665 | (float:DF (match_operand:SI 1 "register_operand" "f")))] | |
46299de9 | 4666 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
8214bf98 | 4667 | "cvt.d.w\\t%0,%1" |
92b4cee1 MM |
4668 | [(set_attr "type" "fcvt") |
4669 | (set_attr "mode" "DF") | |
8214bf98 | 4670 | (set_attr "length" "4")]) |
8ef30996 | 4671 | |
c7343333 | 4672 | |
bb621ad7 | 4673 | (define_insn "floatdidf2" |
8214bf98 RS |
4674 | [(set (match_operand:DF 0 "register_operand" "=f") |
4675 | (float:DF (match_operand:DI 1 "register_operand" "f")))] | |
4676 | "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT" | |
4677 | "cvt.d.l\\t%0,%1" | |
bb621ad7 JW |
4678 | [(set_attr "type" "fcvt") |
4679 | (set_attr "mode" "DF") | |
8214bf98 | 4680 | (set_attr "length" "4")]) |
bb621ad7 JW |
4681 | |
4682 | ||
8ef30996 | 4683 | (define_insn "floatsisf2" |
8214bf98 RS |
4684 | [(set (match_operand:SF 0 "register_operand" "=f") |
4685 | (float:SF (match_operand:SI 1 "register_operand" "f")))] | |
8ef30996 | 4686 | "TARGET_HARD_FLOAT" |
8214bf98 | 4687 | "cvt.s.w\\t%0,%1" |
92b4cee1 MM |
4688 | [(set_attr "type" "fcvt") |
4689 | (set_attr "mode" "SF") | |
8214bf98 | 4690 | (set_attr "length" "4")]) |
bbdb5552 | 4691 | |
8ef30996 | 4692 | |
bb621ad7 | 4693 | (define_insn "floatdisf2" |
8214bf98 RS |
4694 | [(set (match_operand:SF 0 "register_operand" "=f") |
4695 | (float:SF (match_operand:DI 1 "register_operand" "f")))] | |
4696 | "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT" | |
4697 | "cvt.s.l\\t%0,%1" | |
bb621ad7 JW |
4698 | [(set_attr "type" "fcvt") |
4699 | (set_attr "mode" "SF") | |
8214bf98 | 4700 | (set_attr "length" "4")]) |
bb621ad7 JW |
4701 | |
4702 | ||
8ef30996 MM |
4703 | (define_expand "fixuns_truncdfsi2" |
4704 | [(set (match_operand:SI 0 "register_operand" "") | |
4705 | (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))] | |
46299de9 | 4706 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
8ef30996 MM |
4707 | " |
4708 | { | |
4709 | rtx reg1 = gen_reg_rtx (DFmode); | |
4710 | rtx reg2 = gen_reg_rtx (DFmode); | |
4711 | rtx reg3 = gen_reg_rtx (SImode); | |
4712 | rtx label1 = gen_label_rtx (); | |
4713 | rtx label2 = gen_label_rtx (); | |
eef709c7 KG |
4714 | REAL_VALUE_TYPE offset; |
4715 | ||
eaff3bf8 | 4716 | real_2expN (&offset, 31); |
8ef30996 MM |
4717 | |
4718 | if (reg1) /* turn off complaints about unreached code */ | |
4719 | { | |
5692c7bc | 4720 | emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode)); |
8ef30996 MM |
4721 | do_pending_stack_adjust (); |
4722 | ||
4723 | emit_insn (gen_cmpdf (operands[1], reg1)); | |
4724 | emit_jump_insn (gen_bge (label1)); | |
4725 | ||
4726 | emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1])); | |
c5c76735 JL |
4727 | emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, |
4728 | gen_rtx_LABEL_REF (VOIDmode, label2))); | |
8ef30996 MM |
4729 | emit_barrier (); |
4730 | ||
4731 | emit_label (label1); | |
c5c76735 | 4732 | emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1)); |
024c02b1 AO |
4733 | emit_move_insn (reg3, GEN_INT (trunc_int_for_mode |
4734 | (BITMASK_HIGH, SImode))); | |
8ef30996 MM |
4735 | |
4736 | emit_insn (gen_fix_truncdfsi2 (operands[0], reg2)); | |
4737 | emit_insn (gen_iorsi3 (operands[0], operands[0], reg3)); | |
4738 | ||
4739 | emit_label (label2); | |
4740 | ||
4741 | /* allow REG_NOTES to be set on last insn (labels don't have enough | |
4742 | fields, and can't be used for REG_NOTES anyway). */ | |
c5c76735 | 4743 | emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); |
8ef30996 MM |
4744 | DONE; |
4745 | } | |
4746 | }") | |
4747 | ||
c7343333 | 4748 | |
bb621ad7 JW |
4749 | (define_expand "fixuns_truncdfdi2" |
4750 | [(set (match_operand:DI 0 "register_operand" "") | |
4751 | (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))] | |
46299de9 | 4752 | "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT" |
bb621ad7 JW |
4753 | " |
4754 | { | |
4755 | rtx reg1 = gen_reg_rtx (DFmode); | |
4756 | rtx reg2 = gen_reg_rtx (DFmode); | |
4757 | rtx reg3 = gen_reg_rtx (DImode); | |
4758 | rtx label1 = gen_label_rtx (); | |
4759 | rtx label2 = gen_label_rtx (); | |
eef709c7 KG |
4760 | REAL_VALUE_TYPE offset; |
4761 | ||
eaff3bf8 | 4762 | real_2expN (&offset, 63); |
bb621ad7 JW |
4763 | |
4764 | if (reg1) /* turn off complaints about unreached code */ | |
4765 | { | |
5692c7bc | 4766 | emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode)); |
bb621ad7 JW |
4767 | do_pending_stack_adjust (); |
4768 | ||
4769 | emit_insn (gen_cmpdf (operands[1], reg1)); | |
4770 | emit_jump_insn (gen_bge (label1)); | |
4771 | ||
4772 | emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1])); | |
c5c76735 JL |
4773 | emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, |
4774 | gen_rtx_LABEL_REF (VOIDmode, label2))); | |
bb621ad7 JW |
4775 | emit_barrier (); |
4776 | ||
4777 | emit_label (label1); | |
c5c76735 | 4778 | emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1)); |
3a6ee9f4 | 4779 | emit_move_insn (reg3, GEN_INT (BITMASK_HIGH)); |
bb621ad7 JW |
4780 | emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32))); |
4781 | ||
4782 | emit_insn (gen_fix_truncdfdi2 (operands[0], reg2)); | |
4783 | emit_insn (gen_iordi3 (operands[0], operands[0], reg3)); | |
4784 | ||
4785 | emit_label (label2); | |
4786 | ||
4787 | /* allow REG_NOTES to be set on last insn (labels don't have enough | |
4788 | fields, and can't be used for REG_NOTES anyway). */ | |
c5c76735 | 4789 | emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); |
bb621ad7 JW |
4790 | DONE; |
4791 | } | |
4792 | }") | |
4793 | ||
4794 | ||
8ef30996 MM |
4795 | (define_expand "fixuns_truncsfsi2" |
4796 | [(set (match_operand:SI 0 "register_operand" "") | |
4797 | (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))] | |
4798 | "TARGET_HARD_FLOAT" | |
4799 | " | |
4800 | { | |
4801 | rtx reg1 = gen_reg_rtx (SFmode); | |
4802 | rtx reg2 = gen_reg_rtx (SFmode); | |
4803 | rtx reg3 = gen_reg_rtx (SImode); | |
4804 | rtx label1 = gen_label_rtx (); | |
4805 | rtx label2 = gen_label_rtx (); | |
eef709c7 KG |
4806 | REAL_VALUE_TYPE offset; |
4807 | ||
eaff3bf8 | 4808 | real_2expN (&offset, 31); |
8ef30996 MM |
4809 | |
4810 | if (reg1) /* turn off complaints about unreached code */ | |
4811 | { | |
5692c7bc | 4812 | emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode)); |
8ef30996 MM |
4813 | do_pending_stack_adjust (); |
4814 | ||
4815 | emit_insn (gen_cmpsf (operands[1], reg1)); | |
4816 | emit_jump_insn (gen_bge (label1)); | |
4817 | ||
4818 | emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1])); | |
c5c76735 JL |
4819 | emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, |
4820 | gen_rtx_LABEL_REF (VOIDmode, label2))); | |
8ef30996 MM |
4821 | emit_barrier (); |
4822 | ||
4823 | emit_label (label1); | |
c5c76735 | 4824 | emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1)); |
7cbdf575 AO |
4825 | emit_move_insn (reg3, GEN_INT (trunc_int_for_mode |
4826 | (BITMASK_HIGH, SImode))); | |
8ef30996 MM |
4827 | |
4828 | emit_insn (gen_fix_truncsfsi2 (operands[0], reg2)); | |
4829 | emit_insn (gen_iorsi3 (operands[0], operands[0], reg3)); | |
4830 | ||
4831 | emit_label (label2); | |
4832 | ||
4833 | /* allow REG_NOTES to be set on last insn (labels don't have enough | |
4834 | fields, and can't be used for REG_NOTES anyway). */ | |
c5c76735 | 4835 | emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); |
8ef30996 MM |
4836 | DONE; |
4837 | } | |
4838 | }") | |
4839 | ||
8ef30996 | 4840 | |
bb621ad7 JW |
4841 | (define_expand "fixuns_truncsfdi2" |
4842 | [(set (match_operand:DI 0 "register_operand" "") | |
4843 | (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))] | |
46299de9 | 4844 | "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT" |
8ef30996 MM |
4845 | " |
4846 | { | |
bb621ad7 JW |
4847 | rtx reg1 = gen_reg_rtx (SFmode); |
4848 | rtx reg2 = gen_reg_rtx (SFmode); | |
4849 | rtx reg3 = gen_reg_rtx (DImode); | |
4850 | rtx label1 = gen_label_rtx (); | |
4851 | rtx label2 = gen_label_rtx (); | |
eef709c7 KG |
4852 | REAL_VALUE_TYPE offset; |
4853 | ||
eaff3bf8 | 4854 | real_2expN (&offset, 63); |
8ef30996 | 4855 | |
bb621ad7 | 4856 | if (reg1) /* turn off complaints about unreached code */ |
8ef30996 | 4857 | { |
5692c7bc | 4858 | emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode)); |
bb621ad7 | 4859 | do_pending_stack_adjust (); |
8ef30996 | 4860 | |
bb621ad7 JW |
4861 | emit_insn (gen_cmpsf (operands[1], reg1)); |
4862 | emit_jump_insn (gen_bge (label1)); | |
8ef30996 | 4863 | |
bb621ad7 | 4864 | emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1])); |
c5c76735 JL |
4865 | emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, |
4866 | gen_rtx_LABEL_REF (VOIDmode, label2))); | |
bb621ad7 | 4867 | emit_barrier (); |
8ef30996 | 4868 | |
bb621ad7 | 4869 | emit_label (label1); |
c5c76735 | 4870 | emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1)); |
3a6ee9f4 | 4871 | emit_move_insn (reg3, GEN_INT (BITMASK_HIGH)); |
bb621ad7 | 4872 | emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32))); |
8ef30996 | 4873 | |
bb621ad7 JW |
4874 | emit_insn (gen_fix_truncsfdi2 (operands[0], reg2)); |
4875 | emit_insn (gen_iordi3 (operands[0], operands[0], reg3)); | |
8ef30996 | 4876 | |
bb621ad7 | 4877 | emit_label (label2); |
8ef30996 | 4878 | |
bb621ad7 JW |
4879 | /* allow REG_NOTES to be set on last insn (labels don't have enough |
4880 | fields, and can't be used for REG_NOTES anyway). */ | |
c5c76735 | 4881 | emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); |
bb621ad7 | 4882 | DONE; |
8ef30996 | 4883 | } |
bb621ad7 | 4884 | }") |
8ef30996 | 4885 | |
bb621ad7 JW |
4886 | \f |
4887 | ;; | |
4888 | ;; .................... | |
4889 | ;; | |
4890 | ;; DATA MOVEMENT | |
4891 | ;; | |
4892 | ;; .................... | |
8ef30996 | 4893 | |
cafe096b | 4894 | ;; Bit field extract patterns which use lwl/lwr or ldl/ldr. |
c5563e11 | 4895 | |
cafe096b EC |
4896 | (define_expand "extv" |
4897 | [(set (match_operand 0 "register_operand" "") | |
4898 | (sign_extract (match_operand:QI 1 "memory_operand" "") | |
4899 | (match_operand 2 "immediate_operand" "") | |
4900 | (match_operand 3 "immediate_operand" "")))] | |
4901 | "!TARGET_MIPS16" | |
4902 | { | |
4903 | if (mips_expand_unaligned_load (operands[0], operands[1], | |
4904 | INTVAL (operands[2]), | |
4905 | INTVAL (operands[3]))) | |
4906 | DONE; | |
4907 | else | |
4908 | FAIL; | |
4909 | }) | |
c5563e11 | 4910 | |
cafe096b EC |
4911 | (define_expand "extzv" |
4912 | [(set (match_operand 0 "register_operand" "") | |
4913 | (zero_extract (match_operand:QI 1 "memory_operand" "") | |
4914 | (match_operand 2 "immediate_operand" "") | |
4915 | (match_operand 3 "immediate_operand" "")))] | |
2bcb2ab3 | 4916 | "!TARGET_MIPS16" |
cafe096b EC |
4917 | { |
4918 | if (mips_expand_unaligned_load (operands[0], operands[1], | |
4919 | INTVAL (operands[2]), | |
4920 | INTVAL (operands[3]))) | |
4921 | DONE; | |
4922 | else | |
4923 | FAIL; | |
4924 | }) | |
c5563e11 | 4925 | |
cafe096b EC |
4926 | (define_expand "insv" |
4927 | [(set (zero_extract (match_operand:QI 0 "memory_operand" "") | |
4928 | (match_operand 1 "immediate_operand" "") | |
4929 | (match_operand 2 "immediate_operand" "")) | |
4930 | (match_operand 3 "reg_or_0_operand" ""))] | |
4931 | "!TARGET_MIPS16" | |
4932 | { | |
4933 | if (mips_expand_unaligned_store (operands[0], operands[3], | |
4934 | INTVAL (operands[1]), | |
4935 | INTVAL (operands[2]))) | |
4936 | DONE; | |
4937 | else | |
4938 | FAIL; | |
4939 | }) | |
c5563e11 | 4940 | |
cafe096b EC |
4941 | ;; Unaligned word moves generated by the bit field patterns. |
4942 | ;; | |
4943 | ;; As far as the rtl is concerned, both the left-part and right-part | |
4944 | ;; instructions can access the whole field. However, the real operand | |
4945 | ;; refers to just the first or the last byte (depending onendianness). | |
4946 | ;; We therefore use two memory operands to each instruction, one to | |
4947 | ;; describe the rtl effect and one to use in the assembly output. | |
c5563e11 | 4948 | |
cafe096b EC |
4949 | (define_insn "mov_lwl" |
4950 | [(set (match_operand:SI 0 "register_operand" "=d") | |
4951 | (unspec:SI [(match_operand:BLK 1 "general_operand" "m") | |
4952 | (match_operand:QI 2 "general_operand" "m")] | |
4953 | UNSPEC_LWL))] | |
4954 | "!TARGET_MIPS16" | |
4955 | "lwl\t%0,%2" | |
4956 | [(set_attr "type" "load") | |
4957 | (set_attr "mode" "SI")]) | |
c5563e11 | 4958 | |
cafe096b EC |
4959 | (define_insn "mov_lwr" |
4960 | [(set (match_operand:SI 0 "register_operand" "=d") | |
4961 | (unspec:SI [(match_operand:BLK 1 "general_operand" "m") | |
4962 | (match_operand:QI 2 "general_operand" "m") | |
4963 | (match_operand:SI 3 "register_operand" "0")] | |
4964 | UNSPEC_LWR))] | |
4965 | "!TARGET_MIPS16" | |
4966 | "lwr\t%0,%2" | |
4967 | [(set_attr "type" "load") | |
4968 | (set_attr "mode" "SI")]) | |
ed50ab35 | 4969 | |
0d8e55d8 | 4970 | |
cafe096b EC |
4971 | (define_insn "mov_swl" |
4972 | [(set (match_operand:BLK 0 "memory_operand" "=m") | |
4973 | (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ") | |
4974 | (match_operand:QI 2 "general_operand" "m")] | |
4975 | UNSPEC_SWL))] | |
4976 | "!TARGET_MIPS16" | |
4977 | "swl\t%z1,%2" | |
4978 | [(set_attr "type" "store") | |
4979 | (set_attr "mode" "SI")]) | |
0d8e55d8 | 4980 | |
cafe096b EC |
4981 | (define_insn "mov_swr" |
4982 | [(set (match_operand:BLK 0 "memory_operand" "+m") | |
4983 | (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ") | |
4984 | (match_operand:QI 2 "general_operand" "m") | |
4985 | (match_dup 0)] | |
4986 | UNSPEC_SWR))] | |
4987 | "!TARGET_MIPS16" | |
4988 | "swr\t%z1,%2" | |
4989 | [(set_attr "type" "store") | |
4990 | (set_attr "mode" "SI")]) | |
0d8e55d8 | 4991 | |
0d8e55d8 | 4992 | |
cafe096b EC |
4993 | (define_insn "mov_ldl" |
4994 | [(set (match_operand:DI 0 "register_operand" "=d") | |
4995 | (unspec:DI [(match_operand:BLK 1 "general_operand" "m") | |
4996 | (match_operand:QI 2 "general_operand" "m")] | |
4997 | UNSPEC_LDL))] | |
4998 | "TARGET_64BIT && !TARGET_MIPS16" | |
4999 | "ldl\t%0,%2" | |
5000 | [(set_attr "type" "load") | |
5001 | (set_attr "mode" "DI")]) | |
0d8e55d8 | 5002 | |
cafe096b EC |
5003 | (define_insn "mov_ldr" |
5004 | [(set (match_operand:DI 0 "register_operand" "=d") | |
5005 | (unspec:DI [(match_operand:BLK 1 "general_operand" "m") | |
5006 | (match_operand:QI 2 "general_operand" "m") | |
5007 | (match_operand:DI 3 "register_operand" "0")] | |
5008 | UNSPEC_LDR))] | |
5009 | "TARGET_64BIT && !TARGET_MIPS16" | |
5010 | "ldr\t%0,%2" | |
5011 | [(set_attr "type" "load") | |
5012 | (set_attr "mode" "DI")]) | |
0d8e55d8 | 5013 | |
0d8e55d8 | 5014 | |
cafe096b EC |
5015 | (define_insn "mov_sdl" |
5016 | [(set (match_operand:BLK 0 "memory_operand" "=m") | |
5017 | (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ") | |
5018 | (match_operand:QI 2 "general_operand" "m")] | |
5019 | UNSPEC_SDL))] | |
5020 | "TARGET_64BIT && !TARGET_MIPS16" | |
5021 | "sdl\t%z1,%2" | |
5022 | [(set_attr "type" "store") | |
5023 | (set_attr "mode" "DI")]) | |
0d8e55d8 | 5024 | |
cafe096b EC |
5025 | (define_insn "mov_sdr" |
5026 | [(set (match_operand:BLK 0 "memory_operand" "+m") | |
5027 | (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ") | |
5028 | (match_operand:QI 2 "general_operand" "m") | |
5029 | (match_dup 0)] | |
5030 | UNSPEC_SDR))] | |
5031 | "TARGET_64BIT && !TARGET_MIPS16" | |
5032 | "sdr\t%z1,%2" | |
5033 | [(set_attr "type" "store") | |
5034 | (set_attr "mode" "DI")]) | |
0d8e55d8 | 5035 | |
0d8e55d8 | 5036 | |
cafe096b | 5037 | ;; Instructions for loading a relocation expression using "lui". |
0d8e55d8 | 5038 | |
cafe096b EC |
5039 | (define_insn "luisi" |
5040 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5041 | (unspec:SI [(match_operand 1 "const_arith_operand" "")] UNSPEC_HIGH))] | |
5042 | "" | |
5043 | "lui\t%0,%1" | |
5044 | [(set_attr "type" "arith")]) | |
0d8e55d8 | 5045 | |
cafe096b EC |
5046 | (define_insn "luidi" |
5047 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5048 | (unspec:DI [(match_operand 1 "const_arith_operand" "")] UNSPEC_HIGH))] | |
5049 | "TARGET_64BIT" | |
5050 | "lui\t%0,%1" | |
5051 | [(set_attr "type" "arith")]) | |
aa4e54c4 | 5052 | |
aa4e54c4 | 5053 | |
cafe096b EC |
5054 | ;; Instructions for adding the low 16 bits of an address to a register. |
5055 | ;; Operand 2 is the address: print_operand works out which relocation | |
5056 | ;; should be applied. | |
aa4e54c4 | 5057 | |
cafe096b | 5058 | (define_insn "lowsi" |
aa4e54c4 JW |
5059 | [(set (match_operand:SI 0 "register_operand" "=r") |
5060 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
5061 | (match_operand:SI 2 "immediate_operand" "")))] | |
cafe096b EC |
5062 | "!TARGET_MIPS16" |
5063 | "addiu\\t%0,%1,%R2" | |
aa4e54c4 | 5064 | [(set_attr "type" "arith") |
0ff83799 | 5065 | (set_attr "mode" "SI")]) |
aa4e54c4 | 5066 | |
cafe096b EC |
5067 | (define_insn "lowdi" |
5068 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5069 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
5070 | (match_operand:DI 2 "immediate_operand" "")))] | |
5071 | "!TARGET_MIPS16 && TARGET_64BIT" | |
5072 | "daddiu\\t%0,%1,%R2" | |
5073 | [(set_attr "type" "arith") | |
5074 | (set_attr "mode" "DI")]) | |
5075 | ||
8ef30996 MM |
5076 | ;; 64-bit integer moves |
5077 | ||
5078 | ;; Unlike most other insns, the move insns can't be split with | |
5079 | ;; different predicates, because register spilling and other parts of | |
5080 | ;; the compiler, have memoized the insn number already. | |
5081 | ||
ed50ab35 MM |
5082 | (define_expand "movdi" |
5083 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
cafe096b | 5084 | (match_operand:DI 1 "" ""))] |
ed50ab35 MM |
5085 | "" |
5086 | " | |
5087 | { | |
cafe096b EC |
5088 | if (mips_legitimize_move (DImode, operands[0], operands[1])) |
5089 | DONE; | |
aa4e54c4 | 5090 | |
e19ff60f JW |
5091 | /* If we are generating embedded PIC code, and we are referring to a |
5092 | symbol in the .text section, we must use an offset from the start | |
5093 | of the function. */ | |
5094 | if (TARGET_EMBEDDED_PIC | |
5095 | && (GET_CODE (operands[1]) == LABEL_REF | |
5096 | || (GET_CODE (operands[1]) == SYMBOL_REF | |
5097 | && ! SYMBOL_REF_FLAG (operands[1])))) | |
5098 | { | |
5099 | rtx temp; | |
5100 | ||
5101 | temp = embedded_pic_offset (operands[1]); | |
c8d1b2b7 | 5102 | temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (), |
c5c76735 | 5103 | force_reg (DImode, temp)); |
e19ff60f JW |
5104 | emit_move_insn (operands[0], force_reg (DImode, temp)); |
5105 | DONE; | |
5106 | } | |
ed50ab35 MM |
5107 | }") |
5108 | ||
2bcb2ab3 GK |
5109 | ;; For mips16, we need a special case to handle storing $31 into |
5110 | ;; memory, since we don't have a constraint to match $31. This | |
5111 | ;; instruction can be generated by save_restore_insns. | |
5112 | ||
5113 | (define_insn "" | |
cafe096b | 5114 | [(set (match_operand:DI 0 "memory_operand" "=m") |
2bcb2ab3 GK |
5115 | (reg:DI 31))] |
5116 | "TARGET_MIPS16 && TARGET_64BIT" | |
5117 | "* | |
5118 | { | |
5119 | operands[1] = gen_rtx (REG, DImode, 31); | |
5120 | return mips_move_2words (operands, insn); | |
5121 | }" | |
5122 | [(set_attr "type" "store") | |
cafe096b | 5123 | (set_attr "mode" "DI")]) |
2bcb2ab3 | 5124 | |
ed50ab35 | 5125 | (define_insn "movdi_internal" |
cafe096b EC |
5126 | [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m") |
5127 | (match_operand:DI 1 "general_operand" "d,iF,m,d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))] | |
2bcb2ab3 | 5128 | "!TARGET_64BIT && !TARGET_MIPS16 |
bb621ad7 JW |
5129 | && (register_operand (operands[0], DImode) |
5130 | || register_operand (operands[1], DImode) | |
5131 | || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0) | |
5132 | || operands[1] == CONST0_RTX (DImode))" | |
8ef30996 | 5133 | "* return mips_move_2words (operands, insn); " |
cafe096b | 5134 | [(set_attr "type" "move,arith,load,store,hilo,hilo,hilo,xfer,load,xfer,store") |
92b4cee1 | 5135 | (set_attr "mode" "DI") |
cafe096b | 5136 | (set_attr "length" "8,16,*,*,8,8,8,8,*,8,*")]) |
8ef30996 | 5137 | |
2bcb2ab3 | 5138 | (define_insn "" |
cafe096b EC |
5139 | [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") |
5140 | (match_operand:DI 1 "general_operand" "d,d,y,K,N,m,d,*x"))] | |
2bcb2ab3 GK |
5141 | "!TARGET_64BIT && TARGET_MIPS16 |
5142 | && (register_operand (operands[0], DImode) | |
5143 | || register_operand (operands[1], DImode))" | |
5144 | "* return mips_move_2words (operands, insn);" | |
cafe096b | 5145 | [(set_attr "type" "move,move,move,arith,arith,load,store,hilo") |
2bcb2ab3 | 5146 | (set_attr "mode" "DI") |
cafe096b | 5147 | (set_attr "length" "8,8,8,8,12,*,*,8")]) |
2bcb2ab3 | 5148 | |
8ef30996 MM |
5149 | (define_split |
5150 | [(set (match_operand:DI 0 "register_operand" "") | |
5151 | (match_operand:DI 1 "register_operand" ""))] | |
2ca2d9ee EC |
5152 | "reload_completed && !TARGET_64BIT |
5153 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE | |
8ef30996 MM |
5154 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
5155 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))" | |
5156 | ||
5157 | [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0)) | |
ddef6bc7 | 5158 | (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))] |
8ef30996 MM |
5159 | "") |
5160 | ||
bb621ad7 | 5161 | (define_insn "movdi_internal2" |
cafe096b EC |
5162 | [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*d,*x,*a,*B*C*D,*B*C*D,*d,*m") |
5163 | (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J,*x,*d,*J,*d,*m,*B*C*D,*B*C*D"))] | |
2bcb2ab3 | 5164 | "TARGET_64BIT && !TARGET_MIPS16 |
bb621ad7 | 5165 | && (register_operand (operands[0], DImode) |
8214bf98 | 5166 | || register_operand (operands[1], DImode) |
bb621ad7 JW |
5167 | || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0) |
5168 | || operands[1] == CONST0_RTX (DImode))" | |
5169 | "* return mips_move_2words (operands, insn); " | |
cafe096b | 5170 | [(set_attr "type" "move,const,const,load,store,move,xfer,load,xfer,store,hilo,hilo,hilo,hilo,xfer,load,xfer,store") |
bb621ad7 | 5171 | (set_attr "mode" "DI") |
cafe096b | 5172 | (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,8,8,*,8,*")]) |
225b8835 | 5173 | |
8214bf98 RS |
5174 | ;; Sign-extended operands are reloaded using this instruction, so the |
5175 | ;; constraints must handle every SImode source operand X and destination | |
5176 | ;; register R for which: | |
5177 | ;; | |
5178 | ;; mips_secondary_reload_class (CLASS_OF (R), DImode, true, | |
5179 | ;; gen_rtx_SIGN_EXTEND (DImode, X)) | |
5180 | ;; | |
5181 | ;; returns NO_REGS. Also handle memory destinations, where allowed. | |
5182 | ;; | |
5183 | ;; This pattern is essentially a trimmed-down version of movdi_internal2. | |
5184 | ;; The main difference is that dJ -> f and f -> d are the only constraints | |
5185 | ;; involving float registers. See mips_secondary_reload_class for details. | |
8214bf98 RS |
5186 | |
5187 | (define_insn "*movdi_internal2_mips16" | |
cafe096b EC |
5188 | [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d") |
5189 | (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d,*x"))] | |
2bcb2ab3 GK |
5190 | "TARGET_64BIT && TARGET_MIPS16 |
5191 | && (register_operand (operands[0], DImode) | |
cafe096b | 5192 | || register_operand (operands[1], DImode))" |
2bcb2ab3 | 5193 | "* return mips_move_2words (operands, insn);" |
cafe096b | 5194 | [(set_attr "type" "move,move,move,arith,arith,const,load,store,hilo") |
2bcb2ab3 GK |
5195 | (set_attr "mode" "DI") |
5196 | (set_attr_alternative "length" | |
0ff83799 MM |
5197 | [(const_int 4) |
5198 | (const_int 4) | |
5199 | (const_int 4) | |
2bcb2ab3 | 5200 | (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "") |
0ff83799 MM |
5201 | (const_int 4) |
5202 | (const_int 8)) | |
2bcb2ab3 | 5203 | (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "") |
0ff83799 MM |
5204 | (const_int 8) |
5205 | (const_int 12)) | |
cafe096b EC |
5206 | (const_string "*") |
5207 | (const_string "*") | |
5208 | (const_string "*") | |
0ff83799 | 5209 | (const_int 4)])]) |
2bcb2ab3 | 5210 | |
cafe096b | 5211 | |
2bcb2ab3 GK |
5212 | ;; On the mips16, we can split ld $r,N($r) into an add and a load, |
5213 | ;; when the original load is a 4 byte instruction but the add and the | |
5214 | ;; load are 2 2 byte instructions. | |
5215 | ||
5216 | (define_split | |
5217 | [(set (match_operand:DI 0 "register_operand" "") | |
5218 | (mem:DI (plus:DI (match_dup 0) | |
5219 | (match_operand:DI 1 "const_int_operand" ""))))] | |
5220 | "TARGET_64BIT && TARGET_MIPS16 && reload_completed | |
2ca2d9ee | 5221 | && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
5222 | && GET_CODE (operands[0]) == REG |
5223 | && M16_REG_P (REGNO (operands[0])) | |
5224 | && GET_CODE (operands[1]) == CONST_INT | |
5225 | && ((INTVAL (operands[1]) < 0 | |
5226 | && INTVAL (operands[1]) >= -0x10) | |
5227 | || (INTVAL (operands[1]) >= 32 * 8 | |
5228 | && INTVAL (operands[1]) <= 31 * 8 + 0x8) | |
5229 | || (INTVAL (operands[1]) >= 0 | |
5230 | && INTVAL (operands[1]) < 32 * 8 | |
5231 | && (INTVAL (operands[1]) & 7) != 0))" | |
5232 | [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1))) | |
5233 | (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))] | |
5234 | " | |
5235 | { | |
5236 | HOST_WIDE_INT val = INTVAL (operands[1]); | |
5237 | ||
5238 | if (val < 0) | |
5239 | operands[2] = GEN_INT (0); | |
5240 | else if (val >= 32 * 8) | |
5241 | { | |
5242 | int off = val & 7; | |
5243 | ||
5244 | operands[1] = GEN_INT (0x8 + off); | |
5245 | operands[2] = GEN_INT (val - off - 0x8); | |
5246 | } | |
5247 | else | |
5248 | { | |
5249 | int off = val & 7; | |
5250 | ||
5251 | operands[1] = GEN_INT (off); | |
5252 | operands[2] = GEN_INT (val - off); | |
5253 | } | |
5254 | }") | |
5255 | ||
225b8835 ILT |
5256 | ;; Handle input reloads in DImode. |
5257 | ;; This is mainly to handle reloading HILO_REGNUM. Note that we may | |
5258 | ;; see it as the source or the destination, depending upon which way | |
5259 | ;; reload handles the instruction. | |
5260 | ;; Making the second operand TImode is a trick. The compiler may | |
5261 | ;; reuse the same register for operand 0 and operand 2. Using TImode | |
5262 | ;; gives us two registers, so we can always use the one which is not | |
5263 | ;; used. | |
5264 | ||
5265 | (define_expand "reload_indi" | |
5266 | [(set (match_operand:DI 0 "register_operand" "=b") | |
9ec36da5 | 5267 | (match_operand:DI 1 "" "b")) |
225b8835 ILT |
5268 | (clobber (match_operand:TI 2 "register_operand" "=&d"))] |
5269 | "TARGET_64BIT" | |
5270 | " | |
5271 | { | |
c5c76735 | 5272 | rtx scratch = gen_rtx_REG (DImode, |
7a38df19 | 5273 | (REGNO (operands[0]) == REGNO (operands[2]) |
c5c76735 JL |
5274 | ? REGNO (operands[2]) + 1 |
5275 | : REGNO (operands[2]))); | |
225b8835 ILT |
5276 | |
5277 | if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM) | |
5278 | { | |
5279 | if (GET_CODE (operands[1]) == MEM) | |
5280 | { | |
404e4854 | 5281 | rtx memword, offword, hi_word, lo_word; |
9ec36da5 | 5282 | rtx addr = find_replacement (&XEXP (operands[1], 0)); |
792760b9 | 5283 | rtx op1 = replace_equiv_address (operands[1], addr); |
225b8835 | 5284 | |
c5c76735 | 5285 | scratch = gen_rtx_REG (SImode, REGNO (scratch)); |
f4ef873c | 5286 | memword = adjust_address (op1, SImode, 0); |
b72f00af RK |
5287 | offword = adjust_address (op1, SImode, 4); |
5288 | ||
225b8835 ILT |
5289 | if (BYTES_BIG_ENDIAN) |
5290 | { | |
404e4854 KG |
5291 | hi_word = memword; |
5292 | lo_word = offword; | |
225b8835 ILT |
5293 | } |
5294 | else | |
5295 | { | |
404e4854 KG |
5296 | hi_word = offword; |
5297 | lo_word = memword; | |
225b8835 | 5298 | } |
404e4854 | 5299 | emit_move_insn (scratch, hi_word); |
c5c76735 | 5300 | emit_move_insn (gen_rtx_REG (SImode, 64), scratch); |
404e4854 | 5301 | emit_move_insn (scratch, lo_word); |
225b8835 | 5302 | emit_move_insn (gen_rtx (REG, SImode, 65), scratch); |
41f8d041 | 5303 | emit_insn (gen_hilo_delay (operands[0])); |
225b8835 ILT |
5304 | } |
5305 | else | |
5306 | { | |
5307 | emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32))); | |
c5c76735 | 5308 | emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch)); |
225b8835 ILT |
5309 | emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32))); |
5310 | emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32))); | |
5311 | emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch)); | |
41f8d041 | 5312 | emit_insn (gen_hilo_delay (operands[0])); |
225b8835 ILT |
5313 | } |
5314 | DONE; | |
5315 | } | |
5316 | if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM) | |
5317 | { | |
c5c76735 | 5318 | emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65))); |
225b8835 ILT |
5319 | emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32))); |
5320 | emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32))); | |
c5c76735 | 5321 | emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64))); |
225b8835 ILT |
5322 | emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32))); |
5323 | emit_insn (gen_iordi3 (operands[0], operands[0], scratch)); | |
41f8d041 | 5324 | emit_insn (gen_hilo_delay (operands[1])); |
225b8835 ILT |
5325 | DONE; |
5326 | } | |
5327 | /* This handles moves between a float register and HI/LO. */ | |
5328 | emit_move_insn (scratch, operands[1]); | |
5329 | emit_move_insn (operands[0], scratch); | |
5330 | DONE; | |
5331 | }") | |
bb621ad7 | 5332 | |
225b8835 ILT |
5333 | ;; Handle output reloads in DImode. |
5334 | ||
cf877a42 JW |
5335 | ;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we |
5336 | ;; use a TImode scratch reg. | |
5337 | ||
225b8835 | 5338 | (define_expand "reload_outdi" |
3dcaf6e0 | 5339 | [(set (match_operand:DI 0 "general_operand" "=b") |
cafe096b | 5340 | (match_operand:DI 1 "register_operand" "b")) |
cf877a42 | 5341 | (clobber (match_operand:TI 2 "register_operand" "=&d"))] |
225b8835 ILT |
5342 | "TARGET_64BIT" |
5343 | " | |
5344 | { | |
cf877a42 JW |
5345 | rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2])); |
5346 | ||
225b8835 ILT |
5347 | if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM) |
5348 | { | |
cf877a42 JW |
5349 | emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32))); |
5350 | emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch)); | |
5351 | emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32))); | |
5352 | emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32))); | |
5353 | emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch)); | |
41f8d041 | 5354 | emit_insn (gen_hilo_delay (operands[0])); |
225b8835 ILT |
5355 | DONE; |
5356 | } | |
5357 | if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM) | |
5358 | { | |
5359 | if (GET_CODE (operands[0]) == MEM) | |
5360 | { | |
404e4854 | 5361 | rtx scratch, memword, offword, hi_word, lo_word; |
9ec36da5 | 5362 | rtx addr = find_replacement (&XEXP (operands[0], 0)); |
792760b9 | 5363 | rtx op0 = replace_equiv_address (operands[0], addr); |
225b8835 | 5364 | |
c5c76735 | 5365 | scratch = gen_rtx_REG (SImode, REGNO (operands[2])); |
f4ef873c | 5366 | memword = adjust_address (op0, SImode, 0); |
b72f00af RK |
5367 | offword = adjust_address (op0, SImode, 4); |
5368 | ||
225b8835 ILT |
5369 | if (BYTES_BIG_ENDIAN) |
5370 | { | |
404e4854 KG |
5371 | hi_word = memword; |
5372 | lo_word = offword; | |
225b8835 ILT |
5373 | } |
5374 | else | |
5375 | { | |
404e4854 KG |
5376 | hi_word = offword; |
5377 | lo_word = memword; | |
225b8835 | 5378 | } |
c5c76735 | 5379 | emit_move_insn (scratch, gen_rtx_REG (SImode, 64)); |
404e4854 | 5380 | emit_move_insn (hi_word, scratch); |
c5c76735 | 5381 | emit_move_insn (scratch, gen_rtx_REG (SImode, 65)); |
404e4854 | 5382 | emit_move_insn (lo_word, scratch); |
41f8d041 | 5383 | emit_insn (gen_hilo_delay (operands[1])); |
225b8835 | 5384 | } |
cf877a42 JW |
5385 | else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0]))) |
5386 | { | |
5387 | /* Handle the case where operand[0] is not a 'd' register, | |
5388 | and hence we can not directly move from the HILO register | |
5389 | into it. */ | |
5390 | rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); | |
5391 | emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65))); | |
5392 | emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32))); | |
5393 | emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32))); | |
5394 | emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64))); | |
5395 | emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32))); | |
5396 | emit_insn (gen_iordi3 (scratch, scratch, scratch2)); | |
5397 | emit_insn (gen_movdi (operands[0], scratch)); | |
41f8d041 | 5398 | emit_insn (gen_hilo_delay (operands[1])); |
cf877a42 | 5399 | } |
225b8835 ILT |
5400 | else |
5401 | { | |
cf877a42 JW |
5402 | emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65))); |
5403 | emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32))); | |
5404 | emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32))); | |
225b8835 ILT |
5405 | emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64))); |
5406 | emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32))); | |
cf877a42 | 5407 | emit_insn (gen_iordi3 (operands[0], operands[0], scratch)); |
41f8d041 | 5408 | emit_insn (gen_hilo_delay (operands[1])); |
225b8835 ILT |
5409 | } |
5410 | DONE; | |
5411 | } | |
5412 | /* This handles moves between a float register and HI/LO. */ | |
cf877a42 JW |
5413 | emit_move_insn (scratch, operands[1]); |
5414 | emit_move_insn (operands[0], scratch); | |
225b8835 ILT |
5415 | DONE; |
5416 | }") | |
8ef30996 MM |
5417 | |
5418 | ;; 32-bit Integer moves | |
5419 | ||
8ef30996 MM |
5420 | ;; Unlike most other insns, the move insns can't be split with |
5421 | ;; different predicates, because register spilling and other parts of | |
5422 | ;; the compiler, have memoized the insn number already. | |
5423 | ||
f3b39eba MM |
5424 | (define_expand "movsi" |
5425 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
cafe096b | 5426 | (match_operand:SI 1 "" ""))] |
f3b39eba | 5427 | "" |
ed50ab35 MM |
5428 | " |
5429 | { | |
cafe096b EC |
5430 | if (mips_legitimize_move (SImode, operands[0], operands[1])) |
5431 | DONE; | |
aa4e54c4 | 5432 | |
92544bdf ILT |
5433 | /* If we are generating embedded PIC code, and we are referring to a |
5434 | symbol in the .text section, we must use an offset from the start | |
5435 | of the function. */ | |
5436 | if (TARGET_EMBEDDED_PIC | |
5437 | && (GET_CODE (operands[1]) == LABEL_REF | |
5438 | || (GET_CODE (operands[1]) == SYMBOL_REF | |
5439 | && ! SYMBOL_REF_FLAG (operands[1])))) | |
5440 | { | |
5441 | rtx temp; | |
5442 | ||
5443 | temp = embedded_pic_offset (operands[1]); | |
c8d1b2b7 | 5444 | temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (), |
c5c76735 | 5445 | force_reg (SImode, temp)); |
92544bdf ILT |
5446 | emit_move_insn (operands[0], force_reg (SImode, temp)); |
5447 | DONE; | |
5448 | } | |
ed50ab35 | 5449 | }") |
f3b39eba | 5450 | |
07e2e444 AO |
5451 | ;; We can only store $ra directly into a small sp offset. Should the |
5452 | ;; offset be too wide, non-constant or not sp-based, leave it up to | |
5453 | ;; reload to choose a scratch register. | |
2bcb2ab3 GK |
5454 | |
5455 | (define_insn "" | |
07e2e444 AO |
5456 | [(set (mem:SI (plus:SI (reg:SI 29) |
5457 | (match_operand:SI 0 "small_int" "n"))) | |
2bcb2ab3 GK |
5458 | (reg:SI 31))] |
5459 | "TARGET_MIPS16" | |
07e2e444 | 5460 | "sw\\t$31,%0($sp)" |
2bcb2ab3 GK |
5461 | [(set_attr "type" "store") |
5462 | (set_attr "mode" "SI") | |
07e2e444 AO |
5463 | (set_attr_alternative |
5464 | "length" | |
33005162 | 5465 | [(if_then_else |
07e2e444 AO |
5466 | (lt (symbol_ref "(unsigned HOST_WIDE_INT) INTVAL (operands[0])") |
5467 | (const_int 1024)) | |
5468 | (const_int 4) | |
5469 | (const_int 8))])]) | |
2bcb2ab3 | 5470 | |
0fb5ac6f MM |
5471 | ;; The difference between these two is whether or not ints are allowed |
5472 | ;; in FP registers (off by default, use -mdebugh to enable). | |
5473 | ||
8214bf98 | 5474 | (define_insn "movsi_internal" |
cafe096b EC |
5475 | [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*d,*m") |
5476 | (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,J,*x,*d,*a,*d,*m,*B*C*D,*B*C*D"))] | |
8214bf98 | 5477 | "!TARGET_MIPS16 |
ed50ab35 MM |
5478 | && (register_operand (operands[0], SImode) |
5479 | || register_operand (operands[1], SImode) | |
5480 | || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" | |
bb621ad7 | 5481 | "* return mips_move_1word (operands, insn, FALSE);" |
cafe096b | 5482 | [(set_attr "type" "move,const,const,load,store,move,xfer,load,xfer,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,xfer,store") |
0fb5ac6f | 5483 | (set_attr "mode" "SI") |
cafe096b | 5484 | (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,4,4,*,4,*")]) |
225b8835 | 5485 | |
2bcb2ab3 | 5486 | (define_insn "" |
cafe096b EC |
5487 | [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d,*d") |
5488 | (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d,*x,*a"))] | |
2bcb2ab3 GK |
5489 | "TARGET_MIPS16 |
5490 | && (register_operand (operands[0], SImode) | |
cafe096b | 5491 | || register_operand (operands[1], SImode))" |
2bcb2ab3 | 5492 | "* return mips_move_1word (operands, insn, FALSE);" |
cafe096b | 5493 | [(set_attr "type" "move,move,move,arith,arith,const,load,store,hilo,hilo") |
2bcb2ab3 GK |
5494 | (set_attr "mode" "SI") |
5495 | (set_attr_alternative "length" | |
0ff83799 MM |
5496 | [(const_int 4) |
5497 | (const_int 4) | |
5498 | (const_int 4) | |
2bcb2ab3 | 5499 | (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "") |
0ff83799 MM |
5500 | (const_int 4) |
5501 | (const_int 8)) | |
2bcb2ab3 | 5502 | (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "") |
0ff83799 MM |
5503 | (const_int 8) |
5504 | (const_int 12)) | |
cafe096b EC |
5505 | (const_string "*") |
5506 | (const_string "*") | |
5507 | (const_string "*") | |
0ff83799 MM |
5508 | (const_int 4) |
5509 | (const_int 4)])]) | |
2bcb2ab3 GK |
5510 | |
5511 | ;; On the mips16, we can split lw $r,N($r) into an add and a load, | |
5512 | ;; when the original load is a 4 byte instruction but the add and the | |
5513 | ;; load are 2 2 byte instructions. | |
5514 | ||
5515 | (define_split | |
5516 | [(set (match_operand:SI 0 "register_operand" "") | |
5517 | (mem:SI (plus:SI (match_dup 0) | |
5518 | (match_operand:SI 1 "const_int_operand" ""))))] | |
2ca2d9ee | 5519 | "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
5520 | && GET_CODE (operands[0]) == REG |
5521 | && M16_REG_P (REGNO (operands[0])) | |
5522 | && GET_CODE (operands[1]) == CONST_INT | |
5523 | && ((INTVAL (operands[1]) < 0 | |
5524 | && INTVAL (operands[1]) >= -0x80) | |
5525 | || (INTVAL (operands[1]) >= 32 * 4 | |
5526 | && INTVAL (operands[1]) <= 31 * 4 + 0x7c) | |
5527 | || (INTVAL (operands[1]) >= 0 | |
5528 | && INTVAL (operands[1]) < 32 * 4 | |
5529 | && (INTVAL (operands[1]) & 3) != 0))" | |
5530 | [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) | |
5531 | (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))] | |
225b8835 ILT |
5532 | " |
5533 | { | |
2bcb2ab3 GK |
5534 | HOST_WIDE_INT val = INTVAL (operands[1]); |
5535 | ||
5536 | if (val < 0) | |
5537 | operands[2] = GEN_INT (0); | |
5538 | else if (val >= 32 * 4) | |
5539 | { | |
5540 | int off = val & 3; | |
5541 | ||
5542 | operands[1] = GEN_INT (0x7c + off); | |
5543 | operands[2] = GEN_INT (val - off - 0x7c); | |
5544 | } | |
5545 | else | |
5546 | { | |
5547 | int off = val & 3; | |
5548 | ||
5549 | operands[1] = GEN_INT (off); | |
5550 | operands[2] = GEN_INT (val - off); | |
5551 | } | |
5552 | }") | |
5553 | ||
5554 | ;; On the mips16, we can split a load of certain constants into a load | |
5555 | ;; and an add. This turns a 4 byte instruction into 2 2 byte | |
5556 | ;; instructions. | |
5557 | ||
5558 | (define_split | |
5559 | [(set (match_operand:SI 0 "register_operand" "") | |
5560 | (match_operand:SI 1 "const_int_operand" ""))] | |
2ca2d9ee | 5561 | "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
5562 | && GET_CODE (operands[0]) == REG |
5563 | && M16_REG_P (REGNO (operands[0])) | |
5564 | && GET_CODE (operands[1]) == CONST_INT | |
5565 | && INTVAL (operands[1]) >= 0x100 | |
5566 | && INTVAL (operands[1]) <= 0xff + 0x7f" | |
5567 | [(set (match_dup 0) (match_dup 1)) | |
5568 | (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))] | |
5569 | " | |
5570 | { | |
5571 | int val = INTVAL (operands[1]); | |
5572 | ||
5573 | operands[1] = GEN_INT (0xff); | |
5574 | operands[2] = GEN_INT (val - 0xff); | |
5575 | }") | |
5576 | ||
5577 | ;; On the mips16, we can split a load of a negative constant into a | |
5578 | ;; load and a neg. That's what mips_move_1word will generate anyhow. | |
5579 | ||
5580 | (define_split | |
5581 | [(set (match_operand:SI 0 "register_operand" "") | |
5582 | (match_operand:SI 1 "const_int_operand" ""))] | |
2ca2d9ee | 5583 | "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
5584 | && GET_CODE (operands[0]) == REG |
5585 | && M16_REG_P (REGNO (operands[0])) | |
5586 | && GET_CODE (operands[1]) == CONST_INT | |
5587 | && INTVAL (operands[1]) < 0 | |
5588 | && INTVAL (operands[1]) > - 0x8000" | |
5589 | [(set (match_dup 0) (match_dup 1)) | |
5590 | (set (match_dup 0) (neg:SI (match_dup 0)))] | |
5591 | " | |
5592 | { | |
5593 | operands[1] = GEN_INT (- INTVAL (operands[1])); | |
5594 | }") | |
5595 | ||
5596 | ;; Reload HILO_REGNUM in SI mode. This needs a scratch register in | |
5597 | ;; order to set the sign bit correctly in the HI register. | |
5598 | ||
5599 | (define_expand "reload_outsi" | |
5600 | [(set (match_operand:SI 0 "general_operand" "=b") | |
5601 | (match_operand:SI 1 "register_operand" "b")) | |
5602 | (clobber (match_operand:SI 2 "register_operand" "=&d"))] | |
5603 | "TARGET_64BIT || TARGET_MIPS16" | |
5604 | " | |
5605 | { | |
5606 | if (TARGET_64BIT | |
5607 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM) | |
225b8835 | 5608 | { |
c5c76735 | 5609 | emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1])); |
225b8835 ILT |
5610 | emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31))); |
5611 | emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2])); | |
41f8d041 | 5612 | emit_insn (gen_hilo_delay (operands[0])); |
225b8835 ILT |
5613 | DONE; |
5614 | } | |
2bcb2ab3 GK |
5615 | /* Use a mult to reload LO on mips16. ??? This is hideous. */ |
5616 | if (TARGET_MIPS16 | |
5617 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM) | |
5618 | { | |
5619 | emit_insn (gen_movsi (operands[2], GEN_INT (1))); | |
5620 | /* This is gen_mulsi3_internal, but we need to fill in the | |
5621 | scratch registers. */ | |
5622 | emit_insn (gen_rtx (PARALLEL, VOIDmode, | |
5623 | gen_rtvec (3, | |
5624 | gen_rtx (SET, VOIDmode, | |
5625 | operands[0], | |
5626 | gen_rtx (MULT, SImode, | |
5627 | operands[1], | |
5628 | operands[2])), | |
5629 | gen_rtx (CLOBBER, VOIDmode, | |
5630 | gen_rtx (REG, SImode, 64)), | |
5631 | gen_rtx (CLOBBER, VOIDmode, | |
5632 | gen_rtx (REG, SImode, 66))))); | |
5633 | DONE; | |
5634 | } | |
5635 | /* FIXME: I don't know how to get a value into the HI register. */ | |
ca45b913 JW |
5636 | if (GET_CODE (operands[0]) == REG |
5637 | && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0])) | |
5638 | : GP_REG_P (REGNO (operands[0])))) | |
2bcb2ab3 GK |
5639 | { |
5640 | emit_move_insn (operands[0], operands[1]); | |
5641 | DONE; | |
5642 | } | |
225b8835 ILT |
5643 | /* This handles moves between a float register and HI/LO. */ |
5644 | emit_move_insn (operands[2], operands[1]); | |
5645 | emit_move_insn (operands[0], operands[2]); | |
5646 | DONE; | |
5647 | }") | |
0fb5ac6f | 5648 | |
2bcb2ab3 GK |
5649 | ;; Reload a value into HI or LO. There is no mthi or mtlo on mips16, |
5650 | ;; so we use a mult. ??? This is hideous, and we ought to figure out | |
5651 | ;; something better. | |
5652 | ||
bf4f78ee JW |
5653 | ;; We use no predicate for operand1, because it may be a PLUS, and there |
5654 | ;; is no convenient predicate for that. | |
5655 | ||
2bcb2ab3 GK |
5656 | (define_expand "reload_insi" |
5657 | [(set (match_operand:SI 0 "register_operand" "=b") | |
bf4f78ee | 5658 | (match_operand:SI 1 "" "b")) |
2bcb2ab3 GK |
5659 | (clobber (match_operand:SI 2 "register_operand" "=&d"))] |
5660 | "TARGET_MIPS16" | |
5661 | " | |
5662 | { | |
5663 | if (TARGET_MIPS16 | |
5664 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM) | |
5665 | { | |
5666 | emit_insn (gen_movsi (operands[2], GEN_INT (1))); | |
5667 | /* This is gen_mulsi3_internal, but we need to fill in the | |
5668 | scratch registers. */ | |
5669 | emit_insn (gen_rtx (PARALLEL, VOIDmode, | |
5670 | gen_rtvec (3, | |
5671 | gen_rtx (SET, VOIDmode, | |
5672 | operands[0], | |
5673 | gen_rtx (MULT, SImode, | |
5674 | operands[1], | |
5675 | operands[2])), | |
5676 | gen_rtx (CLOBBER, VOIDmode, | |
5677 | gen_rtx (REG, SImode, 64)), | |
5678 | gen_rtx (CLOBBER, VOIDmode, | |
5679 | gen_rtx (REG, SImode, 66))))); | |
5680 | DONE; | |
5681 | } | |
bf4f78ee JW |
5682 | |
5683 | /* If this is a plus, then this must be an add of the stack pointer against | |
5684 | either a hard register or a pseudo. */ | |
5685 | if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS) | |
5686 | { | |
5687 | rtx plus_op; | |
5688 | ||
5689 | if (XEXP (operands[1], 0) == stack_pointer_rtx) | |
5690 | plus_op = XEXP (operands[1], 1); | |
5691 | else if (XEXP (operands[1], 1) == stack_pointer_rtx) | |
5692 | plus_op = XEXP (operands[1], 0); | |
5693 | else | |
5694 | abort (); | |
5695 | ||
5696 | /* We should have a register now. */ | |
5697 | if (GET_CODE (plus_op) != REG) | |
5698 | abort (); | |
5699 | ||
5700 | if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER) | |
5701 | { | |
5702 | /* We have to have at least one temporary register which is not | |
5703 | overlapping plus_op. */ | |
5704 | if (! rtx_equal_p (plus_op, operands[0])) | |
5705 | { | |
5706 | emit_move_insn (operands[0], stack_pointer_rtx); | |
5707 | emit_insn (gen_addsi3 (operands[0], operands[0], plus_op)); | |
5708 | } | |
5709 | else if (! rtx_equal_p (plus_op, operands[2])) | |
5710 | { | |
5711 | emit_move_insn (operands[2], stack_pointer_rtx); | |
5712 | emit_insn (gen_addsi3 (operands[0], plus_op, operands[2])); | |
5713 | } | |
5714 | else | |
5715 | abort (); | |
5716 | } | |
5717 | else | |
5718 | { | |
5719 | /* We need two registers in this case. */ | |
5720 | if (! rtx_equal_p (operands[0], operands[2])) | |
5721 | { | |
5722 | emit_move_insn (operands[0], stack_pointer_rtx); | |
5723 | emit_move_insn (operands[2], plus_op); | |
5724 | emit_insn (gen_addsi3 (operands[0], operands[0], operands[2])); | |
5725 | } | |
5726 | else | |
5727 | abort (); | |
5728 | } | |
5729 | DONE; | |
5730 | } | |
5731 | ||
2bcb2ab3 GK |
5732 | /* FIXME: I don't know how to get a value into the HI register. */ |
5733 | emit_move_insn (operands[0], operands[1]); | |
5734 | DONE; | |
5735 | }") | |
5736 | ||
0e5a4ad8 EC |
5737 | ;; This insn is for the unspec delay for HILO. |
5738 | ||
41f8d041 RS |
5739 | (define_insn "hilo_delay" |
5740 | [(unspec [(match_operand 0 "register_operand" "=b")] UNSPEC_HILO_DELAY)] | |
0e5a4ad8 EC |
5741 | "" |
5742 | "" | |
5743 | [(set_attr "type" "nop") | |
f1ba94dd RH |
5744 | (set_attr "mode" "none") |
5745 | (set_attr "can_delay" "no")]) | |
0e5a4ad8 | 5746 | |
b8eb88d0 ILT |
5747 | ;; This insn handles moving CCmode values. It's really just a |
5748 | ;; slightly simplified copy of movsi_internal2, with additional cases | |
5749 | ;; to move a condition register to a general register and to move | |
5750 | ;; between the general registers and the floating point registers. | |
5751 | ||
5752 | (define_insn "movcc" | |
cafe096b EC |
5753 | [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m") |
5754 | (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))] | |
76ee8042 | 5755 | "ISA_HAS_8CC && TARGET_HARD_FLOAT" |
b8eb88d0 | 5756 | "* return mips_move_1word (operands, insn, FALSE);" |
cafe096b | 5757 | [(set_attr "type" "move,move,load,store,xfer,xfer,move,load,store") |
b8eb88d0 | 5758 | (set_attr "mode" "SI") |
cafe096b | 5759 | (set_attr "length" "8,4,*,*,4,4,4,*,*")]) |
b8eb88d0 | 5760 | |
d12b8c85 RS |
5761 | ;; Reload condition code registers. reload_incc and reload_outcc |
5762 | ;; both handle moves from arbitrary operands into condition code | |
5763 | ;; registers. reload_incc handles the more common case in which | |
5764 | ;; a source operand is constrained to be in a condition-code | |
5765 | ;; register, but has not been allocated to one. | |
5766 | ;; | |
5767 | ;; Sometimes, such as in movcc, we have a CCmode destination whose | |
5768 | ;; constraints do not include 'z'. reload_outcc handles the case | |
5769 | ;; when such an operand is allocated to a condition-code register. | |
5770 | ;; | |
5771 | ;; Note that reloads from a condition code register to some | |
5772 | ;; other location can be done using ordinary moves. Moving | |
5773 | ;; into a GPR takes a single movcc, moving elsewhere takes | |
5774 | ;; two. We can leave these cases to the generic reload code. | |
b8eb88d0 | 5775 | (define_expand "reload_incc" |
d12b8c85 RS |
5776 | [(set (match_operand:CC 0 "fcc_register_operand" "=z") |
5777 | (match_operand:CC 1 "general_operand" "")) | |
b8eb88d0 | 5778 | (clobber (match_operand:TF 2 "register_operand" "=&f"))] |
76ee8042 | 5779 | "ISA_HAS_8CC && TARGET_HARD_FLOAT" |
b8eb88d0 ILT |
5780 | " |
5781 | { | |
d12b8c85 | 5782 | mips_emit_fcc_reload (operands[0], operands[1], operands[2]); |
b8eb88d0 ILT |
5783 | DONE; |
5784 | }") | |
5785 | ||
5786 | (define_expand "reload_outcc" | |
d12b8c85 RS |
5787 | [(set (match_operand:CC 0 "fcc_register_operand" "=z") |
5788 | (match_operand:CC 1 "register_operand" "")) | |
5789 | (clobber (match_operand:TF 2 "register_operand" "=&f"))] | |
76ee8042 | 5790 | "ISA_HAS_8CC && TARGET_HARD_FLOAT" |
b8eb88d0 ILT |
5791 | " |
5792 | { | |
d12b8c85 | 5793 | mips_emit_fcc_reload (operands[0], operands[1], operands[2]); |
b8eb88d0 ILT |
5794 | DONE; |
5795 | }") | |
5796 | ||
5797 | ;; MIPS4 supports loading and storing a floating point register from | |
5798 | ;; the sum of two general registers. We use two versions for each of | |
5799 | ;; these four instructions: one where the two general registers are | |
5800 | ;; SImode, and one where they are DImode. This is because general | |
5801 | ;; registers will be in SImode when they hold 32 bit values, but, | |
5802 | ;; since the 32 bit values are always sign extended, the [ls][wd]xc1 | |
5803 | ;; instructions will still work correctly. | |
5804 | ||
5805 | ;; ??? Perhaps it would be better to support these instructions by | |
5806 | ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since | |
5807 | ;; these instructions can only be used to load and store floating | |
5808 | ;; point registers, that would probably cause trouble in reload. | |
5809 | ||
5810 | (define_insn "" | |
5811 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5812 | (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d") | |
5813 | (match_operand:SI 2 "register_operand" "d"))))] | |
1d5d552e | 5814 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT" |
b8eb88d0 ILT |
5815 | "lwxc1\\t%0,%1(%2)" |
5816 | [(set_attr "type" "load") | |
cafe096b EC |
5817 | (set_attr "mode" "SF") |
5818 | (set_attr "length" "4")]) | |
b8eb88d0 ILT |
5819 | |
5820 | (define_insn "" | |
5821 | [(set (match_operand:SF 0 "register_operand" "=f") | |
cafe096b EC |
5822 | (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d") |
5823 | (match_operand:DI 2 "register_operand" "d"))))] | |
1d5d552e | 5824 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT" |
b8eb88d0 ILT |
5825 | "lwxc1\\t%0,%1(%2)" |
5826 | [(set_attr "type" "load") | |
cafe096b EC |
5827 | (set_attr "mode" "SF") |
5828 | (set_attr "length" "4")]) | |
b8eb88d0 ILT |
5829 | |
5830 | (define_insn "" | |
5831 | [(set (match_operand:DF 0 "register_operand" "=f") | |
5832 | (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d") | |
5833 | (match_operand:SI 2 "register_operand" "d"))))] | |
1d5d552e | 5834 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
b8eb88d0 ILT |
5835 | "ldxc1\\t%0,%1(%2)" |
5836 | [(set_attr "type" "load") | |
cafe096b EC |
5837 | (set_attr "mode" "DF") |
5838 | (set_attr "length" "4")]) | |
b8eb88d0 ILT |
5839 | |
5840 | (define_insn "" | |
5841 | [(set (match_operand:DF 0 "register_operand" "=f") | |
cafe096b EC |
5842 | (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d") |
5843 | (match_operand:DI 2 "register_operand" "d"))))] | |
1d5d552e | 5844 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
b8eb88d0 ILT |
5845 | "ldxc1\\t%0,%1(%2)" |
5846 | [(set_attr "type" "load") | |
cafe096b EC |
5847 | (set_attr "mode" "DF") |
5848 | (set_attr "length" "4")]) | |
b8eb88d0 ILT |
5849 | |
5850 | (define_insn "" | |
5851 | [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d") | |
5852 | (match_operand:SI 2 "register_operand" "d"))) | |
c5c76735 | 5853 | (match_operand:SF 0 "register_operand" "f"))] |
1d5d552e | 5854 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT" |
b8eb88d0 ILT |
5855 | "swxc1\\t%0,%1(%2)" |
5856 | [(set_attr "type" "store") | |
cafe096b EC |
5857 | (set_attr "mode" "SF") |
5858 | (set_attr "length" "4")]) | |
b8eb88d0 ILT |
5859 | |
5860 | (define_insn "" | |
cafe096b EC |
5861 | [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d") |
5862 | (match_operand:DI 2 "register_operand" "d"))) | |
c5c76735 | 5863 | (match_operand:SF 0 "register_operand" "f"))] |
1d5d552e | 5864 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT" |
b8eb88d0 ILT |
5865 | "swxc1\\t%0,%1(%2)" |
5866 | [(set_attr "type" "store") | |
cafe096b EC |
5867 | (set_attr "mode" "SF") |
5868 | (set_attr "length" "4")]) | |
b8eb88d0 ILT |
5869 | |
5870 | (define_insn "" | |
5871 | [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d") | |
5872 | (match_operand:SI 2 "register_operand" "d"))) | |
c5c76735 | 5873 | (match_operand:DF 0 "register_operand" "f"))] |
1d5d552e | 5874 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
b8eb88d0 ILT |
5875 | "sdxc1\\t%0,%1(%2)" |
5876 | [(set_attr "type" "store") | |
cafe096b EC |
5877 | (set_attr "mode" "DF") |
5878 | (set_attr "length" "4")]) | |
b8eb88d0 ILT |
5879 | |
5880 | (define_insn "" | |
cafe096b EC |
5881 | [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d") |
5882 | (match_operand:DI 2 "register_operand" "d"))) | |
c5c76735 | 5883 | (match_operand:DF 0 "register_operand" "f"))] |
1d5d552e | 5884 | "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
b8eb88d0 ILT |
5885 | "sdxc1\\t%0,%1(%2)" |
5886 | [(set_attr "type" "store") | |
cafe096b EC |
5887 | (set_attr "mode" "DF") |
5888 | (set_attr "length" "4")]) | |
b8eb88d0 | 5889 | |
8ef30996 MM |
5890 | ;; 16-bit Integer moves |
5891 | ||
5892 | ;; Unlike most other insns, the move insns can't be split with | |
5893 | ;; different predicates, because register spilling and other parts of | |
5894 | ;; the compiler, have memoized the insn number already. | |
5895 | ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined | |
5896 | ||
0fb5ac6f MM |
5897 | (define_expand "movhi" |
5898 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
5899 | (match_operand:HI 1 "general_operand" ""))] | |
8ef30996 | 5900 | "" |
ed50ab35 MM |
5901 | " |
5902 | { | |
5903 | if ((reload_in_progress | reload_completed) == 0 | |
5904 | && !register_operand (operands[0], HImode) | |
5905 | && !register_operand (operands[1], HImode) | |
2bcb2ab3 GK |
5906 | && (TARGET_MIPS16 |
5907 | || (GET_CODE (operands[1]) != CONST_INT | |
5908 | || INTVAL (operands[1]) != 0))) | |
ed50ab35 MM |
5909 | { |
5910 | rtx temp = force_reg (HImode, operands[1]); | |
5911 | emit_move_insn (operands[0], temp); | |
5912 | DONE; | |
5913 | } | |
5914 | }") | |
0fb5ac6f MM |
5915 | |
5916 | ;; The difference between these two is whether or not ints are allowed | |
5917 | ;; in FP registers (off by default, use -mdebugh to enable). | |
5918 | ||
8214bf98 | 5919 | (define_insn "movhi_internal" |
cafe096b EC |
5920 | [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f*z,*f,*x,*d") |
5921 | (match_operand:HI 1 "general_operand" "d,IK,m,dJ,*f*z,*d,*f,*d,*x"))] | |
8214bf98 | 5922 | "!TARGET_MIPS16 |
ed50ab35 MM |
5923 | && (register_operand (operands[0], HImode) |
5924 | || register_operand (operands[1], HImode) | |
5925 | || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" | |
8ef30996 | 5926 | "* return mips_move_1word (operands, insn, TRUE);" |
cafe096b | 5927 | [(set_attr "type" "move,arith,load,store,xfer,xfer,move,hilo,hilo") |
92b4cee1 | 5928 | (set_attr "mode" "HI") |
cafe096b | 5929 | (set_attr "length" "4,4,*,*,4,4,4,4,4")]) |
8ef30996 | 5930 | |
2bcb2ab3 | 5931 | (define_insn "" |
cafe096b EC |
5932 | [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") |
5933 | (match_operand:HI 1 "general_operand" "d,d,y,K,N,m,d,*x"))] | |
2bcb2ab3 GK |
5934 | "TARGET_MIPS16 |
5935 | && (register_operand (operands[0], HImode) | |
5936 | || register_operand (operands[1], HImode))" | |
5937 | "* return mips_move_1word (operands, insn, TRUE);" | |
cafe096b | 5938 | [(set_attr "type" "move,move,move,arith,arith,load,store,hilo") |
2bcb2ab3 GK |
5939 | (set_attr "mode" "HI") |
5940 | (set_attr_alternative "length" | |
0ff83799 MM |
5941 | [(const_int 4) |
5942 | (const_int 4) | |
5943 | (const_int 4) | |
2bcb2ab3 | 5944 | (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "") |
0ff83799 MM |
5945 | (const_int 4) |
5946 | (const_int 8)) | |
2bcb2ab3 | 5947 | (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "") |
0ff83799 MM |
5948 | (const_int 8) |
5949 | (const_int 12)) | |
cafe096b EC |
5950 | (const_string "*") |
5951 | (const_string "*") | |
0ff83799 | 5952 | (const_int 4)])]) |
2bcb2ab3 GK |
5953 | |
5954 | ||
5955 | ;; On the mips16, we can split lh $r,N($r) into an add and a load, | |
5956 | ;; when the original load is a 4 byte instruction but the add and the | |
5957 | ;; load are 2 2 byte instructions. | |
5958 | ||
5959 | (define_split | |
5960 | [(set (match_operand:HI 0 "register_operand" "") | |
988ee12c | 5961 | (mem:HI (plus:SI (match_dup 0) |
2bcb2ab3 | 5962 | (match_operand:SI 1 "const_int_operand" ""))))] |
2ca2d9ee | 5963 | "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
5964 | && GET_CODE (operands[0]) == REG |
5965 | && M16_REG_P (REGNO (operands[0])) | |
5966 | && GET_CODE (operands[1]) == CONST_INT | |
5967 | && ((INTVAL (operands[1]) < 0 | |
5968 | && INTVAL (operands[1]) >= -0x80) | |
5969 | || (INTVAL (operands[1]) >= 32 * 2 | |
5970 | && INTVAL (operands[1]) <= 31 * 2 + 0x7e) | |
5971 | || (INTVAL (operands[1]) >= 0 | |
5972 | && INTVAL (operands[1]) < 32 * 2 | |
5973 | && (INTVAL (operands[1]) & 1) != 0))" | |
5974 | [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) | |
5975 | (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))] | |
5976 | " | |
5977 | { | |
5978 | HOST_WIDE_INT val = INTVAL (operands[1]); | |
5979 | ||
5980 | if (val < 0) | |
5981 | operands[2] = GEN_INT (0); | |
5982 | else if (val >= 32 * 2) | |
5983 | { | |
5984 | int off = val & 1; | |
5985 | ||
5986 | operands[1] = GEN_INT (0x7e + off); | |
5987 | operands[2] = GEN_INT (val - off - 0x7e); | |
5988 | } | |
5989 | else | |
5990 | { | |
5991 | int off = val & 1; | |
5992 | ||
5993 | operands[1] = GEN_INT (off); | |
5994 | operands[2] = GEN_INT (val - off); | |
5995 | } | |
5996 | }") | |
0fb5ac6f | 5997 | |
8ef30996 MM |
5998 | ;; 8-bit Integer moves |
5999 | ||
6000 | ;; Unlike most other insns, the move insns can't be split with | |
6001 | ;; different predicates, because register spilling and other parts of | |
6002 | ;; the compiler, have memoized the insn number already. | |
6003 | ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined | |
6004 | ||
0fb5ac6f MM |
6005 | (define_expand "movqi" |
6006 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
6007 | (match_operand:QI 1 "general_operand" ""))] | |
8ef30996 | 6008 | "" |
ed50ab35 MM |
6009 | " |
6010 | { | |
6011 | if ((reload_in_progress | reload_completed) == 0 | |
6012 | && !register_operand (operands[0], QImode) | |
6013 | && !register_operand (operands[1], QImode) | |
2bcb2ab3 GK |
6014 | && (TARGET_MIPS16 |
6015 | || (GET_CODE (operands[1]) != CONST_INT | |
6016 | || INTVAL (operands[1]) != 0))) | |
ed50ab35 MM |
6017 | { |
6018 | rtx temp = force_reg (QImode, operands[1]); | |
6019 | emit_move_insn (operands[0], temp); | |
6020 | DONE; | |
6021 | } | |
6022 | }") | |
0fb5ac6f MM |
6023 | |
6024 | ;; The difference between these two is whether or not ints are allowed | |
6025 | ;; in FP registers (off by default, use -mdebugh to enable). | |
6026 | ||
8214bf98 | 6027 | (define_insn "movqi_internal" |
cafe096b EC |
6028 | [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f*z,*f,*x,*d") |
6029 | (match_operand:QI 1 "general_operand" "d,IK,m,dJ,*f*z,*d,*f,*d,*x"))] | |
8214bf98 | 6030 | "!TARGET_MIPS16 |
ed50ab35 MM |
6031 | && (register_operand (operands[0], QImode) |
6032 | || register_operand (operands[1], QImode) | |
6033 | || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" | |
8ef30996 | 6034 | "* return mips_move_1word (operands, insn, TRUE);" |
cafe096b | 6035 | [(set_attr "type" "move,arith,load,store,xfer,xfer,move,hilo,hilo") |
92b4cee1 | 6036 | (set_attr "mode" "QI") |
cafe096b | 6037 | (set_attr "length" "4,4,*,*,4,4,4,4,4")]) |
8ef30996 | 6038 | |
2bcb2ab3 | 6039 | (define_insn "" |
cafe096b EC |
6040 | [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") |
6041 | (match_operand:QI 1 "general_operand" "d,d,y,K,N,m,d,*x"))] | |
2bcb2ab3 GK |
6042 | "TARGET_MIPS16 |
6043 | && (register_operand (operands[0], QImode) | |
6044 | || register_operand (operands[1], QImode))" | |
6045 | "* return mips_move_1word (operands, insn, TRUE);" | |
cafe096b | 6046 | [(set_attr "type" "move,move,move,arith,arith,load,store,hilo") |
2bcb2ab3 GK |
6047 | (set_attr "mode" "QI") |
6048 | (set_attr_alternative "length" | |
0ff83799 MM |
6049 | [(const_int 4) |
6050 | (const_int 4) | |
6051 | (const_int 4) | |
2bcb2ab3 | 6052 | (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "") |
0ff83799 MM |
6053 | (const_int 4) |
6054 | (const_int 8)) | |
2bcb2ab3 | 6055 | (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "") |
0ff83799 MM |
6056 | (const_int 8) |
6057 | (const_int 12)) | |
cafe096b EC |
6058 | (const_string "*") |
6059 | (const_string "*") | |
0ff83799 | 6060 | (const_int 4)])]) |
2bcb2ab3 GK |
6061 | |
6062 | ||
6063 | ;; On the mips16, we can split lb $r,N($r) into an add and a load, | |
6064 | ;; when the original load is a 4 byte instruction but the add and the | |
6065 | ;; load are 2 2 byte instructions. | |
6066 | ||
6067 | (define_split | |
6068 | [(set (match_operand:QI 0 "register_operand" "") | |
6069 | (mem:QI (plus:SI (match_dup 0) | |
6070 | (match_operand:SI 1 "const_int_operand" ""))))] | |
2ca2d9ee | 6071 | "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
6072 | && GET_CODE (operands[0]) == REG |
6073 | && M16_REG_P (REGNO (operands[0])) | |
6074 | && GET_CODE (operands[1]) == CONST_INT | |
6075 | && ((INTVAL (operands[1]) < 0 | |
6076 | && INTVAL (operands[1]) >= -0x80) | |
6077 | || (INTVAL (operands[1]) >= 32 | |
6078 | && INTVAL (operands[1]) <= 31 + 0x7f))" | |
6079 | [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) | |
6080 | (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))] | |
6081 | " | |
6082 | { | |
6083 | HOST_WIDE_INT val = INTVAL (operands[1]); | |
6084 | ||
6085 | if (val < 0) | |
6086 | operands[2] = GEN_INT (0); | |
6087 | else | |
6088 | { | |
6089 | operands[1] = GEN_INT (0x7f); | |
6090 | operands[2] = GEN_INT (val - 0x7f); | |
6091 | } | |
6092 | }") | |
8ef30996 MM |
6093 | |
6094 | ;; 32-bit floating point moves | |
6095 | ||
ed50ab35 MM |
6096 | (define_expand "movsf" |
6097 | [(set (match_operand:SF 0 "nonimmediate_operand" "") | |
6098 | (match_operand:SF 1 "general_operand" ""))] | |
6099 | "" | |
6100 | " | |
6101 | { | |
6102 | if ((reload_in_progress | reload_completed) == 0 | |
6103 | && !register_operand (operands[0], SFmode) | |
1f7422bd RH |
6104 | && !nonmemory_operand (operands[1], SFmode)) |
6105 | operands[1] = force_reg (SFmode, operands[1]); | |
ed50ab35 MM |
6106 | }") |
6107 | ||
b0193a92 | 6108 | (define_insn "movsf_internal1" |
cafe096b EC |
6109 | [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m") |
6110 | (match_operand:SF 1 "general_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))] | |
b0193a92 MM |
6111 | "TARGET_HARD_FLOAT |
6112 | && (register_operand (operands[0], SFmode) | |
1f7422bd | 6113 | || nonmemory_operand (operands[1], SFmode))" |
8ef30996 | 6114 | "* return mips_move_1word (operands, insn, FALSE);" |
cafe096b | 6115 | [(set_attr "type" "move,xfer,load,store,xfer,xfer,move,load,store") |
92b4cee1 | 6116 | (set_attr "mode" "SF") |
cafe096b | 6117 | (set_attr "length" "4,4,*,*,4,4,4,*,*")]) |
8ef30996 | 6118 | |
b0193a92 | 6119 | (define_insn "movsf_internal2" |
cafe096b EC |
6120 | [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m") |
6121 | (match_operand:SF 1 "general_operand" " Gd,m,d"))] | |
2bcb2ab3 | 6122 | "TARGET_SOFT_FLOAT && !TARGET_MIPS16 |
b0193a92 | 6123 | && (register_operand (operands[0], SFmode) |
1f7422bd | 6124 | || nonmemory_operand (operands[1], SFmode))" |
b0193a92 | 6125 | "* return mips_move_1word (operands, insn, FALSE);" |
cafe096b | 6126 | [(set_attr "type" "move,load,store") |
b0193a92 | 6127 | (set_attr "mode" "SF") |
cafe096b | 6128 | (set_attr "length" "4,*,*")]) |
b0193a92 | 6129 | |
2bcb2ab3 | 6130 | (define_insn "" |
cafe096b EC |
6131 | [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m") |
6132 | (match_operand:SF 1 "nonimmediate_operand" "d,d,y,m,d"))] | |
2bcb2ab3 GK |
6133 | "TARGET_MIPS16 |
6134 | && (register_operand (operands[0], SFmode) | |
6135 | || register_operand (operands[1], SFmode))" | |
6136 | "* return mips_move_1word (operands, insn, FALSE);" | |
cafe096b | 6137 | [(set_attr "type" "move,move,move,load,store") |
2bcb2ab3 | 6138 | (set_attr "mode" "SF") |
cafe096b | 6139 | (set_attr "length" "4,4,4,*,*")]) |
2bcb2ab3 | 6140 | |
b0193a92 | 6141 | |
8ef30996 MM |
6142 | ;; 64-bit floating point moves |
6143 | ||
ed50ab35 MM |
6144 | (define_expand "movdf" |
6145 | [(set (match_operand:DF 0 "nonimmediate_operand" "") | |
6146 | (match_operand:DF 1 "general_operand" ""))] | |
6147 | "" | |
6148 | " | |
6149 | { | |
6150 | if ((reload_in_progress | reload_completed) == 0 | |
6151 | && !register_operand (operands[0], DFmode) | |
1f7422bd RH |
6152 | && !nonmemory_operand (operands[1], DFmode)) |
6153 | operands[1] = force_reg (DFmode, operands[1]); | |
ed50ab35 MM |
6154 | }") |
6155 | ||
cafe096b EC |
6156 | (define_insn "movdf_internal1a" |
6157 | [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m") | |
6158 | (match_operand:DF 1 "general_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))] | |
6159 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT | |
b0193a92 | 6160 | && (register_operand (operands[0], DFmode) |
1f7422bd | 6161 | || nonmemory_operand (operands[1], DFmode))" |
8ef30996 | 6162 | "* return mips_move_2words (operands, insn); " |
cafe096b EC |
6163 | [(set_attr "type" "move,move,load,store,xfer,xfer,move,load,store") |
6164 | (set_attr "mode" "DF") | |
6165 | (set_attr "length" "4,8,*,*,4,4,4,*,*")]) | |
8ef30996 | 6166 | |
cafe096b EC |
6167 | (define_insn "movdf_internal1b" |
6168 | [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m") | |
6169 | (match_operand:DF 1 "general_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))] | |
6170 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT | |
64d8baf9 | 6171 | && (register_operand (operands[0], DFmode) |
1f7422bd | 6172 | || nonmemory_operand (operands[1], DFmode))" |
64d8baf9 | 6173 | "* return mips_move_2words (operands, insn); " |
cafe096b | 6174 | [(set_attr "type" "move,move,load,store,xfer,xfer,move,load,store") |
64d8baf9 | 6175 | (set_attr "mode" "DF") |
cafe096b | 6176 | (set_attr "length" "4,8,*,*,8,8,8,*,*")]) |
64d8baf9 | 6177 | |
b0193a92 | 6178 | (define_insn "movdf_internal2" |
cafe096b EC |
6179 | [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f") |
6180 | (match_operand:DF 1 "general_operand" "dG,m,d,f,d,f"))] | |
2bcb2ab3 | 6181 | "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16 |
b0193a92 | 6182 | && (register_operand (operands[0], DFmode) |
1f7422bd | 6183 | || nonmemory_operand (operands[1], DFmode))" |
b0193a92 | 6184 | "* return mips_move_2words (operands, insn); " |
cafe096b | 6185 | [(set_attr "type" "move,load,store,xfer,xfer,move") |
b0193a92 | 6186 | (set_attr "mode" "DF") |
cafe096b | 6187 | (set_attr "length" "8,*,*,8,8,4")]) |
b0193a92 | 6188 | |
2bcb2ab3 | 6189 | (define_insn "" |
cafe096b EC |
6190 | [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m") |
6191 | (match_operand:DF 1 "nonimmediate_operand" "d,d,y,m,d"))] | |
2bcb2ab3 GK |
6192 | "TARGET_MIPS16 |
6193 | && (register_operand (operands[0], DFmode) | |
6194 | || register_operand (operands[1], DFmode))" | |
6195 | "* return mips_move_2words (operands, insn);" | |
cafe096b | 6196 | [(set_attr "type" "move,move,move,load,store") |
2bcb2ab3 | 6197 | (set_attr "mode" "DF") |
cafe096b | 6198 | (set_attr "length" "8,8,8,*,*")]) |
2bcb2ab3 | 6199 | |
8ef30996 MM |
6200 | (define_split |
6201 | [(set (match_operand:DF 0 "register_operand" "") | |
6202 | (match_operand:DF 1 "register_operand" ""))] | |
2ca2d9ee EC |
6203 | "reload_completed && !TARGET_64BIT |
6204 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE | |
8ef30996 MM |
6205 | && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) |
6206 | && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))" | |
8ef30996 | 6207 | [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0)) |
ddef6bc7 | 6208 | (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))] |
8ef30996 MM |
6209 | "") |
6210 | ||
e19ff60f JW |
6211 | ;; Instructions to load the global pointer register. |
6212 | ;; This is volatile to make sure that the scheduler won't move any symbol_ref | |
6213 | ;; uses in front of it. All symbol_refs implicitly use the gp reg. | |
6214 | ||
6215 | (define_insn "loadgp" | |
6216 | [(set (reg:DI 28) | |
cafe096b | 6217 | (unspec_volatile:DI [(match_operand 0 "immediate_operand" "") |
41f8d041 RS |
6218 | (match_operand:DI 1 "register_operand" "")] |
6219 | UNSPEC_LOADGP)) | |
e19ff60f JW |
6220 | (clobber (reg:DI 1))] |
6221 | "" | |
cafe096b | 6222 | "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%0)))\\n\\tdaddu\\t$gp,$1,%1%]" |
e19ff60f JW |
6223 | [(set_attr "type" "move") |
6224 | (set_attr "mode" "DI") | |
0ff83799 | 6225 | (set_attr "length" "12")]) |
26b8e6e5 | 6226 | \f |
8ef30996 MM |
6227 | ;; Block moves, see mips.c for more details. |
6228 | ;; Argument 0 is the destination | |
6229 | ;; Argument 1 is the source | |
6230 | ;; Argument 2 is the length | |
6231 | ;; Argument 3 is the alignment | |
6232 | ||
6233 | (define_expand "movstrsi" | |
e9a25f70 JL |
6234 | [(parallel [(set (match_operand:BLK 0 "general_operand" "") |
6235 | (match_operand:BLK 1 "general_operand" "")) | |
8ef30996 MM |
6236 | (use (match_operand:SI 2 "arith32_operand" "")) |
6237 | (use (match_operand:SI 3 "immediate_operand" ""))])] | |
2bcb2ab3 | 6238 | "!TARGET_MIPS16" |
8ef30996 MM |
6239 | " |
6240 | { | |
6241 | if (operands[0]) /* avoid unused code messages */ | |
6242 | { | |
6243 | expand_block_move (operands); | |
6244 | DONE; | |
6245 | } | |
6246 | }") | |
6247 | ||
842eb20e MM |
6248 | ;; Insn generated by block moves |
6249 | ||
6250 | (define_insn "movstrsi_internal" | |
aa4e54c4 JW |
6251 | [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination |
6252 | (match_operand:BLK 1 "memory_operand" "o")) ;; source | |
26b8e6e5 MM |
6253 | (clobber (match_scratch:SI 4 "=&d")) ;; temp 1 |
6254 | (clobber (match_scratch:SI 5 "=&d")) ;; temp 2 | |
6255 | (clobber (match_scratch:SI 6 "=&d")) ;; temp 3 | |
6256 | (clobber (match_scratch:SI 7 "=&d")) ;; temp 4 | |
6257 | (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move | |
6258 | (use (match_operand:SI 3 "small_int" "I")) ;; alignment | |
6259 | (use (const_int 0))] ;; normal block move | |
6260 | "" | |
6261 | "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);" | |
e9a25f70 | 6262 | [(set_attr "type" "store") |
842eb20e | 6263 | (set_attr "mode" "none") |
0ff83799 | 6264 | (set_attr "length" "80")]) |
842eb20e | 6265 | |
2bcb2ab3 GK |
6266 | ;; We need mips16 versions, because an offset from the stack pointer |
6267 | ;; is not offsettable, since the stack pointer can only handle 4 and 8 | |
6268 | ;; byte loads. | |
6269 | ||
2bcb2ab3 GK |
6270 | (define_insn "" |
6271 | [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination | |
cf45bb06 | 6272 | (match_operand:BLK 1 "memory_operand" "o")) ;; source |
2bcb2ab3 GK |
6273 | (clobber (match_scratch:SI 4 "=&d")) ;; temp 1 |
6274 | (clobber (match_scratch:SI 5 "=&d")) ;; temp 2 | |
6275 | (clobber (match_scratch:SI 6 "=&d")) ;; temp 3 | |
6276 | (clobber (match_scratch:SI 7 "=&d")) ;; temp 4 | |
6277 | (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move | |
6278 | (use (match_operand:SI 3 "small_int" "I")) ;; alignment | |
6279 | (use (const_int 0))] ;; normal block move | |
6280 | "TARGET_MIPS16" | |
6281 | "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);" | |
6282 | [(set_attr "type" "multi") | |
6283 | (set_attr "mode" "none") | |
0ff83799 | 6284 | (set_attr "length" "80")]) |
2bcb2ab3 | 6285 | |
26b8e6e5 MM |
6286 | ;; Split a block move into 2 parts, the first part is everything |
6287 | ;; except for the last move, and the second part is just the last | |
6288 | ;; store, which is exactly 1 instruction (ie, not a usw), so it can | |
6289 | ;; fill a delay slot. This also prevents a bug in delayed branches | |
6290 | ;; from showing up, which reuses one of the registers in our clobbers. | |
6291 | ||
1ba8a9c4 RS |
6292 | ;; ??? Disabled because it doesn't preserve alias information for |
6293 | ;; operands 0 and 1. Also, the rtl for the second insn doesn't mention | |
6294 | ;; that it uses the registers clobbered by the first. | |
6295 | ;; | |
6296 | ;; It would probably be better to split the block into individual | |
6297 | ;; instructions instead. | |
26b8e6e5 MM |
6298 | (define_split |
6299 | [(set (mem:BLK (match_operand:SI 0 "register_operand" "")) | |
6300 | (mem:BLK (match_operand:SI 1 "register_operand" ""))) | |
6301 | (clobber (match_operand:SI 4 "register_operand" "")) | |
6302 | (clobber (match_operand:SI 5 "register_operand" "")) | |
6303 | (clobber (match_operand:SI 6 "register_operand" "")) | |
6304 | (clobber (match_operand:SI 7 "register_operand" "")) | |
6305 | (use (match_operand:SI 2 "small_int" "")) | |
6306 | (use (match_operand:SI 3 "small_int" "")) | |
6307 | (use (const_int 0))] | |
6308 | ||
1ba8a9c4 | 6309 | "reload_completed && 0 && INTVAL (operands[2]) > 0" |
26b8e6e5 MM |
6310 | |
6311 | ;; All but the last move | |
6312 | [(parallel [(set (mem:BLK (match_dup 0)) | |
6313 | (mem:BLK (match_dup 1))) | |
6314 | (clobber (match_dup 4)) | |
6315 | (clobber (match_dup 5)) | |
6316 | (clobber (match_dup 6)) | |
6317 | (clobber (match_dup 7)) | |
6318 | (use (match_dup 2)) | |
6319 | (use (match_dup 3)) | |
6320 | (use (const_int 1))]) | |
6321 | ||
6322 | ;; The last store, so it can fill a delay slot | |
6323 | (parallel [(set (mem:BLK (match_dup 0)) | |
6324 | (mem:BLK (match_dup 1))) | |
6325 | (clobber (match_dup 4)) | |
6326 | (clobber (match_dup 5)) | |
6327 | (clobber (match_dup 6)) | |
6328 | (clobber (match_dup 7)) | |
6329 | (use (match_dup 2)) | |
6330 | (use (match_dup 3)) | |
6331 | (use (const_int 2))])] | |
6332 | ||
6333 | "") | |
6334 | ||
6335 | (define_insn "movstrsi_internal2" | |
aa4e54c4 JW |
6336 | [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination |
6337 | (match_operand:BLK 1 "memory_operand" "o")) ;; source | |
26b8e6e5 MM |
6338 | (clobber (match_scratch:SI 4 "=&d")) ;; temp 1 |
6339 | (clobber (match_scratch:SI 5 "=&d")) ;; temp 2 | |
6340 | (clobber (match_scratch:SI 6 "=&d")) ;; temp 3 | |
6341 | (clobber (match_scratch:SI 7 "=&d")) ;; temp 4 | |
6342 | (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move | |
6343 | (use (match_operand:SI 3 "small_int" "I")) ;; alignment | |
6344 | (use (const_int 1))] ;; all but last store | |
6345 | "" | |
6346 | "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);" | |
e9a25f70 | 6347 | [(set_attr "type" "store") |
26b8e6e5 | 6348 | (set_attr "mode" "none") |
0ff83799 | 6349 | (set_attr "length" "80")]) |
26b8e6e5 | 6350 | |
2bcb2ab3 | 6351 | (define_insn "" |
cf45bb06 RH |
6352 | [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination |
6353 | (match_operand:BLK 1 "memory_operand" "o")) ;; source | |
2bcb2ab3 GK |
6354 | (clobber (match_scratch:SI 4 "=&d")) ;; temp 1 |
6355 | (clobber (match_scratch:SI 5 "=&d")) ;; temp 2 | |
6356 | (clobber (match_scratch:SI 6 "=&d")) ;; temp 3 | |
6357 | (clobber (match_scratch:SI 7 "=&d")) ;; temp 4 | |
6358 | (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move | |
6359 | (use (match_operand:SI 3 "small_int" "I")) ;; alignment | |
6360 | (use (const_int 1))] ;; all but last store | |
6361 | "TARGET_MIPS16" | |
6362 | "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);" | |
6363 | [(set_attr "type" "multi") | |
6364 | (set_attr "mode" "none") | |
0ff83799 | 6365 | (set_attr "length" "80")]) |
2bcb2ab3 | 6366 | |
26b8e6e5 | 6367 | (define_insn "movstrsi_internal3" |
cafe096b EC |
6368 | [(set (match_operand:BLK 0 "memory_operand" "=m") ;; destination |
6369 | (match_operand:BLK 1 "memory_operand" "m")) ;; source | |
26b8e6e5 MM |
6370 | (clobber (match_scratch:SI 4 "=&d")) ;; temp 1 |
6371 | (clobber (match_scratch:SI 5 "=&d")) ;; temp 2 | |
6372 | (clobber (match_scratch:SI 6 "=&d")) ;; temp 3 | |
6373 | (clobber (match_scratch:SI 7 "=&d")) ;; temp 4 | |
6374 | (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move | |
6375 | (use (match_operand:SI 3 "small_int" "I")) ;; alignment | |
bb621ad7 | 6376 | (use (const_int 2))] ;; just last store of block move |
26b8e6e5 MM |
6377 | "" |
6378 | "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);" | |
6379 | [(set_attr "type" "store") | |
0ff83799 | 6380 | (set_attr "mode" "none")]) |
8ef30996 MM |
6381 | \f |
6382 | ;; | |
6383 | ;; .................... | |
6384 | ;; | |
6385 | ;; SHIFTS | |
6386 | ;; | |
6387 | ;; .................... | |
6388 | ||
2bcb2ab3 GK |
6389 | ;; Many of these instructions uses trivial define_expands, because we |
6390 | ;; want to use a different set of constraints when TARGET_MIPS16. | |
6391 | ||
6392 | (define_expand "ashlsi3" | |
8ef30996 MM |
6393 | [(set (match_operand:SI 0 "register_operand" "=d") |
6394 | (ashift:SI (match_operand:SI 1 "register_operand" "d") | |
6395 | (match_operand:SI 2 "arith_operand" "dI")))] | |
6396 | "" | |
2bcb2ab3 GK |
6397 | " |
6398 | { | |
6399 | /* On the mips16, a shift of more than 8 is a four byte instruction, | |
6400 | so, for a shift between 8 and 16, it is just as fast to do two | |
6401 | shifts of 8 or less. If there is a lot of shifting going on, we | |
6402 | may win in CSE. Otherwise combine will put the shifts back | |
6403 | together again. This can be called by function_arg, so we must | |
6404 | be careful not to allocate a new register if we've reached the | |
6405 | reload pass. */ | |
6406 | if (TARGET_MIPS16 | |
6407 | && optimize | |
6408 | && GET_CODE (operands[2]) == CONST_INT | |
6409 | && INTVAL (operands[2]) > 8 | |
6410 | && INTVAL (operands[2]) <= 16 | |
6411 | && ! reload_in_progress | |
6412 | && ! reload_completed) | |
6413 | { | |
6414 | rtx temp = gen_reg_rtx (SImode); | |
6415 | ||
6416 | emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8))); | |
6417 | emit_insn (gen_ashlsi3_internal2 (operands[0], temp, | |
6418 | GEN_INT (INTVAL (operands[2]) - 8))); | |
6419 | DONE; | |
6420 | } | |
6421 | }") | |
6422 | ||
6423 | (define_insn "ashlsi3_internal1" | |
6424 | [(set (match_operand:SI 0 "register_operand" "=d") | |
6425 | (ashift:SI (match_operand:SI 1 "register_operand" "d") | |
6426 | (match_operand:SI 2 "arith_operand" "dI")))] | |
6427 | "!TARGET_MIPS16" | |
8ef30996 MM |
6428 | "* |
6429 | { | |
6430 | if (GET_CODE (operands[2]) == CONST_INT) | |
95936d18 | 6431 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); |
8ef30996 MM |
6432 | |
6433 | return \"sll\\t%0,%1,%2\"; | |
6434 | }" | |
6435 | [(set_attr "type" "arith") | |
0ff83799 | 6436 | (set_attr "mode" "SI")]) |
8ef30996 | 6437 | |
cafe096b EC |
6438 | (define_insn "ashlsi3_internal1_extend" |
6439 | [(set (match_operand:DI 0 "register_operand" "=d") | |
6440 | (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d") | |
6441 | (match_operand:SI 2 "arith_operand" "dI"))))] | |
6442 | "TARGET_64BIT && !TARGET_MIPS16" | |
6443 | "* | |
6444 | { | |
6445 | if (GET_CODE (operands[2]) == CONST_INT) | |
6446 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); | |
6447 | ||
6448 | return \"sll\\t%0,%1,%2\"; | |
6449 | }" | |
6450 | [(set_attr "type" "arith") | |
6451 | (set_attr "mode" "DI")]) | |
6452 | ||
6453 | ||
2bcb2ab3 GK |
6454 | (define_insn "ashlsi3_internal2" |
6455 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
6456 | (ashift:SI (match_operand:SI 1 "register_operand" "0,d") | |
6457 | (match_operand:SI 2 "arith_operand" "d,I")))] | |
6458 | "TARGET_MIPS16" | |
6459 | "* | |
6460 | { | |
6461 | if (which_alternative == 0) | |
6462 | return \"sll\\t%0,%2\"; | |
6463 | ||
6464 | if (GET_CODE (operands[2]) == CONST_INT) | |
95936d18 | 6465 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); |
2bcb2ab3 GK |
6466 | |
6467 | return \"sll\\t%0,%1,%2\"; | |
6468 | }" | |
6469 | [(set_attr "type" "arith") | |
6470 | (set_attr "mode" "SI") | |
6471 | (set_attr_alternative "length" | |
0ff83799 | 6472 | [(const_int 4) |
2bcb2ab3 | 6473 | (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "") |
0ff83799 MM |
6474 | (const_int 4) |
6475 | (const_int 8))])]) | |
2bcb2ab3 GK |
6476 | |
6477 | ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts. | |
6478 | ||
6479 | (define_split | |
6480 | [(set (match_operand:SI 0 "register_operand" "") | |
6481 | (ashift:SI (match_operand:SI 1 "register_operand" "") | |
6482 | (match_operand:SI 2 "const_int_operand" "")))] | |
2ca2d9ee | 6483 | "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
6484 | && GET_CODE (operands[2]) == CONST_INT |
6485 | && INTVAL (operands[2]) > 8 | |
6486 | && INTVAL (operands[2]) <= 16" | |
6487 | [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8))) | |
6488 | (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))] | |
6489 | " | |
6490 | { | |
6491 | operands[2] = GEN_INT (INTVAL (operands[2]) - 8); | |
6492 | }") | |
8ef30996 MM |
6493 | |
6494 | (define_expand "ashldi3" | |
6495 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
cafe096b | 6496 | (ashift:DI (match_operand:DI 1 "register_operand" "") |
8ef30996 MM |
6497 | (match_operand:SI 2 "arith_operand" ""))) |
6498 | (clobber (match_dup 3))])] | |
2bcb2ab3 | 6499 | "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)" |
bb621ad7 JW |
6500 | " |
6501 | { | |
6502 | if (TARGET_64BIT) | |
6503 | { | |
2bcb2ab3 GK |
6504 | /* On the mips16, a shift of more than 8 is a four byte |
6505 | instruction, so, for a shift between 8 and 16, it is just as | |
6506 | fast to do two shifts of 8 or less. If there is a lot of | |
6507 | shifting going on, we may win in CSE. Otherwise combine will | |
6508 | put the shifts back together again. This can be called by | |
6509 | function_arg, so we must be careful not to allocate a new | |
6510 | register if we've reached the reload pass. */ | |
6511 | if (TARGET_MIPS16 | |
6512 | && optimize | |
6513 | && GET_CODE (operands[2]) == CONST_INT | |
6514 | && INTVAL (operands[2]) > 8 | |
6515 | && INTVAL (operands[2]) <= 16 | |
6516 | && ! reload_in_progress | |
6517 | && ! reload_completed) | |
6518 | { | |
6519 | rtx temp = gen_reg_rtx (DImode); | |
6520 | ||
6521 | emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8))); | |
6522 | emit_insn (gen_ashldi3_internal4 (operands[0], temp, | |
6523 | GEN_INT (INTVAL (operands[2]) - 8))); | |
6524 | DONE; | |
6525 | } | |
6526 | ||
bb621ad7 JW |
6527 | emit_insn (gen_ashldi3_internal4 (operands[0], operands[1], |
6528 | operands[2])); | |
6529 | DONE; | |
6530 | } | |
6531 | ||
6532 | operands[3] = gen_reg_rtx (SImode); | |
6533 | }") | |
8ef30996 MM |
6534 | |
6535 | ||
6536 | (define_insn "ashldi3_internal" | |
0fb5ac6f | 6537 | [(set (match_operand:DI 0 "register_operand" "=&d") |
8ef30996 MM |
6538 | (ashift:DI (match_operand:DI 1 "register_operand" "d") |
6539 | (match_operand:SI 2 "register_operand" "d"))) | |
6540 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2bcb2ab3 | 6541 | "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16" |
7a38df19 | 6542 | "* |
8ef30996 MM |
6543 | { |
6544 | operands[4] = const0_rtx; | |
6545 | dslots_jump_total += 3; | |
6546 | dslots_jump_filled += 2; | |
6547 | ||
6548 | return \"sll\\t%3,%2,26\\n\\ | |
6549 | \\tbgez\\t%3,1f\\n\\ | |
6550 | \\tsll\\t%M0,%L1,%2\\n\\ | |
6551 | \\t%(b\\t3f\\n\\ | |
6552 | \\tmove\\t%L0,%z4%)\\n\\ | |
6553 | \\n\\ | |
efa3896a | 6554 | %~1:\\n\\ |
8ef30996 MM |
6555 | \\t%(beq\\t%3,%z4,2f\\n\\ |
6556 | \\tsll\\t%M0,%M1,%2%)\\n\\ | |
6557 | \\n\\ | |
6558 | \\tsubu\\t%3,%z4,%2\\n\\ | |
6559 | \\tsrl\\t%3,%L1,%3\\n\\ | |
6560 | \\tor\\t%M0,%M0,%3\\n\\ | |
efa3896a | 6561 | %~2:\\n\\ |
8ef30996 | 6562 | \\tsll\\t%L0,%L1,%2\\n\\ |
efa3896a | 6563 | %~3:\"; |
8ef30996 MM |
6564 | }" |
6565 | [(set_attr "type" "darith") | |
6566 | (set_attr "mode" "SI") | |
0ff83799 | 6567 | (set_attr "length" "48")]) |
8ef30996 MM |
6568 | |
6569 | ||
6570 | (define_insn "ashldi3_internal2" | |
6571 | [(set (match_operand:DI 0 "register_operand" "=d") | |
6572 | (ashift:DI (match_operand:DI 1 "register_operand" "d") | |
6573 | (match_operand:SI 2 "small_int" "IJK"))) | |
6574 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2bcb2ab3 GK |
6575 | "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 |
6576 | && (INTVAL (operands[2]) & 32) != 0" | |
8ef30996 MM |
6577 | "* |
6578 | { | |
95936d18 | 6579 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); |
8ef30996 MM |
6580 | operands[4] = const0_rtx; |
6581 | return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\"; | |
6582 | }" | |
6583 | [(set_attr "type" "darith") | |
6584 | (set_attr "mode" "DI") | |
0ff83799 | 6585 | (set_attr "length" "8")]) |
8ef30996 MM |
6586 | |
6587 | ||
6588 | (define_split | |
6589 | [(set (match_operand:DI 0 "register_operand" "") | |
6590 | (ashift:DI (match_operand:DI 1 "register_operand" "") | |
6591 | (match_operand:SI 2 "small_int" ""))) | |
6592 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
6593 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT |
6594 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
6595 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
6596 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
6597 | && (INTVAL (operands[2]) & 32) != 0" | |
6598 | ||
ddef6bc7 | 6599 | [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2))) |
8ef30996 MM |
6600 | (set (subreg:SI (match_dup 0) 0) (const_int 0))] |
6601 | ||
95936d18 | 6602 | "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);") |
8ef30996 MM |
6603 | |
6604 | ||
6605 | (define_split | |
6606 | [(set (match_operand:DI 0 "register_operand" "") | |
6607 | (ashift:DI (match_operand:DI 1 "register_operand" "") | |
6608 | (match_operand:SI 2 "small_int" ""))) | |
6609 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
6610 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT |
6611 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
6612 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
6613 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
6614 | && (INTVAL (operands[2]) & 32) != 0" | |
6615 | ||
ddef6bc7 JJ |
6616 | [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2))) |
6617 | (set (subreg:SI (match_dup 0) 4) (const_int 0))] | |
8ef30996 | 6618 | |
95936d18 | 6619 | "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);") |
8ef30996 MM |
6620 | |
6621 | ||
6622 | (define_insn "ashldi3_internal3" | |
6623 | [(set (match_operand:DI 0 "register_operand" "=d") | |
6624 | (ashift:DI (match_operand:DI 1 "register_operand" "d") | |
6625 | (match_operand:SI 2 "small_int" "IJK"))) | |
6626 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2bcb2ab3 | 6627 | "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 |
8ef30996 MM |
6628 | && (INTVAL (operands[2]) & 63) < 32 |
6629 | && (INTVAL (operands[2]) & 63) != 0" | |
6630 | "* | |
6631 | { | |
6632 | int amount = INTVAL (operands[2]); | |
6633 | ||
c5c76735 | 6634 | operands[2] = GEN_INT (amount & 31); |
8ef30996 | 6635 | operands[4] = const0_rtx; |
c5c76735 | 6636 | operands[5] = GEN_INT ((-amount) & 31); |
8ef30996 MM |
6637 | |
6638 | return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\"; | |
6639 | }" | |
6640 | [(set_attr "type" "darith") | |
6641 | (set_attr "mode" "DI") | |
0ff83799 | 6642 | (set_attr "length" "16")]) |
8ef30996 MM |
6643 | |
6644 | ||
6645 | (define_split | |
6646 | [(set (match_operand:DI 0 "register_operand" "") | |
6647 | (ashift:DI (match_operand:DI 1 "register_operand" "") | |
6648 | (match_operand:SI 2 "small_int" ""))) | |
6649 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
6650 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT |
6651 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
6652 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
6653 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
6654 | && (INTVAL (operands[2]) & 63) < 32 | |
6655 | && (INTVAL (operands[2]) & 63) != 0" | |
6656 | ||
ddef6bc7 JJ |
6657 | [(set (subreg:SI (match_dup 0) 4) |
6658 | (ashift:SI (subreg:SI (match_dup 1) 4) | |
8ef30996 MM |
6659 | (match_dup 2))) |
6660 | ||
6661 | (set (match_dup 3) | |
6662 | (lshiftrt:SI (subreg:SI (match_dup 1) 0) | |
6663 | (match_dup 4))) | |
6664 | ||
ddef6bc7 JJ |
6665 | (set (subreg:SI (match_dup 0) 4) |
6666 | (ior:SI (subreg:SI (match_dup 0) 4) | |
8ef30996 MM |
6667 | (match_dup 3))) |
6668 | ||
6669 | (set (subreg:SI (match_dup 0) 0) | |
6670 | (ashift:SI (subreg:SI (match_dup 1) 0) | |
6671 | (match_dup 2)))] | |
6672 | " | |
6673 | { | |
6674 | int amount = INTVAL (operands[2]); | |
c5c76735 JL |
6675 | operands[2] = GEN_INT (amount & 31); |
6676 | operands[4] = GEN_INT ((-amount) & 31); | |
8ef30996 MM |
6677 | }") |
6678 | ||
6679 | ||
6680 | (define_split | |
6681 | [(set (match_operand:DI 0 "register_operand" "") | |
6682 | (ashift:DI (match_operand:DI 1 "register_operand" "") | |
6683 | (match_operand:SI 2 "small_int" ""))) | |
6684 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
6685 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT |
6686 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
6687 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
6688 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
6689 | && (INTVAL (operands[2]) & 63) < 32 | |
6690 | && (INTVAL (operands[2]) & 63) != 0" | |
6691 | ||
6692 | [(set (subreg:SI (match_dup 0) 0) | |
6693 | (ashift:SI (subreg:SI (match_dup 1) 0) | |
6694 | (match_dup 2))) | |
6695 | ||
6696 | (set (match_dup 3) | |
ddef6bc7 | 6697 | (lshiftrt:SI (subreg:SI (match_dup 1) 4) |
8ef30996 MM |
6698 | (match_dup 4))) |
6699 | ||
6700 | (set (subreg:SI (match_dup 0) 0) | |
6701 | (ior:SI (subreg:SI (match_dup 0) 0) | |
6702 | (match_dup 3))) | |
6703 | ||
ddef6bc7 JJ |
6704 | (set (subreg:SI (match_dup 0) 4) |
6705 | (ashift:SI (subreg:SI (match_dup 1) 4) | |
8ef30996 MM |
6706 | (match_dup 2)))] |
6707 | " | |
6708 | { | |
6709 | int amount = INTVAL (operands[2]); | |
c5c76735 JL |
6710 | operands[2] = GEN_INT (amount & 31); |
6711 | operands[4] = GEN_INT ((-amount) & 31); | |
8ef30996 MM |
6712 | }") |
6713 | ||
6714 | ||
bb621ad7 JW |
6715 | (define_insn "ashldi3_internal4" |
6716 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b | 6717 | (ashift:DI (match_operand:DI 1 "register_operand" "d") |
bb621ad7 | 6718 | (match_operand:SI 2 "arith_operand" "dI")))] |
2bcb2ab3 | 6719 | "TARGET_64BIT && !TARGET_MIPS16" |
bb621ad7 JW |
6720 | "* |
6721 | { | |
6722 | if (GET_CODE (operands[2]) == CONST_INT) | |
6723 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); | |
6724 | ||
6725 | return \"dsll\\t%0,%1,%2\"; | |
6726 | }" | |
6727 | [(set_attr "type" "arith") | |
0ff83799 | 6728 | (set_attr "mode" "DI")]) |
bb621ad7 | 6729 | |
2bcb2ab3 GK |
6730 | (define_insn "" |
6731 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
cafe096b | 6732 | (ashift:DI (match_operand:DI 1 "register_operand" "0,d") |
2bcb2ab3 GK |
6733 | (match_operand:SI 2 "arith_operand" "d,I")))] |
6734 | "TARGET_64BIT && TARGET_MIPS16" | |
6735 | "* | |
6736 | { | |
6737 | if (which_alternative == 0) | |
6738 | return \"dsll\\t%0,%2\"; | |
6739 | ||
6740 | if (GET_CODE (operands[2]) == CONST_INT) | |
6741 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); | |
6742 | ||
6743 | return \"dsll\\t%0,%1,%2\"; | |
6744 | }" | |
6745 | [(set_attr "type" "arith") | |
6746 | (set_attr "mode" "DI") | |
6747 | (set_attr_alternative "length" | |
0ff83799 | 6748 | [(const_int 4) |
2bcb2ab3 | 6749 | (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "") |
0ff83799 MM |
6750 | (const_int 4) |
6751 | (const_int 8))])]) | |
2bcb2ab3 | 6752 | |
bb621ad7 | 6753 | |
2bcb2ab3 GK |
6754 | ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts. |
6755 | ||
6756 | (define_split | |
6757 | [(set (match_operand:DI 0 "register_operand" "") | |
6758 | (ashift:DI (match_operand:DI 1 "register_operand" "") | |
6759 | (match_operand:SI 2 "const_int_operand" "")))] | |
2ca2d9ee | 6760 | "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
6761 | && reload_completed |
6762 | && GET_CODE (operands[2]) == CONST_INT | |
6763 | && INTVAL (operands[2]) > 8 | |
6764 | && INTVAL (operands[2]) <= 16" | |
6765 | [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8))) | |
6766 | (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))] | |
6767 | " | |
6768 | { | |
6769 | operands[2] = GEN_INT (INTVAL (operands[2]) - 8); | |
6770 | }") | |
6771 | ||
6772 | (define_expand "ashrsi3" | |
8ef30996 MM |
6773 | [(set (match_operand:SI 0 "register_operand" "=d") |
6774 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "d") | |
6775 | (match_operand:SI 2 "arith_operand" "dI")))] | |
6776 | "" | |
2bcb2ab3 GK |
6777 | " |
6778 | { | |
6779 | /* On the mips16, a shift of more than 8 is a four byte instruction, | |
6780 | so, for a shift between 8 and 16, it is just as fast to do two | |
6781 | shifts of 8 or less. If there is a lot of shifting going on, we | |
6782 | may win in CSE. Otherwise combine will put the shifts back | |
6783 | together again. */ | |
6784 | if (TARGET_MIPS16 | |
6785 | && optimize | |
6786 | && GET_CODE (operands[2]) == CONST_INT | |
6787 | && INTVAL (operands[2]) > 8 | |
6788 | && INTVAL (operands[2]) <= 16) | |
6789 | { | |
6790 | rtx temp = gen_reg_rtx (SImode); | |
6791 | ||
6792 | emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8))); | |
6793 | emit_insn (gen_ashrsi3_internal2 (operands[0], temp, | |
6794 | GEN_INT (INTVAL (operands[2]) - 8))); | |
6795 | DONE; | |
6796 | } | |
6797 | }") | |
6798 | ||
6799 | (define_insn "ashrsi3_internal1" | |
6800 | [(set (match_operand:SI 0 "register_operand" "=d") | |
6801 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "d") | |
6802 | (match_operand:SI 2 "arith_operand" "dI")))] | |
6803 | "!TARGET_MIPS16" | |
8ef30996 MM |
6804 | "* |
6805 | { | |
6806 | if (GET_CODE (operands[2]) == CONST_INT) | |
2bcb2ab3 | 6807 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); |
8ef30996 MM |
6808 | |
6809 | return \"sra\\t%0,%1,%2\"; | |
6810 | }" | |
6811 | [(set_attr "type" "arith") | |
0ff83799 | 6812 | (set_attr "mode" "SI")]) |
8ef30996 | 6813 | |
2bcb2ab3 GK |
6814 | (define_insn "ashrsi3_internal2" |
6815 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
6816 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d") | |
6817 | (match_operand:SI 2 "arith_operand" "d,I")))] | |
6818 | "TARGET_MIPS16" | |
6819 | "* | |
6820 | { | |
6821 | if (which_alternative == 0) | |
6822 | return \"sra\\t%0,%2\"; | |
6823 | ||
6824 | if (GET_CODE (operands[2]) == CONST_INT) | |
95936d18 | 6825 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); |
2bcb2ab3 GK |
6826 | |
6827 | return \"sra\\t%0,%1,%2\"; | |
6828 | }" | |
6829 | [(set_attr "type" "arith") | |
6830 | (set_attr "mode" "SI") | |
6831 | (set_attr_alternative "length" | |
0ff83799 | 6832 | [(const_int 4) |
2bcb2ab3 | 6833 | (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "") |
0ff83799 MM |
6834 | (const_int 4) |
6835 | (const_int 8))])]) | |
2bcb2ab3 GK |
6836 | |
6837 | ||
6838 | ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts. | |
6839 | ||
6840 | (define_split | |
6841 | [(set (match_operand:SI 0 "register_operand" "") | |
6842 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "") | |
6843 | (match_operand:SI 2 "const_int_operand" "")))] | |
2ca2d9ee | 6844 | "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
6845 | && GET_CODE (operands[2]) == CONST_INT |
6846 | && INTVAL (operands[2]) > 8 | |
6847 | && INTVAL (operands[2]) <= 16" | |
6848 | [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8))) | |
6849 | (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))] | |
6850 | " | |
6851 | { | |
6852 | operands[2] = GEN_INT (INTVAL (operands[2]) - 8); | |
6853 | }") | |
8ef30996 MM |
6854 | |
6855 | (define_expand "ashrdi3" | |
6856 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
cafe096b | 6857 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") |
8ef30996 MM |
6858 | (match_operand:SI 2 "arith_operand" ""))) |
6859 | (clobber (match_dup 3))])] | |
2bcb2ab3 | 6860 | "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)" |
bb621ad7 JW |
6861 | " |
6862 | { | |
6863 | if (TARGET_64BIT) | |
6864 | { | |
2bcb2ab3 GK |
6865 | /* On the mips16, a shift of more than 8 is a four byte |
6866 | instruction, so, for a shift between 8 and 16, it is just as | |
6867 | fast to do two shifts of 8 or less. If there is a lot of | |
6868 | shifting going on, we may win in CSE. Otherwise combine will | |
6869 | put the shifts back together again. */ | |
6870 | if (TARGET_MIPS16 | |
6871 | && optimize | |
6872 | && GET_CODE (operands[2]) == CONST_INT | |
6873 | && INTVAL (operands[2]) > 8 | |
6874 | && INTVAL (operands[2]) <= 16) | |
6875 | { | |
6876 | rtx temp = gen_reg_rtx (DImode); | |
6877 | ||
6878 | emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8))); | |
6879 | emit_insn (gen_ashrdi3_internal4 (operands[0], temp, | |
6880 | GEN_INT (INTVAL (operands[2]) - 8))); | |
6881 | DONE; | |
6882 | } | |
6883 | ||
bb621ad7 JW |
6884 | emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1], |
6885 | operands[2])); | |
6886 | DONE; | |
6887 | } | |
6888 | ||
6889 | operands[3] = gen_reg_rtx (SImode); | |
6890 | }") | |
8ef30996 MM |
6891 | |
6892 | ||
6893 | (define_insn "ashrdi3_internal" | |
0fb5ac6f | 6894 | [(set (match_operand:DI 0 "register_operand" "=&d") |
8ef30996 MM |
6895 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") |
6896 | (match_operand:SI 2 "register_operand" "d"))) | |
6897 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2bcb2ab3 | 6898 | "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16" |
7a38df19 | 6899 | "* |
8ef30996 MM |
6900 | { |
6901 | operands[4] = const0_rtx; | |
6902 | dslots_jump_total += 3; | |
6903 | dslots_jump_filled += 2; | |
6904 | ||
6905 | return \"sll\\t%3,%2,26\\n\\ | |
6906 | \\tbgez\\t%3,1f\\n\\ | |
6907 | \\tsra\\t%L0,%M1,%2\\n\\ | |
6908 | \\t%(b\\t3f\\n\\ | |
6909 | \\tsra\\t%M0,%M1,31%)\\n\\ | |
6910 | \\n\\ | |
efa3896a | 6911 | %~1:\\n\\ |
8ef30996 MM |
6912 | \\t%(beq\\t%3,%z4,2f\\n\\ |
6913 | \\tsrl\\t%L0,%L1,%2%)\\n\\ | |
6914 | \\n\\ | |
6915 | \\tsubu\\t%3,%z4,%2\\n\\ | |
6916 | \\tsll\\t%3,%M1,%3\\n\\ | |
6917 | \\tor\\t%L0,%L0,%3\\n\\ | |
efa3896a | 6918 | %~2:\\n\\ |
8ef30996 | 6919 | \\tsra\\t%M0,%M1,%2\\n\\ |
efa3896a | 6920 | %~3:\"; |
8ef30996 MM |
6921 | }" |
6922 | [(set_attr "type" "darith") | |
6923 | (set_attr "mode" "DI") | |
0ff83799 | 6924 | (set_attr "length" "48")]) |
8ef30996 MM |
6925 | |
6926 | ||
6927 | (define_insn "ashrdi3_internal2" | |
6928 | [(set (match_operand:DI 0 "register_operand" "=d") | |
6929 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") | |
6930 | (match_operand:SI 2 "small_int" "IJK"))) | |
6931 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
bb621ad7 | 6932 | "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0" |
8ef30996 MM |
6933 | "* |
6934 | { | |
95936d18 | 6935 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); |
8ef30996 MM |
6936 | return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\"; |
6937 | }" | |
6938 | [(set_attr "type" "darith") | |
6939 | (set_attr "mode" "DI") | |
0ff83799 | 6940 | (set_attr "length" "8")]) |
8ef30996 MM |
6941 | |
6942 | ||
6943 | (define_split | |
6944 | [(set (match_operand:DI 0 "register_operand" "") | |
6945 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
6946 | (match_operand:SI 2 "small_int" ""))) | |
6947 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2ca2d9ee EC |
6948 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT |
6949 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE | |
8ef30996 MM |
6950 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
6951 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
6952 | && (INTVAL (operands[2]) & 32) != 0" | |
6953 | ||
ddef6bc7 JJ |
6954 | [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2))) |
6955 | (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))] | |
8ef30996 | 6956 | |
95936d18 | 6957 | "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);") |
8ef30996 MM |
6958 | |
6959 | ||
6960 | (define_split | |
6961 | [(set (match_operand:DI 0 "register_operand" "") | |
6962 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
6963 | (match_operand:SI 2 "small_int" ""))) | |
6964 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2ca2d9ee EC |
6965 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT |
6966 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE | |
8ef30996 MM |
6967 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
6968 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
6969 | && (INTVAL (operands[2]) & 32) != 0" | |
6970 | ||
ddef6bc7 | 6971 | [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2))) |
8ef30996 MM |
6972 | (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))] |
6973 | ||
95936d18 | 6974 | "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);") |
8ef30996 MM |
6975 | |
6976 | ||
6977 | (define_insn "ashrdi3_internal3" | |
6978 | [(set (match_operand:DI 0 "register_operand" "=d") | |
6979 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") | |
6980 | (match_operand:SI 2 "small_int" "IJK"))) | |
6981 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2bcb2ab3 | 6982 | "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 |
8ef30996 MM |
6983 | && (INTVAL (operands[2]) & 63) < 32 |
6984 | && (INTVAL (operands[2]) & 63) != 0" | |
6985 | "* | |
6986 | { | |
6987 | int amount = INTVAL (operands[2]); | |
6988 | ||
c5c76735 JL |
6989 | operands[2] = GEN_INT (amount & 31); |
6990 | operands[4] = GEN_INT ((-amount) & 31); | |
8ef30996 MM |
6991 | |
6992 | return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\"; | |
6993 | }" | |
6994 | [(set_attr "type" "darith") | |
6995 | (set_attr "mode" "DI") | |
0ff83799 | 6996 | (set_attr "length" "16")]) |
8ef30996 MM |
6997 | |
6998 | ||
6999 | (define_split | |
7000 | [(set (match_operand:DI 0 "register_operand" "") | |
7001 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
7002 | (match_operand:SI 2 "small_int" ""))) | |
7003 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
7004 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT |
7005 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
7006 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
7007 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
7008 | && (INTVAL (operands[2]) & 63) < 32 | |
7009 | && (INTVAL (operands[2]) & 63) != 0" | |
7010 | ||
7011 | [(set (subreg:SI (match_dup 0) 0) | |
7012 | (lshiftrt:SI (subreg:SI (match_dup 1) 0) | |
7013 | (match_dup 2))) | |
7014 | ||
7015 | (set (match_dup 3) | |
ddef6bc7 | 7016 | (ashift:SI (subreg:SI (match_dup 1) 4) |
8ef30996 MM |
7017 | (match_dup 4))) |
7018 | ||
7019 | (set (subreg:SI (match_dup 0) 0) | |
7020 | (ior:SI (subreg:SI (match_dup 0) 0) | |
7021 | (match_dup 3))) | |
7022 | ||
ddef6bc7 JJ |
7023 | (set (subreg:SI (match_dup 0) 4) |
7024 | (ashiftrt:SI (subreg:SI (match_dup 1) 4) | |
8ef30996 MM |
7025 | (match_dup 2)))] |
7026 | " | |
7027 | { | |
7028 | int amount = INTVAL (operands[2]); | |
c5c76735 JL |
7029 | operands[2] = GEN_INT (amount & 31); |
7030 | operands[4] = GEN_INT ((-amount) & 31); | |
8ef30996 MM |
7031 | }") |
7032 | ||
7033 | ||
7034 | (define_split | |
7035 | [(set (match_operand:DI 0 "register_operand" "") | |
7036 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
7037 | (match_operand:SI 2 "small_int" ""))) | |
7038 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
7039 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT |
7040 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
7041 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
7042 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
7043 | && (INTVAL (operands[2]) & 63) < 32 | |
7044 | && (INTVAL (operands[2]) & 63) != 0" | |
7045 | ||
ddef6bc7 JJ |
7046 | [(set (subreg:SI (match_dup 0) 4) |
7047 | (lshiftrt:SI (subreg:SI (match_dup 1) 4) | |
8ef30996 MM |
7048 | (match_dup 2))) |
7049 | ||
7050 | (set (match_dup 3) | |
7051 | (ashift:SI (subreg:SI (match_dup 1) 0) | |
7052 | (match_dup 4))) | |
7053 | ||
ddef6bc7 JJ |
7054 | (set (subreg:SI (match_dup 0) 4) |
7055 | (ior:SI (subreg:SI (match_dup 0) 4) | |
8ef30996 MM |
7056 | (match_dup 3))) |
7057 | ||
7058 | (set (subreg:SI (match_dup 0) 0) | |
7059 | (ashiftrt:SI (subreg:SI (match_dup 1) 0) | |
7060 | (match_dup 2)))] | |
7061 | " | |
7062 | { | |
7063 | int amount = INTVAL (operands[2]); | |
c5c76735 JL |
7064 | operands[2] = GEN_INT (amount & 31); |
7065 | operands[4] = GEN_INT ((-amount) & 31); | |
8ef30996 MM |
7066 | }") |
7067 | ||
7068 | ||
bb621ad7 JW |
7069 | (define_insn "ashrdi3_internal4" |
7070 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b | 7071 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") |
bb621ad7 | 7072 | (match_operand:SI 2 "arith_operand" "dI")))] |
2bcb2ab3 | 7073 | "TARGET_64BIT && !TARGET_MIPS16" |
bb621ad7 JW |
7074 | "* |
7075 | { | |
7076 | if (GET_CODE (operands[2]) == CONST_INT) | |
7077 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); | |
7078 | ||
7079 | return \"dsra\\t%0,%1,%2\"; | |
7080 | }" | |
7081 | [(set_attr "type" "arith") | |
0ff83799 | 7082 | (set_attr "mode" "DI")]) |
bb621ad7 | 7083 | |
2bcb2ab3 GK |
7084 | (define_insn "" |
7085 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
cafe096b | 7086 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0") |
2bcb2ab3 GK |
7087 | (match_operand:SI 2 "arith_operand" "d,I")))] |
7088 | "TARGET_64BIT && TARGET_MIPS16" | |
7089 | "* | |
7090 | { | |
7091 | if (GET_CODE (operands[2]) == CONST_INT) | |
7092 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); | |
7093 | ||
7094 | return \"dsra\\t%0,%2\"; | |
7095 | }" | |
7096 | [(set_attr "type" "arith") | |
7097 | (set_attr "mode" "DI") | |
7098 | (set_attr_alternative "length" | |
0ff83799 | 7099 | [(const_int 4) |
2bcb2ab3 | 7100 | (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "") |
0ff83799 MM |
7101 | (const_int 4) |
7102 | (const_int 8))])]) | |
2bcb2ab3 GK |
7103 | |
7104 | ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts. | |
bb621ad7 | 7105 | |
2bcb2ab3 GK |
7106 | (define_split |
7107 | [(set (match_operand:DI 0 "register_operand" "") | |
7108 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
7109 | (match_operand:SI 2 "const_int_operand" "")))] | |
2ca2d9ee | 7110 | "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
7111 | && reload_completed |
7112 | && GET_CODE (operands[2]) == CONST_INT | |
7113 | && INTVAL (operands[2]) > 8 | |
7114 | && INTVAL (operands[2]) <= 16" | |
7115 | [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8))) | |
7116 | (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))] | |
7117 | " | |
7118 | { | |
7119 | operands[2] = GEN_INT (INTVAL (operands[2]) - 8); | |
7120 | }") | |
7121 | ||
7122 | (define_expand "lshrsi3" | |
8ef30996 MM |
7123 | [(set (match_operand:SI 0 "register_operand" "=d") |
7124 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") | |
7125 | (match_operand:SI 2 "arith_operand" "dI")))] | |
7126 | "" | |
2bcb2ab3 GK |
7127 | " |
7128 | { | |
7129 | /* On the mips16, a shift of more than 8 is a four byte instruction, | |
7130 | so, for a shift between 8 and 16, it is just as fast to do two | |
7131 | shifts of 8 or less. If there is a lot of shifting going on, we | |
7132 | may win in CSE. Otherwise combine will put the shifts back | |
7133 | together again. */ | |
7134 | if (TARGET_MIPS16 | |
7135 | && optimize | |
7136 | && GET_CODE (operands[2]) == CONST_INT | |
7137 | && INTVAL (operands[2]) > 8 | |
7138 | && INTVAL (operands[2]) <= 16) | |
7139 | { | |
7140 | rtx temp = gen_reg_rtx (SImode); | |
7141 | ||
7142 | emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8))); | |
7143 | emit_insn (gen_lshrsi3_internal2 (operands[0], temp, | |
7144 | GEN_INT (INTVAL (operands[2]) - 8))); | |
7145 | DONE; | |
7146 | } | |
7147 | }") | |
7148 | ||
7149 | (define_insn "lshrsi3_internal1" | |
7150 | [(set (match_operand:SI 0 "register_operand" "=d") | |
7151 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") | |
7152 | (match_operand:SI 2 "arith_operand" "dI")))] | |
7153 | "!TARGET_MIPS16" | |
8ef30996 MM |
7154 | "* |
7155 | { | |
7156 | if (GET_CODE (operands[2]) == CONST_INT) | |
95936d18 | 7157 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); |
8ef30996 MM |
7158 | |
7159 | return \"srl\\t%0,%1,%2\"; | |
7160 | }" | |
7161 | [(set_attr "type" "arith") | |
0ff83799 | 7162 | (set_attr "mode" "SI")]) |
8ef30996 | 7163 | |
2bcb2ab3 GK |
7164 | (define_insn "lshrsi3_internal2" |
7165 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
7166 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d") | |
7167 | (match_operand:SI 2 "arith_operand" "d,I")))] | |
7168 | "TARGET_MIPS16" | |
7169 | "* | |
7170 | { | |
7171 | if (which_alternative == 0) | |
7172 | return \"srl\\t%0,%2\"; | |
7173 | ||
7174 | if (GET_CODE (operands[2]) == CONST_INT) | |
95936d18 | 7175 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); |
2bcb2ab3 GK |
7176 | |
7177 | return \"srl\\t%0,%1,%2\"; | |
7178 | }" | |
7179 | [(set_attr "type" "arith") | |
7180 | (set_attr "mode" "SI") | |
7181 | (set_attr_alternative "length" | |
0ff83799 | 7182 | [(const_int 4) |
2bcb2ab3 | 7183 | (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "") |
0ff83799 MM |
7184 | (const_int 4) |
7185 | (const_int 8))])]) | |
2bcb2ab3 GK |
7186 | |
7187 | ||
7188 | ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts. | |
7189 | ||
7190 | (define_split | |
7191 | [(set (match_operand:SI 0 "register_operand" "") | |
7192 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "") | |
7193 | (match_operand:SI 2 "const_int_operand" "")))] | |
2ca2d9ee | 7194 | "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
7195 | && GET_CODE (operands[2]) == CONST_INT |
7196 | && INTVAL (operands[2]) > 8 | |
7197 | && INTVAL (operands[2]) <= 16" | |
7198 | [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8))) | |
7199 | (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))] | |
7200 | " | |
7201 | { | |
7202 | operands[2] = GEN_INT (INTVAL (operands[2]) - 8); | |
7203 | }") | |
7204 | ||
7205 | ;; If we load a byte on the mips16 as a bitfield, the resulting | |
7206 | ;; sequence of instructions is too complicated for combine, because it | |
7207 | ;; involves four instructions: a load, a shift, a constant load into a | |
7208 | ;; register, and an and (the key problem here is that the mips16 does | |
7209 | ;; not have and immediate). We recognize a shift of a load in order | |
7210 | ;; to make it simple enough for combine to understand. | |
7211 | ||
cafe096b | 7212 | ;; ??? FIXME: turn into a define_insn_and_split |
2bcb2ab3 | 7213 | (define_insn "" |
cafe096b EC |
7214 | [(set (match_operand:SI 0 "register_operand" "=d") |
7215 | (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") | |
7216 | (match_operand:SI 2 "immediate_operand" "I")))] | |
7217 | "0 && TARGET_MIPS16" | |
2bcb2ab3 GK |
7218 | "lw\\t%0,%1\;srl\\t%0,%2" |
7219 | [(set_attr "type" "load") | |
7220 | (set_attr "mode" "SI") | |
7221 | (set_attr_alternative "length" | |
7222 | [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "") | |
0ff83799 MM |
7223 | (const_int 12) |
7224 | (const_int 16))])]) | |
2bcb2ab3 GK |
7225 | |
7226 | (define_split | |
7227 | [(set (match_operand:SI 0 "register_operand" "") | |
7228 | (lshiftrt:SI (match_operand:SI 1 "memory_operand" "") | |
7229 | (match_operand:SI 2 "immediate_operand" "")))] | |
2ca2d9ee | 7230 | "TARGET_MIPS16 && !TARGET_DEBUG_D_MODE" |
2bcb2ab3 GK |
7231 | [(set (match_dup 0) (match_dup 1)) |
7232 | (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))] | |
7233 | "") | |
8ef30996 MM |
7234 | |
7235 | (define_expand "lshrdi3" | |
7236 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
cafe096b | 7237 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") |
8ef30996 MM |
7238 | (match_operand:SI 2 "arith_operand" ""))) |
7239 | (clobber (match_dup 3))])] | |
2bcb2ab3 | 7240 | "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)" |
bb621ad7 JW |
7241 | " |
7242 | { | |
7243 | if (TARGET_64BIT) | |
7244 | { | |
2bcb2ab3 GK |
7245 | /* On the mips16, a shift of more than 8 is a four byte |
7246 | instruction, so, for a shift between 8 and 16, it is just as | |
7247 | fast to do two shifts of 8 or less. If there is a lot of | |
7248 | shifting going on, we may win in CSE. Otherwise combine will | |
7249 | put the shifts back together again. */ | |
7250 | if (TARGET_MIPS16 | |
7251 | && optimize | |
7252 | && GET_CODE (operands[2]) == CONST_INT | |
7253 | && INTVAL (operands[2]) > 8 | |
7254 | && INTVAL (operands[2]) <= 16) | |
7255 | { | |
7256 | rtx temp = gen_reg_rtx (DImode); | |
7257 | ||
7258 | emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8))); | |
7259 | emit_insn (gen_lshrdi3_internal4 (operands[0], temp, | |
7260 | GEN_INT (INTVAL (operands[2]) - 8))); | |
7261 | DONE; | |
7262 | } | |
7263 | ||
bb621ad7 JW |
7264 | emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1], |
7265 | operands[2])); | |
7266 | DONE; | |
7267 | } | |
7268 | ||
7269 | operands[3] = gen_reg_rtx (SImode); | |
7270 | }") | |
8ef30996 MM |
7271 | |
7272 | ||
7273 | (define_insn "lshrdi3_internal" | |
7274 | [(set (match_operand:DI 0 "register_operand" "=&d") | |
7275 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") | |
7276 | (match_operand:SI 2 "register_operand" "d"))) | |
7277 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2bcb2ab3 | 7278 | "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16" |
7a38df19 | 7279 | "* |
8ef30996 MM |
7280 | { |
7281 | operands[4] = const0_rtx; | |
7282 | dslots_jump_total += 3; | |
7283 | dslots_jump_filled += 2; | |
7284 | ||
7285 | return \"sll\\t%3,%2,26\\n\\ | |
7286 | \\tbgez\\t%3,1f\\n\\ | |
7287 | \\tsrl\\t%L0,%M1,%2\\n\\ | |
7288 | \\t%(b\\t3f\\n\\ | |
7289 | \\tmove\\t%M0,%z4%)\\n\\ | |
7290 | \\n\\ | |
efa3896a | 7291 | %~1:\\n\\ |
8ef30996 MM |
7292 | \\t%(beq\\t%3,%z4,2f\\n\\ |
7293 | \\tsrl\\t%L0,%L1,%2%)\\n\\ | |
7294 | \\n\\ | |
7295 | \\tsubu\\t%3,%z4,%2\\n\\ | |
7296 | \\tsll\\t%3,%M1,%3\\n\\ | |
7297 | \\tor\\t%L0,%L0,%3\\n\\ | |
efa3896a | 7298 | %~2:\\n\\ |
8ef30996 | 7299 | \\tsrl\\t%M0,%M1,%2\\n\\ |
efa3896a | 7300 | %~3:\"; |
8ef30996 MM |
7301 | }" |
7302 | [(set_attr "type" "darith") | |
7303 | (set_attr "mode" "DI") | |
0ff83799 | 7304 | (set_attr "length" "48")]) |
8ef30996 MM |
7305 | |
7306 | ||
7307 | (define_insn "lshrdi3_internal2" | |
7308 | [(set (match_operand:DI 0 "register_operand" "=d") | |
7309 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") | |
7310 | (match_operand:SI 2 "small_int" "IJK"))) | |
7311 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2bcb2ab3 GK |
7312 | "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 |
7313 | && (INTVAL (operands[2]) & 32) != 0" | |
8ef30996 MM |
7314 | "* |
7315 | { | |
95936d18 | 7316 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); |
8ef30996 MM |
7317 | operands[4] = const0_rtx; |
7318 | return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\"; | |
7319 | }" | |
7320 | [(set_attr "type" "darith") | |
7321 | (set_attr "mode" "DI") | |
0ff83799 | 7322 | (set_attr "length" "8")]) |
8ef30996 MM |
7323 | |
7324 | ||
7325 | (define_split | |
7326 | [(set (match_operand:DI 0 "register_operand" "") | |
7327 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
7328 | (match_operand:SI 2 "small_int" ""))) | |
7329 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
7330 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT |
7331 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
7332 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
7333 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
7334 | && (INTVAL (operands[2]) & 32) != 0" | |
7335 | ||
ddef6bc7 JJ |
7336 | [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2))) |
7337 | (set (subreg:SI (match_dup 0) 4) (const_int 0))] | |
8ef30996 | 7338 | |
95936d18 | 7339 | "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);") |
8ef30996 MM |
7340 | |
7341 | ||
7342 | (define_split | |
7343 | [(set (match_operand:DI 0 "register_operand" "") | |
7344 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
7345 | (match_operand:SI 2 "small_int" ""))) | |
7346 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
7347 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT |
7348 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
7349 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
7350 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
7351 | && (INTVAL (operands[2]) & 32) != 0" | |
7352 | ||
ddef6bc7 | 7353 | [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2))) |
8ef30996 MM |
7354 | (set (subreg:SI (match_dup 0) 0) (const_int 0))] |
7355 | ||
95936d18 | 7356 | "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);") |
8ef30996 MM |
7357 | |
7358 | ||
7359 | (define_insn "lshrdi3_internal3" | |
7360 | [(set (match_operand:DI 0 "register_operand" "=d") | |
7361 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") | |
7362 | (match_operand:SI 2 "small_int" "IJK"))) | |
7363 | (clobber (match_operand:SI 3 "register_operand" "=d"))] | |
2bcb2ab3 | 7364 | "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 |
8ef30996 MM |
7365 | && (INTVAL (operands[2]) & 63) < 32 |
7366 | && (INTVAL (operands[2]) & 63) != 0" | |
7367 | "* | |
7368 | { | |
7369 | int amount = INTVAL (operands[2]); | |
7370 | ||
c5c76735 JL |
7371 | operands[2] = GEN_INT (amount & 31); |
7372 | operands[4] = GEN_INT ((-amount) & 31); | |
8ef30996 MM |
7373 | |
7374 | return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\"; | |
7375 | }" | |
7376 | [(set_attr "type" "darith") | |
7377 | (set_attr "mode" "DI") | |
0ff83799 | 7378 | (set_attr "length" "16")]) |
8ef30996 MM |
7379 | |
7380 | ||
7381 | (define_split | |
7382 | [(set (match_operand:DI 0 "register_operand" "") | |
7383 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
7384 | (match_operand:SI 2 "small_int" ""))) | |
7385 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
7386 | "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT |
7387 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
7388 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
7389 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
7390 | && (INTVAL (operands[2]) & 63) < 32 | |
7391 | && (INTVAL (operands[2]) & 63) != 0" | |
7392 | ||
7393 | [(set (subreg:SI (match_dup 0) 0) | |
7394 | (lshiftrt:SI (subreg:SI (match_dup 1) 0) | |
7395 | (match_dup 2))) | |
7396 | ||
7397 | (set (match_dup 3) | |
ddef6bc7 | 7398 | (ashift:SI (subreg:SI (match_dup 1) 4) |
8ef30996 MM |
7399 | (match_dup 4))) |
7400 | ||
7401 | (set (subreg:SI (match_dup 0) 0) | |
7402 | (ior:SI (subreg:SI (match_dup 0) 0) | |
7403 | (match_dup 3))) | |
7404 | ||
ddef6bc7 JJ |
7405 | (set (subreg:SI (match_dup 0) 4) |
7406 | (lshiftrt:SI (subreg:SI (match_dup 1) 4) | |
8ef30996 MM |
7407 | (match_dup 2)))] |
7408 | " | |
7409 | { | |
7410 | int amount = INTVAL (operands[2]); | |
c5c76735 JL |
7411 | operands[2] = GEN_INT (amount & 31); |
7412 | operands[4] = GEN_INT ((-amount) & 31); | |
8ef30996 MM |
7413 | }") |
7414 | ||
7415 | ||
7416 | (define_split | |
7417 | [(set (match_operand:DI 0 "register_operand" "") | |
7418 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
7419 | (match_operand:SI 2 "small_int" ""))) | |
7420 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
2bcb2ab3 GK |
7421 | "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT |
7422 | && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 | |
8ef30996 MM |
7423 | && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER |
7424 | && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
7425 | && (INTVAL (operands[2]) & 63) < 32 | |
7426 | && (INTVAL (operands[2]) & 63) != 0" | |
7427 | ||
ddef6bc7 JJ |
7428 | [(set (subreg:SI (match_dup 0) 4) |
7429 | (lshiftrt:SI (subreg:SI (match_dup 1) 4) | |
8ef30996 MM |
7430 | (match_dup 2))) |
7431 | ||
7432 | (set (match_dup 3) | |
7433 | (ashift:SI (subreg:SI (match_dup 1) 0) | |
7434 | (match_dup 4))) | |
7435 | ||
ddef6bc7 JJ |
7436 | (set (subreg:SI (match_dup 0) 4) |
7437 | (ior:SI (subreg:SI (match_dup 0) 4) | |
8ef30996 MM |
7438 | (match_dup 3))) |
7439 | ||
7440 | (set (subreg:SI (match_dup 0) 0) | |
7441 | (lshiftrt:SI (subreg:SI (match_dup 1) 0) | |
7442 | (match_dup 2)))] | |
7443 | " | |
7444 | { | |
7445 | int amount = INTVAL (operands[2]); | |
c5c76735 JL |
7446 | operands[2] = GEN_INT (amount & 31); |
7447 | operands[4] = GEN_INT ((-amount) & 31); | |
8ef30996 MM |
7448 | }") |
7449 | ||
bb621ad7 JW |
7450 | |
7451 | (define_insn "lshrdi3_internal4" | |
7452 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b | 7453 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") |
bb621ad7 | 7454 | (match_operand:SI 2 "arith_operand" "dI")))] |
2bcb2ab3 | 7455 | "TARGET_64BIT && !TARGET_MIPS16" |
bb621ad7 JW |
7456 | "* |
7457 | { | |
7458 | if (GET_CODE (operands[2]) == CONST_INT) | |
7459 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); | |
7460 | ||
7461 | return \"dsrl\\t%0,%1,%2\"; | |
7462 | }" | |
7463 | [(set_attr "type" "arith") | |
0ff83799 | 7464 | (set_attr "mode" "DI")]) |
bb621ad7 | 7465 | |
2bcb2ab3 GK |
7466 | (define_insn "" |
7467 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
cafe096b | 7468 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0") |
2bcb2ab3 GK |
7469 | (match_operand:SI 2 "arith_operand" "d,I")))] |
7470 | "TARGET_64BIT && TARGET_MIPS16" | |
7471 | "* | |
7472 | { | |
7473 | if (GET_CODE (operands[2]) == CONST_INT) | |
7474 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); | |
7475 | ||
7476 | return \"dsrl\\t%0,%2\"; | |
7477 | }" | |
7478 | [(set_attr "type" "arith") | |
7479 | (set_attr "mode" "DI") | |
7480 | (set_attr_alternative "length" | |
0ff83799 | 7481 | [(const_int 4) |
2bcb2ab3 | 7482 | (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "") |
0ff83799 MM |
7483 | (const_int 4) |
7484 | (const_int 8))])]) | |
2bcb2ab3 | 7485 | |
5ce6f47b EC |
7486 | (define_insn "rotrsi3" |
7487 | [(set (match_operand:SI 0 "register_operand" "=d") | |
7488 | (rotatert:SI (match_operand:SI 1 "register_operand" "d") | |
7489 | (match_operand:SI 2 "arith_operand" "dn")))] | |
7490 | "ISA_HAS_ROTR_SI" | |
7491 | "* | |
7492 | { | |
7493 | if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT) | |
7494 | return \"rorv\\t%0,%1,%2\"; | |
7495 | ||
7496 | if ((GET_CODE (operands[2]) == CONST_INT) | |
7497 | && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32)) | |
7498 | abort (); | |
7499 | ||
7500 | return \"ror\\t%0,%1,%2\"; | |
7501 | }" | |
7502 | [(set_attr "type" "arith") | |
7503 | (set_attr "mode" "SI")]) | |
7504 | ||
7505 | (define_insn "rotrdi3" | |
7506 | [(set (match_operand:DI 0 "register_operand" "=d") | |
7507 | (rotatert:DI (match_operand:DI 1 "register_operand" "d") | |
7508 | (match_operand:DI 2 "arith_operand" "dn")))] | |
7509 | "ISA_HAS_ROTR_DI" | |
7510 | "* | |
7511 | { | |
7512 | if (TARGET_SR71K) | |
7513 | { | |
7514 | if (GET_CODE (operands[2]) != CONST_INT) | |
7515 | return \"drorv\\t%0,%1,%2\"; | |
7516 | ||
7517 | if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63) | |
7518 | return \"dror32\\t%0,%1,%2\"; | |
7519 | } | |
7520 | ||
7521 | if ((GET_CODE (operands[2]) == CONST_INT) | |
7522 | && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64)) | |
7523 | abort (); | |
7524 | ||
7525 | return \"dror\\t%0,%1,%2\"; | |
7526 | }" | |
7527 | [(set_attr "type" "arith") | |
7528 | (set_attr "mode" "DI")]) | |
7529 | ||
7530 | ||
2bcb2ab3 GK |
7531 | ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts. |
7532 | ||
7533 | (define_split | |
7534 | [(set (match_operand:DI 0 "register_operand" "") | |
7535 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
7536 | (match_operand:SI 2 "const_int_operand" "")))] | |
2ca2d9ee | 7537 | "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE |
2bcb2ab3 GK |
7538 | && GET_CODE (operands[2]) == CONST_INT |
7539 | && INTVAL (operands[2]) > 8 | |
7540 | && INTVAL (operands[2]) <= 16" | |
7541 | [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8))) | |
7542 | (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))] | |
7543 | " | |
7544 | { | |
7545 | operands[2] = GEN_INT (INTVAL (operands[2]) - 8); | |
7546 | }") | |
7547 | ||
8ef30996 MM |
7548 | \f |
7549 | ;; | |
7550 | ;; .................... | |
7551 | ;; | |
7552 | ;; COMPARISONS | |
7553 | ;; | |
7554 | ;; .................... | |
7555 | ||
7556 | ;; Flow here is rather complex: | |
7557 | ;; | |
bb621ad7 | 7558 | ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the |
8ef30996 MM |
7559 | ;; arguments into the branch_cmp array, and the type into |
7560 | ;; branch_type. No RTL is generated. | |
7561 | ;; | |
7562 | ;; 2) The appropriate branch define_expand is called, which then | |
7563 | ;; creates the appropriate RTL for the comparison and branch. | |
7564 | ;; Different CC modes are used, based on what type of branch is | |
7565 | ;; done, so that we can constrain things appropriately. There | |
7566 | ;; are assumptions in the rest of GCC that break if we fold the | |
7567 | ;; operands into the branchs for integer operations, and use cc0 | |
34b650b3 MM |
7568 | ;; for floating point, so we use the fp status register instead. |
7569 | ;; If needed, an appropriate temporary is created to hold the | |
7570 | ;; of the integer compare. | |
8ef30996 MM |
7571 | |
7572 | (define_expand "cmpsi" | |
7573 | [(set (cc0) | |
7574 | (compare:CC (match_operand:SI 0 "register_operand" "") | |
7575 | (match_operand:SI 1 "arith_operand" "")))] | |
7576 | "" | |
7577 | " | |
7578 | { | |
7579 | if (operands[0]) /* avoid unused code message */ | |
7580 | { | |
7581 | branch_cmp[0] = operands[0]; | |
7582 | branch_cmp[1] = operands[1]; | |
7583 | branch_type = CMP_SI; | |
7584 | DONE; | |
7585 | } | |
7586 | }") | |
7587 | ||
7588 | (define_expand "tstsi" | |
7589 | [(set (cc0) | |
7590 | (match_operand:SI 0 "register_operand" ""))] | |
7591 | "" | |
7592 | " | |
7593 | { | |
7594 | if (operands[0]) /* avoid unused code message */ | |
7595 | { | |
7596 | branch_cmp[0] = operands[0]; | |
7597 | branch_cmp[1] = const0_rtx; | |
7598 | branch_type = CMP_SI; | |
7599 | DONE; | |
7600 | } | |
7601 | }") | |
7602 | ||
bb621ad7 JW |
7603 | (define_expand "cmpdi" |
7604 | [(set (cc0) | |
cafe096b EC |
7605 | (compare:CC (match_operand:DI 0 "register_operand" "") |
7606 | (match_operand:DI 1 "arith_operand" "")))] | |
bb621ad7 JW |
7607 | "TARGET_64BIT" |
7608 | " | |
7609 | { | |
7610 | if (operands[0]) /* avoid unused code message */ | |
7611 | { | |
7612 | branch_cmp[0] = operands[0]; | |
7613 | branch_cmp[1] = operands[1]; | |
7614 | branch_type = CMP_DI; | |
7615 | DONE; | |
7616 | } | |
7617 | }") | |
7618 | ||
7619 | (define_expand "tstdi" | |
7620 | [(set (cc0) | |
cafe096b | 7621 | (match_operand:DI 0 "register_operand" ""))] |
bb621ad7 JW |
7622 | "TARGET_64BIT" |
7623 | " | |
7624 | { | |
7625 | if (operands[0]) /* avoid unused code message */ | |
7626 | { | |
7627 | branch_cmp[0] = operands[0]; | |
7628 | branch_cmp[1] = const0_rtx; | |
7629 | branch_type = CMP_DI; | |
7630 | DONE; | |
7631 | } | |
7632 | }") | |
7633 | ||
8ef30996 MM |
7634 | (define_expand "cmpdf" |
7635 | [(set (cc0) | |
b8eb88d0 ILT |
7636 | (compare:CC (match_operand:DF 0 "register_operand" "") |
7637 | (match_operand:DF 1 "register_operand" "")))] | |
46299de9 | 7638 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
8ef30996 MM |
7639 | " |
7640 | { | |
7641 | if (operands[0]) /* avoid unused code message */ | |
7642 | { | |
7643 | branch_cmp[0] = operands[0]; | |
7644 | branch_cmp[1] = operands[1]; | |
7645 | branch_type = CMP_DF; | |
7646 | DONE; | |
7647 | } | |
7648 | }") | |
7649 | ||
8ef30996 MM |
7650 | (define_expand "cmpsf" |
7651 | [(set (cc0) | |
b8eb88d0 ILT |
7652 | (compare:CC (match_operand:SF 0 "register_operand" "") |
7653 | (match_operand:SF 1 "register_operand" "")))] | |
8ef30996 MM |
7654 | "TARGET_HARD_FLOAT" |
7655 | " | |
7656 | { | |
7657 | if (operands[0]) /* avoid unused code message */ | |
7658 | { | |
7659 | branch_cmp[0] = operands[0]; | |
7660 | branch_cmp[1] = operands[1]; | |
7661 | branch_type = CMP_SF; | |
7662 | DONE; | |
7663 | } | |
7664 | }") | |
7665 | ||
8ef30996 MM |
7666 | \f |
7667 | ;; | |
7668 | ;; .................... | |
7669 | ;; | |
7670 | ;; CONDITIONAL BRANCHES | |
7671 | ;; | |
7672 | ;; .................... | |
7673 | ||
0ff83799 MM |
7674 | ;; Conditional branches on floating-point equality tests. |
7675 | ||
7676 | (define_insn "branch_fp" | |
8ef30996 | 7677 | [(set (pc) |
7a38df19 | 7678 | (if_then_else |
0ff83799 MM |
7679 | (match_operator:CC 0 "cmp_op" |
7680 | [(match_operand:CC 2 "register_operand" "z") | |
7681 | (const_int 0)]) | |
7682 | (label_ref (match_operand 1 "" "")) | |
7683 | (pc)))] | |
bb621ad7 | 7684 | "TARGET_HARD_FLOAT" |
8ef30996 MM |
7685 | "* |
7686 | { | |
0ff83799 MM |
7687 | return mips_output_conditional_branch (insn, |
7688 | operands, | |
7689 | /*two_operands_p=*/0, | |
7690 | /*float_p=*/1, | |
7691 | /*inverted_p=*/0, | |
7692 | get_attr_length (insn)); | |
8ef30996 MM |
7693 | }" |
7694 | [(set_attr "type" "branch") | |
0ff83799 | 7695 | (set_attr "mode" "none")]) |
8ef30996 | 7696 | |
0ff83799 | 7697 | (define_insn "branch_fp_inverted" |
8ef30996 | 7698 | [(set (pc) |
7a38df19 | 7699 | (if_then_else |
0ff83799 MM |
7700 | (match_operator:CC 0 "cmp_op" |
7701 | [(match_operand:CC 2 "register_operand" "z") | |
7702 | (const_int 0)]) | |
7703 | (pc) | |
7704 | (label_ref (match_operand 1 "" ""))))] | |
bb621ad7 | 7705 | "TARGET_HARD_FLOAT" |
8ef30996 MM |
7706 | "* |
7707 | { | |
0ff83799 MM |
7708 | return mips_output_conditional_branch (insn, |
7709 | operands, | |
7710 | /*two_operands_p=*/0, | |
7711 | /*float_p=*/1, | |
7712 | /*inverted_p=*/1, | |
7713 | get_attr_length (insn)); | |
8ef30996 MM |
7714 | }" |
7715 | [(set_attr "type" "branch") | |
0ff83799 MM |
7716 | (set_attr "mode" "none")]) |
7717 | ||
7718 | ;; Conditional branches on comparisons with zero. | |
8ef30996 | 7719 | |
34b650b3 | 7720 | (define_insn "branch_zero" |
8ef30996 | 7721 | [(set (pc) |
7a38df19 | 7722 | (if_then_else |
0ff83799 MM |
7723 | (match_operator:SI 0 "cmp_op" |
7724 | [(match_operand:SI 2 "register_operand" "d") | |
7725 | (const_int 0)]) | |
7726 | (label_ref (match_operand 1 "" "")) | |
7727 | (pc)))] | |
2bcb2ab3 | 7728 | "!TARGET_MIPS16" |
8ef30996 MM |
7729 | "* |
7730 | { | |
0ff83799 MM |
7731 | return mips_output_conditional_branch (insn, |
7732 | operands, | |
7733 | /*two_operands_p=*/0, | |
7734 | /*float_p=*/0, | |
7735 | /*inverted_p=*/0, | |
7736 | get_attr_length (insn)); | |
7737 | }" | |
7738 | [(set_attr "type" "branch") | |
7739 | (set_attr "mode" "none")]) | |
8ef30996 | 7740 | |
0ff83799 MM |
7741 | (define_insn "branch_zero_inverted" |
7742 | [(set (pc) | |
7a38df19 | 7743 | (if_then_else |
0ff83799 MM |
7744 | (match_operator:SI 0 "cmp_op" |
7745 | [(match_operand:SI 2 "register_operand" "d") | |
7746 | (const_int 0)]) | |
7747 | (pc) | |
7748 | (label_ref (match_operand 1 "" ""))))] | |
7749 | "!TARGET_MIPS16" | |
7750 | "* | |
7751 | { | |
7752 | return mips_output_conditional_branch (insn, | |
7753 | operands, | |
7754 | /*two_operands_p=*/0, | |
7755 | /*float_p=*/0, | |
7756 | /*inverted_p=*/1, | |
7757 | get_attr_length (insn)); | |
7758 | }" | |
7759 | [(set_attr "type" "branch") | |
7760 | (set_attr "mode" "none")]) | |
8ef30996 | 7761 | |
0ff83799 MM |
7762 | (define_insn "branch_zero_di" |
7763 | [(set (pc) | |
7a38df19 | 7764 | (if_then_else |
0ff83799 | 7765 | (match_operator:DI 0 "cmp_op" |
cafe096b | 7766 | [(match_operand:DI 2 "register_operand" "d") |
0ff83799 MM |
7767 | (const_int 0)]) |
7768 | (label_ref (match_operand 1 "" "")) | |
7769 | (pc)))] | |
7770 | "!TARGET_MIPS16" | |
7771 | "* | |
7772 | { | |
7773 | return mips_output_conditional_branch (insn, | |
7774 | operands, | |
7775 | /*two_operands_p=*/0, | |
7776 | /*float_p=*/0, | |
7777 | /*inverted_p=*/0, | |
7778 | get_attr_length (insn)); | |
8ef30996 MM |
7779 | }" |
7780 | [(set_attr "type" "branch") | |
0ff83799 MM |
7781 | (set_attr "mode" "none")]) |
7782 | ||
7783 | (define_insn "branch_zero_di_inverted" | |
7784 | [(set (pc) | |
7a38df19 | 7785 | (if_then_else |
0ff83799 | 7786 | (match_operator:DI 0 "cmp_op" |
cafe096b | 7787 | [(match_operand:DI 2 "register_operand" "d") |
0ff83799 MM |
7788 | (const_int 0)]) |
7789 | (pc) | |
7790 | (label_ref (match_operand 1 "" ""))))] | |
7791 | "!TARGET_MIPS16" | |
7792 | "* | |
7793 | { | |
7794 | return mips_output_conditional_branch (insn, | |
7795 | operands, | |
7796 | /*two_operands_p=*/0, | |
7797 | /*float_p=*/0, | |
7798 | /*inverted_p=*/1, | |
7799 | get_attr_length (insn)); | |
7800 | }" | |
7801 | [(set_attr "type" "branch") | |
7802 | (set_attr "mode" "none")]) | |
7803 | ||
7804 | ;; Conditional branch on equality comparision. | |
7805 | ||
7806 | (define_insn "branch_equality" | |
7807 | [(set (pc) | |
7a38df19 | 7808 | (if_then_else |
0ff83799 MM |
7809 | (match_operator:SI 0 "equality_op" |
7810 | [(match_operand:SI 2 "register_operand" "d") | |
7811 | (match_operand:SI 3 "register_operand" "d")]) | |
7812 | (label_ref (match_operand 1 "" "")) | |
7813 | (pc)))] | |
7814 | "!TARGET_MIPS16" | |
7815 | "* | |
7816 | { | |
7817 | return mips_output_conditional_branch (insn, | |
7818 | operands, | |
7819 | /*two_operands_p=*/1, | |
7820 | /*float_p=*/0, | |
7821 | /*inverted_p=*/0, | |
7822 | get_attr_length (insn)); | |
7823 | }" | |
7824 | [(set_attr "type" "branch") | |
7825 | (set_attr "mode" "none")]) | |
7826 | ||
7827 | (define_insn "branch_equality_di" | |
7828 | [(set (pc) | |
7a38df19 | 7829 | (if_then_else |
0ff83799 | 7830 | (match_operator:DI 0 "equality_op" |
cafe096b EC |
7831 | [(match_operand:DI 2 "register_operand" "d") |
7832 | (match_operand:DI 3 "register_operand" "d")]) | |
0ff83799 MM |
7833 | (label_ref (match_operand 1 "" "")) |
7834 | (pc)))] | |
7835 | "!TARGET_MIPS16" | |
7836 | "* | |
7837 | { | |
7838 | return mips_output_conditional_branch (insn, | |
7839 | operands, | |
7840 | /*two_operands_p=*/1, | |
7841 | /*float_p=*/0, | |
7842 | /*inverted_p=*/0, | |
7843 | get_attr_length (insn)); | |
7844 | }" | |
7845 | [(set_attr "type" "branch") | |
7846 | (set_attr "mode" "none")]) | |
7847 | ||
7848 | (define_insn "branch_equality_inverted" | |
7849 | [(set (pc) | |
7a38df19 | 7850 | (if_then_else |
0ff83799 MM |
7851 | (match_operator:SI 0 "equality_op" |
7852 | [(match_operand:SI 2 "register_operand" "d") | |
7853 | (match_operand:SI 3 "register_operand" "d")]) | |
7854 | (pc) | |
7855 | (label_ref (match_operand 1 "" ""))))] | |
7856 | "!TARGET_MIPS16" | |
7857 | "* | |
7858 | { | |
7859 | return mips_output_conditional_branch (insn, | |
7860 | operands, | |
7861 | /*two_operands_p=*/1, | |
7862 | /*float_p=*/0, | |
7863 | /*inverted_p=*/1, | |
7864 | get_attr_length (insn)); | |
7865 | }" | |
7866 | [(set_attr "type" "branch") | |
7867 | (set_attr "mode" "none")]) | |
7868 | ||
7869 | (define_insn "branch_equality_di_inverted" | |
7870 | [(set (pc) | |
7a38df19 | 7871 | (if_then_else |
0ff83799 | 7872 | (match_operator:DI 0 "equality_op" |
cafe096b EC |
7873 | [(match_operand:DI 2 "register_operand" "d") |
7874 | (match_operand:DI 3 "register_operand" "d")]) | |
0ff83799 MM |
7875 | (pc) |
7876 | (label_ref (match_operand 1 "" ""))))] | |
7877 | "!TARGET_MIPS16" | |
7878 | "* | |
7879 | { | |
7880 | return mips_output_conditional_branch (insn, | |
7881 | operands, | |
7882 | /*two_operands_p=*/1, | |
7883 | /*float_p=*/0, | |
7884 | /*inverted_p=*/1, | |
7885 | get_attr_length (insn)); | |
7886 | }" | |
7887 | [(set_attr "type" "branch") | |
7888 | (set_attr "mode" "none")]) | |
8ef30996 | 7889 | |
0ff83799 | 7890 | ;; MIPS16 branches |
8ef30996 | 7891 | |
2bcb2ab3 GK |
7892 | (define_insn "" |
7893 | [(set (pc) | |
7894 | (if_then_else (match_operator:SI 0 "equality_op" | |
7895 | [(match_operand:SI 1 "register_operand" "d,t") | |
7896 | (const_int 0)]) | |
7897 | (match_operand 2 "pc_or_label_operand" "") | |
7898 | (match_operand 3 "pc_or_label_operand" "")))] | |
7899 | "TARGET_MIPS16" | |
7900 | "* | |
7901 | { | |
7902 | if (operands[2] != pc_rtx) | |
7903 | { | |
7904 | if (which_alternative == 0) | |
7905 | return \"%*b%C0z\\t%1,%2\"; | |
7906 | else | |
7907 | return \"%*bt%C0z\\t%2\"; | |
7908 | } | |
7909 | else | |
7910 | { | |
7911 | if (which_alternative == 0) | |
7912 | return \"%*b%N0z\\t%1,%3\"; | |
7913 | else | |
7914 | return \"%*bt%N0z\\t%3\"; | |
7915 | } | |
7916 | }" | |
7917 | [(set_attr "type" "branch") | |
7918 | (set_attr "mode" "none") | |
0ff83799 | 7919 | (set_attr "length" "8")]) |
bb621ad7 | 7920 | |
2bcb2ab3 GK |
7921 | (define_insn "" |
7922 | [(set (pc) | |
7923 | (if_then_else (match_operator:DI 0 "equality_op" | |
cafe096b | 7924 | [(match_operand:DI 1 "register_operand" "d,t") |
2bcb2ab3 GK |
7925 | (const_int 0)]) |
7926 | (match_operand 2 "pc_or_label_operand" "") | |
7927 | (match_operand 3 "pc_or_label_operand" "")))] | |
7928 | "TARGET_MIPS16" | |
7929 | "* | |
7930 | { | |
7931 | if (operands[2] != pc_rtx) | |
7932 | { | |
7933 | if (which_alternative == 0) | |
7934 | return \"%*b%C0z\\t%1,%2\"; | |
7935 | else | |
7936 | return \"%*bt%C0z\\t%2\"; | |
7937 | } | |
7938 | else | |
7939 | { | |
7940 | if (which_alternative == 0) | |
7941 | return \"%*b%N0z\\t%1,%3\"; | |
7942 | else | |
7943 | return \"%*bt%N0z\\t%3\"; | |
7944 | } | |
7945 | }" | |
7946 | [(set_attr "type" "branch") | |
7947 | (set_attr "mode" "none") | |
0ff83799 | 7948 | (set_attr "length" "8")]) |
bb621ad7 | 7949 | |
ce3649d2 EC |
7950 | (define_expand "bunordered" |
7951 | [(set (pc) | |
7952 | (if_then_else (unordered:CC (cc0) | |
7953 | (const_int 0)) | |
7954 | (label_ref (match_operand 0 "" "")) | |
7955 | (pc)))] | |
7956 | "" | |
7957 | " | |
7958 | { | |
7959 | if (operands[0]) /* avoid unused code warning */ | |
7960 | { | |
7961 | gen_conditional_branch (operands, UNORDERED); | |
7962 | DONE; | |
7963 | } | |
7964 | }") | |
7965 | ||
7966 | (define_expand "bordered" | |
7967 | [(set (pc) | |
7968 | (if_then_else (ordered:CC (cc0) | |
7969 | (const_int 0)) | |
7970 | (label_ref (match_operand 0 "" "")) | |
7971 | (pc)))] | |
7972 | "" | |
7973 | " | |
7974 | { | |
7975 | if (operands[0]) /* avoid unused code warning */ | |
7976 | { | |
7977 | gen_conditional_branch (operands, ORDERED); | |
7978 | DONE; | |
7979 | } | |
7980 | }") | |
7981 | ||
ce3649d2 EC |
7982 | (define_expand "bunlt" |
7983 | [(set (pc) | |
7984 | (if_then_else (unlt:CC (cc0) | |
7985 | (const_int 0)) | |
7986 | (label_ref (match_operand 0 "" "")) | |
7987 | (pc)))] | |
7988 | "" | |
7989 | " | |
7990 | { | |
7991 | if (operands[0]) /* avoid unused code warning */ | |
7992 | { | |
7993 | gen_conditional_branch (operands, UNLT); | |
7994 | DONE; | |
7995 | } | |
7996 | }") | |
7997 | ||
8ab907e8 RS |
7998 | (define_expand "bunge" |
7999 | [(set (pc) | |
8000 | (if_then_else (unge:CC (cc0) | |
8001 | (const_int 0)) | |
8002 | (label_ref (match_operand 0 "" "")) | |
8003 | (pc)))] | |
8004 | "" | |
8005 | " | |
8006 | { | |
8007 | gen_conditional_branch (operands, UNGE); | |
8008 | DONE; | |
8009 | }") | |
8010 | ||
ce3649d2 EC |
8011 | (define_expand "buneq" |
8012 | [(set (pc) | |
8013 | (if_then_else (uneq:CC (cc0) | |
8014 | (const_int 0)) | |
8015 | (label_ref (match_operand 0 "" "")) | |
8016 | (pc)))] | |
8017 | "" | |
8018 | " | |
8019 | { | |
8020 | if (operands[0]) /* avoid unused code warning */ | |
8021 | { | |
8022 | gen_conditional_branch (operands, UNEQ); | |
8023 | DONE; | |
8024 | } | |
8025 | }") | |
8026 | ||
8ab907e8 RS |
8027 | (define_expand "bltgt" |
8028 | [(set (pc) | |
8029 | (if_then_else (ltgt:CC (cc0) | |
8030 | (const_int 0)) | |
8031 | (label_ref (match_operand 0 "" "")) | |
8032 | (pc)))] | |
8033 | "" | |
8034 | " | |
8035 | { | |
8036 | gen_conditional_branch (operands, LTGT); | |
8037 | DONE; | |
8038 | }") | |
8039 | ||
ce3649d2 EC |
8040 | (define_expand "bunle" |
8041 | [(set (pc) | |
8042 | (if_then_else (unle:CC (cc0) | |
8043 | (const_int 0)) | |
8044 | (label_ref (match_operand 0 "" "")) | |
8045 | (pc)))] | |
8046 | "" | |
8047 | " | |
8048 | { | |
8049 | if (operands[0]) /* avoid unused code warning */ | |
8050 | { | |
8051 | gen_conditional_branch (operands, UNLE); | |
8052 | DONE; | |
8053 | } | |
8054 | }") | |
8055 | ||
8ab907e8 RS |
8056 | (define_expand "bungt" |
8057 | [(set (pc) | |
8058 | (if_then_else (ungt:CC (cc0) | |
8059 | (const_int 0)) | |
8060 | (label_ref (match_operand 0 "" "")) | |
8061 | (pc)))] | |
8062 | "" | |
8063 | " | |
8064 | { | |
8065 | gen_conditional_branch (operands, UNGT); | |
8066 | DONE; | |
8067 | }") | |
8068 | ||
8ef30996 MM |
8069 | (define_expand "beq" |
8070 | [(set (pc) | |
b8eb88d0 ILT |
8071 | (if_then_else (eq:CC (cc0) |
8072 | (const_int 0)) | |
8ef30996 MM |
8073 | (label_ref (match_operand 0 "" "")) |
8074 | (pc)))] | |
8075 | "" | |
8076 | " | |
8077 | { | |
8078 | if (operands[0]) /* avoid unused code warning */ | |
8079 | { | |
8080 | gen_conditional_branch (operands, EQ); | |
8081 | DONE; | |
8082 | } | |
8083 | }") | |
8084 | ||
8085 | (define_expand "bne" | |
8086 | [(set (pc) | |
b8eb88d0 ILT |
8087 | (if_then_else (ne:CC (cc0) |
8088 | (const_int 0)) | |
8ef30996 MM |
8089 | (label_ref (match_operand 0 "" "")) |
8090 | (pc)))] | |
8091 | "" | |
8092 | " | |
8093 | { | |
8094 | if (operands[0]) /* avoid unused code warning */ | |
8095 | { | |
8096 | gen_conditional_branch (operands, NE); | |
8097 | DONE; | |
8098 | } | |
8099 | }") | |
8100 | ||
8101 | (define_expand "bgt" | |
8102 | [(set (pc) | |
8103 | (if_then_else (gt:CC (cc0) | |
8104 | (const_int 0)) | |
8105 | (label_ref (match_operand 0 "" "")) | |
8106 | (pc)))] | |
8107 | "" | |
8108 | " | |
8109 | { | |
8110 | if (operands[0]) /* avoid unused code warning */ | |
8111 | { | |
8112 | gen_conditional_branch (operands, GT); | |
8113 | DONE; | |
8114 | } | |
8115 | }") | |
8116 | ||
8117 | (define_expand "bge" | |
8118 | [(set (pc) | |
8119 | (if_then_else (ge:CC (cc0) | |
8120 | (const_int 0)) | |
8121 | (label_ref (match_operand 0 "" "")) | |
8122 | (pc)))] | |
8123 | "" | |
8124 | " | |
8125 | { | |
8126 | if (operands[0]) /* avoid unused code warning */ | |
8127 | { | |
8128 | gen_conditional_branch (operands, GE); | |
8129 | DONE; | |
8130 | } | |
8131 | }") | |
8132 | ||
8133 | (define_expand "blt" | |
8134 | [(set (pc) | |
8135 | (if_then_else (lt:CC (cc0) | |
8136 | (const_int 0)) | |
8137 | (label_ref (match_operand 0 "" "")) | |
8138 | (pc)))] | |
8139 | "" | |
8140 | " | |
8141 | { | |
8142 | if (operands[0]) /* avoid unused code warning */ | |
8143 | { | |
8144 | gen_conditional_branch (operands, LT); | |
8145 | DONE; | |
8146 | } | |
8147 | }") | |
8148 | ||
8149 | (define_expand "ble" | |
8150 | [(set (pc) | |
8151 | (if_then_else (le:CC (cc0) | |
8152 | (const_int 0)) | |
8153 | (label_ref (match_operand 0 "" "")) | |
8154 | (pc)))] | |
8155 | "" | |
8156 | " | |
8157 | { | |
8158 | if (operands[0]) /* avoid unused code warning */ | |
8159 | { | |
8160 | gen_conditional_branch (operands, LE); | |
8161 | DONE; | |
8162 | } | |
8163 | }") | |
8164 | ||
8165 | (define_expand "bgtu" | |
8166 | [(set (pc) | |
8167 | (if_then_else (gtu:CC (cc0) | |
8168 | (const_int 0)) | |
8169 | (label_ref (match_operand 0 "" "")) | |
8170 | (pc)))] | |
8171 | "" | |
8172 | " | |
8173 | { | |
8174 | if (operands[0]) /* avoid unused code warning */ | |
8175 | { | |
8176 | gen_conditional_branch (operands, GTU); | |
8177 | DONE; | |
8178 | } | |
8179 | }") | |
8180 | ||
8181 | (define_expand "bgeu" | |
8182 | [(set (pc) | |
8183 | (if_then_else (geu:CC (cc0) | |
8184 | (const_int 0)) | |
8185 | (label_ref (match_operand 0 "" "")) | |
8186 | (pc)))] | |
8187 | "" | |
8188 | " | |
8189 | { | |
8190 | if (operands[0]) /* avoid unused code warning */ | |
8191 | { | |
8192 | gen_conditional_branch (operands, GEU); | |
8193 | DONE; | |
8194 | } | |
8195 | }") | |
8196 | ||
8197 | ||
8198 | (define_expand "bltu" | |
8199 | [(set (pc) | |
8200 | (if_then_else (ltu:CC (cc0) | |
8201 | (const_int 0)) | |
8202 | (label_ref (match_operand 0 "" "")) | |
8203 | (pc)))] | |
8204 | "" | |
8205 | " | |
8206 | { | |
8207 | if (operands[0]) /* avoid unused code warning */ | |
8208 | { | |
8209 | gen_conditional_branch (operands, LTU); | |
8210 | DONE; | |
8211 | } | |
8212 | }") | |
8213 | ||
8214 | (define_expand "bleu" | |
8215 | [(set (pc) | |
8216 | (if_then_else (leu:CC (cc0) | |
8217 | (const_int 0)) | |
8218 | (label_ref (match_operand 0 "" "")) | |
8219 | (pc)))] | |
8220 | "" | |
8221 | " | |
8222 | { | |
8223 | if (operands[0]) /* avoid unused code warning */ | |
8224 | { | |
8225 | gen_conditional_branch (operands, LEU); | |
8226 | DONE; | |
8227 | } | |
8228 | }") | |
8229 | ||
8230 | \f | |
8231 | ;; | |
8232 | ;; .................... | |
8233 | ;; | |
8234 | ;; SETTING A REGISTER FROM A COMPARISON | |
8235 | ;; | |
8236 | ;; .................... | |
8237 | ||
8238 | (define_expand "seq" | |
8239 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 MM |
8240 | (eq:SI (match_dup 1) |
8241 | (match_dup 2)))] | |
8ef30996 MM |
8242 | "" |
8243 | " | |
8244 | { | |
bb621ad7 | 8245 | if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI)) |
8ef30996 MM |
8246 | FAIL; |
8247 | ||
8248 | /* set up operands from compare. */ | |
8249 | operands[1] = branch_cmp[0]; | |
8250 | operands[2] = branch_cmp[1]; | |
8251 | ||
2bcb2ab3 | 8252 | if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16) |
34b650b3 MM |
8253 | { |
8254 | gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0); | |
8255 | DONE; | |
8256 | } | |
8257 | ||
8ef30996 MM |
8258 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) |
8259 | operands[2] = force_reg (SImode, operands[2]); | |
8260 | ||
8261 | /* fall through and generate default code */ | |
8262 | }") | |
8263 | ||
34b650b3 MM |
8264 | |
8265 | (define_insn "seq_si_zero" | |
8266 | [(set (match_operand:SI 0 "register_operand" "=d") | |
8267 | (eq:SI (match_operand:SI 1 "register_operand" "d") | |
8268 | (const_int 0)))] | |
2bcb2ab3 | 8269 | "!TARGET_MIPS16" |
34b650b3 | 8270 | "sltu\\t%0,%1,1" |
bb621ad7 | 8271 | [(set_attr "type" "arith") |
0ff83799 | 8272 | (set_attr "mode" "SI")]) |
34b650b3 | 8273 | |
2bcb2ab3 GK |
8274 | (define_insn "" |
8275 | [(set (match_operand:SI 0 "register_operand" "=t") | |
8276 | (eq:SI (match_operand:SI 1 "register_operand" "d") | |
8277 | (const_int 0)))] | |
8278 | "TARGET_MIPS16" | |
8279 | "sltu\\t%1,1" | |
8280 | [(set_attr "type" "arith") | |
0ff83799 | 8281 | (set_attr "mode" "SI")]) |
2bcb2ab3 | 8282 | |
bb621ad7 JW |
8283 | (define_insn "seq_di_zero" |
8284 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b | 8285 | (eq:DI (match_operand:DI 1 "register_operand" "d") |
bb621ad7 | 8286 | (const_int 0)))] |
2bcb2ab3 | 8287 | "TARGET_64BIT && !TARGET_MIPS16" |
bb621ad7 JW |
8288 | "sltu\\t%0,%1,1" |
8289 | [(set_attr "type" "arith") | |
0ff83799 | 8290 | (set_attr "mode" "DI")]) |
bb621ad7 | 8291 | |
2bcb2ab3 GK |
8292 | (define_insn "" |
8293 | [(set (match_operand:DI 0 "register_operand" "=t") | |
cafe096b | 8294 | (eq:DI (match_operand:DI 1 "register_operand" "d") |
2bcb2ab3 GK |
8295 | (const_int 0)))] |
8296 | "TARGET_64BIT && TARGET_MIPS16" | |
8297 | "sltu\\t%1,1" | |
8298 | [(set_attr "type" "arith") | |
0ff83799 | 8299 | (set_attr "mode" "DI")]) |
2bcb2ab3 | 8300 | |
34b650b3 MM |
8301 | (define_insn "seq_si" |
8302 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
8303 | (eq:SI (match_operand:SI 1 "register_operand" "%d,d") | |
8304 | (match_operand:SI 2 "uns_arith_operand" "d,K")))] | |
2bcb2ab3 | 8305 | "TARGET_DEBUG_C_MODE && !TARGET_MIPS16" |
8ef30996 | 8306 | "@ |
8ef30996 | 8307 | xor\\t%0,%1,%2\;sltu\\t%0,%0,1 |
34b650b3 | 8308 | xori\\t%0,%1,%2\;sltu\\t%0,%0,1" |
bb621ad7 JW |
8309 | [(set_attr "type" "arith") |
8310 | (set_attr "mode" "SI") | |
0ff83799 | 8311 | (set_attr "length" "8")]) |
bb621ad7 JW |
8312 | |
8313 | (define_split | |
8314 | [(set (match_operand:SI 0 "register_operand" "") | |
8315 | (eq:SI (match_operand:SI 1 "register_operand" "") | |
8316 | (match_operand:SI 2 "uns_arith_operand" "")))] | |
2bcb2ab3 | 8317 | "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16 |
bb621ad7 JW |
8318 | && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)" |
8319 | [(set (match_dup 0) | |
8320 | (xor:SI (match_dup 1) | |
8321 | (match_dup 2))) | |
8322 | (set (match_dup 0) | |
8323 | (ltu:SI (match_dup 0) | |
8324 | (const_int 1)))] | |
8325 | "") | |
8326 | ||
8327 | (define_insn "seq_di" | |
8328 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
cafe096b EC |
8329 | (eq:DI (match_operand:DI 1 "register_operand" "%d,d") |
8330 | (match_operand:DI 2 "uns_arith_operand" "d,K")))] | |
2bcb2ab3 | 8331 | "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16" |
bb621ad7 JW |
8332 | "@ |
8333 | xor\\t%0,%1,%2\;sltu\\t%0,%0,1 | |
8334 | xori\\t%0,%1,%2\;sltu\\t%0,%0,1" | |
8335 | [(set_attr "type" "arith") | |
8336 | (set_attr "mode" "DI") | |
0ff83799 | 8337 | (set_attr "length" "8")]) |
8ef30996 MM |
8338 | |
8339 | (define_split | |
bb621ad7 | 8340 | [(set (match_operand:DI 0 "register_operand" "") |
cafe096b EC |
8341 | (eq:DI (match_operand:DI 1 "register_operand" "") |
8342 | (match_operand:DI 2 "uns_arith_operand" "")))] | |
bb621ad7 | 8343 | "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE |
2bcb2ab3 | 8344 | && !TARGET_MIPS16 |
26b8e6e5 | 8345 | && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)" |
8ef30996 | 8346 | [(set (match_dup 0) |
bb621ad7 | 8347 | (xor:DI (match_dup 1) |
8ef30996 MM |
8348 | (match_dup 2))) |
8349 | (set (match_dup 0) | |
bb621ad7 | 8350 | (ltu:DI (match_dup 0) |
8ef30996 MM |
8351 | (const_int 1)))] |
8352 | "") | |
8353 | ||
2bcb2ab3 GK |
8354 | ;; On the mips16 the default code is better than using sltu. |
8355 | ||
8ef30996 MM |
8356 | (define_expand "sne" |
8357 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 MM |
8358 | (ne:SI (match_dup 1) |
8359 | (match_dup 2)))] | |
2bcb2ab3 | 8360 | "!TARGET_MIPS16" |
8ef30996 MM |
8361 | " |
8362 | { | |
bb621ad7 | 8363 | if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI)) |
8ef30996 MM |
8364 | FAIL; |
8365 | ||
8366 | /* set up operands from compare. */ | |
8367 | operands[1] = branch_cmp[0]; | |
8368 | operands[2] = branch_cmp[1]; | |
8369 | ||
bb621ad7 | 8370 | if (TARGET_64BIT || !TARGET_DEBUG_C_MODE) |
34b650b3 MM |
8371 | { |
8372 | gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0); | |
8373 | DONE; | |
8374 | } | |
8375 | ||
8ef30996 MM |
8376 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) |
8377 | operands[2] = force_reg (SImode, operands[2]); | |
8378 | ||
8379 | /* fall through and generate default code */ | |
8380 | }") | |
8381 | ||
34b650b3 MM |
8382 | (define_insn "sne_si_zero" |
8383 | [(set (match_operand:SI 0 "register_operand" "=d") | |
8384 | (ne:SI (match_operand:SI 1 "register_operand" "d") | |
8385 | (const_int 0)))] | |
2bcb2ab3 | 8386 | "!TARGET_MIPS16" |
34b650b3 | 8387 | "sltu\\t%0,%.,%1" |
bb621ad7 | 8388 | [(set_attr "type" "arith") |
0ff83799 | 8389 | (set_attr "mode" "SI")]) |
8ef30996 | 8390 | |
bb621ad7 JW |
8391 | (define_insn "sne_di_zero" |
8392 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b | 8393 | (ne:DI (match_operand:DI 1 "register_operand" "d") |
bb621ad7 | 8394 | (const_int 0)))] |
2bcb2ab3 | 8395 | "TARGET_64BIT && !TARGET_MIPS16" |
bb621ad7 JW |
8396 | "sltu\\t%0,%.,%1" |
8397 | [(set_attr "type" "arith") | |
0ff83799 | 8398 | (set_attr "mode" "DI")]) |
bb621ad7 | 8399 | |
34b650b3 MM |
8400 | (define_insn "sne_si" |
8401 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
8402 | (ne:SI (match_operand:SI 1 "register_operand" "%d,d") | |
8403 | (match_operand:SI 2 "uns_arith_operand" "d,K")))] | |
2bcb2ab3 | 8404 | "TARGET_DEBUG_C_MODE && !TARGET_MIPS16" |
34b650b3 MM |
8405 | "@ |
8406 | xor\\t%0,%1,%2\;sltu\\t%0,%.,%0 | |
8407 | xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0" | |
bb621ad7 | 8408 | [(set_attr "type" "arith") |
92b4cee1 | 8409 | (set_attr "mode" "SI") |
0ff83799 | 8410 | (set_attr "length" "8")]) |
8ef30996 MM |
8411 | |
8412 | (define_split | |
8413 | [(set (match_operand:SI 0 "register_operand" "") | |
34b650b3 MM |
8414 | (ne:SI (match_operand:SI 1 "register_operand" "") |
8415 | (match_operand:SI 2 "uns_arith_operand" "")))] | |
2bcb2ab3 | 8416 | "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16 |
26b8e6e5 | 8417 | && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)" |
8ef30996 MM |
8418 | [(set (match_dup 0) |
8419 | (xor:SI (match_dup 1) | |
8420 | (match_dup 2))) | |
8421 | (set (match_dup 0) | |
34b650b3 | 8422 | (gtu:SI (match_dup 0) |
8ef30996 MM |
8423 | (const_int 0)))] |
8424 | "") | |
8425 | ||
bb621ad7 JW |
8426 | (define_insn "sne_di" |
8427 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
cafe096b EC |
8428 | (ne:DI (match_operand:DI 1 "register_operand" "%d,d") |
8429 | (match_operand:DI 2 "uns_arith_operand" "d,K")))] | |
2bcb2ab3 | 8430 | "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16" |
bb621ad7 JW |
8431 | "@ |
8432 | xor\\t%0,%1,%2\;sltu\\t%0,%.,%0 | |
8433 | xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0" | |
8434 | [(set_attr "type" "arith") | |
8435 | (set_attr "mode" "DI") | |
0ff83799 | 8436 | (set_attr "length" "8")]) |
bb621ad7 JW |
8437 | |
8438 | (define_split | |
8439 | [(set (match_operand:DI 0 "register_operand" "") | |
cafe096b EC |
8440 | (ne:DI (match_operand:DI 1 "register_operand" "") |
8441 | (match_operand:DI 2 "uns_arith_operand" "")))] | |
bb621ad7 | 8442 | "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE |
2bcb2ab3 | 8443 | && !TARGET_MIPS16 |
bb621ad7 JW |
8444 | && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)" |
8445 | [(set (match_dup 0) | |
8446 | (xor:DI (match_dup 1) | |
8447 | (match_dup 2))) | |
8448 | (set (match_dup 0) | |
8449 | (gtu:DI (match_dup 0) | |
8450 | (const_int 0)))] | |
8451 | "") | |
8452 | ||
8ef30996 MM |
8453 | (define_expand "sgt" |
8454 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8455 | (gt:SI (match_dup 1) |
8ef30996 MM |
8456 | (match_dup 2)))] |
8457 | "" | |
8458 | " | |
8459 | { | |
bb621ad7 | 8460 | if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI)) |
8ef30996 MM |
8461 | FAIL; |
8462 | ||
8463 | /* set up operands from compare. */ | |
8464 | operands[1] = branch_cmp[0]; | |
8465 | operands[2] = branch_cmp[1]; | |
8466 | ||
2bcb2ab3 | 8467 | if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16) |
34b650b3 MM |
8468 | { |
8469 | gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0); | |
8470 | DONE; | |
8471 | } | |
8472 | ||
8ef30996 MM |
8473 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0) |
8474 | operands[2] = force_reg (SImode, operands[2]); | |
8475 | ||
8476 | /* fall through and generate default code */ | |
8477 | }") | |
8478 | ||
8479 | (define_insn "sgt_si" | |
8480 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8481 | (gt:SI (match_operand:SI 1 "register_operand" "d") |
8ef30996 | 8482 | (match_operand:SI 2 "reg_or_0_operand" "dJ")))] |
2bcb2ab3 | 8483 | "!TARGET_MIPS16" |
8ef30996 | 8484 | "slt\\t%0,%z2,%1" |
bb621ad7 | 8485 | [(set_attr "type" "arith") |
0ff83799 | 8486 | (set_attr "mode" "SI")]) |
8ef30996 | 8487 | |
2bcb2ab3 GK |
8488 | (define_insn "" |
8489 | [(set (match_operand:SI 0 "register_operand" "=t") | |
8490 | (gt:SI (match_operand:SI 1 "register_operand" "d") | |
8491 | (match_operand:SI 2 "register_operand" "d")))] | |
8492 | "TARGET_MIPS16" | |
8493 | "slt\\t%2,%1" | |
8494 | [(set_attr "type" "arith") | |
0ff83799 | 8495 | (set_attr "mode" "SI")]) |
2bcb2ab3 | 8496 | |
bb621ad7 JW |
8497 | (define_insn "sgt_di" |
8498 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
8499 | (gt:DI (match_operand:DI 1 "register_operand" "d") |
8500 | (match_operand:DI 2 "reg_or_0_operand" "dJ")))] | |
2bcb2ab3 | 8501 | "TARGET_64BIT && !TARGET_MIPS16" |
bb621ad7 JW |
8502 | "slt\\t%0,%z2,%1" |
8503 | [(set_attr "type" "arith") | |
0ff83799 | 8504 | (set_attr "mode" "DI")]) |
bb621ad7 | 8505 | |
2bcb2ab3 GK |
8506 | (define_insn "" |
8507 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
8508 | (gt:DI (match_operand:DI 1 "register_operand" "d") |
8509 | (match_operand:DI 2 "register_operand" "d")))] | |
2bcb2ab3 GK |
8510 | "TARGET_64BIT && TARGET_MIPS16" |
8511 | "slt\\t%2,%1" | |
8512 | [(set_attr "type" "arith") | |
0ff83799 | 8513 | (set_attr "mode" "DI")]) |
2bcb2ab3 | 8514 | |
8ef30996 MM |
8515 | (define_expand "sge" |
8516 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8517 | (ge:SI (match_dup 1) |
8ef30996 MM |
8518 | (match_dup 2)))] |
8519 | "" | |
8520 | " | |
8521 | { | |
bb621ad7 | 8522 | if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI)) |
8ef30996 MM |
8523 | FAIL; |
8524 | ||
8525 | /* set up operands from compare. */ | |
8526 | operands[1] = branch_cmp[0]; | |
8527 | operands[2] = branch_cmp[1]; | |
8528 | ||
2bcb2ab3 | 8529 | if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16) |
34b650b3 MM |
8530 | { |
8531 | gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0); | |
8532 | DONE; | |
8533 | } | |
8534 | ||
8ef30996 MM |
8535 | /* fall through and generate default code */ |
8536 | }") | |
8537 | ||
8538 | (define_insn "sge_si" | |
8539 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8540 | (ge:SI (match_operand:SI 1 "register_operand" "d") |
8ef30996 | 8541 | (match_operand:SI 2 "arith_operand" "dI")))] |
2bcb2ab3 | 8542 | "TARGET_DEBUG_C_MODE && !TARGET_MIPS16" |
8ef30996 | 8543 | "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001" |
bb621ad7 | 8544 | [(set_attr "type" "arith") |
8ef30996 | 8545 | (set_attr "mode" "SI") |
0ff83799 | 8546 | (set_attr "length" "8")]) |
8ef30996 MM |
8547 | |
8548 | (define_split | |
8549 | [(set (match_operand:SI 0 "register_operand" "") | |
34b650b3 | 8550 | (ge:SI (match_operand:SI 1 "register_operand" "") |
8ef30996 | 8551 | (match_operand:SI 2 "arith_operand" "")))] |
2bcb2ab3 | 8552 | "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16" |
8ef30996 | 8553 | [(set (match_dup 0) |
34b650b3 | 8554 | (lt:SI (match_dup 1) |
8ef30996 MM |
8555 | (match_dup 2))) |
8556 | (set (match_dup 0) | |
8557 | (xor:SI (match_dup 0) | |
8558 | (const_int 1)))] | |
8559 | "") | |
8560 | ||
bb621ad7 JW |
8561 | (define_insn "sge_di" |
8562 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
8563 | (ge:DI (match_operand:DI 1 "register_operand" "d") |
8564 | (match_operand:DI 2 "arith_operand" "dI")))] | |
2bcb2ab3 | 8565 | "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16" |
bb621ad7 JW |
8566 | "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001" |
8567 | [(set_attr "type" "arith") | |
8568 | (set_attr "mode" "DI") | |
0ff83799 | 8569 | (set_attr "length" "8")]) |
bb621ad7 JW |
8570 | |
8571 | (define_split | |
8572 | [(set (match_operand:DI 0 "register_operand" "") | |
cafe096b EC |
8573 | (ge:DI (match_operand:DI 1 "register_operand" "") |
8574 | (match_operand:DI 2 "arith_operand" "")))] | |
2bcb2ab3 GK |
8575 | "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE |
8576 | && !TARGET_MIPS16" | |
bb621ad7 JW |
8577 | [(set (match_dup 0) |
8578 | (lt:DI (match_dup 1) | |
8579 | (match_dup 2))) | |
8580 | (set (match_dup 0) | |
8581 | (xor:DI (match_dup 0) | |
8582 | (const_int 1)))] | |
8583 | "") | |
8584 | ||
8ef30996 MM |
8585 | (define_expand "slt" |
8586 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8587 | (lt:SI (match_dup 1) |
8ef30996 MM |
8588 | (match_dup 2)))] |
8589 | "" | |
8590 | " | |
8591 | { | |
bb621ad7 | 8592 | if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI)) |
8ef30996 MM |
8593 | FAIL; |
8594 | ||
8595 | /* set up operands from compare. */ | |
8596 | operands[1] = branch_cmp[0]; | |
8597 | operands[2] = branch_cmp[1]; | |
8598 | ||
2bcb2ab3 | 8599 | if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16) |
34b650b3 MM |
8600 | { |
8601 | gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0); | |
8602 | DONE; | |
8603 | } | |
8604 | ||
8ef30996 MM |
8605 | /* fall through and generate default code */ |
8606 | }") | |
8607 | ||
8608 | (define_insn "slt_si" | |
8609 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8610 | (lt:SI (match_operand:SI 1 "register_operand" "d") |
8ef30996 | 8611 | (match_operand:SI 2 "arith_operand" "dI")))] |
2bcb2ab3 | 8612 | "!TARGET_MIPS16" |
8ef30996 | 8613 | "slt\\t%0,%1,%2" |
bb621ad7 | 8614 | [(set_attr "type" "arith") |
0ff83799 | 8615 | (set_attr "mode" "SI")]) |
8ef30996 | 8616 | |
2bcb2ab3 GK |
8617 | (define_insn "" |
8618 | [(set (match_operand:SI 0 "register_operand" "=t,t") | |
8619 | (lt:SI (match_operand:SI 1 "register_operand" "d,d") | |
8620 | (match_operand:SI 2 "arith_operand" "d,I")))] | |
8621 | "TARGET_MIPS16" | |
8622 | "slt\\t%1,%2" | |
8623 | [(set_attr "type" "arith") | |
8624 | (set_attr "mode" "SI") | |
8625 | (set_attr_alternative "length" | |
0ff83799 | 8626 | [(const_int 4) |
2bcb2ab3 | 8627 | (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "") |
0ff83799 MM |
8628 | (const_int 4) |
8629 | (const_int 8))])]) | |
2bcb2ab3 | 8630 | |
bb621ad7 JW |
8631 | (define_insn "slt_di" |
8632 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
8633 | (lt:DI (match_operand:DI 1 "register_operand" "d") |
8634 | (match_operand:DI 2 "arith_operand" "dI")))] | |
2bcb2ab3 | 8635 | "TARGET_64BIT && !TARGET_MIPS16" |
bb621ad7 JW |
8636 | "slt\\t%0,%1,%2" |
8637 | [(set_attr "type" "arith") | |
0ff83799 | 8638 | (set_attr "mode" "DI")]) |
bb621ad7 | 8639 | |
2bcb2ab3 GK |
8640 | (define_insn "" |
8641 | [(set (match_operand:DI 0 "register_operand" "=t,t") | |
cafe096b EC |
8642 | (lt:DI (match_operand:DI 1 "register_operand" "d,d") |
8643 | (match_operand:DI 2 "arith_operand" "d,I")))] | |
2bcb2ab3 GK |
8644 | "TARGET_64BIT && TARGET_MIPS16" |
8645 | "slt\\t%1,%2" | |
8646 | [(set_attr "type" "arith") | |
8647 | (set_attr "mode" "DI") | |
8648 | (set_attr_alternative "length" | |
0ff83799 | 8649 | [(const_int 4) |
2bcb2ab3 | 8650 | (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "") |
0ff83799 MM |
8651 | (const_int 4) |
8652 | (const_int 8))])]) | |
2bcb2ab3 | 8653 | |
8ef30996 MM |
8654 | (define_expand "sle" |
8655 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8656 | (le:SI (match_dup 1) |
8ef30996 MM |
8657 | (match_dup 2)))] |
8658 | "" | |
8659 | " | |
8660 | { | |
bb621ad7 | 8661 | if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI)) |
8ef30996 MM |
8662 | FAIL; |
8663 | ||
8664 | /* set up operands from compare. */ | |
8665 | operands[1] = branch_cmp[0]; | |
8666 | operands[2] = branch_cmp[1]; | |
8667 | ||
2bcb2ab3 | 8668 | if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16) |
34b650b3 MM |
8669 | { |
8670 | gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0); | |
8671 | DONE; | |
8672 | } | |
8673 | ||
8ef30996 MM |
8674 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767) |
8675 | operands[2] = force_reg (SImode, operands[2]); | |
8676 | ||
8677 | /* fall through and generate default code */ | |
8678 | }") | |
8679 | ||
34b650b3 MM |
8680 | (define_insn "sle_si_const" |
8681 | [(set (match_operand:SI 0 "register_operand" "=d") | |
8682 | (le:SI (match_operand:SI 1 "register_operand" "d") | |
8683 | (match_operand:SI 2 "small_int" "I")))] | |
2bcb2ab3 | 8684 | "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767" |
34b650b3 MM |
8685 | "* |
8686 | { | |
95936d18 | 8687 | operands[2] = GEN_INT (INTVAL (operands[2])+1); |
34b650b3 MM |
8688 | return \"slt\\t%0,%1,%2\"; |
8689 | }" | |
bb621ad7 | 8690 | [(set_attr "type" "arith") |
0ff83799 | 8691 | (set_attr "mode" "SI")]) |
34b650b3 | 8692 | |
2bcb2ab3 GK |
8693 | (define_insn "" |
8694 | [(set (match_operand:SI 0 "register_operand" "=t") | |
8695 | (le:SI (match_operand:SI 1 "register_operand" "d") | |
8696 | (match_operand:SI 2 "small_int" "I")))] | |
8697 | "TARGET_MIPS16 && INTVAL (operands[2]) < 32767" | |
8698 | "* | |
8699 | { | |
95936d18 | 8700 | operands[2] = GEN_INT (INTVAL (operands[2])+1); |
2bcb2ab3 GK |
8701 | return \"slt\\t%1,%2\"; |
8702 | }" | |
8703 | [(set_attr "type" "arith") | |
8704 | (set_attr "mode" "SI") | |
8705 | (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "") | |
0ff83799 MM |
8706 | (const_int 4) |
8707 | (const_int 8)))]) | |
2bcb2ab3 | 8708 | |
bb621ad7 JW |
8709 | (define_insn "sle_di_const" |
8710 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b | 8711 | (le:DI (match_operand:DI 1 "register_operand" "d") |
bb621ad7 | 8712 | (match_operand:DI 2 "small_int" "I")))] |
2bcb2ab3 | 8713 | "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767" |
bb621ad7 JW |
8714 | "* |
8715 | { | |
95936d18 | 8716 | operands[2] = GEN_INT (INTVAL (operands[2])+1); |
bb621ad7 JW |
8717 | return \"slt\\t%0,%1,%2\"; |
8718 | }" | |
8719 | [(set_attr "type" "arith") | |
0ff83799 | 8720 | (set_attr "mode" "DI")]) |
bb621ad7 | 8721 | |
2bcb2ab3 GK |
8722 | (define_insn "" |
8723 | [(set (match_operand:DI 0 "register_operand" "=t") | |
cafe096b | 8724 | (le:DI (match_operand:DI 1 "register_operand" "d") |
2bcb2ab3 GK |
8725 | (match_operand:DI 2 "small_int" "I")))] |
8726 | "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767" | |
8727 | "* | |
8728 | { | |
95936d18 | 8729 | operands[2] = GEN_INT (INTVAL (operands[2])+1); |
2bcb2ab3 GK |
8730 | return \"slt\\t%1,%2\"; |
8731 | }" | |
8732 | [(set_attr "type" "arith") | |
8733 | (set_attr "mode" "DI") | |
8734 | (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "") | |
0ff83799 MM |
8735 | (const_int 4) |
8736 | (const_int 8)))]) | |
2bcb2ab3 | 8737 | |
34b650b3 MM |
8738 | (define_insn "sle_si_reg" |
8739 | [(set (match_operand:SI 0 "register_operand" "=d") | |
8740 | (le:SI (match_operand:SI 1 "register_operand" "d") | |
8741 | (match_operand:SI 2 "register_operand" "d")))] | |
2bcb2ab3 | 8742 | "TARGET_DEBUG_C_MODE && !TARGET_MIPS16" |
34b650b3 | 8743 | "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001" |
bb621ad7 | 8744 | [(set_attr "type" "arith") |
34b650b3 | 8745 | (set_attr "mode" "SI") |
0ff83799 | 8746 | (set_attr "length" "8")]) |
8ef30996 MM |
8747 | |
8748 | (define_split | |
8749 | [(set (match_operand:SI 0 "register_operand" "") | |
34b650b3 | 8750 | (le:SI (match_operand:SI 1 "register_operand" "") |
8ef30996 | 8751 | (match_operand:SI 2 "register_operand" "")))] |
2bcb2ab3 | 8752 | "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16" |
8ef30996 | 8753 | [(set (match_dup 0) |
34b650b3 | 8754 | (lt:SI (match_dup 2) |
8ef30996 MM |
8755 | (match_dup 1))) |
8756 | (set (match_dup 0) | |
8757 | (xor:SI (match_dup 0) | |
8758 | (const_int 1)))] | |
8759 | "") | |
8760 | ||
bb621ad7 JW |
8761 | (define_insn "sle_di_reg" |
8762 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
8763 | (le:DI (match_operand:DI 1 "register_operand" "d") |
8764 | (match_operand:DI 2 "register_operand" "d")))] | |
2bcb2ab3 | 8765 | "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16" |
bb621ad7 JW |
8766 | "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001" |
8767 | [(set_attr "type" "arith") | |
8768 | (set_attr "mode" "DI") | |
0ff83799 | 8769 | (set_attr "length" "8")]) |
bb621ad7 JW |
8770 | |
8771 | (define_split | |
8772 | [(set (match_operand:DI 0 "register_operand" "") | |
cafe096b EC |
8773 | (le:DI (match_operand:DI 1 "register_operand" "") |
8774 | (match_operand:DI 2 "register_operand" "")))] | |
2bcb2ab3 GK |
8775 | "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE |
8776 | && !TARGET_MIPS16" | |
bb621ad7 JW |
8777 | [(set (match_dup 0) |
8778 | (lt:DI (match_dup 2) | |
8779 | (match_dup 1))) | |
8780 | (set (match_dup 0) | |
8781 | (xor:DI (match_dup 0) | |
8782 | (const_int 1)))] | |
8783 | "") | |
8784 | ||
8ef30996 MM |
8785 | (define_expand "sgtu" |
8786 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8787 | (gtu:SI (match_dup 1) |
8ef30996 MM |
8788 | (match_dup 2)))] |
8789 | "" | |
8790 | " | |
8791 | { | |
bb621ad7 | 8792 | if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI)) |
8ef30996 MM |
8793 | FAIL; |
8794 | ||
8795 | /* set up operands from compare. */ | |
8796 | operands[1] = branch_cmp[0]; | |
8797 | operands[2] = branch_cmp[1]; | |
8798 | ||
2bcb2ab3 | 8799 | if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16) |
34b650b3 MM |
8800 | { |
8801 | gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0); | |
8802 | DONE; | |
8803 | } | |
8804 | ||
8ef30996 MM |
8805 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0) |
8806 | operands[2] = force_reg (SImode, operands[2]); | |
8807 | ||
8808 | /* fall through and generate default code */ | |
8809 | }") | |
8810 | ||
8811 | (define_insn "sgtu_si" | |
8812 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8813 | (gtu:SI (match_operand:SI 1 "register_operand" "d") |
8ef30996 | 8814 | (match_operand:SI 2 "reg_or_0_operand" "dJ")))] |
479f2cea | 8815 | "!TARGET_MIPS16" |
8ef30996 | 8816 | "sltu\\t%0,%z2,%1" |
bb621ad7 | 8817 | [(set_attr "type" "arith") |
0ff83799 | 8818 | (set_attr "mode" "SI")]) |
8ef30996 | 8819 | |
2bcb2ab3 GK |
8820 | (define_insn "" |
8821 | [(set (match_operand:SI 0 "register_operand" "=t") | |
8822 | (gtu:SI (match_operand:SI 1 "register_operand" "d") | |
8823 | (match_operand:SI 2 "register_operand" "d")))] | |
479f2cea | 8824 | "TARGET_MIPS16" |
2bcb2ab3 GK |
8825 | "sltu\\t%2,%1" |
8826 | [(set_attr "type" "arith") | |
0ff83799 | 8827 | (set_attr "mode" "SI")]) |
2bcb2ab3 | 8828 | |
bb621ad7 JW |
8829 | (define_insn "sgtu_di" |
8830 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
8831 | (gtu:DI (match_operand:DI 1 "register_operand" "d") |
8832 | (match_operand:DI 2 "reg_or_0_operand" "dJ")))] | |
479f2cea | 8833 | "TARGET_64BIT && !TARGET_MIPS16" |
bb621ad7 JW |
8834 | "sltu\\t%0,%z2,%1" |
8835 | [(set_attr "type" "arith") | |
0ff83799 | 8836 | (set_attr "mode" "DI")]) |
bb621ad7 | 8837 | |
2bcb2ab3 GK |
8838 | (define_insn "" |
8839 | [(set (match_operand:DI 0 "register_operand" "=t") | |
cafe096b EC |
8840 | (gtu:DI (match_operand:DI 1 "register_operand" "d") |
8841 | (match_operand:DI 2 "register_operand" "d")))] | |
479f2cea | 8842 | "TARGET_64BIT && TARGET_MIPS16" |
2bcb2ab3 GK |
8843 | "sltu\\t%2,%1" |
8844 | [(set_attr "type" "arith") | |
0ff83799 | 8845 | (set_attr "mode" "DI")]) |
2bcb2ab3 | 8846 | |
8ef30996 MM |
8847 | (define_expand "sgeu" |
8848 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8849 | (geu:SI (match_dup 1) |
8ef30996 MM |
8850 | (match_dup 2)))] |
8851 | "" | |
8852 | " | |
8853 | { | |
bb621ad7 | 8854 | if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI)) |
8ef30996 MM |
8855 | FAIL; |
8856 | ||
8857 | /* set up operands from compare. */ | |
8858 | operands[1] = branch_cmp[0]; | |
8859 | operands[2] = branch_cmp[1]; | |
8860 | ||
2bcb2ab3 | 8861 | if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16) |
34b650b3 MM |
8862 | { |
8863 | gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0); | |
8864 | DONE; | |
8865 | } | |
8866 | ||
8ef30996 MM |
8867 | /* fall through and generate default code */ |
8868 | }") | |
8869 | ||
8870 | (define_insn "sgeu_si" | |
8871 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8872 | (geu:SI (match_operand:SI 1 "register_operand" "d") |
8ef30996 | 8873 | (match_operand:SI 2 "arith_operand" "dI")))] |
2bcb2ab3 | 8874 | "TARGET_DEBUG_C_MODE && !TARGET_MIPS16" |
8ef30996 | 8875 | "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001" |
bb621ad7 | 8876 | [(set_attr "type" "arith") |
8ef30996 | 8877 | (set_attr "mode" "SI") |
0ff83799 | 8878 | (set_attr "length" "8")]) |
8ef30996 MM |
8879 | |
8880 | (define_split | |
8881 | [(set (match_operand:SI 0 "register_operand" "") | |
34b650b3 | 8882 | (geu:SI (match_operand:SI 1 "register_operand" "") |
8ef30996 | 8883 | (match_operand:SI 2 "arith_operand" "")))] |
2bcb2ab3 | 8884 | "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16" |
8ef30996 | 8885 | [(set (match_dup 0) |
34b650b3 | 8886 | (ltu:SI (match_dup 1) |
8ef30996 MM |
8887 | (match_dup 2))) |
8888 | (set (match_dup 0) | |
8889 | (xor:SI (match_dup 0) | |
8890 | (const_int 1)))] | |
8891 | "") | |
8892 | ||
bb621ad7 JW |
8893 | (define_insn "sgeu_di" |
8894 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
8895 | (geu:DI (match_operand:DI 1 "register_operand" "d") |
8896 | (match_operand:DI 2 "arith_operand" "dI")))] | |
2bcb2ab3 | 8897 | "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16" |
bb621ad7 JW |
8898 | "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001" |
8899 | [(set_attr "type" "arith") | |
8900 | (set_attr "mode" "DI") | |
0ff83799 | 8901 | (set_attr "length" "8")]) |
bb621ad7 JW |
8902 | |
8903 | (define_split | |
8904 | [(set (match_operand:DI 0 "register_operand" "") | |
cafe096b EC |
8905 | (geu:DI (match_operand:DI 1 "register_operand" "") |
8906 | (match_operand:DI 2 "arith_operand" "")))] | |
2bcb2ab3 GK |
8907 | "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE |
8908 | && !TARGET_MIPS16" | |
bb621ad7 JW |
8909 | [(set (match_dup 0) |
8910 | (ltu:DI (match_dup 1) | |
8911 | (match_dup 2))) | |
8912 | (set (match_dup 0) | |
8913 | (xor:DI (match_dup 0) | |
8914 | (const_int 1)))] | |
8915 | "") | |
8916 | ||
8ef30996 MM |
8917 | (define_expand "sltu" |
8918 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8919 | (ltu:SI (match_dup 1) |
8ef30996 MM |
8920 | (match_dup 2)))] |
8921 | "" | |
8922 | " | |
8923 | { | |
bb621ad7 | 8924 | if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI)) |
8ef30996 MM |
8925 | FAIL; |
8926 | ||
8927 | /* set up operands from compare. */ | |
8928 | operands[1] = branch_cmp[0]; | |
8929 | operands[2] = branch_cmp[1]; | |
8930 | ||
2bcb2ab3 | 8931 | if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16) |
34b650b3 MM |
8932 | { |
8933 | gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0); | |
8934 | DONE; | |
8935 | } | |
8936 | ||
8ef30996 MM |
8937 | /* fall through and generate default code */ |
8938 | }") | |
8939 | ||
8940 | (define_insn "sltu_si" | |
8941 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8942 | (ltu:SI (match_operand:SI 1 "register_operand" "d") |
8ef30996 | 8943 | (match_operand:SI 2 "arith_operand" "dI")))] |
2bcb2ab3 | 8944 | "!TARGET_MIPS16" |
8ef30996 | 8945 | "sltu\\t%0,%1,%2" |
bb621ad7 | 8946 | [(set_attr "type" "arith") |
0ff83799 | 8947 | (set_attr "mode" "SI")]) |
8ef30996 | 8948 | |
2bcb2ab3 GK |
8949 | (define_insn "" |
8950 | [(set (match_operand:SI 0 "register_operand" "=t,t") | |
8951 | (ltu:SI (match_operand:SI 1 "register_operand" "d,d") | |
8952 | (match_operand:SI 2 "arith_operand" "d,I")))] | |
8953 | "TARGET_MIPS16" | |
8954 | "sltu\\t%1,%2" | |
8955 | [(set_attr "type" "arith") | |
8956 | (set_attr "mode" "SI") | |
8957 | (set_attr_alternative "length" | |
0ff83799 | 8958 | [(const_int 4) |
2bcb2ab3 | 8959 | (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "") |
0ff83799 MM |
8960 | (const_int 4) |
8961 | (const_int 8))])]) | |
2bcb2ab3 | 8962 | |
bb621ad7 JW |
8963 | (define_insn "sltu_di" |
8964 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
8965 | (ltu:DI (match_operand:DI 1 "register_operand" "d") |
8966 | (match_operand:DI 2 "arith_operand" "dI")))] | |
2bcb2ab3 | 8967 | "TARGET_64BIT && !TARGET_MIPS16" |
bb621ad7 JW |
8968 | "sltu\\t%0,%1,%2" |
8969 | [(set_attr "type" "arith") | |
0ff83799 | 8970 | (set_attr "mode" "DI")]) |
bb621ad7 | 8971 | |
2bcb2ab3 GK |
8972 | (define_insn "" |
8973 | [(set (match_operand:DI 0 "register_operand" "=t,t") | |
cafe096b EC |
8974 | (ltu:DI (match_operand:DI 1 "register_operand" "d,d") |
8975 | (match_operand:DI 2 "arith_operand" "d,I")))] | |
2bcb2ab3 GK |
8976 | "TARGET_64BIT && TARGET_MIPS16" |
8977 | "sltu\\t%1,%2" | |
8978 | [(set_attr "type" "arith") | |
8979 | (set_attr "mode" "DI") | |
8980 | (set_attr_alternative "length" | |
0ff83799 | 8981 | [(const_int 4) |
2bcb2ab3 | 8982 | (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "") |
0ff83799 MM |
8983 | (const_int 4) |
8984 | (const_int 8))])]) | |
2bcb2ab3 | 8985 | |
8ef30996 MM |
8986 | (define_expand "sleu" |
8987 | [(set (match_operand:SI 0 "register_operand" "=d") | |
34b650b3 | 8988 | (leu:SI (match_dup 1) |
8ef30996 MM |
8989 | (match_dup 2)))] |
8990 | "" | |
8991 | " | |
8992 | { | |
bb621ad7 | 8993 | if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI)) |
8ef30996 MM |
8994 | FAIL; |
8995 | ||
8996 | /* set up operands from compare. */ | |
8997 | operands[1] = branch_cmp[0]; | |
8998 | operands[2] = branch_cmp[1]; | |
8999 | ||
2bcb2ab3 | 9000 | if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16) |
34b650b3 MM |
9001 | { |
9002 | gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0); | |
9003 | DONE; | |
9004 | } | |
9005 | ||
8ef30996 MM |
9006 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767) |
9007 | operands[2] = force_reg (SImode, operands[2]); | |
9008 | ||
9009 | /* fall through and generate default code */ | |
9010 | }") | |
9011 | ||
34b650b3 MM |
9012 | (define_insn "sleu_si_const" |
9013 | [(set (match_operand:SI 0 "register_operand" "=d") | |
9014 | (leu:SI (match_operand:SI 1 "register_operand" "d") | |
9015 | (match_operand:SI 2 "small_int" "I")))] | |
2bcb2ab3 | 9016 | "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767" |
34b650b3 MM |
9017 | "* |
9018 | { | |
c5c76735 | 9019 | operands[2] = GEN_INT (INTVAL (operands[2]) + 1); |
34b650b3 MM |
9020 | return \"sltu\\t%0,%1,%2\"; |
9021 | }" | |
bb621ad7 | 9022 | [(set_attr "type" "arith") |
0ff83799 | 9023 | (set_attr "mode" "SI")]) |
34b650b3 | 9024 | |
2bcb2ab3 GK |
9025 | (define_insn "" |
9026 | [(set (match_operand:SI 0 "register_operand" "=t") | |
9027 | (leu:SI (match_operand:SI 1 "register_operand" "d") | |
9028 | (match_operand:SI 2 "small_int" "I")))] | |
9029 | "TARGET_MIPS16 && INTVAL (operands[2]) < 32767" | |
9030 | "* | |
9031 | { | |
95936d18 | 9032 | operands[2] = GEN_INT (INTVAL (operands[2])+1); |
2bcb2ab3 GK |
9033 | return \"sltu\\t%1,%2\"; |
9034 | }" | |
9035 | [(set_attr "type" "arith") | |
9036 | (set_attr "mode" "SI") | |
9037 | (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "") | |
0ff83799 MM |
9038 | (const_int 4) |
9039 | (const_int 8)))]) | |
2bcb2ab3 | 9040 | |
bb621ad7 JW |
9041 | (define_insn "sleu_di_const" |
9042 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b | 9043 | (leu:DI (match_operand:DI 1 "register_operand" "d") |
bb621ad7 | 9044 | (match_operand:DI 2 "small_int" "I")))] |
2bcb2ab3 | 9045 | "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767" |
bb621ad7 JW |
9046 | "* |
9047 | { | |
c5c76735 | 9048 | operands[2] = GEN_INT (INTVAL (operands[2]) + 1); |
bb621ad7 JW |
9049 | return \"sltu\\t%0,%1,%2\"; |
9050 | }" | |
9051 | [(set_attr "type" "arith") | |
0ff83799 | 9052 | (set_attr "mode" "DI")]) |
bb621ad7 | 9053 | |
2bcb2ab3 GK |
9054 | (define_insn "" |
9055 | [(set (match_operand:DI 0 "register_operand" "=t") | |
cafe096b | 9056 | (leu:DI (match_operand:DI 1 "register_operand" "d") |
2bcb2ab3 GK |
9057 | (match_operand:DI 2 "small_int" "I")))] |
9058 | "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767" | |
9059 | "* | |
9060 | { | |
95936d18 | 9061 | operands[2] = GEN_INT (INTVAL (operands[2])+1); |
2bcb2ab3 GK |
9062 | return \"sltu\\t%1,%2\"; |
9063 | }" | |
9064 | [(set_attr "type" "arith") | |
9065 | (set_attr "mode" "DI") | |
9066 | (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "") | |
0ff83799 MM |
9067 | (const_int 4) |
9068 | (const_int 8)))]) | |
2bcb2ab3 | 9069 | |
34b650b3 MM |
9070 | (define_insn "sleu_si_reg" |
9071 | [(set (match_operand:SI 0 "register_operand" "=d") | |
9072 | (leu:SI (match_operand:SI 1 "register_operand" "d") | |
9073 | (match_operand:SI 2 "register_operand" "d")))] | |
2bcb2ab3 | 9074 | "TARGET_DEBUG_C_MODE && !TARGET_MIPS16" |
34b650b3 | 9075 | "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001" |
bb621ad7 | 9076 | [(set_attr "type" "arith") |
34b650b3 | 9077 | (set_attr "mode" "SI") |
0ff83799 | 9078 | (set_attr "length" "8")]) |
8ef30996 MM |
9079 | |
9080 | (define_split | |
9081 | [(set (match_operand:SI 0 "register_operand" "") | |
34b650b3 | 9082 | (leu:SI (match_operand:SI 1 "register_operand" "") |
8ef30996 | 9083 | (match_operand:SI 2 "register_operand" "")))] |
2bcb2ab3 | 9084 | "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16" |
8ef30996 | 9085 | [(set (match_dup 0) |
34b650b3 | 9086 | (ltu:SI (match_dup 2) |
8ef30996 MM |
9087 | (match_dup 1))) |
9088 | (set (match_dup 0) | |
9089 | (xor:SI (match_dup 0) | |
9090 | (const_int 1)))] | |
9091 | "") | |
9092 | ||
bb621ad7 JW |
9093 | (define_insn "sleu_di_reg" |
9094 | [(set (match_operand:DI 0 "register_operand" "=d") | |
cafe096b EC |
9095 | (leu:DI (match_operand:DI 1 "register_operand" "d") |
9096 | (match_operand:DI 2 "register_operand" "d")))] | |
2bcb2ab3 | 9097 | "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16" |
bb621ad7 JW |
9098 | "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001" |
9099 | [(set_attr "type" "arith") | |
9100 | (set_attr "mode" "DI") | |
0ff83799 | 9101 | (set_attr "length" "8")]) |
bb621ad7 JW |
9102 | |
9103 | (define_split | |
9104 | [(set (match_operand:DI 0 "register_operand" "") | |
cafe096b EC |
9105 | (leu:DI (match_operand:DI 1 "register_operand" "") |
9106 | (match_operand:DI 2 "register_operand" "")))] | |
2bcb2ab3 GK |
9107 | "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE |
9108 | && !TARGET_MIPS16" | |
bb621ad7 JW |
9109 | [(set (match_dup 0) |
9110 | (ltu:DI (match_dup 2) | |
9111 | (match_dup 1))) | |
9112 | (set (match_dup 0) | |
9113 | (xor:DI (match_dup 0) | |
9114 | (const_int 1)))] | |
9115 | "") | |
9116 | ||
34b650b3 MM |
9117 | \f |
9118 | ;; | |
9119 | ;; .................... | |
9120 | ;; | |
9121 | ;; FLOATING POINT COMPARISONS | |
9122 | ;; | |
9123 | ;; .................... | |
9124 | ||
ce3649d2 EC |
9125 | (define_insn "sunordered_df" |
9126 | [(set (match_operand:CC 0 "register_operand" "=z") | |
9127 | (unordered:CC (match_operand:DF 1 "register_operand" "f") | |
9128 | (match_operand:DF 2 "register_operand" "f")))] | |
9129 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" | |
9130 | "* | |
9131 | { | |
9132 | return mips_fill_delay_slot (\"c.un.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); | |
9133 | }" | |
9134 | [(set_attr "type" "fcmp") | |
9135 | (set_attr "mode" "FPSW")]) | |
9136 | ||
ce3649d2 EC |
9137 | (define_insn "sunlt_df" |
9138 | [(set (match_operand:CC 0 "register_operand" "=z") | |
9139 | (unlt:CC (match_operand:DF 1 "register_operand" "f") | |
9140 | (match_operand:DF 2 "register_operand" "f")))] | |
9141 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" | |
9142 | "* | |
9143 | { | |
9144 | return mips_fill_delay_slot (\"c.ult.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); | |
9145 | }" | |
9146 | [(set_attr "type" "fcmp") | |
9147 | (set_attr "mode" "FPSW")]) | |
9148 | ||
9149 | (define_insn "suneq_df" | |
9150 | [(set (match_operand:CC 0 "register_operand" "=z") | |
9151 | (uneq:CC (match_operand:DF 1 "register_operand" "f") | |
9152 | (match_operand:DF 2 "register_operand" "f")))] | |
9153 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" | |
9154 | "* | |
9155 | { | |
9156 | return mips_fill_delay_slot (\"c.ueq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); | |
9157 | }" | |
9158 | [(set_attr "type" "fcmp") | |
9159 | (set_attr "mode" "FPSW")]) | |
9160 | ||
ce3649d2 EC |
9161 | (define_insn "sunle_df" |
9162 | [(set (match_operand:CC 0 "register_operand" "=z") | |
9163 | (unle:CC (match_operand:DF 1 "register_operand" "f") | |
9164 | (match_operand:DF 2 "register_operand" "f")))] | |
9165 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" | |
9166 | "* | |
9167 | { | |
9168 | return mips_fill_delay_slot (\"c.ule.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); | |
9169 | }" | |
9170 | [(set_attr "type" "fcmp") | |
9171 | (set_attr "mode" "FPSW")]) | |
9172 | ||
34b650b3 | 9173 | (define_insn "seq_df" |
b8eb88d0 ILT |
9174 | [(set (match_operand:CC 0 "register_operand" "=z") |
9175 | (eq:CC (match_operand:DF 1 "register_operand" "f") | |
9176 | (match_operand:DF 2 "register_operand" "f")))] | |
46299de9 | 9177 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
34b650b3 MM |
9178 | "* |
9179 | { | |
b8eb88d0 | 9180 | return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); |
34b650b3 MM |
9181 | }" |
9182 | [(set_attr "type" "fcmp") | |
0ff83799 | 9183 | (set_attr "mode" "FPSW")]) |
34b650b3 MM |
9184 | |
9185 | (define_insn "slt_df" | |
b8eb88d0 ILT |
9186 | [(set (match_operand:CC 0 "register_operand" "=z") |
9187 | (lt:CC (match_operand:DF 1 "register_operand" "f") | |
9188 | (match_operand:DF 2 "register_operand" "f")))] | |
46299de9 | 9189 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
34b650b3 MM |
9190 | "* |
9191 | { | |
b8eb88d0 | 9192 | return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); |
34b650b3 MM |
9193 | }" |
9194 | [(set_attr "type" "fcmp") | |
0ff83799 | 9195 | (set_attr "mode" "FPSW")]) |
34b650b3 MM |
9196 | |
9197 | (define_insn "sle_df" | |
b8eb88d0 ILT |
9198 | [(set (match_operand:CC 0 "register_operand" "=z") |
9199 | (le:CC (match_operand:DF 1 "register_operand" "f") | |
9200 | (match_operand:DF 2 "register_operand" "f")))] | |
46299de9 | 9201 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
34b650b3 MM |
9202 | "* |
9203 | { | |
b8eb88d0 | 9204 | return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); |
34b650b3 MM |
9205 | }" |
9206 | [(set_attr "type" "fcmp") | |
0ff83799 | 9207 | (set_attr "mode" "FPSW")]) |
34b650b3 MM |
9208 | |
9209 | (define_insn "sgt_df" | |
b8eb88d0 ILT |
9210 | [(set (match_operand:CC 0 "register_operand" "=z") |
9211 | (gt:CC (match_operand:DF 1 "register_operand" "f") | |
9212 | (match_operand:DF 2 "register_operand" "f")))] | |
46299de9 | 9213 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
34b650b3 MM |
9214 | "* |
9215 | { | |
b8eb88d0 | 9216 | return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn); |
34b650b3 MM |
9217 | }" |
9218 | [(set_attr "type" "fcmp") | |
0ff83799 | 9219 | (set_attr "mode" "FPSW")]) |
34b650b3 MM |
9220 | |
9221 | (define_insn "sge_df" | |
b8eb88d0 ILT |
9222 | [(set (match_operand:CC 0 "register_operand" "=z") |
9223 | (ge:CC (match_operand:DF 1 "register_operand" "f") | |
9224 | (match_operand:DF 2 "register_operand" "f")))] | |
46299de9 | 9225 | "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
34b650b3 MM |
9226 | "* |
9227 | { | |
b8eb88d0 | 9228 | return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn); |
34b650b3 MM |
9229 | }" |
9230 | [(set_attr "type" "fcmp") | |
0ff83799 | 9231 | (set_attr "mode" "FPSW")]) |
34b650b3 | 9232 | |
ce3649d2 EC |
9233 | (define_insn "sunordered_sf" |
9234 | [(set (match_operand:CC 0 "register_operand" "=z") | |
9235 | (unordered:CC (match_operand:SF 1 "register_operand" "f") | |
9236 | (match_operand:SF 2 "register_operand" "f")))] | |
9237 | "TARGET_HARD_FLOAT" | |
9238 | "* | |
9239 | { | |
9240 | return mips_fill_delay_slot (\"c.un.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); | |
9241 | }" | |
9242 | [(set_attr "type" "fcmp") | |
9243 | (set_attr "mode" "FPSW")]) | |
9244 | ||
ce3649d2 EC |
9245 | (define_insn "sunlt_sf" |
9246 | [(set (match_operand:CC 0 "register_operand" "=z") | |
9247 | (unlt:CC (match_operand:SF 1 "register_operand" "f") | |
9248 | (match_operand:SF 2 "register_operand" "f")))] | |
e49ec17d | 9249 | "TARGET_HARD_FLOAT" |
ce3649d2 EC |
9250 | "* |
9251 | { | |
9252 | return mips_fill_delay_slot (\"c.ult.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); | |
9253 | }" | |
9254 | [(set_attr "type" "fcmp") | |
9255 | (set_attr "mode" "FPSW")]) | |
9256 | ||
9257 | (define_insn "suneq_sf" | |
9258 | [(set (match_operand:CC 0 "register_operand" "=z") | |
9259 | (uneq:CC (match_operand:SF 1 "register_operand" "f") | |
9260 | (match_operand:SF 2 "register_operand" "f")))] | |
e49ec17d | 9261 | "TARGET_HARD_FLOAT" |
ce3649d2 EC |
9262 | "* |
9263 | { | |
9264 | return mips_fill_delay_slot (\"c.ueq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); | |
9265 | }" | |
9266 | [(set_attr "type" "fcmp") | |
9267 | (set_attr "mode" "FPSW")]) | |
9268 | ||
ce3649d2 EC |
9269 | (define_insn "sunle_sf" |
9270 | [(set (match_operand:CC 0 "register_operand" "=z") | |
9271 | (unle:CC (match_operand:SF 1 "register_operand" "f") | |
9272 | (match_operand:SF 2 "register_operand" "f")))] | |
e49ec17d | 9273 | "TARGET_HARD_FLOAT" |
ce3649d2 EC |
9274 | "* |
9275 | { | |
9276 | return mips_fill_delay_slot (\"c.ule.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); | |
9277 | }" | |
9278 | [(set_attr "type" "fcmp") | |
9279 | (set_attr "mode" "FPSW")]) | |
9280 | ||
34b650b3 | 9281 | (define_insn "seq_sf" |
b8eb88d0 ILT |
9282 | [(set (match_operand:CC 0 "register_operand" "=z") |
9283 | (eq:CC (match_operand:SF 1 "register_operand" "f") | |
9284 | (match_operand:SF 2 "register_operand" "f")))] | |
bb621ad7 | 9285 | "TARGET_HARD_FLOAT" |
34b650b3 MM |
9286 | "* |
9287 | { | |
b8eb88d0 | 9288 | return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); |
34b650b3 MM |
9289 | }" |
9290 | [(set_attr "type" "fcmp") | |
0ff83799 | 9291 | (set_attr "mode" "FPSW")]) |
34b650b3 MM |
9292 | |
9293 | (define_insn "slt_sf" | |
b8eb88d0 ILT |
9294 | [(set (match_operand:CC 0 "register_operand" "=z") |
9295 | (lt:CC (match_operand:SF 1 "register_operand" "f") | |
9296 | (match_operand:SF 2 "register_operand" "f")))] | |
bb621ad7 | 9297 | "TARGET_HARD_FLOAT" |
34b650b3 MM |
9298 | "* |
9299 | { | |
b8eb88d0 | 9300 | return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); |
34b650b3 MM |
9301 | }" |
9302 | [(set_attr "type" "fcmp") | |
0ff83799 | 9303 | (set_attr "mode" "FPSW")]) |
34b650b3 MM |
9304 | |
9305 | (define_insn "sle_sf" | |
b8eb88d0 ILT |
9306 | [(set (match_operand:CC 0 "register_operand" "=z") |
9307 | (le:CC (match_operand:SF 1 "register_operand" "f") | |
9308 | (match_operand:SF 2 "register_operand" "f")))] | |
bb621ad7 | 9309 | "TARGET_HARD_FLOAT" |
34b650b3 MM |
9310 | "* |
9311 | { | |
b8eb88d0 | 9312 | return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn); |
34b650b3 MM |
9313 | }" |
9314 | [(set_attr "type" "fcmp") | |
0ff83799 | 9315 | (set_attr "mode" "FPSW")]) |
34b650b3 MM |
9316 | |
9317 | (define_insn "sgt_sf" | |
b8eb88d0 ILT |
9318 | [(set (match_operand:CC 0 "register_operand" "=z") |
9319 | (gt:CC (match_operand:SF 1 "register_operand" "f") | |
9320 | (match_operand:SF 2 "register_operand" "f")))] | |
bb621ad7 | 9321 | "TARGET_HARD_FLOAT" |
34b650b3 MM |
9322 | "* |
9323 | { | |
b8eb88d0 | 9324 | return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn); |
34b650b3 MM |
9325 | }" |
9326 | [(set_attr "type" "fcmp") | |
0ff83799 | 9327 | (set_attr "mode" "FPSW")]) |
34b650b3 MM |
9328 | |
9329 | (define_insn "sge_sf" | |
b8eb88d0 ILT |
9330 | [(set (match_operand:CC 0 "register_operand" "=z") |
9331 | (ge:CC (match_operand:SF 1 "register_operand" "f") | |
9332 | (match_operand:SF 2 "register_operand" "f")))] | |
bb621ad7 | 9333 | "TARGET_HARD_FLOAT" |
34b650b3 MM |
9334 | "* |
9335 | { | |
b8eb88d0 | 9336 | return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn); |
34b650b3 MM |
9337 | }" |
9338 | [(set_attr "type" "fcmp") | |
0ff83799 | 9339 | (set_attr "mode" "FPSW")]) |
34b650b3 | 9340 | |
8ef30996 MM |
9341 | \f |
9342 | ;; | |
9343 | ;; .................... | |
9344 | ;; | |
9345 | ;; UNCONDITIONAL BRANCHES | |
9346 | ;; | |
9347 | ;; .................... | |
9348 | ||
9349 | ;; Unconditional branches. | |
9350 | ||
9351 | (define_insn "jump" | |
9352 | [(set (pc) | |
9353 | (label_ref (match_operand 0 "" "")))] | |
2bcb2ab3 | 9354 | "!TARGET_MIPS16" |
8ef30996 MM |
9355 | "* |
9356 | { | |
852dff61 AO |
9357 | if (flag_pic && ! TARGET_EMBEDDED_PIC) |
9358 | { | |
9359 | if (get_attr_length (insn) <= 8) | |
9360 | return \"%*b\\t%l0\"; | |
9361 | else if (Pmode == DImode) | |
9362 | return \"%[dla\\t%@,%l0\;%*jr\\t%@%]\"; | |
9363 | else | |
9364 | return \"%[la\\t%@,%l0\;%*jr\\t%@%]\"; | |
9365 | } | |
7a38df19 | 9366 | else |
8ef30996 MM |
9367 | return \"%*j\\t%l0\"; |
9368 | }" | |
9369 | [(set_attr "type" "jump") | |
852dff61 AO |
9370 | (set_attr "mode" "none") |
9371 | (set (attr "length") | |
9372 | ;; we can't use `j' when emitting non-embedded PIC, so we emit | |
9373 | ;; branch, if it's in range, or load the address of the branch | |
9374 | ;; target into $at in a PIC-compatible way and then jump to it. | |
cafe096b | 9375 | (if_then_else |
852dff61 AO |
9376 | (ior (eq (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC") |
9377 | (const_int 0)) | |
9378 | (lt (abs (minus (match_dup 0) | |
9379 | (plus (pc) (const_int 4)))) | |
9380 | (const_int 131072))) | |
9381 | (const_int 4) (const_int 16)))]) | |
8ef30996 | 9382 | |
2bcb2ab3 GK |
9383 | ;; We need a different insn for the mips16, because a mips16 branch |
9384 | ;; does not have a delay slot. | |
9385 | ||
9386 | (define_insn "" | |
9387 | [(set (pc) | |
9388 | (label_ref (match_operand 0 "" "")))] | |
852dff61 | 9389 | "TARGET_MIPS16" |
2bcb2ab3 GK |
9390 | "b\\t%l0" |
9391 | [(set_attr "type" "branch") | |
9392 | (set_attr "mode" "none") | |
0ff83799 | 9393 | (set_attr "length" "8")]) |
2bcb2ab3 | 9394 | |
bb621ad7 JW |
9395 | (define_expand "indirect_jump" |
9396 | [(set (pc) (match_operand 0 "register_operand" "d"))] | |
8ef30996 | 9397 | "" |
bb621ad7 JW |
9398 | " |
9399 | { | |
9400 | rtx dest; | |
9401 | ||
9402 | if (operands[0]) /* eliminate unused code warnings */ | |
9403 | { | |
9404 | dest = operands[0]; | |
9405 | if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode) | |
9406 | operands[0] = copy_to_mode_reg (Pmode, dest); | |
9407 | ||
1eeed24e | 9408 | if (!(Pmode == DImode)) |
bb621ad7 JW |
9409 | emit_jump_insn (gen_indirect_jump_internal1 (operands[0])); |
9410 | else | |
9411 | emit_jump_insn (gen_indirect_jump_internal2 (operands[0])); | |
9412 | ||
9413 | DONE; | |
9414 | } | |
9415 | }") | |
9416 | ||
9417 | (define_insn "indirect_jump_internal1" | |
9418 | [(set (pc) (match_operand:SI 0 "register_operand" "d"))] | |
1eeed24e | 9419 | "!(Pmode == DImode)" |
bb621ad7 JW |
9420 | "%*j\\t%0" |
9421 | [(set_attr "type" "jump") | |
0ff83799 | 9422 | (set_attr "mode" "none")]) |
bb621ad7 JW |
9423 | |
9424 | (define_insn "indirect_jump_internal2" | |
cafe096b | 9425 | [(set (pc) (match_operand:DI 0 "register_operand" "d"))] |
1eeed24e | 9426 | "Pmode == DImode" |
8ef30996 MM |
9427 | "%*j\\t%0" |
9428 | [(set_attr "type" "jump") | |
0ff83799 | 9429 | (set_attr "mode" "none")]) |
8ef30996 | 9430 | |
bb621ad7 | 9431 | (define_expand "tablejump" |
8ef30996 | 9432 | [(set (pc) |
bb621ad7 | 9433 | (match_operand 0 "register_operand" "d")) |
8ef30996 MM |
9434 | (use (label_ref (match_operand 1 "" "")))] |
9435 | "" | |
bb621ad7 JW |
9436 | " |
9437 | { | |
bb621ad7 JW |
9438 | if (operands[0]) /* eliminate unused code warnings */ |
9439 | { | |
2bcb2ab3 GK |
9440 | if (TARGET_MIPS16) |
9441 | { | |
9442 | if (GET_MODE (operands[0]) != HImode) | |
9443 | abort (); | |
1eeed24e | 9444 | if (!(Pmode == DImode)) |
bf4f78ee | 9445 | emit_insn (gen_tablejump_mips161 (operands[0], operands[1])); |
2bcb2ab3 | 9446 | else |
bf4f78ee | 9447 | emit_insn (gen_tablejump_mips162 (operands[0], operands[1])); |
2bcb2ab3 GK |
9448 | DONE; |
9449 | } | |
9450 | ||
cafe096b | 9451 | if (GET_MODE (operands[0]) != ptr_mode) |
bb621ad7 JW |
9452 | abort (); |
9453 | ||
cafe096b EC |
9454 | if (TARGET_GPWORD) |
9455 | operands[0] = expand_binop (ptr_mode, add_optab, operands[0], | |
9456 | pic_offset_table_rtx, 0, 0, OPTAB_WIDEN); | |
bb621ad7 | 9457 | |
cafe096b EC |
9458 | if (Pmode == SImode) |
9459 | emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1])); | |
9460 | else | |
9461 | emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1])); | |
bb621ad7 JW |
9462 | DONE; |
9463 | } | |
9464 | }") | |
9465 | ||
9466 | (define_insn "tablejump_internal1" | |
9467 | [(set (pc) | |
9468 | (match_operand:SI 0 "register_operand" "d")) | |
9469 | (use (label_ref (match_operand 1 "" "")))] | |
cafe096b | 9470 | "" |
9fa0af71 | 9471 | "%*j\\t%0" |
bb621ad7 | 9472 | [(set_attr "type" "jump") |
0ff83799 | 9473 | (set_attr "mode" "none")]) |
bb621ad7 JW |
9474 | |
9475 | (define_insn "tablejump_internal2" | |
9476 | [(set (pc) | |
cafe096b | 9477 | (match_operand:DI 0 "register_operand" "d")) |
bb621ad7 | 9478 | (use (label_ref (match_operand 1 "" "")))] |
cafe096b | 9479 | "TARGET_64BIT" |
9fa0af71 JW |
9480 | "%*j\\t%0" |
9481 | [(set_attr "type" "jump") | |
0ff83799 | 9482 | (set_attr "mode" "none")]) |
9fa0af71 | 9483 | |
2bcb2ab3 GK |
9484 | (define_expand "tablejump_mips161" |
9485 | [(set (pc) (plus:SI (sign_extend:SI | |
9486 | (match_operand:HI 0 "register_operand" "d")) | |
cf45bb06 | 9487 | (label_ref:SI (match_operand 1 "" ""))))] |
1eeed24e | 9488 | "TARGET_MIPS16 && !(Pmode == DImode)" |
2bcb2ab3 GK |
9489 | " |
9490 | { | |
9491 | if (operands[0]) /* eliminate unused code warnings. */ | |
9492 | { | |
9493 | rtx t1, t2, t3; | |
9494 | ||
9495 | t1 = gen_reg_rtx (SImode); | |
9496 | t2 = gen_reg_rtx (SImode); | |
9497 | t3 = gen_reg_rtx (SImode); | |
9498 | emit_insn (gen_extendhisi2 (t1, operands[0])); | |
6bbdc759 | 9499 | emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1])); |
2bcb2ab3 | 9500 | emit_insn (gen_addsi3 (t3, t1, t2)); |
bf4f78ee | 9501 | emit_jump_insn (gen_tablejump_internal1 (t3, operands[1])); |
2bcb2ab3 GK |
9502 | DONE; |
9503 | } | |
9504 | }") | |
9505 | ||
9506 | (define_expand "tablejump_mips162" | |
9507 | [(set (pc) (plus:DI (sign_extend:DI | |
9508 | (match_operand:HI 0 "register_operand" "d")) | |
cf45bb06 | 9509 | (label_ref:DI (match_operand 1 "" ""))))] |
1eeed24e | 9510 | "TARGET_MIPS16 && Pmode == DImode" |
2bcb2ab3 GK |
9511 | " |
9512 | { | |
9513 | if (operands[0]) /* eliminate unused code warnings. */ | |
9514 | { | |
9515 | rtx t1, t2, t3; | |
9516 | ||
9517 | t1 = gen_reg_rtx (DImode); | |
9518 | t2 = gen_reg_rtx (DImode); | |
9519 | t3 = gen_reg_rtx (DImode); | |
9520 | emit_insn (gen_extendhidi2 (t1, operands[0])); | |
6bbdc759 | 9521 | emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1])); |
2bcb2ab3 | 9522 | emit_insn (gen_adddi3 (t3, t1, t2)); |
bf4f78ee | 9523 | emit_jump_insn (gen_tablejump_internal2 (t3, operands[1])); |
2bcb2ab3 | 9524 | DONE; |
cafe096b EC |
9525 | } |
9526 | }") | |
8ef30996 | 9527 | |
e0bfcea5 ILT |
9528 | ;; Implement a switch statement when generating embedded PIC code. |
9529 | ;; Switches are implemented by `tablejump' when not using -membedded-pic. | |
9530 | ||
9531 | (define_expand "casesi" | |
9532 | [(set (match_dup 5) | |
9533 | (minus:SI (match_operand:SI 0 "register_operand" "d") | |
9534 | (match_operand:SI 1 "arith_operand" "dI"))) | |
9535 | (set (cc0) | |
9536 | (compare:CC (match_dup 5) | |
9537 | (match_operand:SI 2 "arith_operand" ""))) | |
9538 | (set (pc) | |
9539 | (if_then_else (gtu (cc0) | |
9540 | (const_int 0)) | |
9541 | (label_ref (match_operand 4 "" "")) | |
9542 | (pc))) | |
9543 | (parallel | |
9544 | [(set (pc) | |
9545 | (mem:SI (plus:SI (mult:SI (match_dup 5) | |
9546 | (const_int 4)) | |
9547 | (label_ref (match_operand 3 "" ""))))) | |
9548 | (clobber (match_scratch:SI 6 "")) | |
9549 | (clobber (reg:SI 31))])] | |
9550 | "TARGET_EMBEDDED_PIC" | |
9551 | " | |
9552 | { | |
e0bfcea5 ILT |
9553 | if (operands[0]) |
9554 | { | |
9555 | rtx reg = gen_reg_rtx (SImode); | |
9556 | ||
e0bfcea5 ILT |
9557 | /* If the index is too large, go to the default label. */ |
9558 | emit_insn (gen_subsi3 (reg, operands[0], operands[1])); | |
9559 | emit_insn (gen_cmpsi (reg, operands[2])); | |
9560 | emit_insn (gen_bgtu (operands[4])); | |
9561 | ||
9562 | /* Do the PIC jump. */ | |
9c9e7632 | 9563 | if (Pmode != DImode) |
7a38df19 | 9564 | emit_jump_insn (gen_casesi_internal (reg, operands[3], |
9c9e7632 GK |
9565 | gen_reg_rtx (SImode))); |
9566 | else | |
7a38df19 | 9567 | emit_jump_insn (gen_casesi_internal_di (reg, operands[3], |
9c9e7632 | 9568 | gen_reg_rtx (DImode))); |
e0bfcea5 ILT |
9569 | |
9570 | DONE; | |
9571 | } | |
9572 | }") | |
9573 | ||
9574 | ;; An embedded PIC switch statement looks like this: | |
9575 | ;; bal $LS1 | |
810c1b83 | 9576 | ;; sll $reg,$index,2 |
e0bfcea5 ILT |
9577 | ;; $LS1: |
9578 | ;; addu $reg,$reg,$31 | |
9579 | ;; lw $reg,$L1-$LS1($reg) | |
9580 | ;; addu $reg,$reg,$31 | |
9581 | ;; j $reg | |
9582 | ;; $L1: | |
9583 | ;; .word case1-$LS1 | |
9584 | ;; .word case2-$LS1 | |
9585 | ;; ... | |
9586 | ||
9587 | (define_insn "casesi_internal" | |
9588 | [(set (pc) | |
9589 | (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d") | |
9590 | (const_int 4)) | |
9591 | (label_ref (match_operand 1 "" ""))))) | |
0e7e9155 | 9592 | (clobber (match_operand:SI 2 "register_operand" "=d")) |
e0bfcea5 ILT |
9593 | (clobber (reg:SI 31))] |
9594 | "TARGET_EMBEDDED_PIC" | |
810c1b83 | 9595 | "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\ |
246a46e0 | 9596 | lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2" |
e0bfcea5 ILT |
9597 | [(set_attr "type" "jump") |
9598 | (set_attr "mode" "none") | |
0ff83799 | 9599 | (set_attr "length" "24")]) |
e0bfcea5 | 9600 | |
6a5ea3f4 CD |
9601 | ;; This code assumes that the table index will never be >= 29 bits wide, |
9602 | ;; which allows the 'sign extend' from SI to DI be a no-op. | |
9c9e7632 GK |
9603 | (define_insn "casesi_internal_di" |
9604 | [(set (pc) | |
7a38df19 | 9605 | (mem:DI (plus:DI (sign_extend:DI |
9c9e7632 | 9606 | (mult:SI (match_operand:SI 0 "register_operand" "d") |
6a5ea3f4 | 9607 | (const_int 8))) |
9c9e7632 GK |
9608 | (label_ref (match_operand 1 "" ""))))) |
9609 | (clobber (match_operand:DI 2 "register_operand" "=d")) | |
9610 | (clobber (reg:DI 31))] | |
9611 | "TARGET_EMBEDDED_PIC" | |
6a5ea3f4 | 9612 | "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\ |
246a46e0 | 9613 | ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" |
9c9e7632 GK |
9614 | [(set_attr "type" "jump") |
9615 | (set_attr "mode" "none") | |
9616 | (set_attr "length" "24")]) | |
9617 | ||
6fd1c67b RH |
9618 | ;; For o32/n32/n64, we save the gp in the jmp_buf as well. While it is |
9619 | ;; possible to either pull it off the stack (in the o32 case) or recalculate | |
9620 | ;; it given t9 and our target label, it takes 3 or 4 insns to do so, and | |
9621 | ;; this is easy. | |
9622 | ||
9623 | (define_expand "builtin_setjmp_setup" | |
41f8d041 | 9624 | [(unspec [(match_operand 0 "register_operand" "r")] UNSPEC_SETJMP)] |
6fd1c67b | 9625 | "TARGET_ABICALLS" |
d5d1738a JW |
9626 | " |
9627 | { | |
1eeed24e | 9628 | if (Pmode == DImode) |
6fd1c67b RH |
9629 | emit_insn (gen_builtin_setjmp_setup_64 (operands[0])); |
9630 | else | |
9631 | emit_insn (gen_builtin_setjmp_setup_32 (operands[0])); | |
9632 | DONE; | |
d5d1738a | 9633 | }") |
c85f7c16 | 9634 | |
6fd1c67b RH |
9635 | (define_expand "builtin_setjmp_setup_32" |
9636 | [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r") | |
9637 | (const_int 12))) | |
9638 | (reg:SI 28))] | |
1eeed24e | 9639 | "TARGET_ABICALLS && ! (Pmode == DImode)" |
6fd1c67b | 9640 | "") |
c85f7c16 | 9641 | |
6fd1c67b RH |
9642 | (define_expand "builtin_setjmp_setup_64" |
9643 | [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r") | |
9644 | (const_int 24))) | |
9645 | (reg:DI 28))] | |
1eeed24e | 9646 | "TARGET_ABICALLS && Pmode == DImode" |
6fd1c67b RH |
9647 | "") |
9648 | ||
7a38df19 | 9649 | ;; For o32/n32/n64, we need to arrange for longjmp to put the |
6fd1c67b RH |
9650 | ;; target address in t9 so that we can use it for loading $gp. |
9651 | ||
9652 | (define_expand "builtin_longjmp" | |
41f8d041 | 9653 | [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPEC_LONGJMP)] |
6fd1c67b | 9654 | "TARGET_ABICALLS" |
c85f7c16 JL |
9655 | " |
9656 | { | |
6fd1c67b | 9657 | /* The elements of the buffer are, in order: */ |
1eeed24e | 9658 | int W = (Pmode == DImode ? 8 : 4); |
6fd1c67b RH |
9659 | rtx fp = gen_rtx_MEM (Pmode, operands[0]); |
9660 | rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W)); | |
9661 | rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W)); | |
9662 | rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W)); | |
9663 | rtx pv = gen_rtx_REG (Pmode, 25); | |
9664 | rtx gp = gen_rtx_REG (Pmode, 28); | |
9665 | ||
9666 | /* This bit is the same as expand_builtin_longjmp. */ | |
9667 | emit_move_insn (hard_frame_pointer_rtx, fp); | |
9668 | emit_move_insn (pv, lab); | |
9669 | emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX); | |
9670 | emit_move_insn (gp, gpv); | |
9671 | emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx)); | |
9672 | emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); | |
9673 | emit_insn (gen_rtx_USE (VOIDmode, gp)); | |
9674 | emit_indirect_jump (pv); | |
9675 | DONE; | |
c85f7c16 | 9676 | }") |
0fb5ac6f MM |
9677 | \f |
9678 | ;; | |
9679 | ;; .................... | |
9680 | ;; | |
9681 | ;; Function prologue/epilogue | |
9682 | ;; | |
9683 | ;; .................... | |
9684 | ;; | |
9685 | ||
9686 | (define_expand "prologue" | |
9687 | [(const_int 1)] | |
9688 | "" | |
9689 | " | |
9690 | { | |
9691 | if (mips_isa >= 0) /* avoid unused code warnings */ | |
9692 | { | |
9693 | mips_expand_prologue (); | |
9694 | DONE; | |
9695 | } | |
9696 | }") | |
9697 | ||
d8d5b1e1 MM |
9698 | ;; Block any insns from being moved before this point, since the |
9699 | ;; profiling call to mcount can use various registers that aren't | |
9700 | ;; saved or used to pass arguments. | |
9701 | ||
9702 | (define_insn "blockage" | |
41f8d041 | 9703 | [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)] |
d8d5b1e1 MM |
9704 | "" |
9705 | "" | |
9706 | [(set_attr "type" "unknown") | |
9707 | (set_attr "mode" "none") | |
9708 | (set_attr "length" "0")]) | |
9709 | ||
1f2d8f51 JL |
9710 | (define_expand "epilogue" |
9711 | [(const_int 2)] | |
9712 | "" | |
1f2d8f51 | 9713 | { |
cafe096b EC |
9714 | mips_expand_epilogue (false); |
9715 | DONE; | |
9716 | }) | |
9717 | ||
9718 | (define_expand "sibcall_epilogue" | |
9719 | [(const_int 2)] | |
9720 | "" | |
9721 | { | |
9722 | mips_expand_epilogue (true); | |
9723 | DONE; | |
9724 | }) | |
0fb5ac6f | 9725 | |
1f2d8f51 JL |
9726 | ;; Trivial return. Make it look like a normal return insn as that |
9727 | ;; allows jump optimizations to work better . | |
9728 | (define_insn "return" | |
9729 | [(return)] | |
9730 | "mips_can_use_return_insn ()" | |
8fa4e1b4 | 9731 | "%*j\\t$31" |
1f2d8f51 | 9732 | [(set_attr "type" "jump") |
0ff83799 | 9733 | (set_attr "mode" "none")]) |
1f2d8f51 JL |
9734 | |
9735 | ;; Normal return. | |
0e7e9155 | 9736 | |
1f2d8f51 | 9737 | (define_insn "return_internal" |
0e7e9155 | 9738 | [(use (match_operand 0 "pmode_register_operand" "")) |
1f2d8f51 JL |
9739 | (return)] |
9740 | "" | |
2bcb2ab3 GK |
9741 | "* |
9742 | { | |
9743 | return \"%*j\\t%0\"; | |
9744 | }" | |
1f2d8f51 | 9745 | [(set_attr "type" "jump") |
0ff83799 | 9746 | (set_attr "mode" "none")]) |
7a38df19 | 9747 | |
92544bdf ILT |
9748 | ;; When generating embedded PIC code we need to get the address of the |
9749 | ;; current function. This specialized instruction does just that. | |
9750 | ||
9751 | (define_insn "get_fnaddr" | |
0d3b5987 | 9752 | [(set (match_operand 0 "register_operand" "=d") |
41f8d041 | 9753 | (unspec [(match_operand 1 "" "")] UNSPEC_GET_FNADDR)) |
92544bdf ILT |
9754 | (clobber (reg:SI 31))] |
9755 | "TARGET_EMBEDDED_PIC | |
9756 | && GET_CODE (operands[1]) == SYMBOL_REF" | |
ae598ab9 | 9757 | "%($LF%= = . + 8\;bal\\t$LF%=\;nop;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31" |
92544bdf ILT |
9758 | [(set_attr "type" "call") |
9759 | (set_attr "mode" "none") | |
7fa9ed65 | 9760 | (set_attr "length" "20")]) |
92544bdf | 9761 | |
9e800206 RH |
9762 | ;; This is used in compiling the unwind routines. |
9763 | (define_expand "eh_return" | |
9764 | [(use (match_operand 0 "general_operand" "")) | |
9765 | (use (match_operand 1 "general_operand" ""))] | |
9766 | "" | |
9767 | " | |
9768 | { | |
9769 | enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode; | |
9770 | ||
9771 | if (GET_MODE (operands[1]) != gpr_mode) | |
9772 | operands[1] = convert_to_mode (gpr_mode, operands[1], 0); | |
9773 | if (TARGET_64BIT) | |
9774 | emit_insn (gen_eh_set_lr_di (operands[1])); | |
9775 | else | |
9776 | emit_insn (gen_eh_set_lr_si (operands[1])); | |
9777 | ||
9778 | emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]); | |
9779 | DONE; | |
9780 | }") | |
9781 | ||
9782 | ;; Clobber the return address on the stack. We can't expand this | |
9783 | ;; until we know where it will be put in the stack frame. | |
9784 | ||
9785 | (define_insn "eh_set_lr_si" | |
ead0c1d5 RS |
9786 | [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN) |
9787 | (clobber (match_scratch:SI 1 "=&d"))] | |
9e800206 RH |
9788 | "! TARGET_64BIT" |
9789 | "#") | |
9790 | ||
9791 | (define_insn "eh_set_lr_di" | |
ead0c1d5 RS |
9792 | [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN) |
9793 | (clobber (match_scratch:DI 1 "=&d"))] | |
9e800206 RH |
9794 | "TARGET_64BIT" |
9795 | "#") | |
9796 | ||
9797 | (define_split | |
41f8d041 | 9798 | [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN) |
13c508d9 | 9799 | (clobber (match_scratch 1 ""))] |
2ca2d9ee | 9800 | "reload_completed && !TARGET_DEBUG_D_MODE" |
9e800206 RH |
9801 | [(const_int 0)] |
9802 | " | |
9803 | { | |
b2471838 | 9804 | mips_set_return_address (operands[0], operands[1]); |
9e800206 RH |
9805 | DONE; |
9806 | }") | |
68f4edf0 RH |
9807 | |
9808 | (define_insn "exception_receiver" | |
41f8d041 | 9809 | [(unspec_volatile [(const_int 0)] UNSPEC_EH_RECEIVER)] |
68f4edf0 | 9810 | "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)" |
b2471838 | 9811 | "* return mips_restore_gp (operands, insn);" |
68f4edf0 RH |
9812 | [(set_attr "type" "load") |
9813 | (set_attr "length" "8")]) | |
8ef30996 MM |
9814 | \f |
9815 | ;; | |
9816 | ;; .................... | |
9817 | ;; | |
9818 | ;; FUNCTION CALLS | |
9819 | ;; | |
9820 | ;; .................... | |
9821 | ||
cafe096b | 9822 | ;; Sibling calls. All these patterns use direct jumps. |
3f1f8d8c | 9823 | |
cafe096b EC |
9824 | ;; call_insn_operand will only accepts constant addresses if a direct |
9825 | ;; jump is acceptable. Since the 'S' constraint is defined in terms of | |
9826 | ;; call_insn_operand, the same is true of the contraints. | |
2bcb2ab3 | 9827 | |
cafe096b EC |
9828 | ;; When we use an indirect jump, we need a register that will be |
9829 | ;; preserved by the epilogue. Since TARGET_ABICALLS forces us to | |
9830 | ;; use $25 for this purpose -- and $25 is never clobbered by the | |
9831 | ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well. | |
8ef30996 | 9832 | |
cafe096b | 9833 | (define_expand "sibcall" |
aa4e54c4 JW |
9834 | [(parallel [(call (match_operand 0 "" "") |
9835 | (match_operand 1 "" "")) | |
cafe096b EC |
9836 | (use (match_operand 2 "" "")) ;; next_arg_reg |
9837 | (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx | |
9838 | "TARGET_SIBCALLS" | |
8ef30996 | 9839 | { |
cafe096b EC |
9840 | mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true); |
9841 | DONE; | |
9842 | }) | |
3f1f8d8c | 9843 | |
cafe096b EC |
9844 | (define_insn "sibcall_internal" |
9845 | [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S")) | |
9846 | (match_operand 1 "" ""))] | |
9847 | "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" | |
9848 | "@ | |
9849 | %*jr\\t%0 | |
9850 | %*j\\t%0" | |
9851 | [(set_attr "type" "call")]) | |
8ef30996 | 9852 | |
cafe096b | 9853 | (define_expand "sibcall_value" |
aa4e54c4 JW |
9854 | [(parallel [(set (match_operand 0 "" "") |
9855 | (call (match_operand 1 "" "") | |
9856 | (match_operand 2 "" ""))) | |
cafe096b EC |
9857 | (use (match_operand 3 "" ""))])] ;; next_arg_reg |
9858 | "TARGET_SIBCALLS" | |
84a92af4 | 9859 | { |
cafe096b EC |
9860 | mips_expand_call (operands[0], XEXP (operands[1], 0), |
9861 | operands[2], operands[3], true); | |
9862 | DONE; | |
9863 | }) | |
6d4503c3 | 9864 | |
cafe096b EC |
9865 | (define_insn "sibcall_value_internal" |
9866 | [(set (match_operand 0 "register_operand" "=df,df") | |
9867 | (call (mem:SI (match_operand 1 "call_insn_operand" "j,S")) | |
9868 | (match_operand 2 "" "")))] | |
9869 | "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" | |
9870 | "@ | |
9871 | %*jr\\t%1 | |
9872 | %*j\\t%1" | |
9873 | [(set_attr "type" "call")]) | |
9874 | ||
9875 | (define_insn "sibcall_value_multiple_internal" | |
9876 | [(set (match_operand 0 "register_operand" "=df,df") | |
9877 | (call (mem:SI (match_operand 1 "call_insn_operand" "j,S")) | |
9878 | (match_operand 2 "" ""))) | |
9879 | (set (match_operand 3 "register_operand" "=df,df") | |
9880 | (call (mem:SI (match_dup 1)) | |
9881 | (match_dup 2)))] | |
9882 | "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" | |
9883 | "@ | |
9884 | %*jr\\t%1 | |
9885 | %*j\\t%1" | |
9886 | [(set_attr "type" "call")]) | |
d1399bd0 | 9887 | |
cafe096b EC |
9888 | (define_expand "call" |
9889 | [(parallel [(call (match_operand 0 "" "") | |
9890 | (match_operand 1 "" "")) | |
9891 | (use (match_operand 2 "" "")) ;; next_arg_reg | |
9892 | (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx | |
9893 | "" | |
bb621ad7 | 9894 | { |
cafe096b EC |
9895 | mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false); |
9896 | DONE; | |
9897 | }) | |
bb621ad7 | 9898 | |
cafe096b EC |
9899 | (define_insn_and_split "call_internal" |
9900 | [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S")) | |
9901 | (match_operand 1 "" "")) | |
9902 | (clobber (reg:SI 31))] | |
9903 | "" | |
9904 | "%*jal\\t%0" | |
9905 | "reload_completed && TARGET_SPLIT_CALLS" | |
9906 | [(const_int 0)] | |
9907 | { | |
9908 | emit_call_insn (gen_call_split (operands[0], operands[1])); | |
9909 | emit_insn (gen_exception_receiver ()); | |
9910 | DONE; | |
9911 | } | |
9912 | [(set_attr "jal" "indirect,direct") | |
9913 | (set_attr "extended_mips16" "no,yes")]) | |
9914 | ||
9915 | (define_insn "call_split" | |
9916 | [(call (mem:SI (match_operand 0 "call_insn_operand" "c")) | |
9917 | (match_operand 1 "" "")) | |
9918 | (clobber (reg:SI 31)) | |
9919 | (const_int 1)] | |
9920 | "TARGET_SPLIT_CALLS" | |
9921 | "%*jalr\\t%0" | |
9922 | [(set_attr "type" "call")]) | |
84a92af4 | 9923 | |
cafe096b | 9924 | (define_expand "call_value" |
aa4e54c4 JW |
9925 | [(parallel [(set (match_operand 0 "" "") |
9926 | (call (match_operand 1 "" "") | |
9927 | (match_operand 2 "" ""))) | |
cafe096b | 9928 | (use (match_operand 3 "" ""))])] ;; next_arg_reg |
aa4e54c4 | 9929 | "" |
8f7f2b3d | 9930 | { |
cafe096b EC |
9931 | mips_expand_call (operands[0], XEXP (operands[1], 0), |
9932 | operands[2], operands[3], false); | |
9933 | DONE; | |
9934 | }) | |
8f7f2b3d | 9935 | |
cafe096b EC |
9936 | (define_insn_and_split "call_value_internal" |
9937 | [(set (match_operand 0 "register_operand" "=df,df") | |
9938 | (call (mem:SI (match_operand 1 "call_insn_operand" "c,S")) | |
9939 | (match_operand 2 "" ""))) | |
9940 | (clobber (reg:SI 31))] | |
9941 | "" | |
9942 | "%*jal\\t%1" | |
9943 | "reload_completed && TARGET_SPLIT_CALLS" | |
9944 | [(const_int 0)] | |
9945 | { | |
9946 | emit_call_insn (gen_call_value_split (operands[0], operands[1], | |
9947 | operands[2])); | |
9948 | emit_insn (gen_exception_receiver ()); | |
9949 | DONE; | |
9950 | } | |
9951 | [(set_attr "jal" "indirect,direct") | |
9952 | (set_attr "extended_mips16" "no,yes")]) | |
9953 | ||
9954 | (define_insn "call_value_split" | |
9955 | [(set (match_operand 0 "register_operand" "=df") | |
9956 | (call (mem:SI (match_operand 1 "call_insn_operand" "c")) | |
9957 | (match_operand 2 "" ""))) | |
9958 | (clobber (reg:SI 31)) | |
9959 | (const_int 1)] | |
9960 | "TARGET_SPLIT_CALLS" | |
9961 | "%*jalr\\t%1" | |
9962 | [(set_attr "type" "call")]) | |
9963 | ||
9964 | (define_insn_and_split "call_value_multiple_internal" | |
9965 | [(set (match_operand 0 "register_operand" "=df,df") | |
9966 | (call (mem:SI (match_operand 1 "call_insn_operand" "c,S")) | |
9967 | (match_operand 2 "" ""))) | |
9968 | (set (match_operand 3 "register_operand" "=df,df") | |
9969 | (call (mem:SI (match_dup 1)) | |
9970 | (match_dup 2))) | |
9971 | (clobber (reg:SI 31))] | |
9972 | "" | |
9973 | "%*jal\\t%1" | |
9974 | "reload_completed && TARGET_SPLIT_CALLS" | |
9975 | [(const_int 0)] | |
9976 | { | |
9977 | emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1], | |
9978 | operands[2], operands[3])); | |
9979 | emit_insn (gen_exception_receiver ()); | |
9980 | DONE; | |
9981 | } | |
9982 | [(set_attr "jal" "indirect,direct") | |
9983 | (set_attr "extended_mips16" "no,yes")]) | |
9984 | ||
9985 | (define_insn "call_value_multiple_split" | |
bd16a708 | 9986 | [(set (match_operand 0 "register_operand" "=df") |
cafe096b EC |
9987 | (call (mem:SI (match_operand 1 "call_insn_operand" "c")) |
9988 | (match_operand 2 "" ""))) | |
bd16a708 | 9989 | (set (match_operand 3 "register_operand" "=df") |
cafe096b EC |
9990 | (call (mem:SI (match_dup 1)) |
9991 | (match_dup 2))) | |
9992 | (clobber (reg:SI 31)) | |
9993 | (const_int 1)] | |
9994 | "TARGET_SPLIT_CALLS" | |
9995 | "%*jalr\\t%1" | |
9996 | [(set_attr "type" "call")]) | |
bd16a708 | 9997 | |
a93821e9 TW |
9998 | ;; Call subroutine returning any type. |
9999 | ||
10000 | (define_expand "untyped_call" | |
10001 | [(parallel [(call (match_operand 0 "" "") | |
10002 | (const_int 0)) | |
10003 | (match_operand 1 "" "") | |
10004 | (match_operand 2 "" "")])] | |
10005 | "" | |
10006 | " | |
10007 | { | |
cafe096b | 10008 | int i; |
a93821e9 | 10009 | |
cafe096b | 10010 | emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx)); |
a93821e9 | 10011 | |
cafe096b EC |
10012 | for (i = 0; i < XVECLEN (operands[2], 0); i++) |
10013 | { | |
10014 | rtx set = XVECEXP (operands[2], 0, i); | |
10015 | emit_move_insn (SET_DEST (set), SET_SRC (set)); | |
740b4585 | 10016 | } |
cafe096b EC |
10017 | |
10018 | emit_insn (gen_blockage ()); | |
10019 | DONE; | |
a93821e9 | 10020 | }") |
8ef30996 MM |
10021 | \f |
10022 | ;; | |
10023 | ;; .................... | |
10024 | ;; | |
10025 | ;; MISC. | |
10026 | ;; | |
10027 | ;; .................... | |
10028 | ;; | |
10029 | ||
8f2e3902 EC |
10030 | |
10031 | (define_expand "prefetch" | |
10032 | [(prefetch (match_operand 0 "address_operand" "") | |
10033 | (match_operand 1 "const_int_operand" "") | |
10034 | (match_operand 2 "const_int_operand" ""))] | |
10035 | "ISA_HAS_PREFETCH" | |
cafe096b EC |
10036 | { |
10037 | if (symbolic_operand (operands[0], GET_MODE (operands[0]))) | |
10038 | operands[0] = force_reg (GET_MODE (operands[0]), operands[0]); | |
10039 | }) | |
8f2e3902 EC |
10040 | |
10041 | (define_insn "prefetch_si_address" | |
10042 | [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r") | |
10043 | (match_operand:SI 3 "const_int_operand" "i")) | |
10044 | (match_operand:SI 1 "const_int_operand" "n") | |
10045 | (match_operand:SI 2 "const_int_operand" "n"))] | |
10046 | "ISA_HAS_PREFETCH && Pmode == SImode" | |
10047 | "* return mips_emit_prefetch (operands);" | |
cafe096b | 10048 | [(set_attr "type" "prefetch")]) |
8f2e3902 EC |
10049 | |
10050 | (define_insn "prefetch_si" | |
10051 | [(prefetch (match_operand:SI 0 "register_operand" "r") | |
10052 | (match_operand:SI 1 "const_int_operand" "n") | |
10053 | (match_operand:SI 2 "const_int_operand" "n"))] | |
10054 | "ISA_HAS_PREFETCH && Pmode == SImode" | |
10055 | "* return mips_emit_prefetch (operands);" | |
cafe096b | 10056 | [(set_attr "type" "prefetch")]) |
8f2e3902 EC |
10057 | |
10058 | (define_insn "prefetch_di_address" | |
cafe096b | 10059 | [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r") |
8f2e3902 EC |
10060 | (match_operand:DI 3 "const_int_operand" "i")) |
10061 | (match_operand:DI 1 "const_int_operand" "n") | |
10062 | (match_operand:DI 2 "const_int_operand" "n"))] | |
10063 | "ISA_HAS_PREFETCH && Pmode == DImode" | |
10064 | "* return mips_emit_prefetch (operands);" | |
cafe096b | 10065 | [(set_attr "type" "prefetch")]) |
8f2e3902 EC |
10066 | |
10067 | (define_insn "prefetch_di" | |
cafe096b | 10068 | [(prefetch (match_operand:DI 0 "register_operand" "r") |
8f2e3902 EC |
10069 | (match_operand:DI 1 "const_int_operand" "n") |
10070 | (match_operand:DI 2 "const_int_operand" "n"))] | |
10071 | "ISA_HAS_PREFETCH && Pmode == DImode" | |
10072 | "* return mips_emit_prefetch (operands);" | |
cafe096b | 10073 | [(set_attr "type" "prefetch")]) |
8f2e3902 | 10074 | |
8ef30996 MM |
10075 | (define_insn "nop" |
10076 | [(const_int 0)] | |
10077 | "" | |
10078 | "%(nop%)" | |
10079 | [(set_attr "type" "nop") | |
0ff83799 | 10080 | (set_attr "mode" "none")]) |
8ef30996 | 10081 | |
e454beb7 ILT |
10082 | ;; The MIPS chip does not seem to require stack probes. |
10083 | ;; | |
10084 | ;; (define_expand "probe" | |
10085 | ;; [(set (match_dup 0) | |
10086 | ;; (match_dup 1))] | |
10087 | ;; "" | |
10088 | ;; " | |
10089 | ;; { | |
10090 | ;; operands[0] = gen_reg_rtx (SImode); | |
c5c76735 | 10091 | ;; operands[1] = gen_rtx_MEM (SImode, stack_pointer_rtx); |
e454beb7 | 10092 | ;; MEM_VOLATILE_P (operands[1]) = TRUE; |
7a38df19 | 10093 | ;; |
e454beb7 ILT |
10094 | ;; /* fall through and generate default code */ |
10095 | ;; }") | |
10096 | ;; | |
e19ff60f JW |
10097 | \f |
10098 | ;; | |
10099 | ;; MIPS4 Conditional move instructions. | |
10100 | ||
10101 | (define_insn "" | |
10102 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
10103 | (if_then_else:SI | |
10104 | (match_operator 4 "equality_op" | |
10105 | [(match_operand:SI 1 "register_operand" "d,d") | |
10106 | (const_int 0)]) | |
10107 | (match_operand:SI 2 "reg_or_0_operand" "dJ,0") | |
10108 | (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))] | |
0025b7fa | 10109 | "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE" |
e19ff60f JW |
10110 | "@ |
10111 | mov%B4\\t%0,%z2,%1 | |
10112 | mov%b4\\t%0,%z3,%1" | |
10113 | [(set_attr "type" "move") | |
10114 | (set_attr "mode" "SI")]) | |
10115 | ||
197b2bf3 JW |
10116 | (define_insn "" |
10117 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
10118 | (if_then_else:SI | |
10119 | (match_operator 4 "equality_op" | |
cafe096b | 10120 | [(match_operand:DI 1 "register_operand" "d,d") |
197b2bf3 JW |
10121 | (const_int 0)]) |
10122 | (match_operand:SI 2 "reg_or_0_operand" "dJ,0") | |
10123 | (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))] | |
0025b7fa | 10124 | "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE" |
197b2bf3 JW |
10125 | "@ |
10126 | mov%B4\\t%0,%z2,%1 | |
10127 | mov%b4\\t%0,%z3,%1" | |
10128 | [(set_attr "type" "move") | |
10129 | (set_attr "mode" "SI")]) | |
10130 | ||
e19ff60f JW |
10131 | (define_insn "" |
10132 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
10133 | (if_then_else:SI | |
b8eb88d0 ILT |
10134 | (match_operator 3 "equality_op" [(match_operand:CC 4 |
10135 | "register_operand" | |
10136 | "z,z") | |
10137 | (const_int 0)]) | |
e19ff60f JW |
10138 | (match_operand:SI 1 "reg_or_0_operand" "dJ,0") |
10139 | (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))] | |
76ee8042 | 10140 | "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT" |
e19ff60f | 10141 | "@ |
b8eb88d0 ILT |
10142 | mov%T3\\t%0,%z1,%4 |
10143 | mov%t3\\t%0,%z2,%4" | |
e19ff60f JW |
10144 | [(set_attr "type" "move") |
10145 | (set_attr "mode" "SI")]) | |
10146 | ||
197b2bf3 JW |
10147 | (define_insn "" |
10148 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
10149 | (if_then_else:DI | |
10150 | (match_operator 4 "equality_op" | |
10151 | [(match_operand:SI 1 "register_operand" "d,d") | |
10152 | (const_int 0)]) | |
cafe096b EC |
10153 | (match_operand:DI 2 "reg_or_0_operand" "dJ,0") |
10154 | (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))] | |
d6b6ba29 | 10155 | "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT" |
197b2bf3 JW |
10156 | "@ |
10157 | mov%B4\\t%0,%z2,%1 | |
10158 | mov%b4\\t%0,%z3,%1" | |
10159 | [(set_attr "type" "move") | |
10160 | (set_attr "mode" "DI")]) | |
10161 | ||
e19ff60f JW |
10162 | (define_insn "" |
10163 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
10164 | (if_then_else:DI | |
10165 | (match_operator 4 "equality_op" | |
cafe096b | 10166 | [(match_operand:DI 1 "register_operand" "d,d") |
e19ff60f | 10167 | (const_int 0)]) |
cafe096b EC |
10168 | (match_operand:DI 2 "reg_or_0_operand" "dJ,0") |
10169 | (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))] | |
d6b6ba29 | 10170 | "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT" |
e19ff60f JW |
10171 | "@ |
10172 | mov%B4\\t%0,%z2,%1 | |
10173 | mov%b4\\t%0,%z3,%1" | |
10174 | [(set_attr "type" "move") | |
10175 | (set_attr "mode" "DI")]) | |
10176 | ||
10177 | (define_insn "" | |
10178 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
10179 | (if_then_else:DI | |
b8eb88d0 ILT |
10180 | (match_operator 3 "equality_op" [(match_operand:CC 4 |
10181 | "register_operand" | |
10182 | "z,z") | |
10183 | (const_int 0)]) | |
cafe096b EC |
10184 | (match_operand:DI 1 "reg_or_0_operand" "dJ,0") |
10185 | (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))] | |
d6b6ba29 | 10186 | "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT" |
e19ff60f | 10187 | "@ |
b8eb88d0 ILT |
10188 | mov%T3\\t%0,%z1,%4 |
10189 | mov%t3\\t%0,%z2,%4" | |
e19ff60f JW |
10190 | [(set_attr "type" "move") |
10191 | (set_attr "mode" "DI")]) | |
10192 | ||
10193 | (define_insn "" | |
10194 | [(set (match_operand:SF 0 "register_operand" "=f,f") | |
10195 | (if_then_else:SF | |
10196 | (match_operator 4 "equality_op" | |
10197 | [(match_operand:SI 1 "register_operand" "d,d") | |
10198 | (const_int 0)]) | |
10199 | (match_operand:SF 2 "register_operand" "f,0") | |
10200 | (match_operand:SF 3 "register_operand" "0,f")))] | |
76ee8042 | 10201 | "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT" |
e19ff60f JW |
10202 | "@ |
10203 | mov%B4.s\\t%0,%2,%1 | |
10204 | mov%b4.s\\t%0,%3,%1" | |
10205 | [(set_attr "type" "move") | |
10206 | (set_attr "mode" "SF")]) | |
10207 | ||
b3a79892 MM |
10208 | (define_insn "" |
10209 | [(set (match_operand:SF 0 "register_operand" "=f,f") | |
10210 | (if_then_else:SF | |
10211 | (match_operator 4 "equality_op" | |
cafe096b | 10212 | [(match_operand:DI 1 "register_operand" "d,d") |
b3a79892 MM |
10213 | (const_int 0)]) |
10214 | (match_operand:SF 2 "register_operand" "f,0") | |
10215 | (match_operand:SF 3 "register_operand" "0,f")))] | |
76ee8042 | 10216 | "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT" |
b3a79892 MM |
10217 | "@ |
10218 | mov%B4.s\\t%0,%2,%1 | |
10219 | mov%b4.s\\t%0,%3,%1" | |
10220 | [(set_attr "type" "move") | |
10221 | (set_attr "mode" "SF")]) | |
10222 | ||
e19ff60f JW |
10223 | (define_insn "" |
10224 | [(set (match_operand:SF 0 "register_operand" "=f,f") | |
10225 | (if_then_else:SF | |
b8eb88d0 ILT |
10226 | (match_operator 3 "equality_op" [(match_operand:CC 4 |
10227 | "register_operand" | |
10228 | "z,z") | |
10229 | (const_int 0)]) | |
e19ff60f JW |
10230 | (match_operand:SF 1 "register_operand" "f,0") |
10231 | (match_operand:SF 2 "register_operand" "0,f")))] | |
76ee8042 | 10232 | "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT" |
e19ff60f | 10233 | "@ |
b8eb88d0 ILT |
10234 | mov%T3.s\\t%0,%1,%4 |
10235 | mov%t3.s\\t%0,%2,%4" | |
e19ff60f JW |
10236 | [(set_attr "type" "move") |
10237 | (set_attr "mode" "SF")]) | |
10238 | ||
10239 | (define_insn "" | |
10240 | [(set (match_operand:DF 0 "register_operand" "=f,f") | |
10241 | (if_then_else:DF | |
10242 | (match_operator 4 "equality_op" | |
10243 | [(match_operand:SI 1 "register_operand" "d,d") | |
10244 | (const_int 0)]) | |
10245 | (match_operand:DF 2 "register_operand" "f,0") | |
10246 | (match_operand:DF 3 "register_operand" "0,f")))] | |
76ee8042 | 10247 | "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
b3a79892 MM |
10248 | "@ |
10249 | mov%B4.d\\t%0,%2,%1 | |
10250 | mov%b4.d\\t%0,%3,%1" | |
10251 | [(set_attr "type" "move") | |
10252 | (set_attr "mode" "DF")]) | |
10253 | ||
10254 | (define_insn "" | |
10255 | [(set (match_operand:DF 0 "register_operand" "=f,f") | |
10256 | (if_then_else:DF | |
10257 | (match_operator 4 "equality_op" | |
cafe096b | 10258 | [(match_operand:DI 1 "register_operand" "d,d") |
b3a79892 MM |
10259 | (const_int 0)]) |
10260 | (match_operand:DF 2 "register_operand" "f,0") | |
10261 | (match_operand:DF 3 "register_operand" "0,f")))] | |
76ee8042 | 10262 | "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
e19ff60f JW |
10263 | "@ |
10264 | mov%B4.d\\t%0,%2,%1 | |
10265 | mov%b4.d\\t%0,%3,%1" | |
10266 | [(set_attr "type" "move") | |
10267 | (set_attr "mode" "DF")]) | |
10268 | ||
10269 | (define_insn "" | |
10270 | [(set (match_operand:DF 0 "register_operand" "=f,f") | |
10271 | (if_then_else:DF | |
b8eb88d0 ILT |
10272 | (match_operator 3 "equality_op" [(match_operand:CC 4 |
10273 | "register_operand" | |
10274 | "z,z") | |
10275 | (const_int 0)]) | |
e19ff60f JW |
10276 | (match_operand:DF 1 "register_operand" "f,0") |
10277 | (match_operand:DF 2 "register_operand" "0,f")))] | |
76ee8042 | 10278 | "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
e19ff60f | 10279 | "@ |
b8eb88d0 ILT |
10280 | mov%T3.d\\t%0,%1,%4 |
10281 | mov%t3.d\\t%0,%2,%4" | |
e19ff60f JW |
10282 | [(set_attr "type" "move") |
10283 | (set_attr "mode" "DF")]) | |
10284 | ||
10285 | ;; These are the main define_expand's used to make conditional moves. | |
10286 | ||
10287 | (define_expand "movsicc" | |
10288 | [(set (match_dup 4) (match_operand 1 "comparison_operator" "")) | |
10289 | (set (match_operand:SI 0 "register_operand" "") | |
10290 | (if_then_else:SI (match_dup 5) | |
10291 | (match_operand:SI 2 "reg_or_0_operand" "") | |
10292 | (match_operand:SI 3 "reg_or_0_operand" "")))] | |
0025b7fa | 10293 | "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE" |
e19ff60f JW |
10294 | " |
10295 | { | |
b8eb88d0 ILT |
10296 | gen_conditional_move (operands); |
10297 | DONE; | |
10298 | }") | |
e19ff60f | 10299 | |
b8eb88d0 ILT |
10300 | (define_expand "movdicc" |
10301 | [(set (match_dup 4) (match_operand 1 "comparison_operator" "")) | |
10302 | (set (match_operand:DI 0 "register_operand" "") | |
10303 | (if_then_else:DI (match_dup 5) | |
cafe096b EC |
10304 | (match_operand:DI 2 "reg_or_0_operand" "") |
10305 | (match_operand:DI 3 "reg_or_0_operand" "")))] | |
d6b6ba29 | 10306 | "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT" |
b8eb88d0 ILT |
10307 | " |
10308 | { | |
10309 | gen_conditional_move (operands); | |
10310 | DONE; | |
10311 | }") | |
e19ff60f | 10312 | |
b8eb88d0 ILT |
10313 | (define_expand "movsfcc" |
10314 | [(set (match_dup 4) (match_operand 1 "comparison_operator" "")) | |
10315 | (set (match_operand:SF 0 "register_operand" "") | |
10316 | (if_then_else:SF (match_dup 5) | |
91760fce ILT |
10317 | (match_operand:SF 2 "register_operand" "") |
10318 | (match_operand:SF 3 "register_operand" "")))] | |
76ee8042 | 10319 | "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT" |
b8eb88d0 ILT |
10320 | " |
10321 | { | |
10322 | gen_conditional_move (operands); | |
10323 | DONE; | |
e19ff60f JW |
10324 | }") |
10325 | ||
b8eb88d0 ILT |
10326 | (define_expand "movdfcc" |
10327 | [(set (match_dup 4) (match_operand 1 "comparison_operator" "")) | |
10328 | (set (match_operand:DF 0 "register_operand" "") | |
10329 | (if_then_else:DF (match_dup 5) | |
91760fce ILT |
10330 | (match_operand:DF 2 "register_operand" "") |
10331 | (match_operand:DF 3 "register_operand" "")))] | |
76ee8042 | 10332 | "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" |
b8eb88d0 ILT |
10333 | " |
10334 | { | |
10335 | gen_conditional_move (operands); | |
10336 | DONE; | |
10337 | }") | |
2bcb2ab3 GK |
10338 | \f |
10339 | ;; | |
10340 | ;; .................... | |
10341 | ;; | |
10342 | ;; mips16 inline constant tables | |
10343 | ;; | |
10344 | ;; .................... | |
10345 | ;; | |
10346 | ||
10347 | (define_insn "consttable_qi" | |
41f8d041 RS |
10348 | [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")] |
10349 | UNSPEC_CONSTTABLE_QI)] | |
2bcb2ab3 GK |
10350 | "TARGET_MIPS16" |
10351 | "* | |
10352 | { | |
c8af3574 | 10353 | assemble_integer (operands[0], 1, BITS_PER_UNIT, 1); |
2bcb2ab3 GK |
10354 | return \"\"; |
10355 | }" | |
10356 | [(set_attr "type" "unknown") | |
10357 | (set_attr "mode" "QI") | |
0ff83799 | 10358 | (set_attr "length" "8")]) |
2bcb2ab3 GK |
10359 | |
10360 | (define_insn "consttable_hi" | |
41f8d041 RS |
10361 | [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")] |
10362 | UNSPEC_CONSTTABLE_HI)] | |
2bcb2ab3 GK |
10363 | "TARGET_MIPS16" |
10364 | "* | |
10365 | { | |
c8af3574 | 10366 | assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1); |
2bcb2ab3 GK |
10367 | return \"\"; |
10368 | }" | |
10369 | [(set_attr "type" "unknown") | |
10370 | (set_attr "mode" "HI") | |
0ff83799 | 10371 | (set_attr "length" "8")]) |
2bcb2ab3 GK |
10372 | |
10373 | (define_insn "consttable_si" | |
41f8d041 RS |
10374 | [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")] |
10375 | UNSPEC_CONSTTABLE_SI)] | |
2bcb2ab3 GK |
10376 | "TARGET_MIPS16" |
10377 | "* | |
10378 | { | |
c8af3574 | 10379 | assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1); |
2bcb2ab3 GK |
10380 | return \"\"; |
10381 | }" | |
10382 | [(set_attr "type" "unknown") | |
10383 | (set_attr "mode" "SI") | |
0ff83799 | 10384 | (set_attr "length" "8")]) |
2bcb2ab3 GK |
10385 | |
10386 | (define_insn "consttable_di" | |
41f8d041 RS |
10387 | [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")] |
10388 | UNSPEC_CONSTTABLE_DI)] | |
2bcb2ab3 GK |
10389 | "TARGET_MIPS16" |
10390 | "* | |
10391 | { | |
c8af3574 | 10392 | assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1); |
2bcb2ab3 GK |
10393 | return \"\"; |
10394 | }" | |
10395 | [(set_attr "type" "unknown") | |
10396 | (set_attr "mode" "DI") | |
0ff83799 | 10397 | (set_attr "length" "16")]) |
2bcb2ab3 GK |
10398 | |
10399 | (define_insn "consttable_sf" | |
41f8d041 RS |
10400 | [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")] |
10401 | UNSPEC_CONSTTABLE_SF)] | |
2bcb2ab3 GK |
10402 | "TARGET_MIPS16" |
10403 | "* | |
10404 | { | |
81b4c798 | 10405 | REAL_VALUE_TYPE d; |
2bcb2ab3 GK |
10406 | |
10407 | if (GET_CODE (operands[0]) != CONST_DOUBLE) | |
10408 | abort (); | |
81b4c798 ZW |
10409 | REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]); |
10410 | assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode)); | |
2bcb2ab3 GK |
10411 | return \"\"; |
10412 | }" | |
10413 | [(set_attr "type" "unknown") | |
10414 | (set_attr "mode" "SF") | |
0ff83799 | 10415 | (set_attr "length" "8")]) |
2bcb2ab3 GK |
10416 | |
10417 | (define_insn "consttable_df" | |
41f8d041 RS |
10418 | [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")] |
10419 | UNSPEC_CONSTTABLE_DF)] | |
2bcb2ab3 GK |
10420 | "TARGET_MIPS16" |
10421 | "* | |
10422 | { | |
81b4c798 | 10423 | REAL_VALUE_TYPE d; |
2bcb2ab3 GK |
10424 | |
10425 | if (GET_CODE (operands[0]) != CONST_DOUBLE) | |
10426 | abort (); | |
81b4c798 ZW |
10427 | REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]); |
10428 | assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode)); | |
2bcb2ab3 GK |
10429 | return \"\"; |
10430 | }" | |
10431 | [(set_attr "type" "unknown") | |
10432 | (set_attr "mode" "DF") | |
0ff83799 | 10433 | (set_attr "length" "16")]) |
2bcb2ab3 GK |
10434 | |
10435 | (define_insn "align_2" | |
41f8d041 | 10436 | [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_2)] |
2bcb2ab3 GK |
10437 | "TARGET_MIPS16" |
10438 | ".align 1" | |
10439 | [(set_attr "type" "unknown") | |
10440 | (set_attr "mode" "HI") | |
0ff83799 | 10441 | (set_attr "length" "8")]) |
2bcb2ab3 GK |
10442 | |
10443 | (define_insn "align_4" | |
41f8d041 | 10444 | [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_4)] |
2bcb2ab3 GK |
10445 | "TARGET_MIPS16" |
10446 | ".align 2" | |
10447 | [(set_attr "type" "unknown") | |
10448 | (set_attr "mode" "SI") | |
0ff83799 | 10449 | (set_attr "length" "8")]) |
2bcb2ab3 GK |
10450 | |
10451 | (define_insn "align_8" | |
41f8d041 | 10452 | [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_8)] |
2bcb2ab3 GK |
10453 | "TARGET_MIPS16" |
10454 | ".align 3" | |
10455 | [(set_attr "type" "unknown") | |
10456 | (set_attr "mode" "DI") | |
0ff83799 | 10457 | (set_attr "length" "12")]) |
2bcb2ab3 GK |
10458 | \f |
10459 | ;; | |
10460 | ;; .................... | |
10461 | ;; | |
10462 | ;; mips16 peepholes | |
10463 | ;; | |
10464 | ;; .................... | |
10465 | ;; | |
10466 | ||
10467 | ;; On the mips16, reload will sometimes decide that a pseudo register | |
10468 | ;; should go into $24, and then later on have to reload that register. | |
10469 | ;; When that happens, we get a load of a general register followed by | |
10470 | ;; a move from the general register to $24 followed by a branch. | |
10471 | ;; These peepholes catch the common case, and fix it to just use the | |
10472 | ;; general register for the branch. | |
10473 | ||
10474 | (define_peephole | |
10475 | [(set (match_operand:SI 0 "register_operand" "=t") | |
10476 | (match_operand:SI 1 "register_operand" "d")) | |
10477 | (set (pc) | |
10478 | (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0) | |
10479 | (const_int 0)]) | |
10480 | (match_operand 3 "pc_or_label_operand" "") | |
10481 | (match_operand 4 "pc_or_label_operand" "")))] | |
10482 | "TARGET_MIPS16 | |
10483 | && GET_CODE (operands[0]) == REG | |
10484 | && REGNO (operands[0]) == 24 | |
10485 | && dead_or_set_p (insn, operands[0]) | |
10486 | && GET_CODE (operands[1]) == REG | |
10487 | && M16_REG_P (REGNO (operands[1]))" | |
10488 | "* | |
10489 | { | |
10490 | if (operands[3] != pc_rtx) | |
10491 | return \"%*b%C2z\\t%1,%3\"; | |
10492 | else | |
10493 | return \"%*b%N2z\\t%1,%4\"; | |
10494 | }" | |
10495 | [(set_attr "type" "branch") | |
10496 | (set_attr "mode" "none") | |
0ff83799 | 10497 | (set_attr "length" "8")]) |
2bcb2ab3 GK |
10498 | |
10499 | (define_peephole | |
10500 | [(set (match_operand:DI 0 "register_operand" "=t") | |
10501 | (match_operand:DI 1 "register_operand" "d")) | |
10502 | (set (pc) | |
10503 | (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0) | |
10504 | (const_int 0)]) | |
10505 | (match_operand 3 "pc_or_label_operand" "") | |
10506 | (match_operand 4 "pc_or_label_operand" "")))] | |
10507 | "TARGET_MIPS16 && TARGET_64BIT | |
10508 | && GET_CODE (operands[0]) == REG | |
10509 | && REGNO (operands[0]) == 24 | |
10510 | && dead_or_set_p (insn, operands[0]) | |
10511 | && GET_CODE (operands[1]) == REG | |
10512 | && M16_REG_P (REGNO (operands[1]))" | |
10513 | "* | |
10514 | { | |
10515 | if (operands[3] != pc_rtx) | |
10516 | return \"%*b%C2z\\t%1,%3\"; | |
10517 | else | |
10518 | return \"%*b%N2z\\t%1,%4\"; | |
10519 | }" | |
10520 | [(set_attr "type" "branch") | |
10521 | (set_attr "mode" "none") | |
0ff83799 | 10522 | (set_attr "length" "8")]) |
2bcb2ab3 GK |
10523 | |
10524 | ;; We can also have the reverse reload: reload will spill $24 into | |
10525 | ;; another register, and then do a branch on that register when it | |
10526 | ;; could have just stuck with $24. | |
10527 | ||
10528 | (define_peephole | |
10529 | [(set (match_operand:SI 0 "register_operand" "=d") | |
10530 | (match_operand:SI 1 "register_operand" "t")) | |
10531 | (set (pc) | |
10532 | (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0) | |
10533 | (const_int 0)]) | |
10534 | (match_operand 3 "pc_or_label_operand" "") | |
10535 | (match_operand 4 "pc_or_label_operand" "")))] | |
10536 | "TARGET_MIPS16 | |
10537 | && GET_CODE (operands[1]) == REG | |
10538 | && REGNO (operands[1]) == 24 | |
10539 | && GET_CODE (operands[0]) == REG | |
10540 | && M16_REG_P (REGNO (operands[0])) | |
10541 | && dead_or_set_p (insn, operands[0])" | |
10542 | "* | |
10543 | { | |
10544 | if (operands[3] != pc_rtx) | |
10545 | return \"%*bt%C2z\\t%3\"; | |
10546 | else | |
10547 | return \"%*bt%N2z\\t%4\"; | |
10548 | }" | |
10549 | [(set_attr "type" "branch") | |
10550 | (set_attr "mode" "none") | |
0ff83799 | 10551 | (set_attr "length" "8")]) |
2bcb2ab3 GK |
10552 | |
10553 | (define_peephole | |
10554 | [(set (match_operand:DI 0 "register_operand" "=d") | |
10555 | (match_operand:DI 1 "register_operand" "t")) | |
10556 | (set (pc) | |
10557 | (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0) | |
10558 | (const_int 0)]) | |
10559 | (match_operand 3 "pc_or_label_operand" "") | |
10560 | (match_operand 4 "pc_or_label_operand" "")))] | |
10561 | "TARGET_MIPS16 && TARGET_64BIT | |
10562 | && GET_CODE (operands[1]) == REG | |
10563 | && REGNO (operands[1]) == 24 | |
10564 | && GET_CODE (operands[0]) == REG | |
10565 | && M16_REG_P (REGNO (operands[0])) | |
10566 | && dead_or_set_p (insn, operands[0])" | |
10567 | "* | |
10568 | { | |
10569 | if (operands[3] != pc_rtx) | |
10570 | return \"%*bt%C2z\\t%3\"; | |
10571 | else | |
10572 | return \"%*bt%N2z\\t%4\"; | |
10573 | }" | |
10574 | [(set_attr "type" "branch") | |
10575 | (set_attr "mode" "none") | |
0ff83799 | 10576 | (set_attr "length" "8")]) |