]>
Commit | Line | Data |
---|---|---|
65c78c7d | 1 | ;; Machine description for the TMS320C[34]x for GNU C compiler |
ae1f640f | 2 | ;; Copyright (C) 1994, 1995, 1996, 1997, 1998, |
e03f5d43 | 3 | ;; 1999, 2000, 2002 Free Software Foundation, Inc. |
cb0ca284 | 4 | |
5e6a42d9 | 5 | ;; Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz) |
cb0ca284 MH |
6 | ;; and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl) |
7 | ||
8 | ;; This file is part of GNU CC. | |
9 | ||
10 | ;; GNU CC is free software; you can redistribute it and/or modify | |
11 | ;; it under the terms of the GNU General Public License as published by | |
12 | ;; the Free Software Foundation; either version 2, or (at your option) | |
13 | ;; any later version. | |
14 | ||
15 | ;; GNU CC is distributed in the hope that it will be useful, | |
16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | ;; GNU General Public License for more details. | |
19 | ||
20 | ;; You should have received a copy of the GNU General Public License | |
21 | ;; along with GNU CC; see the file COPYING. If not, write to | |
22 | ;; the Free Software Foundation, 59 Temple Place - Suite 330, | |
23 | ;; Boston, MA 02111-1307, USA. | |
24 | ||
25 | ; | |
26 | ; TODO : | |
cb0ca284 MH |
27 | ; Try using PQImode again for addresses since C30 only uses |
28 | ; 24-bit addresses. Ideally GCC would emit different insns | |
29 | ; for QImode and Pmode, whether Pmode was QImode or PQImode. | |
30 | ; For addresses we wouldn't have to have a clobber of the CC | |
31 | ; associated with each insn and we could use MPYI in address | |
32 | ; calculations without having to synthesise a proper 32 bit multiply. | |
33 | ||
34 | ; Additional C30/C40 instructions not coded: | |
35 | ; CALLcond, IACK, IDLE, LDE, LDFI, LDII, LDM, NORM, RETIcond | |
8a119a7d | 36 | ; ROLC, RORC, SIGI, STFI, STII, SUBC, SWI |
cb0ca284 MH |
37 | |
38 | ; Additional C40 instructions not coded: | |
8a119a7d | 39 | ; LDEP, LDPE, LWRct, LAJcond, RETIcondD |
cb0ca284 MH |
40 | |
41 | ; | |
42 | ; C4x MODES | |
43 | ; | |
44 | ; QImode char, short, int, long (32-bits) | |
45 | ; HImode long long (64-bits) | |
46 | ; QFmode float, double (32-bits) | |
47 | ; HFmode long double (40-bits) | |
48 | ; CCmode | |
49 | ; CC_NOOVmode | |
50 | ||
51 | ; | |
52 | ; C4x PREDICATES: | |
53 | ; | |
54 | ; comparison_operator LT, GT, LE, GE, LTU, GTU, LEU, GEU, EQ, NE | |
55 | ; memory_operand memory [m] | |
56 | ; immediate_operand immediate constant [IKN] | |
57 | ; register_operand register [rf] | |
58 | ; general_operand register, memory, constant [rfmI] | |
59 | ||
60 | ; addr_reg_operand AR0-AR7, pseudo reg [a] | |
61 | ; sp_reg_operand SP [b] | |
62 | ; std_reg_operand AR0-AR7, IR0-IR1, RC, RS, RE, SP, pseudo [c] | |
63 | ; ext_reg_operand R0-R11, pseudo reg [f] | |
64 | ; ext_low_reg_operand R0-R7, pseudo reg [q] | |
65 | ; index_reg_operand IR0-IR1, pseudo reg [x] | |
66 | ; st_reg_operand ST [y] | |
67 | ; dp_reg_operand DP [z] | |
68 | ; stik_const_operand 5-bit const [K] | |
50c33087 | 69 | ; src_operand general operand [rfHmI] |
cb0ca284 MH |
70 | ; par_ind_operand indirect S mode (ARx + 0, 1, IRx) [S<>] |
71 | ; parallel_operand par_ind_operand or ext_low_reg_operand | |
31445126 MH |
72 | ; symbolic_address_operand |
73 | ; call_address_operand | |
cb0ca284 MH |
74 | |
75 | ; ADDI src2, src1, dst three operand op | |
76 | ; ADDI src, dst two operand op | |
77 | ||
78 | ; Note that the predicates are only used when selecting a pattern | |
79 | ; to determine if an operand is valid. | |
80 | ||
81 | ; The constraints then select which of the possible valid operands | |
82 | ; is present (and guide register selection). The actual assembly | |
83 | ; instruction is then selected on the basis of the constraints. | |
84 | ||
85 | ; The extra constraint (valid_operands) is used to determine if | |
86 | ; the combination of operands is legitimate for the pattern. | |
87 | ||
88 | ; | |
89 | ; C4x CONSTRAINTS: | |
90 | ; | |
91 | ; a address reg AR0-AR7 | |
92 | ; b stack pointer SP | |
93 | ; c other int reg AR0-AR7, IR0-IR1, RC, RS, RE | |
94 | ; d fp reg R0-R11 (sets CC when dst) | |
959e0a76 | 95 | ; e |
cb0ca284 MH |
96 | ; f fp reg R0-R11 (sets CC when dst) |
97 | ; g general reg, memory, constant | |
959e0a76 | 98 | ; h fp reg (HFmode) R0-R11 (sets CC when dst) |
cb0ca284 | 99 | ; i immediate int constant |
959e0a76 MH |
100 | ; j |
101 | ; k block count BK | |
102 | ; l | |
cb0ca284 | 103 | ; m memory |
959e0a76 MH |
104 | ; n immediate int constant with known numeric value |
105 | ; o offsettable memory | |
106 | ; p memory address | |
cb0ca284 MH |
107 | ; q low fp reg R0-R7 (sets CC when dst) |
108 | ; r general reg R0-R11, AR0-AR7, IR0-IR1, RC, RS, RE | |
959e0a76 | 109 | ; s immediate int constant (value not explicit) |
cb0ca284 MH |
110 | ; t R0-R1 |
111 | ; u R2-R3 | |
959e0a76 MH |
112 | ; v repeat count reg RC |
113 | ; w | |
cb0ca284 MH |
114 | ; x index reg IR0-IR1 |
115 | ; y status (CC) reg ST | |
116 | ; z data pointer DP | |
117 | ||
118 | ; G fp zero | |
119 | ; H fp 16-bit constant | |
120 | ; I signed 16-bit | |
121 | ; J signed 8-bit (C4x only) | |
122 | ; K signed 5-bit (C4x only) | |
123 | ; L unsigned 16-bit | |
124 | ; M unsigned 8-bit (C4x only) | |
125 | ; N ones complement of unsigned 16-bit | |
126 | ; O 16 bit high constant | |
127 | ; Q ARx + 9-bit signed disp | |
128 | ; R ARx + 5-bit unsigned disp (C4x only) | |
129 | ; S ARx + 0, 1, IRx disp | |
50c33087 | 130 | ; T direct memory operand |
959e0a76 MH |
131 | ; V non offsettable memory |
132 | ; X any operand | |
cb0ca284 MH |
133 | ; < memory operand with autodecrement addressing |
134 | ; > memory operand with autoincrement addressing | |
135 | ; { memory operand with pre-modify addressing | |
136 | ; } memory operand with post-modify addressing | |
137 | ||
50c33087 MH |
138 | ; Note that the 'd', 'f', and 'h' constraints are equivalent. |
139 | ; The m constraint is equivalent to 'QT<>{}' | |
140 | ||
141 | ; Note we cannot use the 'g' constraint with Pmode (i.e, QImode) | |
142 | ; operations since LEGITIMATE_CONSTANT_P accepts SYMBOL_REF. | |
143 | ; So instead we use 'rIm' for signed operands or 'rLm' for unsigned operands. | |
cb0ca284 MH |
144 | |
145 | ; Note that the constraints are used to select the operands | |
146 | ; for a chosen pattern. The constraint that requires the fewest | |
147 | ; instructions to load an operand is chosen. | |
148 | ||
149 | ; Note that the 'r' constraint is mostly only used for src integer register | |
150 | ; operands, while 'c' and 'd' constraints are generally only used for dst | |
151 | ; integer register operands (the 'r' constraint is the union of the 'c' and | |
152 | ; 'd' constraints). When a register satisfying the 'd' constraint | |
153 | ; is used as a dst operand, the CC gets clobbered (except for LDIcond)---but | |
154 | ; not for 'c'. | |
155 | ||
156 | ; The 'f' constraint is only for float register operands---when | |
157 | ; a register satisying the 'f' constraint is used as a dst operand, | |
158 | ; the CC gets clobbered (except for LDFcond). | |
159 | ||
160 | ; The ! in front of the 'b' constaint says to GCC to disparage the | |
161 | ; use of this constraint. The 'b' constraint applies only to the SP. | |
162 | ||
163 | ; Note that we deal with the condition code CC like some of the RISC | |
164 | ; architectures (arm, sh, sparc) where it is stored in a general register, | |
165 | ; in this case the hard register ST (21). Unlike these other architectures | |
166 | ; that do not set the CC with many instructions, the C[34]x architectures | |
167 | ; sets the CC for many instructions when the destination register is | |
168 | ; an extended precision register. While it would have been easier | |
169 | ; to use the generic cc0 register to store the CC, as with most of | |
170 | ; the other ported architectures, this constrains the setting and testing | |
171 | ; of the CC to be consecutive insns. Thus we would reduce the benefit | |
172 | ; of scheduling instructions to avoid pipeline conflicts and filling of | |
173 | ; delayed branch slots. | |
174 | ||
175 | ; Since the C[34]x has many instructions that set the CC, we pay the | |
176 | ; price of having to explicity define which insns clobber the CC | |
177 | ; (rather than using the macro NOTICE_UPDATE_CC). | |
178 | ||
179 | ; Note that many patterns say that the CC is clobbered when in fact | |
180 | ; that it may not be (depending on the destination register). | |
181 | ; We have to cover ourselves if an extended precision register | |
182 | ; is allocated to the destination register. | |
183 | ; Unfortunately, it is not easy to tell GCC that the clobbering of CC | |
184 | ; is register dependent. If we could tolerate the ST register being | |
185 | ; copied about, then we could store the CC in a pseudo register and | |
186 | ; use constructs such as (clobber (match_scratch:CC N "&y,X")) to | |
187 | ; indicate that the 'y' class (ST register) is clobbered for the | |
188 | ; first combination of operands, but not with the second. | |
189 | ; I tried this approach for a while but reload got unhappy since I | |
190 | ; didn't allow it to move the CC around. | |
191 | ||
192 | ; Note that fundamental operations, such as moves, must not clobber the | |
193 | ; CC. Thus movqi choses a move instruction that doesn't clobber the CC. | |
194 | ; If GCC wants to combine a move with a compare, it is smart enough to | |
195 | ; chose the move instruction that sets the CC. | |
196 | ||
197 | ; Unfortunately, the C[34]x instruction set does not have arithmetic or | |
198 | ; logical operations that never touch the CC. We thus have to assume | |
199 | ; that the CC may be clobbered at all times. If we define patterns | |
200 | ; such as addqi without the clobber of CC, then GCC will be forced | |
201 | ; to use registers such as the auxiliary registers which can cause | |
202 | ; horrible pipeline conflicts. The tradeoff is that GCC can't now | |
203 | ; sneak in an add instruction between setting and testing of the CC. | |
204 | ||
205 | ; Most of the C[34]x instructions require operands of the following formats, | |
206 | ; where imm represents an immediate constant, dir a direct memory reference, | |
207 | ; ind an indirect memory reference, and reg a register: | |
208 | ||
209 | ; src2 (op2) src1 (op1) dst (op0) | |
210 | ; imm dir ind reg | imm dir ind reg | reg Notes | |
211 | ;---------------------+----------------------+------ | |
212 | ; ILH T Q<> r | - - - 0 | r 2 operand | |
213 | ; - - S<> r | - - S<> r | r | |
214 | ; J - R - | - - R r | r C4x | |
215 | ||
216 | ; Arithmetic operations use the I, J constraints for immediate constants, | |
217 | ; while logical operations use the L, J constraints. Floating point | |
218 | ; operations use the H constraint for immediate constants. | |
219 | ||
220 | ; With most instructions the src2 and src1 operands are commutative | |
221 | ; (except for SUB, SUBR, ANDN). The assembler considers | |
222 | ; ADDI 10, R0, R1 and ADDI R0, 10, R1 to be equivalent. | |
223 | ; We thus match src2 and src1 with the src_operand predicate and | |
224 | ; use valid_operands as the extra constraint to reject invalid | |
225 | ; operand combinations. For example, ADDI @foo, @bar, R0. | |
226 | ||
227 | ; Note that we use the ? modifier so that reload doesn't preferentially | |
228 | ; try the alternative where three registers are acceptable as | |
229 | ; operands (whenever an operand requires reloading). Instead it will try | |
230 | ; the 2 operand form which will produce better code since it won't require | |
231 | ; a new spill register. | |
232 | ||
233 | ; Note that the floating point representation of 0.0 on the C4x | |
234 | ; is 0x80000000 (-2147483648). This value produces an warning | |
235 | ; message on 32-bit machines about the decimal constant being so large | |
236 | ; that it is unsigned. | |
237 | ||
238 | ; With two operand instructions patterns having two sets, | |
239 | ; the compare set must come first to keep the combiner happy. | |
240 | ; While the combiner seems to cope most of the time with the | |
241 | ; compare set coming second, it's best to have it first. | |
242 | ||
243 | ; | |
244 | ; C4x CONSTANT attributes | |
245 | ; | |
246 | (define_attr "cpu" "c4x,c3x" | |
247 | (const | |
248 | (cond [(symbol_ref "TARGET_C3X") (const_string "c3x")] | |
249 | (const_string "c4x")))) | |
250 | ||
251 | ; | |
252 | ; C4x INSN ATTRIBUTES: | |
253 | ; | |
254 | ; lda load address, non-clobber CC | |
255 | ; store memory store, non-clobber CC | |
256 | ; load_load parallel memory loads, non-clobber CC | |
257 | ; load_store parallel memory load and store, non-clobber CC | |
258 | ; store_load parallel memory store and load, non-clobber CC | |
259 | ; store_store parallel memory stores, non-clobber CC | |
260 | ; unary two operand arithmetic, non-clobber CC | |
261 | ; unarycc two operand arithmetic, clobber CC | |
262 | ; binary three operand arithmetic, non-clobber CC | |
263 | ; binarycc three operand arithmetic, clobber CC | |
264 | ; compare compare, clobber CC | |
265 | ; call function call | |
266 | ; rets return from subroutine | |
267 | ; jump unconditional branch | |
268 | ; jmpc conditional branch | |
269 | ; db decrement and branch (unconditional) | |
270 | ; dbc decrement and branch (conditional) | |
271 | ; ldp load DP | |
272 | ; push stack push | |
273 | ; pop stack pop | |
274 | ; repeat block repeat | |
275 | ; repeat_top block repeat top | |
276 | ; laj link and jump | |
277 | ; multi multiple instruction | |
278 | ; misc nop (default) | |
279 | ||
280 | ; The only real instructions that affect things are the ones that modify | |
281 | ; address registers and ones that call or jump. Note that the number | |
282 | ; of operands refers to the RTL insn pattern, not the number of explicit | |
283 | ; operands in the machine instruction. | |
284 | ; | |
285 | (define_attr "type" "lda,store,unary,unarycc,binary,binarycc,compare,call,rets,jump,jmpc,db,dbc,misc,ldp,repeat,repeat_top,laj,load_load,load_store,store_load,store_store,push,pop,multi" | |
286 | (const_string "misc")) | |
287 | ||
288 | ||
289 | ; Some instructions operate on unsigned data constants, some on signed data | |
290 | ; constants, or the ones complement of unsigned constants. | |
291 | ; This differentiates them. Default to signed. This attribute | |
292 | ; is used by the macro SMALL_CONST () (defined in c4x.h) to determine | |
293 | ; whether an immediate integer constant will fit within the instruction, | |
294 | ; or will have to be loaded using direct addressing from memory. | |
295 | ; Note that logical operations assume unsigned integers whereas | |
296 | ; arithmetic operations assume signed integers. Note that the C4x | |
297 | ; small immediate constant (J) used as src2 in three operand instructions | |
298 | ; is always signed. not_uint16 refers to a number that fits into 16-bits | |
299 | ; when one's complemented. | |
300 | ; | |
301 | (define_attr "data" "int16,uint16,high_16,not_uint16" (const_string "int16")) | |
302 | ||
303 | (define_asm_attributes | |
304 | [(set_attr "type" "multi")]) | |
305 | ||
306 | ; | |
307 | ; C4x DELAY SLOTS | |
308 | ; | |
309 | ; Define delay slot scheduling for branch and call instructions. | |
310 | ; The C[34]x has three delay slots. Note that none of the three instructions | |
311 | ; that follow a delayed branch can be a Bcond, BcondD, BR, BRD, DBcond, | |
312 | ; DBcondD, CALL, CALLcond, TRAPcond, RETIcond, RETScond, RPTB, RPTS, or IDLE. | |
313 | ; | |
314 | ; Annulled branches are a bit difficult because the next instructions | |
315 | ; are preprocessed. | |
316 | ; The table below shows what phase of the c4x is executed. | |
317 | ; BccA[TF] label | |
318 | ; op1 fetch, decode and read executed | |
319 | ; op2 fetch and decode executed | |
320 | ; op3 fetch executed | |
321 | ; This means that we can allow any instruction in the last delay slot | |
322 | ; and only instructions which modify registers in the first two. | |
323 | ; lda can not be executed in the first delay slot | |
324 | ; and ldpk can not be executed in the first two delay slots. | |
325 | ||
326 | (define_attr "onlyreg" "false,true" | |
327 | (cond [(eq_attr "type" "unary,unarycc") | |
328 | (if_then_else (and (match_operand 0 "reg_imm_operand" "") | |
329 | (match_operand 1 "reg_imm_operand" "")) | |
330 | (const_string "true") (const_string "false")) | |
331 | (eq_attr "type" "binary,binarycc") | |
332 | (if_then_else (and (match_operand 0 "reg_imm_operand" "") | |
333 | (and (match_operand 1 "reg_imm_operand" "") | |
334 | (match_operand 2 "reg_imm_operand" ""))) | |
335 | (const_string "true") (const_string "false"))] | |
336 | (const_string "false"))) | |
337 | ||
338 | (define_attr "onlyreg_nomod" "false,true" | |
339 | (cond [(eq_attr "type" "unary,unarycc,compare,lda,store") | |
340 | (if_then_else (and (match_operand 0 "not_modify_reg" "") | |
341 | (match_operand 1 "not_modify_reg" "")) | |
342 | (const_string "true") (const_string "false")) | |
343 | (eq_attr "type" "binary,binarycc") | |
344 | (if_then_else (and (match_operand 0 "not_modify_reg" "") | |
345 | (and (match_operand 1 "not_modify_reg" "") | |
346 | (match_operand 2 "not_modify_reg" ""))) | |
347 | (const_string "true") (const_string "false"))] | |
348 | (const_string "false"))) | |
349 | ||
350 | (define_attr "not_repeat_reg" "false,true" | |
077613ba | 351 | (cond [(eq_attr "type" "unary,unarycc,compare,lda,ldp,store") |
cb0ca284 MH |
352 | (if_then_else (and (match_operand 0 "not_rc_reg" "") |
353 | (match_operand 1 "not_rc_reg" "")) | |
354 | (const_string "true") (const_string "false")) | |
355 | (eq_attr "type" "binary,binarycc") | |
356 | (if_then_else (and (match_operand 0 "not_rc_reg" "") | |
357 | (and (match_operand 1 "not_rc_reg" "") | |
358 | (match_operand 2 "not_rc_reg" ""))) | |
359 | (const_string "true") (const_string "false"))] | |
360 | (const_string "false"))) | |
361 | ||
077613ba MH |
362 | /* Disable compare because the c4x contains a bug. The cmpi insn sets the CC |
363 | in the read phase of the pipeline instead of the execution phase when | |
364 | two registers are compared. */ | |
cb0ca284 MH |
365 | (define_attr "in_annul_slot_1" "false,true" |
366 | (if_then_else (and (and (eq_attr "cpu" "c4x") | |
367 | (eq_attr "type" "!jump,call,rets,jmpc,compare,db,dbc,repeat,repeat_top,laj,push,pop,lda,ldp,multi")) | |
368 | (eq_attr "onlyreg" "true")) | |
369 | (const_string "true") | |
370 | (const_string "false"))) | |
371 | ||
372 | (define_attr "in_annul_slot_2" "false,true" | |
373 | (if_then_else (and (and (eq_attr "cpu" "c4x") | |
374 | (eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,push,pop,ldp,multi")) | |
375 | (eq_attr "onlyreg_nomod" "true")) | |
376 | (const_string "true") | |
377 | (const_string "false"))) | |
378 | ||
8a119a7d | 379 | /* Disable ldp because the c4x contains a bug. The ldp insn modifies |
5078f5eb HB |
380 | the dp register when the insn is anulled or not. |
381 | Also disable autoincrement insns because of a silicon bug. */ | |
cb0ca284 | 382 | (define_attr "in_annul_slot_3" "false,true" |
5078f5eb HB |
383 | (if_then_else (and (and (eq_attr "cpu" "c4x") |
384 | (eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,push,pop,ldp,multi")) | |
385 | (eq_attr "onlyreg_nomod" "true")) | |
cb0ca284 MH |
386 | (const_string "true") |
387 | (const_string "false"))) | |
388 | ||
389 | (define_attr "in_delay_slot" "false,true" | |
390 | (if_then_else (eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,multi") | |
391 | (const_string "true") | |
392 | (const_string "false"))) | |
393 | ||
394 | (define_attr "in_repeat_slot" "false,true" | |
395 | (if_then_else (and (eq_attr "cpu" "c4x") | |
396 | (and (eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,multi") | |
397 | (eq_attr "not_repeat_reg" "true"))) | |
398 | (const_string "true") | |
399 | (const_string "false"))) | |
400 | ||
401 | (define_attr "in_dbc_slot" "false,true" | |
402 | (if_then_else (eq_attr "type" "!jump,call,rets,jmpc,unarycc,binarycc,compare,db,dbc,repeat,repeat_top,laj,multi") | |
403 | (const_string "true") | |
404 | (const_string "false"))) | |
405 | ||
406 | (define_delay (eq_attr "type" "jmpc") | |
407 | [(eq_attr "in_delay_slot" "true") | |
408 | (eq_attr "in_annul_slot_1" "true") | |
409 | (eq_attr "in_annul_slot_1" "true") | |
410 | ||
411 | (eq_attr "in_delay_slot" "true") | |
412 | (eq_attr "in_annul_slot_2" "true") | |
413 | (eq_attr "in_annul_slot_2" "true") | |
414 | ||
415 | (eq_attr "in_delay_slot" "true") | |
416 | (eq_attr "in_annul_slot_3" "true") | |
417 | (eq_attr "in_annul_slot_3" "true") ]) | |
418 | ||
419 | ||
420 | (define_delay (eq_attr "type" "repeat_top") | |
421 | [(eq_attr "in_repeat_slot" "true") (nil) (nil) | |
422 | (eq_attr "in_repeat_slot" "true") (nil) (nil) | |
423 | (eq_attr "in_repeat_slot" "true") (nil) (nil)]) | |
424 | ||
425 | (define_delay (eq_attr "type" "jump,db") | |
426 | [(eq_attr "in_delay_slot" "true") (nil) (nil) | |
427 | (eq_attr "in_delay_slot" "true") (nil) (nil) | |
428 | (eq_attr "in_delay_slot" "true") (nil) (nil)]) | |
429 | ||
430 | ||
431 | ; Decrement and branch conditional instructions cannot modify the | |
432 | ; condition codes for the cycles in the delay slots. | |
433 | ; | |
434 | (define_delay (eq_attr "type" "dbc") | |
435 | [(eq_attr "in_dbc_slot" "true") (nil) (nil) | |
436 | (eq_attr "in_dbc_slot" "true") (nil) (nil) | |
437 | (eq_attr "in_dbc_slot" "true") (nil) (nil)]) | |
438 | ||
439 | ; The LAJ instruction has three delay slots but the last slot is | |
440 | ; used for pushing the return address. Thus we can only use two slots. | |
441 | ; | |
442 | (define_delay (eq_attr "type" "laj") | |
443 | [(eq_attr "in_delay_slot" "true") (nil) (nil) | |
444 | (eq_attr "in_delay_slot" "true") (nil) (nil)]) | |
445 | ||
446 | ; | |
447 | ; C4x UNSPEC NUMBERS | |
448 | ; | |
449 | ; 1 BU/BUD | |
450 | ; 2 RPTS | |
451 | ; 3 LSH | |
452 | ; 4 cmphi | |
453 | ; 5 RCPF | |
454 | ; 6 RND | |
455 | ; 7 repeat block filler | |
456 | ; 8 loadhf_int | |
457 | ; 9 storehf_int | |
458 | ; 10 RSQRF | |
ebcc44f4 MH |
459 | ; 11 loadqf_int |
460 | ; 12 storeqf_int | |
b027470f | 461 | ; 13 Conditional load on overflow |
52695ce0 HB |
462 | ; 14 push_st |
463 | ; 15 pop_st | |
464 | ; 16 push_dp | |
465 | ; 17 pop_dp | |
466 | ; 18 popqi_unspec | |
467 | ; 19 popqf_unspec | |
468 | ; 20 andn_st | |
ebcc44f4 | 469 | ; 22 rptb_init |
8a119a7d MH |
470 | ; 23 toieee |
471 | ; 24 frieee | |
cb0ca284 MH |
472 | |
473 | ; | |
474 | ; C4x FUNCTIONAL UNITS | |
475 | ; | |
476 | ; Define functional units for instruction scheduling to minimise | |
477 | ; pipeline conflicts. | |
478 | ; | |
479 | ; With the C3x, an external memory write (with no wait states) takes | |
480 | ; two cycles and an external memory read (with no wait states) takes | |
481 | ; one cycle. However, an external read following an external write | |
482 | ; takes two cycles. With internal memory, reads and writes take | |
483 | ; half a cycle. | |
484 | ; | |
485 | ; When a C4x address register is loaded it will not be available for | |
486 | ; an extra machine cycle. Calculating with a C4x address register | |
487 | ; makes it unavailable for 2 machine cycles. To notify GCC of these | |
488 | ; pipeline delays, each of the auxiliary and index registers are declared | |
489 | ; as separate functional units. | |
490 | ; | |
491 | ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY | |
492 | ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST]) | |
493 | ; | |
494 | ; MULTIPLICITY 1 (C4x has no independent identical function units) | |
495 | ; SIMULTANEITY 0 (C4x is pipelined) | |
496 | ; READY_DELAY 1 (Results usually ready after every cyle) | |
497 | ; ISSUE_DELAY 1 (Can issue insns every cycle) | |
498 | ||
499 | ; Just some dummy definitions. The real work is done in c4x_adjust_cost. | |
500 | ; These are needed so the min/max READY_DELAY is known. | |
501 | ||
502 | (define_function_unit "dummy" 1 0 (const_int 0) 1 1) | |
503 | (define_function_unit "dummy" 1 0 (const_int 0) 2 1) | |
504 | (define_function_unit "dummy" 1 0 (const_int 0) 3 1) | |
505 | ||
cb0ca284 MH |
506 | ; The attribute setar0 is set to 1 for insns where ar0 is a dst operand. |
507 | ; Note that the attributes unarycc and binarycc do not apply | |
508 | ; if ar0 is a dst operand (only loading an ext. prec. reg. sets CC) | |
509 | (define_attr "setar0" "" | |
510 | (cond [(eq_attr "type" "unary,binary") | |
511 | (if_then_else (match_operand 0 "ar0_reg_operand" "") | |
512 | (const_int 1) (const_int 0))] | |
513 | (const_int 0))) | |
514 | ||
515 | (define_attr "setlda_ar0" "" | |
516 | (cond [(eq_attr "type" "lda") | |
517 | (if_then_else (match_operand 0 "ar0_reg_operand" "") | |
518 | (const_int 1) (const_int 0))] | |
519 | (const_int 0))) | |
520 | ||
521 | ; The attribute usear0 is set to 1 for insns where ar0 is used | |
522 | ; for addressing, as a src operand, or as a dst operand. | |
523 | (define_attr "usear0" "" | |
524 | (cond [(eq_attr "type" "compare,store") | |
525 | (if_then_else (match_operand 0 "ar0_mem_operand" "") | |
526 | (const_int 1) (const_int 0)) | |
527 | (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc") | |
528 | (if_then_else (match_operand 1 "ar0_mem_operand" "") | |
529 | (const_int 1) (const_int 0)) | |
530 | (eq_attr "type" "binary,binarycc") | |
531 | (if_then_else (match_operand 2 "ar0_mem_operand" "") | |
532 | (const_int 1) (const_int 0)) | |
533 | (eq_attr "type" "db,dbc") | |
534 | (if_then_else (match_operand 0 "ar0_reg_operand" "") | |
535 | (const_int 1) (const_int 0))] | |
536 | (const_int 0))) | |
537 | ||
538 | ; The attribute readar0 is set to 1 for insns where ar0 is a src operand. | |
539 | (define_attr "readar0" "" | |
540 | (cond [(eq_attr "type" "compare") | |
541 | (if_then_else (match_operand 0 "ar0_reg_operand" "") | |
542 | (const_int 1) (const_int 0)) | |
543 | (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc") | |
544 | (if_then_else (match_operand 1 "ar0_reg_operand" "") | |
545 | (const_int 1) (const_int 0)) | |
546 | (eq_attr "type" "binary,binarycc") | |
547 | (if_then_else (match_operand 2 "ar0_reg_operand" "") | |
548 | (const_int 1) (const_int 0))] | |
549 | (const_int 0))) | |
550 | ||
cb0ca284 MH |
551 | (define_attr "setar1" "" |
552 | (cond [(eq_attr "type" "unary,binary") | |
553 | (if_then_else (match_operand 0 "ar1_reg_operand" "") | |
554 | (const_int 1) (const_int 0))] | |
555 | (const_int 0))) | |
556 | ||
557 | (define_attr "setlda_ar1" "" | |
558 | (cond [(eq_attr "type" "lda") | |
559 | (if_then_else (match_operand 0 "ar1_reg_operand" "") | |
560 | (const_int 1) (const_int 0))] | |
561 | (const_int 0))) | |
562 | ||
563 | (define_attr "usear1" "" | |
564 | (cond [(eq_attr "type" "compare,store") | |
565 | (if_then_else (match_operand 0 "ar1_mem_operand" "") | |
566 | (const_int 1) (const_int 0)) | |
567 | (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc") | |
568 | (if_then_else (match_operand 1 "ar1_mem_operand" "") | |
569 | (const_int 1) (const_int 0)) | |
570 | (eq_attr "type" "binary,binarycc") | |
571 | (if_then_else (match_operand 2 "ar1_mem_operand" "") | |
572 | (const_int 1) (const_int 0)) | |
573 | (eq_attr "type" "db,dbc") | |
574 | (if_then_else (match_operand 0 "ar1_reg_operand" "") | |
575 | (const_int 1) (const_int 0))] | |
576 | (const_int 0))) | |
577 | ||
578 | (define_attr "readar1" "" | |
579 | (cond [(eq_attr "type" "compare") | |
580 | (if_then_else (match_operand 0 "ar1_reg_operand" "") | |
581 | (const_int 1) (const_int 0)) | |
582 | (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc") | |
583 | (if_then_else (match_operand 1 "ar1_reg_operand" "") | |
584 | (const_int 1) (const_int 0)) | |
585 | (eq_attr "type" "binary,binarycc") | |
586 | (if_then_else (match_operand 2 "ar1_reg_operand" "") | |
587 | (const_int 1) (const_int 0))] | |
588 | (const_int 0))) | |
589 | ||
cb0ca284 MH |
590 | (define_attr "setar2" "" |
591 | (cond [(eq_attr "type" "unary,binary") | |
592 | (if_then_else (match_operand 0 "ar2_reg_operand" "") | |
593 | (const_int 1) (const_int 0))] | |
594 | (const_int 0))) | |
595 | ||
596 | (define_attr "setlda_ar2" "" | |
597 | (cond [(eq_attr "type" "lda") | |
598 | (if_then_else (match_operand 0 "ar2_reg_operand" "") | |
599 | (const_int 1) (const_int 0))] | |
600 | (const_int 0))) | |
601 | ||
602 | (define_attr "usear2" "" | |
603 | (cond [(eq_attr "type" "compare,store") | |
604 | (if_then_else (match_operand 0 "ar2_mem_operand" "") | |
605 | (const_int 1) (const_int 0)) | |
606 | (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc") | |
607 | (if_then_else (match_operand 1 "ar2_mem_operand" "") | |
608 | (const_int 1) (const_int 0)) | |
609 | (eq_attr "type" "binary,binarycc") | |
610 | (if_then_else (match_operand 2 "ar2_mem_operand" "") | |
611 | (const_int 1) (const_int 0)) | |
612 | (eq_attr "type" "db,dbc") | |
613 | (if_then_else (match_operand 0 "ar2_reg_operand" "") | |
614 | (const_int 1) (const_int 0))] | |
615 | (const_int 0))) | |
616 | ||
617 | (define_attr "readar2" "" | |
618 | (cond [(eq_attr "type" "compare") | |
619 | (if_then_else (match_operand 0 "ar2_reg_operand" "") | |
620 | (const_int 1) (const_int 0)) | |
621 | (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc") | |
622 | (if_then_else (match_operand 1 "ar2_reg_operand" "") | |
623 | (const_int 1) (const_int 0)) | |
624 | (eq_attr "type" "binary,binarycc") | |
625 | (if_then_else (match_operand 2 "ar2_reg_operand" "") | |
626 | (const_int 1) (const_int 0))] | |
627 | (const_int 0))) | |
628 | ||
cb0ca284 MH |
629 | (define_attr "setar3" "" |
630 | (cond [(eq_attr "type" "unary,binary") | |
631 | (if_then_else (match_operand 0 "ar3_reg_operand" "") | |
632 | (const_int 1) (const_int 0))] | |
633 | (const_int 0))) | |
634 | ||
635 | (define_attr "setlda_ar3" "" | |
636 | (cond [(eq_attr "type" "lda") | |
637 | (if_then_else (match_operand 0 "ar3_reg_operand" "") | |
638 | (const_int 1) (const_int 0))] | |
639 | (const_int 0))) | |
640 | ||
641 | (define_attr "usear3" "" | |
642 | (cond [(eq_attr "type" "compare,store") | |
643 | (if_then_else (match_operand 0 "ar3_mem_operand" "") | |
644 | (const_int 1) (const_int 0)) | |
645 | (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc") | |
646 | (if_then_else (match_operand 1 "ar3_mem_operand" "") | |
647 | (const_int 1) (const_int 0)) | |
648 | (eq_attr "type" "binary,binarycc") | |
649 | (if_then_else (match_operand 2 "ar3_mem_operand" "") | |
650 | (const_int 1) (const_int 0)) | |
651 | (eq_attr "type" "db,dbc") | |
652 | (if_then_else (match_operand 0 "ar3_reg_operand" "") | |
653 | (const_int 1) (const_int 0))] | |
654 | (const_int 0))) | |
655 | ||
656 | (define_attr "readar3" "" | |
657 | (cond [(eq_attr "type" "compare") | |
658 | (if_then_else (match_operand 0 "ar3_reg_operand" "") | |
659 | (const_int 1) (const_int 0)) | |
660 | (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc") | |
661 | (if_then_else (match_operand 1 "ar3_reg_operand" "") | |
662 | (const_int 1) (const_int 0)) | |
663 | (eq_attr "type" "binary,binarycc") | |
664 | (if_then_else (match_operand 2 "ar3_reg_operand" "") | |
665 | (const_int 1) (const_int 0))] | |
666 | (const_int 0))) | |
667 | ||
cb0ca284 MH |
668 | (define_attr "setar4" "" |
669 | (cond [(eq_attr "type" "unary,binary") | |
670 | (if_then_else (match_operand 0 "ar4_reg_operand" "") | |
671 | (const_int 1) (const_int 0))] | |
672 | (const_int 0))) | |
673 | ||
674 | (define_attr "setlda_ar4" "" | |
675 | (cond [(eq_attr "type" "lda") | |
676 | (if_then_else (match_operand 0 "ar4_reg_operand" "") | |
677 | (const_int 1) (const_int 0))] | |
678 | (const_int 0))) | |
679 | ||
680 | (define_attr "usear4" "" | |
681 | (cond [(eq_attr "type" "compare,store") | |
682 | (if_then_else (match_operand 0 "ar4_mem_operand" "") | |
683 | (const_int 1) (const_int 0)) | |
684 | (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc") | |
685 | (if_then_else (match_operand 1 "ar4_mem_operand" "") | |
686 | (const_int 1) (const_int 0)) | |
687 | (eq_attr "type" "binary,binarycc") | |
688 | (if_then_else (match_operand 2 "ar4_mem_operand" "") | |
689 | (const_int 1) (const_int 0)) | |
690 | (eq_attr "type" "db,dbc") | |
691 | (if_then_else (match_operand 0 "ar4_reg_operand" "") | |
692 | (const_int 1) (const_int 0))] | |
693 | (const_int 0))) | |
694 | ||
695 | (define_attr "readar4" "" | |
696 | (cond [(eq_attr "type" "compare") | |
697 | (if_then_else (match_operand 0 "ar4_reg_operand" "") | |
698 | (const_int 1) (const_int 0)) | |
699 | (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc") | |
700 | (if_then_else (match_operand 1 "ar4_reg_operand" "") | |
701 | (const_int 1) (const_int 0)) | |
702 | (eq_attr "type" "binary,binarycc") | |
703 | (if_then_else (match_operand 2 "ar4_reg_operand" "") | |
704 | (const_int 1) (const_int 0))] | |
705 | (const_int 0))) | |
706 | ||
cb0ca284 MH |
707 | (define_attr "setar5" "" |
708 | (cond [(eq_attr "type" "unary,binary") | |
709 | (if_then_else (match_operand 0 "ar5_reg_operand" "") | |
710 | (const_int 1) (const_int 0))] | |
711 | (const_int 0))) | |
712 | ||
713 | (define_attr "setlda_ar5" "" | |
714 | (cond [(eq_attr "type" "lda") | |
715 | (if_then_else (match_operand 0 "ar5_reg_operand" "") | |
716 | (const_int 1) (const_int 0))] | |
717 | (const_int 0))) | |
718 | ||
719 | (define_attr "usear5" "" | |
720 | (cond [(eq_attr "type" "compare,store") | |
721 | (if_then_else (match_operand 0 "ar5_mem_operand" "") | |
722 | (const_int 1) (const_int 0)) | |
723 | (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc") | |
724 | (if_then_else (match_operand 1 "ar5_mem_operand" "") | |
725 | (const_int 1) (const_int 0)) | |
726 | (eq_attr "type" "binary,binarycc") | |
727 | (if_then_else (match_operand 2 "ar5_mem_operand" "") | |
728 | (const_int 1) (const_int 0)) | |
729 | (eq_attr "type" "db,dbc") | |
730 | (if_then_else (match_operand 0 "ar5_reg_operand" "") | |
731 | (const_int 1) (const_int 0))] | |
732 | (const_int 0))) | |
733 | ||
734 | (define_attr "readar5" "" | |
735 | (cond [(eq_attr "type" "compare") | |
736 | (if_then_else (match_operand 0 "ar5_reg_operand" "") | |
737 | (const_int 1) (const_int 0)) | |
738 | (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc") | |
739 | (if_then_else (match_operand 1 "ar5_reg_operand" "") | |
740 | (const_int 1) (const_int 0)) | |
741 | (eq_attr "type" "binary,binarycc") | |
742 | (if_then_else (match_operand 2 "ar5_reg_operand" "") | |
743 | (const_int 1) (const_int 0))] | |
744 | (const_int 0))) | |
745 | ||
cb0ca284 MH |
746 | (define_attr "setar6" "" |
747 | (cond [(eq_attr "type" "unary,binary") | |
748 | (if_then_else (match_operand 0 "ar6_reg_operand" "") | |
749 | (const_int 1) (const_int 0))] | |
750 | (const_int 0))) | |
751 | ||
752 | (define_attr "setlda_ar6" "" | |
753 | (cond [(eq_attr "type" "lda") | |
754 | (if_then_else (match_operand 0 "ar6_reg_operand" "") | |
755 | (const_int 1) (const_int 0))] | |
756 | (const_int 0))) | |
757 | ||
758 | (define_attr "usear6" "" | |
759 | (cond [(eq_attr "type" "compare,store") | |
760 | (if_then_else (match_operand 0 "ar6_mem_operand" "") | |
761 | (const_int 1) (const_int 0)) | |
762 | (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc") | |
763 | (if_then_else (match_operand 1 "ar6_mem_operand" "") | |
764 | (const_int 1) (const_int 0)) | |
765 | (eq_attr "type" "binary,binarycc") | |
766 | (if_then_else (match_operand 2 "ar6_mem_operand" "") | |
767 | (const_int 1) (const_int 0)) | |
768 | (eq_attr "type" "db,dbc") | |
769 | (if_then_else (match_operand 0 "ar6_reg_operand" "") | |
770 | (const_int 1) (const_int 0))] | |
771 | (const_int 0))) | |
772 | ||
773 | (define_attr "readar6" "" | |
774 | (cond [(eq_attr "type" "compare") | |
775 | (if_then_else (match_operand 0 "ar6_reg_operand" "") | |
776 | (const_int 1) (const_int 0)) | |
777 | (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc") | |
778 | (if_then_else (match_operand 1 "ar6_reg_operand" "") | |
779 | (const_int 1) (const_int 0)) | |
780 | (eq_attr "type" "binary,binarycc") | |
781 | (if_then_else (match_operand 2 "ar6_reg_operand" "") | |
782 | (const_int 1) (const_int 0))] | |
783 | (const_int 0))) | |
784 | ||
cb0ca284 MH |
785 | (define_attr "setar7" "" |
786 | (cond [(eq_attr "type" "unary,binary") | |
787 | (if_then_else (match_operand 0 "ar7_reg_operand" "") | |
788 | (const_int 1) (const_int 0))] | |
789 | (const_int 0))) | |
790 | ||
791 | (define_attr "setlda_ar7" "" | |
792 | (cond [(eq_attr "type" "lda") | |
793 | (if_then_else (match_operand 0 "ar7_reg_operand" "") | |
794 | (const_int 1) (const_int 0))] | |
795 | (const_int 0))) | |
796 | ||
797 | (define_attr "usear7" "" | |
798 | (cond [(eq_attr "type" "compare,store") | |
799 | (if_then_else (match_operand 0 "ar7_mem_operand" "") | |
800 | (const_int 1) (const_int 0)) | |
801 | (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc") | |
802 | (if_then_else (match_operand 1 "ar7_mem_operand" "") | |
803 | (const_int 1) (const_int 0)) | |
804 | (eq_attr "type" "binary,binarycc") | |
805 | (if_then_else (match_operand 2 "ar7_mem_operand" "") | |
806 | (const_int 1) (const_int 0)) | |
807 | (eq_attr "type" "db,dbc") | |
808 | (if_then_else (match_operand 0 "ar7_reg_operand" "") | |
809 | (const_int 1) (const_int 0))] | |
810 | (const_int 0))) | |
811 | ||
812 | (define_attr "readar7" "" | |
813 | (cond [(eq_attr "type" "compare") | |
814 | (if_then_else (match_operand 0 "ar7_reg_operand" "") | |
815 | (const_int 1) (const_int 0)) | |
816 | (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc") | |
817 | (if_then_else (match_operand 1 "ar7_reg_operand" "") | |
818 | (const_int 1) (const_int 0)) | |
819 | (eq_attr "type" "binary,binarycc") | |
820 | (if_then_else (match_operand 2 "ar7_reg_operand" "") | |
821 | (const_int 1) (const_int 0))] | |
822 | (const_int 0))) | |
823 | ||
cb0ca284 MH |
824 | (define_attr "setir0" "" |
825 | (cond [(eq_attr "type" "unary,binary") | |
826 | (if_then_else (match_operand 0 "ir0_reg_operand" "") | |
827 | (const_int 1) (const_int 0))] | |
828 | (const_int 0))) | |
829 | ||
830 | (define_attr "setlda_ir0" "" | |
831 | (cond [(eq_attr "type" "lda") | |
832 | (if_then_else (match_operand 0 "ir0_reg_operand" "") | |
833 | (const_int 1) (const_int 0))] | |
834 | (const_int 0))) | |
835 | ||
836 | (define_attr "useir0" "" | |
837 | (cond [(eq_attr "type" "compare,store") | |
838 | (if_then_else (match_operand 0 "ir0_mem_operand" "") | |
839 | (const_int 1) (const_int 0)) | |
840 | (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc") | |
841 | (if_then_else (match_operand 1 "ir0_mem_operand" "") | |
842 | (const_int 1) (const_int 0)) | |
843 | (eq_attr "type" "binary,binarycc") | |
844 | (if_then_else (match_operand 2 "ir0_mem_operand" "") | |
845 | (const_int 1) (const_int 0))] | |
846 | (const_int 0))) | |
847 | ||
cb0ca284 MH |
848 | (define_attr "setir1" "" |
849 | (cond [(eq_attr "type" "unary,binary") | |
850 | (if_then_else (match_operand 0 "ir1_reg_operand" "") | |
851 | (const_int 1) (const_int 0))] | |
852 | (const_int 0))) | |
853 | ||
854 | (define_attr "setlda_ir1" "" | |
855 | (cond [(eq_attr "type" "lda") | |
856 | (if_then_else (match_operand 0 "ir1_reg_operand" "") | |
857 | (const_int 1) (const_int 0))] | |
858 | (const_int 0))) | |
859 | ||
860 | (define_attr "useir1" "" | |
861 | (cond [(eq_attr "type" "compare,store") | |
862 | (if_then_else (match_operand 0 "ir1_mem_operand" "") | |
863 | (const_int 1) (const_int 0)) | |
864 | (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc") | |
865 | (if_then_else (match_operand 1 "ir1_mem_operand" "") | |
866 | (const_int 1) (const_int 0)) | |
867 | (eq_attr "type" "binary,binarycc") | |
868 | (if_then_else (match_operand 2 "ir1_mem_operand" "") | |
869 | (const_int 1) (const_int 0))] | |
870 | (const_int 0))) | |
871 | ||
872 | ; With the C3x, things are simpler, but slower, i.e. more pipeline conflicts :( | |
873 | ; There are three functional groups: | |
874 | ; (1) AR0-AR7, IR0-IR1, BK | |
875 | ; (2) DP | |
876 | ; (3) SP | |
877 | ; | |
878 | ; When a register in one of these functional groups is loaded, | |
879 | ; the contents of that or any other register in its group | |
880 | ; will not be available to the next instruction for 2 machine cycles. | |
881 | ; Similarly, when a register in one of the functional groups is read | |
882 | ; excepting (IR0-IR1, BK, DP) the contents of that or any other register | |
883 | ; in its group will not be available to the next instruction for | |
884 | ; 1 machine cycle. | |
885 | ; | |
886 | ; Let's ignore functional groups 2 and 3 for now, since they are not | |
887 | ; so important. | |
888 | ||
cb0ca284 MH |
889 | (define_attr "setgroup1" "" |
890 | (cond [(eq_attr "type" "lda,unary,binary") | |
891 | (if_then_else (match_operand 0 "group1_reg_operand" "") | |
892 | (const_int 1) (const_int 0))] | |
893 | (const_int 0))) | |
894 | ||
895 | (define_attr "usegroup1" "" | |
896 | (cond [(eq_attr "type" "compare,store,store_store,store_load") | |
897 | (if_then_else (match_operand 0 "group1_mem_operand" "") | |
898 | (const_int 1) (const_int 0)) | |
899 | (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc,load_load,load_store") | |
900 | (if_then_else (match_operand 1 "group1_mem_operand" "") | |
901 | (const_int 1) (const_int 0)) | |
902 | (eq_attr "type" "store_store,load_store") | |
903 | (if_then_else (match_operand 2 "group1_mem_operand" "") | |
904 | (const_int 1) (const_int 0)) | |
905 | (eq_attr "type" "load_load,store_load") | |
906 | (if_then_else (match_operand 3 "group1_mem_operand" "") | |
907 | (const_int 1) (const_int 0))] | |
908 | (const_int 0))) | |
909 | ||
910 | (define_attr "readarx" "" | |
911 | (cond [(eq_attr "type" "compare") | |
912 | (if_then_else (match_operand 0 "arx_reg_operand" "") | |
913 | (const_int 1) (const_int 0)) | |
914 | (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc") | |
915 | (if_then_else (match_operand 1 "arx_reg_operand" "") | |
916 | (const_int 1) (const_int 0)) | |
917 | (eq_attr "type" "binary,binarycc") | |
918 | (if_then_else (match_operand 2 "arx_reg_operand" "") | |
919 | (const_int 1) (const_int 0))] | |
920 | (const_int 0))) | |
921 | ||
959e0a76 MH |
922 | |
923 | ; | |
924 | ; C4x INSN PATTERNS: | |
925 | ; | |
926 | ; Note that the movMM and addP patterns can be called during reload | |
927 | ; so we need to take special care with theses patterns since | |
928 | ; we cannot blindly clobber CC or generate new pseudo registers. | |
929 | ||
cb0ca284 MH |
930 | ; |
931 | ; TWO OPERAND INTEGER INSTRUCTIONS | |
932 | ; | |
933 | ||
934 | ; | |
935 | ; LDP/LDPK | |
936 | ; | |
937 | (define_insn "set_ldp" | |
938 | [(set (match_operand:QI 0 "dp_reg_operand" "=z") | |
939 | (high:QI (match_operand:QI 1 "" "")))] | |
4ddb3ea6 | 940 | "! TARGET_SMALL" |
cb0ca284 MH |
941 | "* return (TARGET_C3X) ? \"ldp\\t%A1\" : \"ldpk\\t%A1\";" |
942 | [(set_attr "type" "ldp")]) | |
943 | ||
52695ce0 HB |
944 | (define_insn "set_ldp_prologue" |
945 | [(set (match_operand:QI 0 "dp_reg_operand" "=z") | |
946 | (high:QI (match_operand:QI 1 "" "")))] | |
947 | "TARGET_SMALL && TARGET_PARANOID" | |
948 | "* return (TARGET_C3X) ? \"ldp\\t@data_sec\" : \"ldpk\\t@data_sec\";" | |
949 | [(set_attr "type" "ldp")]) | |
950 | ||
50c33087 MH |
951 | (define_insn "set_high" |
952 | [(set (match_operand:QI 0 "std_reg_operand" "=c") | |
55310df7 | 953 | (high:QI (match_operand:QI 1 "symbolic_address_operand" "")))] |
dfafcb4d | 954 | "! TARGET_C3X && ! TARGET_TI" |
cb0ca284 MH |
955 | "ldhi\\t^%H1,%0" |
956 | [(set_attr "type" "unary")]) | |
957 | ||
50c33087 | 958 | (define_insn "set_lo_sum" |
8a119a7d | 959 | [(set (match_operand:QI 0 "std_reg_operand" "+c") |
50c33087 | 960 | (lo_sum:QI (match_dup 0) |
55310df7 | 961 | (match_operand:QI 1 "symbolic_address_operand" "")))] |
dfafcb4d | 962 | "! TARGET_TI" |
cb0ca284 MH |
963 | "or\\t#%H1,%0" |
964 | [(set_attr "type" "unary")]) | |
965 | ||
50c33087 MH |
966 | (define_split |
967 | [(set (match_operand:QI 0 "std_reg_operand" "") | |
55310df7 | 968 | (match_operand:QI 1 "symbolic_address_operand" ""))] |
d001969e | 969 | "reload_completed && ! TARGET_C3X && ! TARGET_TI" |
50c33087 MH |
970 | [(set (match_dup 0) (high:QI (match_dup 1))) |
971 | (set (match_dup 0) (lo_sum:QI (match_dup 0) (match_dup 1)))] | |
972 | "") | |
973 | ||
8d485e2d MH |
974 | (define_split |
975 | [(set (match_operand:QI 0 "reg_operand" "") | |
976 | (match_operand:QI 1 "const_int_operand" "")) | |
977 | (clobber (reg:QI 16))] | |
978 | "! TARGET_C3X | |
979 | && ! IS_INT16_CONST (INTVAL (operands[1])) | |
980 | && ! IS_HIGH_CONST (INTVAL (operands[1])) | |
981 | && reload_completed | |
982 | && std_reg_operand (operands[0], QImode)" | |
983 | [(set (match_dup 0) (match_dup 2)) | |
984 | (set (match_dup 0) (ior:QI (match_dup 0) (match_dup 3)))] | |
985 | " | |
986 | { | |
987 | operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & ~0xffff); | |
988 | operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff); | |
989 | }") | |
990 | ||
c08733d0 | 991 | (define_split |
483dd5be | 992 | [(set (match_operand:QI 0 "reg_operand" "") |
c08733d0 MH |
993 | (match_operand:QI 1 "const_int_operand" ""))] |
994 | "! TARGET_C3X | |
483dd5be MH |
995 | && ! IS_INT16_CONST (INTVAL (operands[1])) |
996 | && ! IS_HIGH_CONST (INTVAL (operands[1])) | |
997 | && reload_completed | |
998 | && std_reg_operand (operands[0], QImode)" | |
c08733d0 MH |
999 | [(set (match_dup 0) (match_dup 2)) |
1000 | (set (match_dup 0) (ior:QI (match_dup 0) (match_dup 3)))] | |
1001 | " | |
1002 | { | |
1003 | operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & ~0xffff); | |
1004 | operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff); | |
1005 | }") | |
1006 | ||
8d485e2d MH |
1007 | (define_split |
1008 | [(set (match_operand:QI 0 "reg_operand" "") | |
1009 | (match_operand:QI 1 "const_int_operand" "")) | |
1010 | (clobber (reg:QI 16))] | |
1011 | "TARGET_C3X && ! TARGET_SMALL | |
1012 | && ! IS_INT16_CONST (INTVAL (operands[1])) | |
1013 | && reload_completed | |
1014 | && std_reg_operand (operands[0], QImode) | |
1015 | && c4x_shiftable_constant (operands[1]) < 0" | |
1016 | [(set (match_dup 0) (match_dup 2)) | |
1017 | (set (match_dup 0) (ashift:QI (match_dup 0) (match_dup 4))) | |
1018 | (set (match_dup 0) (ior:QI (match_dup 0) (match_dup 3)))] | |
1019 | " | |
1020 | { | |
1021 | /* Generate two's complement value of 16 MSBs. */ | |
1022 | operands[2] = gen_rtx (CONST_INT, VOIDmode, | |
1023 | (((INTVAL (operands[1]) >> 16) & 0xffff) | |
1024 | - 0x8000) ^ ~0x7fff); | |
1025 | operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff); | |
1026 | operands[4] = gen_rtx (CONST_INT, VOIDmode, 16); | |
1027 | }") | |
1028 | ||
483dd5be MH |
1029 | (define_split |
1030 | [(set (match_operand:QI 0 "reg_operand" "") | |
1031 | (match_operand:QI 1 "const_int_operand" ""))] | |
1032 | "TARGET_C3X && ! TARGET_SMALL | |
1033 | && ! IS_INT16_CONST (INTVAL (operands[1])) | |
1034 | && reload_completed | |
1035 | && std_reg_operand (operands[0], QImode) | |
1036 | && c4x_shiftable_constant (operands[1]) < 0" | |
1037 | [(set (match_dup 0) (match_dup 2)) | |
1038 | (set (match_dup 0) (ashift:QI (match_dup 0) (match_dup 4))) | |
1039 | (set (match_dup 0) (ior:QI (match_dup 0) (match_dup 3)))] | |
1040 | " | |
1041 | { | |
1042 | /* Generate two's complement value of 16 MSBs. */ | |
1043 | operands[2] = gen_rtx (CONST_INT, VOIDmode, | |
1044 | (((INTVAL (operands[1]) >> 16) & 0xffff) | |
1045 | - 0x8000) ^ ~0x7fff); | |
1046 | operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff); | |
1047 | operands[4] = gen_rtx (CONST_INT, VOIDmode, 16); | |
1048 | }") | |
1049 | ||
8d485e2d MH |
1050 | (define_split |
1051 | [(set (match_operand:QI 0 "reg_operand" "") | |
1052 | (match_operand:QI 1 "const_int_operand" "")) | |
1053 | (clobber (reg:QI 16))] | |
1054 | "TARGET_C3X | |
1055 | && ! IS_INT16_CONST (INTVAL (operands[1])) | |
1056 | && reload_completed | |
1057 | && std_reg_operand (operands[0], QImode) | |
1058 | && c4x_shiftable_constant (operands[1]) >= 0" | |
1059 | [(set (match_dup 0) (match_dup 2)) | |
1060 | (set (match_dup 0) (ashift:QI (match_dup 0) (match_dup 3)))] | |
1061 | " | |
1062 | { | |
1063 | /* Generate two's complement value of MSBs. */ | |
1064 | int shift = c4x_shiftable_constant (operands[1]); | |
1065 | ||
1066 | operands[2] = gen_rtx (CONST_INT, VOIDmode, | |
1067 | (((INTVAL (operands[1]) >> shift) & 0xffff) | |
1068 | - 0x8000) ^ ~0x7fff); | |
1069 | operands[3] = gen_rtx (CONST_INT, VOIDmode, shift); | |
1070 | }") | |
1071 | ||
483dd5be MH |
1072 | (define_split |
1073 | [(set (match_operand:QI 0 "reg_operand" "") | |
1074 | (match_operand:QI 1 "const_int_operand" ""))] | |
1075 | "TARGET_C3X | |
1076 | && ! IS_INT16_CONST (INTVAL (operands[1])) | |
1077 | && reload_completed | |
1078 | && std_reg_operand (operands[0], QImode) | |
1079 | && c4x_shiftable_constant (operands[1]) >= 0" | |
1080 | [(set (match_dup 0) (match_dup 2)) | |
1081 | (set (match_dup 0) (ashift:QI (match_dup 0) (match_dup 3)))] | |
1082 | " | |
1083 | { | |
1084 | /* Generate two's complement value of MSBs. */ | |
1085 | int shift = c4x_shiftable_constant (operands[1]); | |
1086 | ||
1087 | operands[2] = gen_rtx (CONST_INT, VOIDmode, | |
1088 | (((INTVAL (operands[1]) >> shift) & 0xffff) | |
1089 | - 0x8000) ^ ~0x7fff); | |
1090 | operands[3] = gen_rtx (CONST_INT, VOIDmode, shift); | |
1091 | }") | |
1092 | ||
8d485e2d MH |
1093 | (define_split |
1094 | [(set (match_operand:QI 0 "reg_operand" "") | |
1095 | (match_operand:QI 1 "const_int_operand" "")) | |
1096 | (clobber (reg:QI 16))] | |
1097 | "! TARGET_SMALL | |
1098 | && ! IS_INT16_CONST (INTVAL (operands[1])) | |
1099 | && ! IS_HIGH_CONST (INTVAL (operands[1])) | |
1100 | && reload_completed | |
1101 | && ! std_reg_operand (operands[0], QImode)" | |
1102 | [(set (match_dup 2) (high:QI (match_dup 3))) | |
1103 | (set (match_dup 0) (match_dup 4)) | |
1104 | (use (match_dup 1))] | |
1105 | " | |
1106 | { | |
1107 | rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO); | |
1108 | operands[2] = dp_reg; | |
1109 | operands[3] = force_const_mem (Pmode, operands[1]); | |
1110 | operands[4] = change_address (operands[3], QImode, | |
1111 | gen_rtx_LO_SUM (Pmode, dp_reg, | |
1112 | XEXP (operands[3], 0))); | |
1113 | operands[3] = XEXP (operands[3], 0); | |
1114 | }") | |
1115 | ||
483dd5be MH |
1116 | (define_split |
1117 | [(set (match_operand:QI 0 "reg_operand" "") | |
1118 | (match_operand:QI 1 "const_int_operand" ""))] | |
1119 | "! TARGET_SMALL | |
1120 | && ! IS_INT16_CONST (INTVAL (operands[1])) | |
1121 | && ! IS_HIGH_CONST (INTVAL (operands[1])) | |
1122 | && reload_completed | |
1123 | && ! std_reg_operand (operands[0], QImode)" | |
1124 | [(set (match_dup 2) (high:QI (match_dup 3))) | |
1125 | (set (match_dup 0) (match_dup 4)) | |
1126 | (use (match_dup 1))] | |
1127 | " | |
1128 | { | |
1129 | rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO); | |
1130 | operands[2] = dp_reg; | |
1131 | operands[3] = force_const_mem (Pmode, operands[1]); | |
1132 | operands[4] = change_address (operands[3], QImode, | |
1133 | gen_rtx_LO_SUM (Pmode, dp_reg, | |
1134 | XEXP (operands[3], 0))); | |
1135 | operands[3] = XEXP (operands[3], 0); | |
1136 | }") | |
1137 | ||
8d485e2d MH |
1138 | (define_split |
1139 | [(set (match_operand:QI 0 "reg_operand" "") | |
1140 | (match_operand:QI 1 "const_int_operand" "")) | |
1141 | (clobber (reg:QI 16))] | |
1142 | "TARGET_SMALL | |
1143 | && ! IS_INT16_CONST (INTVAL (operands[1])) | |
1144 | && ! IS_HIGH_CONST (INTVAL (operands[1])) | |
1145 | && reload_completed | |
1146 | && ((TARGET_C3X && c4x_shiftable_constant (operands[1]) < 0) | |
1147 | || ! std_reg_operand (operands[0], QImode))" | |
1148 | [(set (match_dup 0) (match_dup 2)) | |
1149 | (use (match_dup 1))] | |
1150 | " | |
1151 | { | |
1152 | rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO); | |
1153 | operands[2] = force_const_mem (Pmode, operands[1]); | |
1154 | operands[2] = change_address (operands[2], QImode, | |
1155 | gen_rtx_LO_SUM (Pmode, dp_reg, | |
1156 | XEXP (operands[2], 0))); | |
1157 | }") | |
1158 | ||
483dd5be MH |
1159 | (define_split |
1160 | [(set (match_operand:QI 0 "reg_operand" "") | |
1161 | (match_operand:QI 1 "const_int_operand" ""))] | |
1162 | "TARGET_SMALL | |
1163 | && ! IS_INT16_CONST (INTVAL (operands[1])) | |
1164 | && ! IS_HIGH_CONST (INTVAL (operands[1])) | |
1165 | && reload_completed | |
f416f18c | 1166 | && ((TARGET_C3X && c4x_shiftable_constant (operands[1]) < 0) |
483dd5be MH |
1167 | || ! std_reg_operand (operands[0], QImode))" |
1168 | [(set (match_dup 0) (match_dup 2)) | |
1169 | (use (match_dup 1))] | |
1170 | " | |
1171 | { | |
1172 | rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO); | |
1173 | operands[2] = force_const_mem (Pmode, operands[1]); | |
1174 | operands[2] = change_address (operands[2], QImode, | |
1175 | gen_rtx_LO_SUM (Pmode, dp_reg, | |
1176 | XEXP (operands[2], 0))); | |
1177 | }") | |
1178 | ||
1179 | (define_split | |
1180 | [(set (match_operand:HI 0 "reg_operand" "") | |
8d485e2d MH |
1181 | (match_operand:HI 1 "const_int_operand" "")) |
1182 | (clobber (reg:QI 16))] | |
483dd5be MH |
1183 | "reload_completed" |
1184 | [(set (match_dup 2) (match_dup 4)) | |
1185 | (set (match_dup 3) (match_dup 5))] | |
1186 | " | |
1187 | { | |
1188 | operands[2] = c4x_operand_subword (operands[0], 0, 1, HImode); | |
1189 | operands[3] = c4x_operand_subword (operands[0], 1, 1, HImode); | |
1190 | operands[4] = c4x_operand_subword (operands[1], 0, 1, HImode); | |
1191 | operands[5] = c4x_operand_subword (operands[1], 1, 1, HImode); | |
1192 | }") | |
1193 | ||
cf92d7df MH |
1194 | |
1195 | ; We need to clobber the DP reg to be safe in case we | |
1196 | ; need to load this address from memory | |
1197 | (define_insn "load_immed_address" | |
1198 | [(set (match_operand:QI 0 "reg_operand" "=a?x?c*r") | |
1199 | (match_operand:QI 1 "symbolic_address_operand" "")) | |
1200 | (clobber (reg:QI 16))] | |
1201 | "TARGET_LOAD_ADDRESS" | |
1202 | "#" | |
1203 | [(set_attr "type" "multi")]) | |
1204 | ||
1205 | ||
1206 | (define_split | |
1207 | [(set (match_operand:QI 0 "std_reg_operand" "") | |
1208 | (match_operand:QI 1 "symbolic_address_operand" "")) | |
1209 | (clobber (reg:QI 16))] | |
d001969e | 1210 | "reload_completed && ! TARGET_C3X && ! TARGET_TI" |
cf92d7df MH |
1211 | [(set (match_dup 0) (high:QI (match_dup 1))) |
1212 | (set (match_dup 0) (lo_sum:QI (match_dup 0) (match_dup 1)))] | |
1213 | "") | |
1214 | ||
50c33087 MH |
1215 | ; CC has been selected to load a symbolic address. We force the address |
1216 | ; into memory and then generate LDP and LDIU insns. | |
1217 | ; This is also required for the C30 if we pretend that we can | |
1218 | ; easily load symbolic addresses into a register. | |
1219 | (define_split | |
1220 | [(set (match_operand:QI 0 "reg_operand" "") | |
cf92d7df MH |
1221 | (match_operand:QI 1 "symbolic_address_operand" "")) |
1222 | (clobber (reg:QI 16))] | |
d001969e HB |
1223 | "reload_completed |
1224 | && ! TARGET_SMALL | |
1225 | && (TARGET_C3X || TARGET_TI || ! std_reg_operand (operands[0], QImode))" | |
50c33087 MH |
1226 | [(set (match_dup 2) (high:QI (match_dup 3))) |
1227 | (set (match_dup 0) (match_dup 4)) | |
1228 | (use (match_dup 1))] | |
1229 | " | |
1230 | { | |
1231 | rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO); | |
1232 | operands[2] = dp_reg; | |
1233 | operands[3] = force_const_mem (Pmode, operands[1]); | |
1234 | operands[4] = change_address (operands[3], QImode, | |
1235 | gen_rtx_LO_SUM (Pmode, dp_reg, | |
1236 | XEXP (operands[3], 0))); | |
1237 | operands[3] = XEXP (operands[3], 0); | |
1238 | }") | |
1239 | ||
1240 | ; This pattern is similar to the above but does not emit a LDP | |
1241 | ; for the small memory model. | |
1242 | (define_split | |
1243 | [(set (match_operand:QI 0 "reg_operand" "") | |
cf92d7df MH |
1244 | (match_operand:QI 1 "symbolic_address_operand" "")) |
1245 | (clobber (reg:QI 16))] | |
d001969e HB |
1246 | "reload_completed |
1247 | && TARGET_SMALL | |
1248 | && (TARGET_C3X || TARGET_TI || ! std_reg_operand (operands[0], QImode))" | |
b2e9a2fd MH |
1249 | [(set (match_dup 0) (match_dup 2)) |
1250 | (use (match_dup 1))] | |
50c33087 MH |
1251 | " |
1252 | { | |
1253 | rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO); | |
b2e9a2fd MH |
1254 | operands[2] = force_const_mem (Pmode, operands[1]); |
1255 | operands[2] = change_address (operands[2], QImode, | |
50c33087 | 1256 | gen_rtx_LO_SUM (Pmode, dp_reg, |
b2e9a2fd | 1257 | XEXP (operands[2], 0))); |
50c33087 MH |
1258 | }") |
1259 | ||
483dd5be MH |
1260 | (define_insn "loadhi_big_constant" |
1261 | [(set (match_operand:HI 0 "reg_operand" "=c*d") | |
8d485e2d MH |
1262 | (match_operand:HI 1 "const_int_operand" "")) |
1263 | (clobber (reg:QI 16))] | |
483dd5be | 1264 | "" |
50c33087 MH |
1265 | "#" |
1266 | [(set_attr "type" "multi")]) | |
1267 | ||
cb0ca284 MH |
1268 | ; |
1269 | ; LDIU/LDA/STI/STIK | |
959e0a76 | 1270 | ; |
cb0ca284 MH |
1271 | ; The following moves will not set the condition codes register. |
1272 | ; | |
1273 | ||
1274 | ; This must come before the general case | |
1275 | (define_insn "*movqi_stik" | |
1276 | [(set (match_operand:QI 0 "memory_operand" "=m") | |
1277 | (match_operand:QI 1 "stik_const_operand" "K"))] | |
4ddb3ea6 | 1278 | "! TARGET_C3X" |
cb0ca284 MH |
1279 | "stik\\t%1,%0" |
1280 | [(set_attr "type" "store")]) | |
1281 | ||
483dd5be MH |
1282 | (define_insn "loadqi_big_constant" |
1283 | [(set (match_operand:QI 0 "reg_operand" "=c*d") | |
8d485e2d MH |
1284 | (match_operand:QI 1 "const_int_operand" "")) |
1285 | (clobber (reg:QI 16))] | |
483dd5be MH |
1286 | "! IS_INT16_CONST (INTVAL (operands[1])) |
1287 | && ! IS_HIGH_CONST (INTVAL (operands[1]))" | |
1288 | "#" | |
1289 | [(set_attr "type" "multi")]) | |
1290 | ||
cb0ca284 MH |
1291 | ; We must provide an alternative to store to memory in case we have to |
1292 | ; spill a register. | |
1293 | (define_insn "movqi_noclobber" | |
f416f18c | 1294 | [(set (match_operand:QI 0 "dst_operand" "=d,*c,m,r") |
50c33087 MH |
1295 | (match_operand:QI 1 "src_hi_operand" "rIm,rIm,r,O"))] |
1296 | "(REG_P (operands[0]) || REG_P (operands[1]) | |
1297 | || GET_CODE (operands[0]) == SUBREG | |
1298 | || GET_CODE (operands[1]) == SUBREG) | |
55310df7 | 1299 | && ! symbolic_address_operand (operands[1], QImode)" |
cb0ca284 MH |
1300 | "* |
1301 | if (which_alternative == 2) | |
1302 | return \"sti\\t%1,%0\"; | |
1303 | ||
4ddb3ea6 | 1304 | if (! TARGET_C3X && which_alternative == 3) |
cb0ca284 | 1305 | { |
e27f8c8a | 1306 | operands[1] = GEN_INT ((INTVAL (operands[1]) >> 16) & 0xffff); |
cb0ca284 MH |
1307 | return \"ldhi\\t%1,%0\"; |
1308 | } | |
1309 | ||
1310 | /* The lda instruction cannot use the same register as source | |
1311 | and destination. */ | |
4ddb3ea6 | 1312 | if (! TARGET_C3X && which_alternative == 1 |
bc46716b MH |
1313 | && ( IS_ADDR_REG (operands[0]) |
1314 | || IS_INDEX_REG (operands[0]) | |
1315 | || IS_SP_REG (operands[0])) | |
cb0ca284 MH |
1316 | && (REGNO (operands[0]) != REGNO (operands[1]))) |
1317 | return \"lda\\t%1,%0\"; | |
1318 | return \"ldiu\\t%1,%0\"; | |
1319 | " | |
1320 | [(set_attr "type" "unary,lda,store,unary") | |
1321 | (set_attr "data" "int16,int16,int16,high_16")]) | |
1322 | ||
1323 | ; | |
1324 | ; LDI | |
1325 | ; | |
1326 | ||
1327 | ; We shouldn't need these peepholes, but the combiner seems to miss them... | |
1328 | (define_peephole | |
1329 | [(set (match_operand:QI 0 "ext_reg_operand" "=d") | |
50c33087 | 1330 | (match_operand:QI 1 "src_operand" "rIm")) |
cb0ca284 MH |
1331 | (set (reg:CC 21) |
1332 | (compare:CC (match_dup 0) (const_int 0)))] | |
1333 | "" | |
3b67042a | 1334 | "ldi\\t%1,%0" |
cb0ca284 MH |
1335 | [(set_attr "type" "unarycc") |
1336 | (set_attr "data" "int16")]) | |
1337 | ||
1338 | (define_insn "*movqi_set" | |
1339 | [(set (reg:CC 21) | |
50c33087 | 1340 | (compare:CC (match_operand:QI 1 "src_operand" "rIm") |
cb0ca284 MH |
1341 | (const_int 0))) |
1342 | (set (match_operand:QI 0 "ext_reg_operand" "=d") | |
1343 | (match_dup 1))] | |
1344 | "" | |
3b67042a | 1345 | "ldi\\t%1,%0" |
cb0ca284 MH |
1346 | [(set_attr "type" "unarycc") |
1347 | (set_attr "data" "int16")]) | |
1348 | ||
1349 | ; This pattern probably gets in the way and requires a scratch register | |
1350 | ; when a simple compare with zero will suffice. | |
1351 | ;(define_insn "*movqi_test" | |
1352 | ; [(set (reg:CC 21) | |
50c33087 | 1353 | ; (compare:CC (match_operand:QI 1 "src_operand" "rIm") |
cb0ca284 MH |
1354 | ; (const_int 0))) |
1355 | ; (clobber (match_scratch:QI 0 "=d"))] | |
1356 | ; "" | |
1357 | ; "@ | |
1358 | ; ldi\\t%1,%0" | |
1359 | ; [(set_attr "type" "unarycc") | |
1360 | ; (set_attr "data" "int16")]) | |
1361 | ||
1362 | ; If one of the operands is not a register, then we should | |
1363 | ; emit two insns, using a scratch register. This will produce | |
1364 | ; better code in loops if the source operand is invariant, since | |
1365 | ; the source reload can be optimised out. During reload we cannot | |
1366 | ; use change_address or force_reg which will allocate new pseudo regs. | |
1367 | ||
1368 | ; Unlike most other insns, the move insns can't be split with | |
1369 | ; different predicates, because register spilling and other parts of | |
1370 | ; the compiler, have memoized the insn number already. | |
1371 | ||
1372 | (define_expand "movqi" | |
50c33087 MH |
1373 | [(set (match_operand:QI 0 "general_operand" "") |
1374 | (match_operand:QI 1 "general_operand" ""))] | |
cb0ca284 MH |
1375 | "" |
1376 | " | |
50c33087 MH |
1377 | { |
1378 | if (c4x_emit_move_sequence (operands, QImode)) | |
1379 | DONE; | |
1380 | }") | |
cb0ca284 | 1381 | |
cb0ca284 | 1382 | |
52695ce0 HB |
1383 | ; As far as GCC is concerned, the moves are performed in parallel |
1384 | ; thus it must be convinced that there is no aliasing. | |
1385 | ; It also assumes that the input operands are simultaneously loaded | |
1386 | ; and then the output operands are simultaneously stored. | |
1387 | ; With the C4x, if there are parallel stores to the same address | |
1388 | ; both stores are executed. | |
1389 | ; If there is a parallel load and store to the same address, | |
1390 | ; the load is performed first. | |
1391 | ; The problem with this pattern is that reload can spoil | |
1392 | ; the show when it eliminates a reference to the frame pointer. | |
1393 | ; This can invalidate the memory addressing mode, i.e., when | |
1394 | ; the displacement is greater than 1. | |
cb0ca284 | 1395 | (define_insn "movqi_parallel" |
1f7c7f6f MH |
1396 | [(set (match_operand:QI 0 "parallel_operand" "=q,S<>!V,q,S<>!V") |
1397 | (match_operand:QI 1 "parallel_operand" "S<>!V,q,S<>!V,q")) | |
1398 | (set (match_operand:QI 2 "parallel_operand" "=q,S<>!V,S<>!V,q") | |
1399 | (match_operand:QI 3 "parallel_operand" "S<>!V,q,q,S<>!V"))] | |
1400 | "TARGET_PARALLEL && valid_parallel_load_store (operands, QImode)" | |
cb0ca284 MH |
1401 | "@ |
1402 | ldi1\\t%1,%0\\n||\\tldi2\\t%3,%2 | |
1403 | sti1\\t%1,%0\\n||\\tsti2\\t%3,%2 | |
1404 | ldi\\t%1,%0\\n||\\tsti\\t%3,%2 | |
1405 | ldi\\t%3,%2\\n||\\tsti\\t%1,%0" | |
1406 | [(set_attr "type" "load_load,store_store,load_store,store_load")]) | |
1407 | ||
1408 | ; | |
1409 | ; PUSH/POP | |
1410 | ; | |
52695ce0 | 1411 | (define_insn "pushqi" |
cb0ca284 MH |
1412 | [(set (mem:QI (pre_inc:QI (reg:QI 20))) |
1413 | (match_operand:QI 0 "reg_operand" "r"))] | |
1414 | "" | |
1415 | "push\\t%0" | |
1416 | [(set_attr "type" "push")]) | |
1417 | ||
52695ce0 HB |
1418 | (define_insn "push_st" |
1419 | [(set (mem:QI (pre_inc:QI (reg:QI 20))) (unspec:QI [(reg:QI 21)] 14)) | |
1420 | (use (reg:QI 21))] | |
1421 | "" | |
1422 | "push\\tst" | |
1423 | [(set_attr "type" "push")]) | |
1424 | ||
1425 | (define_insn "push_dp" | |
1426 | [(set (mem:QI (pre_inc:QI (reg:QI 20))) (unspec:QI [(reg:QI 16)] 16)) | |
1427 | (use (reg:QI 16))] | |
1428 | "" | |
1429 | "push\\tdp" | |
1430 | [(set_attr "type" "push")]) | |
1431 | ||
1432 | (define_insn "popqi" | |
cb0ca284 MH |
1433 | [(set (match_operand:QI 0 "reg_operand" "=r") |
1434 | (mem:QI (post_dec:QI (reg:QI 20)))) | |
1435 | (clobber (reg:CC 21))] | |
1436 | "" | |
1437 | "pop\\t%0" | |
1438 | [(set_attr "type" "pop")]) | |
1439 | ||
52695ce0 HB |
1440 | (define_insn "pop_st" |
1441 | [(set (unspec:QI [(reg:QI 21)] 15) (mem:QI (post_dec:QI (reg:QI 20)))) | |
1442 | (clobber (reg:CC 21))] | |
1443 | "" | |
1444 | "pop\\tst" | |
1445 | [(set_attr "type" "pop")]) | |
1446 | ||
1447 | (define_insn "pop_dp" | |
1448 | [(set (unspec:QI [(reg:QI 16)] 17) (mem:QI (post_dec:QI (reg:QI 20)))) | |
1449 | (clobber (reg:CC 16))] | |
1450 | "" | |
1451 | "pop\\tdp" | |
1452 | [(set_attr "type" "pop")]) | |
1453 | ||
1454 | (define_insn "popqi_unspec" | |
1455 | [(set (unspec:QI [(match_operand:QI 0 "reg_operand" "=r")] 18) | |
1456 | (mem:QI (post_dec:QI (reg:QI 20)))) | |
1457 | (clobber (match_dup 0)) | |
1458 | (clobber (reg:CC 21))] | |
1459 | "" | |
1460 | "pop\\t%0" | |
1461 | [(set_attr "type" "pop")]) | |
1462 | ||
cb0ca284 MH |
1463 | ; |
1464 | ; ABSI | |
1465 | ; | |
1466 | (define_expand "absqi2" | |
1467 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
1468 | (abs:QI (match_operand:QI 1 "src_operand" ""))) | |
1469 | (clobber (reg:CC_NOOV 21))])] | |
1470 | "" | |
1471 | "") | |
1472 | ||
1473 | (define_insn "*absqi2_clobber" | |
1474 | [(set (match_operand:QI 0 "reg_operand" "=d,c") | |
50c33087 | 1475 | (abs:QI (match_operand:QI 1 "src_operand" "rIm,rIm"))) |
cb0ca284 MH |
1476 | (clobber (reg:CC_NOOV 21))] |
1477 | "" | |
1478 | "absi\\t%1,%0" | |
1479 | [(set_attr "type" "unarycc,unary") | |
1480 | (set_attr "data" "int16,int16")]) | |
1481 | ||
57e5bce8 MH |
1482 | (define_insn "*absqi2_noclobber" |
1483 | [(set (match_operand:QI 0 "std_reg_operand" "=c") | |
1484 | (abs:QI (match_operand:QI 1 "src_operand" "rIm")))] | |
1485 | "" | |
1486 | "absi\\t%1,%0" | |
1487 | [(set_attr "type" "unary") | |
1488 | (set_attr "data" "int16")]) | |
1489 | ||
1490 | (define_split | |
1491 | [(set (match_operand:QI 0 "std_reg_operand" "") | |
1492 | (abs:QI (match_operand:QI 1 "src_operand" ""))) | |
1493 | (clobber (reg:CC_NOOV 21))] | |
1494 | "reload_completed" | |
1495 | [(set (match_dup 0) | |
1496 | (abs:QI (match_dup 1)))] | |
1497 | "") | |
1498 | ||
cb0ca284 MH |
1499 | (define_insn "*absqi2_test" |
1500 | [(set (reg:CC_NOOV 21) | |
50c33087 | 1501 | (compare:CC_NOOV (abs:QI (match_operand:QI 1 "src_operand" "rIm")) |
cb0ca284 MH |
1502 | (const_int 0))) |
1503 | (clobber (match_scratch:QI 0 "=d"))] | |
1504 | "" | |
1505 | "absi\\t%1,%0" | |
1506 | [(set_attr "type" "unarycc") | |
1507 | (set_attr "data" "int16")]) | |
1508 | ||
1509 | (define_insn "*absqi2_set" | |
1510 | [(set (reg:CC_NOOV 21) | |
50c33087 | 1511 | (compare:CC_NOOV (abs:QI (match_operand:QI 1 "src_operand" "rIm")) |
cb0ca284 MH |
1512 | (const_int 0))) |
1513 | (set (match_operand:QI 0 "ext_reg_operand" "=d") | |
1514 | (abs:QI (match_dup 1)))] | |
1515 | "" | |
1516 | "absi\\t%1,%0" | |
1517 | [(set_attr "type" "unarycc") | |
1518 | (set_attr "data" "int16")]) | |
1519 | ||
1520 | ; | |
1521 | ; NEGI | |
1522 | ; | |
1523 | (define_expand "negqi2" | |
1524 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
1525 | (neg:QI (match_operand:QI 1 "src_operand" ""))) | |
1526 | (clobber (reg:CC_NOOV 21))])] | |
1527 | "" | |
1528 | "") | |
1529 | ||
1530 | (define_insn "*negqi2_clobber" | |
1531 | [(set (match_operand:QI 0 "reg_operand" "=d,c") | |
50c33087 | 1532 | (neg:QI (match_operand:QI 1 "src_operand" "rIm,rIm"))) |
cb0ca284 MH |
1533 | (clobber (reg:CC_NOOV 21))] |
1534 | "" | |
1535 | "negi\\t%1,%0" | |
1536 | [(set_attr "type" "unarycc,unary") | |
1537 | (set_attr "data" "int16,int16")]) | |
1538 | ||
57e5bce8 MH |
1539 | (define_insn "*negqi2_noclobber" |
1540 | [(set (match_operand:QI 0 "std_reg_operand" "=c") | |
1541 | (neg:QI (match_operand:QI 1 "src_operand" "rIm")))] | |
1542 | "" | |
1543 | "negi\\t%1,%0" | |
1544 | [(set_attr "type" "unary") | |
1545 | (set_attr "data" "int16")]) | |
1546 | ||
1547 | (define_split | |
1548 | [(set (match_operand:QI 0 "std_reg_operand" "") | |
1549 | (neg:QI (match_operand:QI 1 "src_operand" ""))) | |
1550 | (clobber (reg:CC_NOOV 21))] | |
1551 | "reload_completed" | |
1552 | [(set (match_dup 0) | |
1553 | (neg:QI (match_dup 1)))] | |
1554 | "") | |
1555 | ||
cb0ca284 MH |
1556 | (define_insn "*negqi2_test" |
1557 | [(set (reg:CC_NOOV 21) | |
50c33087 | 1558 | (compare:CC_NOOV (neg:QI (match_operand:QI 1 "src_operand" "rIm")) |
cb0ca284 MH |
1559 | (const_int 0))) |
1560 | (clobber (match_scratch:QI 0 "=d"))] | |
1561 | "" | |
1562 | "negi\\t%1,%0" | |
1563 | [(set_attr "type" "unarycc") | |
1564 | (set_attr "data" "int16")]) | |
1565 | ||
1566 | (define_insn "*negqi2_set" | |
1567 | [(set (reg:CC_NOOV 21) | |
50c33087 | 1568 | (compare:CC_NOOV (neg:QI (match_operand:QI 1 "src_operand" "rIm")) |
cb0ca284 MH |
1569 | (const_int 0))) |
1570 | (set (match_operand:QI 0 "ext_reg_operand" "=d") | |
1571 | (neg:QI (match_dup 1)))] | |
1572 | "" | |
1573 | "negi\\t%1,%0" | |
1574 | [(set_attr "type" "unarycc") | |
1575 | (set_attr "data" "int16")]) | |
1576 | ||
1577 | (define_insn "*negbqi2_clobber" | |
1578 | [(set (match_operand:QI 0 "ext_reg_operand" "=d") | |
50c33087 | 1579 | (neg:QI (match_operand:QI 1 "src_operand" "rIm"))) |
cb0ca284 MH |
1580 | (use (reg:CC_NOOV 21)) |
1581 | (clobber (reg:CC_NOOV 21))] | |
1582 | "" | |
1583 | "negb\\t%1,%0" | |
1584 | [(set_attr "type" "unarycc") | |
1585 | (set_attr "data" "int16")]) | |
1586 | ||
1587 | ; | |
1588 | ; NOT | |
1589 | ; | |
1590 | (define_expand "one_cmplqi2" | |
1591 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
1592 | (not:QI (match_operand:QI 1 "lsrc_operand" ""))) | |
1593 | (clobber (reg:CC 21))])] | |
1594 | "" | |
1595 | "") | |
1596 | ||
1597 | (define_insn "*one_cmplqi2_clobber" | |
1598 | [(set (match_operand:QI 0 "reg_operand" "=d,c") | |
50c33087 | 1599 | (not:QI (match_operand:QI 1 "lsrc_operand" "rLm,rLm"))) |
cb0ca284 MH |
1600 | (clobber (reg:CC 21))] |
1601 | "" | |
1602 | "not\\t%1,%0" | |
1603 | [(set_attr "type" "unarycc,unary") | |
1604 | (set_attr "data" "uint16,uint16")]) | |
1605 | ||
57e5bce8 MH |
1606 | (define_insn "*one_cmplqi2_noclobber" |
1607 | [(set (match_operand:QI 0 "std_reg_operand" "=c") | |
1608 | (not:QI (match_operand:QI 1 "lsrc_operand" "rLm")))] | |
1609 | "" | |
1610 | "not\\t%1,%0" | |
1611 | [(set_attr "type" "unary") | |
1612 | (set_attr "data" "uint16")]) | |
1613 | ||
1614 | (define_split | |
1615 | [(set (match_operand:QI 0 "std_reg_operand" "") | |
1616 | (not:QI (match_operand:QI 1 "lsrc_operand" ""))) | |
1617 | (clobber (reg:CC 21))] | |
1618 | "reload_completed" | |
1619 | [(set (match_dup 0) | |
1620 | (not:QI (match_dup 1)))] | |
1621 | "") | |
1622 | ||
cb0ca284 MH |
1623 | (define_insn "*one_cmplqi2_test" |
1624 | [(set (reg:CC 21) | |
50c33087 | 1625 | (compare:CC (not:QI (match_operand:QI 1 "lsrc_operand" "rLm")) |
cb0ca284 MH |
1626 | (const_int 0))) |
1627 | (clobber (match_scratch:QI 0 "=d"))] | |
1628 | "" | |
1629 | "not\\t%1,%0" | |
1630 | [(set_attr "type" "unarycc") | |
1631 | (set_attr "data" "uint16")]) | |
1632 | ||
1633 | (define_insn "*one_cmplqi2_set" | |
1634 | [(set (reg:CC 21) | |
50c33087 | 1635 | (compare:CC (not:QI (match_operand:QI 1 "lsrc_operand" "rLm")) |
cb0ca284 MH |
1636 | (const_int 0))) |
1637 | (set (match_operand:QI 0 "ext_reg_operand" "=d") | |
1638 | (not:QI (match_dup 1)))] | |
1639 | "" | |
1640 | "not\\t%1,%0" | |
1641 | [(set_attr "type" "unarycc") | |
1642 | (set_attr "data" "uint16")]) | |
1643 | ||
1644 | (define_insn "*one_cmplqi2_const_clobber" | |
1645 | [(set (match_operand:QI 0 "reg_operand" "=d,c") | |
1646 | (match_operand:QI 1 "not_const_operand" "N,N")) | |
1647 | (clobber (reg:CC 21))] | |
1648 | "" | |
1649 | "@ | |
1650 | not\\t%N1,%0 | |
1651 | not\\t%N1,%0" | |
1652 | [(set_attr "type" "unarycc,unary") | |
1653 | (set_attr "data" "not_uint16,not_uint16")]) | |
1654 | ||
1655 | ; movqi can use this for loading an integer that can't normally | |
1656 | ; fit into a 16-bit signed integer. The drawback is that it cannot | |
1657 | ; go into R0-R11 since that will clobber the CC and movqi shouldn't | |
1658 | ; do that. This can cause additional reloading but in most cases | |
1659 | ; this will cause only an additional register move. With the large | |
1660 | ; memory model we require an extra instruction to load DP anyway, | |
1661 | ; if we're loading the constant from memory. The big advantage of | |
1662 | ; allowing constants that satisfy not_const_operand in movqi, is that | |
1663 | ; it allows andn to be generated more often. | |
1664 | ; However, there is a problem if GCC has decided that it wants | |
1665 | ; to use R0-R11, since we won't have a matching pattern... | |
1666 | ; In interim, we prevent immed_const allowing `N' constants. | |
1667 | (define_insn "*one_cmplqi2_const_noclobber" | |
1668 | [(set (match_operand:QI 0 "std_reg_operand" "=c") | |
1669 | (match_operand:QI 1 "not_const_operand" "N"))] | |
1670 | "" | |
1671 | "not\\t%N1,%0" | |
1672 | [(set_attr "type" "unary") | |
1673 | (set_attr "data" "not_uint16")]) | |
1674 | ||
1675 | ; | |
1676 | ; ROL | |
1677 | ; | |
1678 | (define_expand "rotlqi3" | |
1679 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
1680 | (rotate:QI (match_operand:QI 1 "reg_operand" "") | |
1681 | (match_operand:QI 2 "const_int_operand" ""))) | |
1682 | (clobber (reg:CC 21))])] | |
1683 | "" | |
5e6a42d9 | 1684 | "if (INTVAL (operands[2]) > 4) |
cb0ca284 MH |
1685 | FAIL; /* Open code as two shifts and an or */ |
1686 | if (INTVAL (operands[2]) > 1) | |
1687 | { | |
1688 | int i; | |
5e6a42d9 | 1689 | rtx tmp; |
cb0ca284 MH |
1690 | |
1691 | /* If we have 4 or fewer shifts, then it is probably faster | |
1692 | to emit separate ROL instructions. A C3x requires | |
1693 | at least 4 instructions (a C4x requires at least 3), to | |
1694 | perform a rotation by shifts. */ | |
1695 | ||
5e6a42d9 MH |
1696 | tmp = operands[1]; |
1697 | for (i = 0; i < INTVAL (operands[2]) - 1; i++) | |
1698 | { | |
1699 | tmp = gen_reg_rtx (QImode); | |
1700 | emit_insn (gen_rotl_1_clobber (tmp, operands[1])); | |
1701 | operands[1] = tmp; | |
1702 | } | |
1703 | emit_insn (gen_rotl_1_clobber (operands[0], tmp)); | |
cb0ca284 MH |
1704 | DONE; |
1705 | }") | |
1706 | ||
1707 | (define_insn "rotl_1_clobber" | |
1708 | [(set (match_operand:QI 0 "reg_operand" "=d,c") | |
1709 | (rotate:QI (match_operand:QI 1 "reg_operand" "0,0") | |
1710 | (const_int 1))) | |
1711 | (clobber (reg:CC 21))] | |
1712 | "" | |
1713 | "rol\\t%0" | |
1714 | [(set_attr "type" "unarycc,unary")]) | |
1715 | ; Default to int16 data attr. | |
1716 | ||
1717 | ; | |
1718 | ; ROR | |
1719 | ; | |
1720 | (define_expand "rotrqi3" | |
1721 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
1722 | (rotatert:QI (match_operand:QI 1 "reg_operand" "") | |
1723 | (match_operand:QI 2 "const_int_operand" ""))) | |
1724 | (clobber (reg:CC 21))])] | |
1725 | "" | |
5e6a42d9 | 1726 | "if (INTVAL (operands[2]) > 4) |
cb0ca284 MH |
1727 | FAIL; /* Open code as two shifts and an or */ |
1728 | if (INTVAL (operands[2]) > 1) | |
1729 | { | |
1730 | int i; | |
5e6a42d9 | 1731 | rtx tmp; |
cb0ca284 MH |
1732 | |
1733 | /* If we have 4 or fewer shifts, then it is probably faster | |
1734 | to emit separate ROL instructions. A C3x requires | |
1735 | at least 4 instructions (a C4x requires at least 3), to | |
1736 | perform a rotation by shifts. */ | |
1737 | ||
5e6a42d9 MH |
1738 | tmp = operands[1]; |
1739 | for (i = 0; i < INTVAL (operands[2]) - 1; i++) | |
1740 | { | |
1741 | tmp = gen_reg_rtx (QImode); | |
1742 | emit_insn (gen_rotr_1_clobber (tmp, operands[1])); | |
1743 | operands[1] = tmp; | |
1744 | } | |
1745 | emit_insn (gen_rotr_1_clobber (operands[0], tmp)); | |
cb0ca284 MH |
1746 | DONE; |
1747 | }") | |
1748 | ||
1749 | (define_insn "rotr_1_clobber" | |
1750 | [(set (match_operand:QI 0 "reg_operand" "=d,c") | |
1751 | (rotatert:QI (match_operand:QI 1 "reg_operand" "0,0") | |
1752 | (const_int 1))) | |
1753 | (clobber (reg:CC 21))] | |
1754 | "" | |
1755 | "ror\\t%0" | |
1756 | [(set_attr "type" "unarycc,unary")]) | |
1757 | ; Default to int16 data attr. | |
1758 | ||
1759 | ||
1760 | ; | |
1761 | ; THREE OPERAND INTEGER INSTRUCTIONS | |
1762 | ; | |
1763 | ||
1764 | ; | |
1765 | ; ADDI | |
1766 | ; | |
f3ed04e7 MH |
1767 | ; This is used by reload when it calls gen_add2_insn for address arithmetic |
1768 | ; so we must emit the pattern that doesn't clobber CC. | |
1769 | ; | |
cb0ca284 | 1770 | (define_expand "addqi3" |
ed3614cd | 1771 | [(parallel [(set (match_operand:QI 0 "std_or_reg_operand" "") |
cb0ca284 MH |
1772 | (plus:QI (match_operand:QI 1 "src_operand" "") |
1773 | (match_operand:QI 2 "src_operand" ""))) | |
1774 | (clobber (reg:CC_NOOV 21))])] | |
1775 | "" | |
f3ed04e7 | 1776 | "legitimize_operands (PLUS, operands, QImode); |
e4e30b3d | 1777 | if (reload_in_progress |
bc46716b MH |
1778 | || (! IS_PSEUDO_REG (operands[0]) |
1779 | && ! IS_EXT_REG (operands[0]))) | |
f3ed04e7 MH |
1780 | { |
1781 | emit_insn (gen_addqi3_noclobber (operands[0], operands[1], operands[2])); | |
1782 | DONE; | |
1783 | }") | |
cb0ca284 MH |
1784 | |
1785 | (define_insn "*addqi3_clobber" | |
65c78c7d MH |
1786 | [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c") |
1787 | (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>") | |
1788 | (match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>"))) | |
cb0ca284 MH |
1789 | (clobber (reg:CC_NOOV 21))] |
1790 | "valid_operands (PLUS, operands, QImode)" | |
1791 | "@ | |
65c78c7d | 1792 | addi\\t%2,%0 |
cb0ca284 MH |
1793 | addi3\\t%2,%1,%0 |
1794 | addi3\\t%2,%1,%0 | |
1795 | addi\\t%2,%0 | |
1796 | addi3\\t%2,%1,%0 | |
65c78c7d | 1797 | addi3\\t%2,%1,%0" |
cb0ca284 MH |
1798 | [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")]) |
1799 | ; Default to int16 data attr. | |
1800 | ||
57e5bce8 MH |
1801 | (define_split |
1802 | [(set (match_operand:QI 0 "std_reg_operand" "") | |
1803 | (plus:QI (match_operand:QI 1 "src_operand" "") | |
1804 | (match_operand:QI 2 "src_operand" ""))) | |
1805 | (clobber (reg:CC_NOOV 21))] | |
1806 | "reload_completed" | |
1807 | [(set (match_dup 0) | |
1808 | (plus:QI (match_dup 1) | |
1809 | (match_dup 2)))] | |
1810 | "") | |
1811 | ||
cb0ca284 MH |
1812 | (define_insn "*addqi3_test" |
1813 | [(set (reg:CC_NOOV 21) | |
65c78c7d MH |
1814 | (compare:CC_NOOV (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") |
1815 | (match_operand:QI 2 "src_operand" "rIm,JR,rS<>")) | |
cb0ca284 | 1816 | (const_int 0))) |
65c78c7d | 1817 | (clobber (match_scratch:QI 0 "=d,d,d"))] |
cb0ca284 MH |
1818 | "valid_operands (PLUS, operands, QImode)" |
1819 | "@ | |
65c78c7d | 1820 | addi\\t%2,%0 |
cb0ca284 | 1821 | addi3\\t%2,%1,%0 |
65c78c7d | 1822 | addi3\\t%2,%1,%0" |
cb0ca284 MH |
1823 | [(set_attr "type" "binarycc,binarycc,binarycc")]) |
1824 | ; Default to int16 data attr. | |
1825 | ||
1826 | ; gcc does this in combine.c we just reverse it here | |
1827 | (define_insn "*cmp_neg" | |
1828 | [(set (reg:CC_NOOV 21) | |
65c78c7d MH |
1829 | (compare:CC_NOOV (match_operand:QI 1 "src_operand" "%0,rR,rS<>") |
1830 | (neg: QI (match_operand:QI 2 "src_operand" "g,JR,rS<>")))) | |
1831 | (clobber (match_scratch:QI 0 "=d,d,d"))] | |
cb0ca284 MH |
1832 | "valid_operands (PLUS, operands, QImode)" |
1833 | "@ | |
65c78c7d | 1834 | addi\\t%2,%0 |
cb0ca284 | 1835 | addi3\\t%2,%1,%0 |
65c78c7d | 1836 | addi3\\t%2,%1,%0" |
cb0ca284 MH |
1837 | [(set_attr "type" "binarycc,binarycc,binarycc")]) |
1838 | ||
1839 | (define_peephole | |
65c78c7d MH |
1840 | [(parallel [(set (match_operand:QI 0 "ext_reg_operand" "=d,d,d") |
1841 | (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") | |
1842 | (match_operand:QI 2 "src_operand" "g,JR,rS<>"))) | |
cb0ca284 MH |
1843 | (clobber (reg:CC_NOOV 21))]) |
1844 | (set (reg:CC_NOOV 21) | |
1845 | (compare:CC_NOOV (match_dup 0) (const_int 0)))] | |
1846 | "valid_operands (PLUS, operands, QImode)" | |
1847 | "@ | |
65c78c7d | 1848 | addi\\t%2,%0 |
cb0ca284 | 1849 | addi3\\t%2,%1,%0 |
65c78c7d | 1850 | addi3\\t%2,%1,%0" |
cb0ca284 MH |
1851 | [(set_attr "type" "binarycc,binarycc,binarycc")]) |
1852 | ||
1853 | (define_insn "*addqi3_set" | |
1854 | [(set (reg:CC_NOOV 21) | |
65c78c7d MH |
1855 | (compare:CC_NOOV (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") |
1856 | (match_operand:QI 2 "src_operand" "rIm,JR,rS<>")) | |
cb0ca284 | 1857 | (const_int 0))) |
65c78c7d | 1858 | (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d") |
cb0ca284 MH |
1859 | (plus:QI (match_dup 1) (match_dup 2)))] |
1860 | "valid_operands (PLUS, operands, QImode)" | |
1861 | "@ | |
65c78c7d | 1862 | addi\\t%2,%0 |
cb0ca284 | 1863 | addi3\\t%2,%1,%0 |
65c78c7d | 1864 | addi3\\t%2,%1,%0" |
cb0ca284 MH |
1865 | [(set_attr "type" "binarycc,binarycc,binarycc")]) |
1866 | ; Default to int16 data attr. | |
1867 | ||
1868 | ; This pattern is required primarily for manipulating the stack pointer | |
959e0a76 MH |
1869 | ; where GCC doesn't expect CC to be clobbered or for calculating |
1870 | ; addresses during reload. | |
cb0ca284 | 1871 | (define_insn "addqi3_noclobber" |
65c78c7d MH |
1872 | [(set (match_operand:QI 0 "std_reg_operand" "=c,c,c") |
1873 | (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") | |
1874 | (match_operand:QI 2 "src_operand" "rIm,JR,rS<>")))] | |
cb0ca284 MH |
1875 | "valid_operands (PLUS, operands, QImode)" |
1876 | "@ | |
65c78c7d | 1877 | addi\\t%2,%0 |
cb0ca284 | 1878 | addi3\\t%2,%1,%0 |
65c78c7d | 1879 | addi3\\t%2,%1,%0" |
cb0ca284 | 1880 | [(set_attr "type" "binary,binary,binary")]) |
e4e30b3d MH |
1881 | ; Default to int16 data attr. |
1882 | ||
1883 | ||
1884 | ; This pattern is required during reload when eliminate_regs_in_insn | |
1885 | ; effectively converts a move insn into an add insn when the src | |
1886 | ; operand is the frame pointer plus a constant. Without this | |
1887 | ; pattern, gen_addqi3 can be called with a register for operand0 | |
1888 | ; that can clobber CC. | |
1889 | ; For example, we may have (set (mem (reg ar0)) (reg 99)) | |
1890 | ; with (set (reg 99) (plus (reg ar3) (const_int 8))) | |
1891 | ; Now since ar3, the frame pointer, is unchanging within the function, | |
1892 | ; (plus (reg ar3) (const_int 8)) is considered a constant. | |
1893 | ; eliminate_regs_in_insn substitutes this constant to give | |
1894 | ; (set (mem (reg ar0)) (plus (reg ar3) (const_int 8))). | |
1895 | ; This is an invalid C4x insn but if we don't provide a pattern | |
1896 | ; for it, it will be considered to be a move insn for reloading. | |
e4e30b3d | 1897 | (define_insn "*addqi3_noclobber_reload" |
ed3614cd HB |
1898 | [(set (match_operand:QI 0 "std_reg_operand" "=c,c,c") |
1899 | (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") | |
1900 | (match_operand:QI 2 "src_operand" "rIm,JR,rS<>")))] | |
e4e30b3d | 1901 | "reload_in_progress" |
ed3614cd HB |
1902 | "@ |
1903 | addi\\t%2,%0 | |
1904 | addi3\\t%2,%1,%0 | |
1905 | addi3\\t%2,%1,%0" | |
1906 | [(set_attr "type" "binary,binary,binary")]) | |
cb0ca284 MH |
1907 | ; Default to int16 data attr. |
1908 | ||
1909 | ||
1910 | (define_insn "*addqi3_carry_clobber" | |
65c78c7d MH |
1911 | [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c") |
1912 | (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>") | |
1913 | (match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>"))) | |
cb0ca284 MH |
1914 | (use (reg:CC_NOOV 21)) |
1915 | (clobber (reg:CC_NOOV 21))] | |
1916 | "valid_operands (PLUS, operands, QImode)" | |
1917 | "@ | |
65c78c7d | 1918 | addc\\t%2,%0 |
cb0ca284 MH |
1919 | addc3\\t%2,%1,%0 |
1920 | addc3\\t%2,%1,%0 | |
1921 | addc\\t%2,%0 | |
1922 | addc3\\t%2,%1,%0 | |
65c78c7d | 1923 | addc3\\t%2,%1,%0" |
cb0ca284 MH |
1924 | [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")]) |
1925 | ; Default to int16 data attr. | |
1926 | ||
1927 | ||
1928 | ; | |
1929 | ; SUBI/SUBRI | |
1930 | ; | |
1931 | (define_expand "subqi3" | |
1932 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
1933 | (minus:QI (match_operand:QI 1 "src_operand" "") | |
1934 | (match_operand:QI 2 "src_operand" ""))) | |
1935 | (clobber (reg:CC_NOOV 21))])] | |
1936 | "" | |
1937 | "legitimize_operands (MINUS, operands, QImode);") | |
1938 | ||
1939 | (define_insn "*subqi3_clobber" | |
65c78c7d MH |
1940 | [(set (match_operand:QI 0 "reg_operand" "=d,d,d,?d,c,c,c,?c") |
1941 | (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>,0,rIm,rR,rS<>") | |
1942 | (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>,rIm,0,JR,rS<>"))) | |
cb0ca284 MH |
1943 | (clobber (reg:CC_NOOV 21))] |
1944 | "valid_operands (MINUS, operands, QImode)" | |
1945 | "@ | |
cb0ca284 MH |
1946 | subi\\t%2,%0 |
1947 | subri\\t%1,%0 | |
1948 | subi3\\t%2,%1,%0 | |
1949 | subi3\\t%2,%1,%0 | |
1950 | subi\\t%2,%0 | |
65c78c7d MH |
1951 | subri\\t%1,%0 |
1952 | subi3\\t%2,%1,%0 | |
1953 | subi3\\t%2,%1,%0" | |
cb0ca284 MH |
1954 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc,binary,binary,binary,binary")]) |
1955 | ; Default to int16 data attr. | |
1956 | ||
57e5bce8 MH |
1957 | (define_split |
1958 | [(set (match_operand:QI 0 "std_reg_operand" "") | |
1959 | (minus:QI (match_operand:QI 1 "src_operand" "") | |
1960 | (match_operand:QI 2 "src_operand" ""))) | |
1961 | (clobber (reg:CC_NOOV 21))] | |
1962 | "reload_completed" | |
1963 | [(set (match_dup 0) | |
1964 | (minus:QI (match_dup 1) | |
1965 | (match_dup 2)))] | |
1966 | "") | |
1967 | ||
cb0ca284 MH |
1968 | (define_insn "*subqi3_test" |
1969 | [(set (reg:CC_NOOV 21) | |
65c78c7d MH |
1970 | (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>") |
1971 | (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>")) | |
cb0ca284 | 1972 | (const_int 0))) |
65c78c7d | 1973 | (clobber (match_scratch:QI 0 "=d,d,d,?d"))] |
cb0ca284 MH |
1974 | "valid_operands (MINUS, operands, QImode)" |
1975 | "@ | |
cb0ca284 | 1976 | subi\\t%2,%0 |
65c78c7d MH |
1977 | subri\\t%1,%0 |
1978 | subi3\\t%2,%1,%0 | |
1979 | subi3\\t%2,%1,%0" | |
cb0ca284 MH |
1980 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")]) |
1981 | ; Default to int16 data attr. | |
1982 | ||
1983 | (define_peephole | |
65c78c7d MH |
1984 | [(parallel [(set (match_operand:QI 0 "ext_reg_operand" "=d,d,d,?d") |
1985 | (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>") | |
1986 | (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>"))) | |
cb0ca284 MH |
1987 | (clobber (reg:CC_NOOV 21))]) |
1988 | (set (reg:CC_NOOV 21) | |
1989 | (compare:CC_NOOV (match_dup 0) (const_int 0)))] | |
1990 | "valid_operands (MINUS, operands, QImode)" | |
1991 | "@ | |
cb0ca284 | 1992 | subi\\t%2,%0 |
65c78c7d MH |
1993 | subri\\t%1,%0 |
1994 | subi3\\t%2,%1,%0 | |
1995 | subi3\\t%2,%1,%0" | |
cb0ca284 MH |
1996 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")]) |
1997 | ||
1998 | (define_insn "*subqi3_set" | |
1999 | [(set (reg:CC_NOOV 21) | |
65c78c7d MH |
2000 | (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>") |
2001 | (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>")) | |
cb0ca284 | 2002 | (const_int 0))) |
65c78c7d | 2003 | (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d,?d") |
cb0ca284 MH |
2004 | (minus:QI (match_dup 1) |
2005 | (match_dup 2)))] | |
2006 | "valid_operands (MINUS, operands, QImode)" | |
2007 | "@ | |
cb0ca284 | 2008 | subi\\t%2,%0 |
65c78c7d MH |
2009 | subri\\t%1,%0 |
2010 | subi3\\t%2,%1,%0 | |
2011 | subi3\\t%2,%1,%0" | |
cb0ca284 MH |
2012 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")]) |
2013 | ; Default to int16 data attr. | |
2014 | ||
57e5bce8 MH |
2015 | (define_insn "*subqi3_noclobber" |
2016 | [(set (match_operand:QI 0 "std_reg_operand" "=c,c,c,?c") | |
2017 | (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>") | |
2018 | (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>")))] | |
2019 | "valid_operands (MINUS, operands, QImode)" | |
2020 | "@ | |
2021 | subi\\t%2,%0 | |
2022 | subri\\t%1,%0 | |
2023 | subi3\\t%2,%1,%0 | |
2024 | subi3\\t%2,%1,%0" | |
2025 | [(set_attr "type" "binary,binary,binary,binary")]) | |
2026 | ; Default to int16 data attr. | |
2027 | ||
cb0ca284 | 2028 | (define_insn "*subqi3_carry_clobber" |
65c78c7d MH |
2029 | [(set (match_operand:QI 0 "reg_operand" "=d,d,d,?d,c,c,c,?c") |
2030 | (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>,0,rIm,rR,rS<>") | |
2031 | (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>,rIm,0,JR,rS<>"))) | |
cb0ca284 MH |
2032 | (use (reg:CC_NOOV 21)) |
2033 | (clobber (reg:CC_NOOV 21))] | |
2034 | "valid_operands (MINUS, operands, QImode)" | |
2035 | "@ | |
cb0ca284 MH |
2036 | subb\\t%2,%0 |
2037 | subrb\\t%1,%0 | |
2038 | subb3\\t%2,%1,%0 | |
2039 | subb3\\t%2,%1,%0 | |
2040 | subb\\t%2,%0 | |
65c78c7d MH |
2041 | subrb\\t%1,%0 |
2042 | subb3\\t%2,%1,%0 | |
2043 | subb3\\t%2,%1,%0" | |
cb0ca284 MH |
2044 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc,binary,binary,binary,binary")]) |
2045 | ; Default to int16 data attr. | |
2046 | ||
2047 | (define_insn "*subqi3_carry_set" | |
2048 | [(set (reg:CC_NOOV 21) | |
65c78c7d MH |
2049 | (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>") |
2050 | (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>")) | |
cb0ca284 | 2051 | (const_int 0))) |
65c78c7d | 2052 | (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d,?d") |
cb0ca284 MH |
2053 | (minus:QI (match_dup 1) |
2054 | (match_dup 2))) | |
2055 | (use (reg:CC_NOOV 21))] | |
2056 | "valid_operands (MINUS, operands, QImode)" | |
2057 | "@ | |
cb0ca284 | 2058 | subb\\t%2,%0 |
65c78c7d MH |
2059 | subrb\\t%1,%0 |
2060 | subb3\\t%2,%1,%0 | |
2061 | subb3\\t%2,%1,%0" | |
cb0ca284 MH |
2062 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")]) |
2063 | ; Default to int16 data attr. | |
2064 | ||
2065 | ; | |
2066 | ; MPYI | |
2067 | ; | |
2068 | (define_expand "mulqi3" | |
2069 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
2070 | (mult:QI (match_operand:QI 1 "src_operand" "") | |
2071 | (match_operand:QI 2 "src_operand" ""))) | |
2072 | (clobber (reg:CC_NOOV 21))])] | |
2073 | "" | |
2074 | "if (TARGET_MPYI || (GET_CODE (operands[2]) == CONST_INT | |
2075 | && exact_log2 (INTVAL (operands[2])) >= 0)) | |
2076 | legitimize_operands (MULT, operands, QImode); | |
2077 | else | |
2078 | { | |
2079 | if (GET_CODE (operands[2]) == CONST_INT) | |
2080 | { | |
2081 | /* Let GCC try to synthesise the multiplication using shifts | |
2082 | and adds. In most cases this will be more profitable than | |
2083 | using the C3x MPYI. */ | |
2084 | FAIL; | |
2085 | } | |
2086 | if (operands[1] == operands[2]) | |
2087 | { | |
2088 | /* Do the squaring operation in-line. */ | |
959e0a76 | 2089 | emit_insn (gen_sqrqi2_inline (operands[0], operands[1])); |
cb0ca284 MH |
2090 | DONE; |
2091 | } | |
2092 | if (TARGET_INLINE) | |
2093 | { | |
959e0a76 MH |
2094 | emit_insn (gen_mulqi3_inline (operands[0], operands[1], |
2095 | operands[2])); | |
cb0ca284 MH |
2096 | DONE; |
2097 | } | |
4fda2521 HB |
2098 | c4x_emit_libcall3 (smul_optab->handlers[(int) QImode].libfunc, |
2099 | MULT, QImode, operands); | |
cb0ca284 MH |
2100 | DONE; |
2101 | } | |
2102 | ") | |
2103 | ||
2104 | (define_insn "*mulqi3_clobber" | |
65c78c7d MH |
2105 | [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c") |
2106 | (mult:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>") | |
2107 | (match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>"))) | |
cb0ca284 MH |
2108 | (clobber (reg:CC_NOOV 21))] |
2109 | "valid_operands (MULT, operands, QImode)" | |
2110 | "* | |
65c78c7d | 2111 | if (which_alternative == 0 || which_alternative == 3) |
cb0ca284 MH |
2112 | { |
2113 | if (TARGET_C3X | |
2114 | && GET_CODE (operands[2]) == CONST_INT | |
2115 | && exact_log2 (INTVAL (operands[2])) >= 0) | |
2116 | return \"ash\\t%L2,%0\"; | |
2117 | else | |
2118 | return \"mpyi\\t%2,%0\"; | |
2119 | } | |
2120 | else | |
2121 | return \"mpyi3\\t%2,%1,%0\";" | |
2122 | [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")]) | |
2123 | ; Default to int16 data attr. | |
2124 | ||
2125 | (define_insn "*mulqi3_test" | |
2126 | [(set (reg:CC_NOOV 21) | |
65c78c7d MH |
2127 | (compare:CC_NOOV (mult:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") |
2128 | (match_operand:QI 2 "src_operand" "rIm,JR,rS<>")) | |
cb0ca284 | 2129 | (const_int 0))) |
65c78c7d | 2130 | (clobber (match_scratch:QI 0 "=d,d,d"))] |
cb0ca284 MH |
2131 | "valid_operands (MULT, operands, QImode)" |
2132 | "* | |
65c78c7d | 2133 | if (which_alternative == 0) |
cb0ca284 MH |
2134 | { |
2135 | if (TARGET_C3X | |
2136 | && GET_CODE (operands[2]) == CONST_INT | |
2137 | && exact_log2 (INTVAL (operands[2])) >= 0) | |
2138 | return \"ash\\t%L2,%0\"; | |
2139 | else | |
2140 | return \"mpyi\\t%2,%0\"; | |
2141 | } | |
2142 | else | |
2143 | return \"mpyi3\\t%2,%1,%0\";" | |
2144 | [(set_attr "type" "binarycc,binarycc,binarycc")]) | |
2145 | ; Default to int16 data attr. | |
2146 | ||
2147 | (define_insn "*mulqi3_set" | |
2148 | [(set (reg:CC_NOOV 21) | |
65c78c7d MH |
2149 | (compare:CC_NOOV (mult:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") |
2150 | (match_operand:QI 2 "src_operand" "rIm,JR,rS<>")) | |
cb0ca284 | 2151 | (const_int 0))) |
65c78c7d | 2152 | (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d") |
cb0ca284 MH |
2153 | (mult:QI (match_dup 1) |
2154 | (match_dup 2)))] | |
2155 | "valid_operands (MULT, operands, QImode)" | |
2156 | "* | |
65c78c7d | 2157 | if (which_alternative == 0) |
cb0ca284 MH |
2158 | { |
2159 | if (TARGET_C3X | |
2160 | && GET_CODE (operands[2]) == CONST_INT | |
2161 | && exact_log2 (INTVAL (operands[2])) >= 0) | |
2162 | return \"ash\\t%L2,%0\"; | |
2163 | else | |
2164 | return \"mpyi\\t%2,%0\"; | |
2165 | } | |
2166 | else | |
2167 | return \"mpyi3\\t%2,%1,%0\";" | |
2168 | [(set_attr "type" "binarycc,binarycc,binarycc")]) | |
2169 | ; Default to int16 data attr. | |
2170 | ||
2171 | ; The C3x multiply instruction assumes 24-bit signed integer operands | |
2172 | ; and the 48-bit result is truncated to 32-bits. | |
8a119a7d | 2173 | (define_insn "mulqi3_24_clobber" |
65c78c7d | 2174 | [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c") |
cb0ca284 MH |
2175 | (mult:QI |
2176 | (sign_extend:QI | |
65c78c7d | 2177 | (and:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>") |
cb0ca284 MH |
2178 | (const_int 16777215))) |
2179 | (sign_extend:QI | |
65c78c7d | 2180 | (and:QI (match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>") |
cb0ca284 MH |
2181 | (const_int 16777215))))) |
2182 | (clobber (reg:CC_NOOV 21))] | |
2183 | "TARGET_C3X && valid_operands (MULT, operands, QImode)" | |
2184 | "@ | |
65c78c7d | 2185 | mpyi\\t%2,%0 |
cb0ca284 MH |
2186 | mpyi3\\t%2,%1,%0 |
2187 | mpyi3\\t%2,%1,%0 | |
2188 | mpyi\\t%2,%0 | |
2189 | mpyi3\\t%2,%1,%0 | |
65c78c7d | 2190 | mpyi3\\t%2,%1,%0" |
cb0ca284 MH |
2191 | [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")]) |
2192 | ; Default to int16 data attr. | |
2193 | ||
2194 | ||
2195 | ; Fast square function for C3x where TARGET_MPYI not asserted | |
2196 | (define_expand "sqrqi2_inline" | |
2197 | [(set (match_dup 7) (match_operand:QI 1 "src_operand" "")) | |
2198 | (parallel [(set (match_dup 3) | |
2199 | (lshiftrt:QI (match_dup 7) (const_int 16))) | |
2200 | (clobber (reg:CC 21))]) | |
2201 | (parallel [(set (match_dup 2) | |
2202 | (and:QI (match_dup 7) (const_int 65535))) | |
2203 | (clobber (reg:CC 21))]) | |
2204 | (parallel [(set (match_dup 4) | |
2205 | (mult:QI (sign_extend:QI (and:QI (match_dup 2) | |
2206 | (const_int 16777215))) | |
2207 | (sign_extend:QI (and:QI (match_dup 2) | |
2208 | (const_int 16777215))))) | |
2209 | (clobber (reg:CC_NOOV 21))]) | |
2210 | (parallel [(set (match_dup 5) | |
2211 | (mult:QI (sign_extend:QI (and:QI (match_dup 2) | |
2212 | (const_int 16777215))) | |
2213 | (sign_extend:QI (and:QI (match_dup 3) | |
2214 | (const_int 16777215))))) | |
2215 | (clobber (reg:CC_NOOV 21))]) | |
2216 | (parallel [(set (match_dup 6) | |
2217 | (ashift:QI (match_dup 5) (const_int 17))) | |
2218 | (clobber (reg:CC 21))]) | |
2219 | (parallel [(set (match_operand:QI 0 "reg_operand" "") | |
2220 | (plus:QI (match_dup 4) (match_dup 6))) | |
2221 | (clobber (reg:CC_NOOV 21))])] | |
2222 | "" | |
2223 | " | |
2224 | operands[2] = gen_reg_rtx (QImode); /* a = val & 0xffff */ | |
2225 | operands[3] = gen_reg_rtx (QImode); /* b = val >> 16 */ | |
2226 | operands[4] = gen_reg_rtx (QImode); /* a * a */ | |
2227 | operands[5] = gen_reg_rtx (QImode); /* a * b */ | |
2228 | operands[6] = gen_reg_rtx (QImode); /* (a * b) << 17 */ | |
2229 | operands[7] = gen_reg_rtx (QImode); /* val */ | |
2230 | ") | |
2231 | ||
2232 | ; Inlined integer multiply for C3x | |
2233 | (define_expand "mulqi3_inline" | |
2234 | [(set (match_dup 12) (const_int -16)) | |
2235 | (set (match_dup 13) (match_operand:QI 1 "src_operand" "")) | |
2236 | (set (match_dup 14) (match_operand:QI 2 "src_operand" "")) | |
2237 | (parallel [(set (match_dup 4) | |
2238 | (lshiftrt:QI (match_dup 13) (neg:QI (match_dup 12)))) | |
2239 | (clobber (reg:CC 21))]) | |
2240 | (parallel [(set (match_dup 6) | |
2241 | (lshiftrt:QI (match_dup 14) (neg:QI (match_dup 12)))) | |
2242 | (clobber (reg:CC 21))]) | |
2243 | (parallel [(set (match_dup 3) | |
2244 | (and:QI (match_dup 13) | |
2245 | (const_int 65535))) | |
2246 | (clobber (reg:CC 21))]) | |
2247 | (parallel [(set (match_dup 5) | |
2248 | (and:QI (match_dup 14) | |
2249 | (const_int 65535))) | |
2250 | (clobber (reg:CC 21))]) | |
2251 | (parallel [(set (match_dup 7) | |
2252 | (mult:QI (sign_extend:QI (and:QI (match_dup 4) | |
2253 | (const_int 16777215))) | |
2254 | (sign_extend:QI (and:QI (match_dup 5) | |
2255 | (const_int 16777215))))) | |
2256 | (clobber (reg:CC_NOOV 21))]) | |
2257 | (parallel [(set (match_dup 8) | |
2258 | (mult:QI (sign_extend:QI (and:QI (match_dup 3) | |
2259 | (const_int 16777215))) | |
2260 | (sign_extend:QI (and:QI (match_dup 5) | |
2261 | (const_int 16777215))))) | |
2262 | (clobber (reg:CC_NOOV 21))]) | |
2263 | (parallel [(set (match_dup 9) | |
2264 | (mult:QI (sign_extend:QI (and:QI (match_dup 3) | |
2265 | (const_int 16777215))) | |
2266 | (sign_extend:QI (and:QI (match_dup 6) | |
2267 | (const_int 16777215))))) | |
2268 | (clobber (reg:CC_NOOV 21))]) | |
2269 | (parallel [(set (match_dup 10) | |
2270 | (plus:QI (match_dup 7) (match_dup 9))) | |
2271 | (clobber (reg:CC_NOOV 21))]) | |
2272 | (parallel [(set (match_dup 11) | |
2273 | (ashift:QI (match_dup 10) (const_int 16))) | |
2274 | (clobber (reg:CC 21))]) | |
2275 | (parallel [(set (match_operand:QI 0 "reg_operand" "") | |
2276 | (plus:QI (match_dup 8) (match_dup 11))) | |
2277 | (clobber (reg:CC_NOOV 21))])] | |
2278 | "TARGET_C3X" | |
2279 | " | |
2280 | operands[3] = gen_reg_rtx (QImode); /* a = arg1 & 0xffff */ | |
2281 | operands[4] = gen_reg_rtx (QImode); /* b = arg1 >> 16 */ | |
2282 | operands[5] = gen_reg_rtx (QImode); /* a = arg2 & 0xffff */ | |
2283 | operands[6] = gen_reg_rtx (QImode); /* b = arg2 >> 16 */ | |
2284 | operands[7] = gen_reg_rtx (QImode); /* b * c */ | |
2285 | operands[8] = gen_reg_rtx (QImode); /* a * c */ | |
2286 | operands[9] = gen_reg_rtx (QImode); /* a * d */ | |
2287 | operands[10] = gen_reg_rtx (QImode); /* b * c + a * d */ | |
2288 | operands[11] = gen_reg_rtx (QImode); /* (b *c + a * d) << 16 */ | |
2289 | operands[12] = gen_reg_rtx (QImode); /* -16 */ | |
2290 | operands[13] = gen_reg_rtx (QImode); /* arg1 */ | |
2291 | operands[14] = gen_reg_rtx (QImode); /* arg2 */ | |
2292 | ") | |
2293 | ||
2294 | ; | |
2295 | ; MPYSHI (C4x only) | |
2296 | ; | |
2297 | (define_expand "smulqi3_highpart" | |
2298 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
2299 | (truncate:QI | |
2300 | (lshiftrt:HI | |
2301 | (mult:HI | |
2302 | (sign_extend:HI (match_operand:QI 1 "src_operand" "")) | |
2303 | (sign_extend:HI (match_operand:QI 2 "src_operand" ""))) | |
2304 | (const_int 32)))) | |
2305 | (clobber (reg:CC_NOOV 21))])] | |
2306 | "" | |
2307 | "legitimize_operands (MULT, operands, QImode); | |
2308 | if (TARGET_C3X) | |
2309 | { | |
4fda2521 | 2310 | c4x_emit_libcall_mulhi (smulhi3_libfunc, SIGN_EXTEND, QImode, operands); |
cb0ca284 MH |
2311 | DONE; |
2312 | } | |
2313 | ") | |
2314 | ||
2315 | (define_insn "*smulqi3_highpart_clobber" | |
65c78c7d | 2316 | [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c") |
cb0ca284 MH |
2317 | (truncate:QI |
2318 | (lshiftrt:HI | |
2319 | (mult:HI | |
65c78c7d MH |
2320 | (sign_extend:HI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>")) |
2321 | (sign_extend:HI (match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>"))) | |
cb0ca284 MH |
2322 | (const_int 32)))) |
2323 | (clobber (reg:CC_NOOV 21))] | |
4ddb3ea6 | 2324 | "! TARGET_C3X && valid_operands (MULT, operands, QImode)" |
cb0ca284 | 2325 | "@ |
ccd63d90 | 2326 | mpyshi\\t%2,%0 |
cb0ca284 MH |
2327 | mpyshi3\\t%2,%1,%0 |
2328 | mpyshi3\\t%2,%1,%0 | |
2329 | mpyshi\\t%2,%0 | |
2330 | mpyshi3\\t%2,%1,%0 | |
ccd63d90 | 2331 | mpyshi3\\t%2,%1,%0" |
cb0ca284 MH |
2332 | [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary") |
2333 | (set_attr "data" "int16,int16,int16,int16,int16,int16")]) | |
2334 | ||
f42850b9 MH |
2335 | (define_insn "*smulqi3_highpart_noclobber" |
2336 | [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c") | |
2337 | (truncate:QI | |
2338 | (lshiftrt:HI | |
2339 | (mult:HI | |
2340 | (sign_extend:HI (match_operand:QI 1 "src_operand" "0,rR,rS<>")) | |
2341 | (sign_extend:HI (match_operand:QI 2 "src_operand" "rIm,JR,rS<>"))) | |
2342 | (const_int 32))))] | |
2343 | "! TARGET_C3X && valid_operands (MULT, operands, QImode)" | |
2344 | "@ | |
2345 | mpyshi\\t%2,%0 | |
2346 | mpyshi3\\t%2,%1,%0 | |
2347 | mpyshi3\\t%2,%1,%0" | |
2348 | [(set_attr "type" "binary,binary,binary") | |
2349 | (set_attr "data" "int16,int16,int16")]) | |
2350 | ||
cb0ca284 MH |
2351 | ; |
2352 | ; MPYUHI (C4x only) | |
2353 | ; | |
2354 | (define_expand "umulqi3_highpart" | |
2355 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
2356 | (truncate:QI | |
2357 | (lshiftrt:HI | |
2358 | (mult:HI | |
2359 | (zero_extend:HI (match_operand:QI 1 "src_operand" "")) | |
2360 | (zero_extend:HI (match_operand:QI 2 "lsrc_operand" ""))) | |
2361 | (const_int 32)))) | |
2362 | (clobber (reg:CC_NOOV 21))])] | |
2363 | "" | |
2364 | "legitimize_operands (MULT, operands, QImode); | |
2365 | if (TARGET_C3X) | |
2366 | { | |
4fda2521 | 2367 | c4x_emit_libcall_mulhi (umulhi3_libfunc, ZERO_EXTEND, QImode, operands); |
cb0ca284 MH |
2368 | DONE; |
2369 | } | |
2370 | ") | |
2371 | ||
2372 | (define_insn "*umulqi3_highpart_clobber" | |
65c78c7d | 2373 | [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c") |
cb0ca284 MH |
2374 | (truncate:QI |
2375 | (lshiftrt:HI | |
2376 | (mult:HI | |
65c78c7d | 2377 | (zero_extend:HI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>")) |
f155b943 | 2378 | (zero_extend:HI (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>,rLm,JR,rS<>"))) |
cb0ca284 MH |
2379 | (const_int 32)))) |
2380 | (clobber (reg:CC_NOOV 21))] | |
4ddb3ea6 | 2381 | "! TARGET_C3X && valid_operands (MULT, operands, QImode)" |
cb0ca284 | 2382 | "@ |
ccd63d90 | 2383 | mpyuhi\\t%2,%0 |
cb0ca284 MH |
2384 | mpyuhi3\\t%2,%1,%0 |
2385 | mpyuhi3\\t%2,%1,%0 | |
2386 | mpyuhi\\t%2,%0 | |
2387 | mpyuhi3\\t%2,%1,%0 | |
ccd63d90 | 2388 | mpyuhi3\\t%2,%1,%0" |
cb0ca284 MH |
2389 | [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary") |
2390 | (set_attr "data" "uint16,uint16,uint16,uint16,uint16,uint16")]) | |
2391 | ||
f42850b9 MH |
2392 | (define_insn "*umulqi3_highpart_noclobber" |
2393 | [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c") | |
2394 | (truncate:QI | |
2395 | (lshiftrt:HI | |
2396 | (mult:HI | |
2397 | (zero_extend:HI (match_operand:QI 1 "src_operand" "0,rR,rS<>")) | |
2398 | (zero_extend:HI (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>"))) | |
2399 | (const_int 32))))] | |
2400 | "! TARGET_C3X && valid_operands (MULT, operands, QImode)" | |
2401 | "@ | |
2402 | mpyuhi\\t%2,%0 | |
2403 | mpyuhi3\\t%2,%1,%0 | |
2404 | mpyuhi3\\t%2,%1,%0" | |
2405 | [(set_attr "type" "binary,binary,binary") | |
2406 | (set_attr "data" "uint16,uint16,uint16")]) | |
2407 | ||
cb0ca284 MH |
2408 | ; |
2409 | ; AND | |
2410 | ; | |
2411 | (define_expand "andqi3" | |
2412 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
2413 | (and:QI (match_operand:QI 1 "src_operand" "") | |
2414 | (match_operand:QI 2 "tsrc_operand" ""))) | |
2415 | (clobber (reg:CC 21))])] | |
2416 | "" | |
2417 | "legitimize_operands (AND, operands, QImode);") | |
2418 | ||
d98d16b1 MH |
2419 | |
2420 | (define_insn "*andqi3_255_clobber" | |
65c78c7d | 2421 | [(set (match_operand:QI 0 "reg_operand" "=d,c") |
d98d16b1 MH |
2422 | (and:QI (match_operand:QI 1 "src_operand" "mr,mr") |
2423 | (const_int 255))) | |
2424 | (clobber (reg:CC 21))] | |
2425 | "! TARGET_C3X" | |
2426 | "lbu0\\t%1,%0" | |
57e5bce8 MH |
2427 | [(set_attr "type" "unarycc,unary")]) |
2428 | ||
2429 | (define_insn "*andqi3_255_noclobber" | |
2430 | [(set (match_operand:QI 0 "reg_operand" "=c") | |
2431 | (and:QI (match_operand:QI 1 "src_operand" "mr") | |
2432 | (const_int 255)))] | |
2433 | "! TARGET_C3X" | |
2434 | "lbu0\\t%1,%0" | |
2435 | [(set_attr "type" "unary")]) | |
d98d16b1 MH |
2436 | |
2437 | ||
2438 | (define_insn "*andqi3_65535_clobber" | |
65c78c7d | 2439 | [(set (match_operand:QI 0 "reg_operand" "=d,c") |
d98d16b1 MH |
2440 | (and:QI (match_operand:QI 1 "src_operand" "mr,mr") |
2441 | (const_int 65535))) | |
2442 | (clobber (reg:CC 21))] | |
2443 | "! TARGET_C3X" | |
2444 | "lhu0\\t%1,%0" | |
57e5bce8 | 2445 | [(set_attr "type" "unarycc,unary")]) |
d98d16b1 | 2446 | |
57e5bce8 MH |
2447 | (define_insn "*andqi3_65535_noclobber" |
2448 | [(set (match_operand:QI 0 "reg_operand" "=c") | |
2449 | (and:QI (match_operand:QI 1 "src_operand" "mr") | |
2450 | (const_int 65535)))] | |
2451 | "! TARGET_C3X" | |
2452 | "lhu0\\t%1,%0" | |
2453 | [(set_attr "type" "unary")]) | |
d98d16b1 | 2454 | |
cb0ca284 | 2455 | (define_insn "*andqi3_clobber" |
65c78c7d MH |
2456 | [(set (match_operand:QI 0 "reg_operand" "=d,d,d,?d,c,c,c,?c") |
2457 | (and:QI (match_operand:QI 1 "src_operand" "%0,0,rR,rS<>,0,0,rR,rS<>") | |
2458 | (match_operand:QI 2 "tsrc_operand" "N,rLm,JR,rS<>,N,rLm,JR,rS<>"))) | |
cb0ca284 MH |
2459 | (clobber (reg:CC 21))] |
2460 | "valid_operands (AND, operands, QImode)" | |
2461 | "@ | |
cb0ca284 MH |
2462 | andn\\t%N2,%0 |
2463 | and\\t%2,%0 | |
2464 | and3\\t%2,%1,%0 | |
2465 | and3\\t%2,%1,%0 | |
2466 | andn\\t%N2,%0 | |
65c78c7d MH |
2467 | and\\t%2,%0 |
2468 | and3\\t%2,%1,%0 | |
2469 | and3\\t%2,%1,%0" | |
cb0ca284 | 2470 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc,binary,binary,binary,binary") |
65c78c7d | 2471 | (set_attr "data" "not_uint16,uint16,int16,uint16,not_uint16,uint16,int16,uint16")]) |
cb0ca284 | 2472 | |
57e5bce8 MH |
2473 | (define_insn "*andqi3_noclobber" |
2474 | [(set (match_operand:QI 0 "std_reg_operand" "=c,c,c,?c") | |
2475 | (and:QI (match_operand:QI 1 "src_operand" "%0,0,rR,rS<>") | |
2476 | (match_operand:QI 2 "tsrc_operand" "N,rLm,JR,rS<>")))] | |
2477 | "valid_operands (AND, operands, QImode)" | |
2478 | "@ | |
2479 | andn\\t%N2,%0 | |
2480 | and\\t%2,%0 | |
2481 | and3\\t%2,%1,%0 | |
2482 | and3\\t%2,%1,%0" | |
2483 | [(set_attr "type" "binary,binary,binary,binary") | |
2484 | (set_attr "data" "not_uint16,uint16,int16,uint16")]) | |
2485 | ||
52695ce0 HB |
2486 | (define_insn "andn_st" |
2487 | [(set (unspec:QI [(reg:QI 21)] 20) | |
2488 | (and:QI (unspec:QI [(reg:QI 21)] 20) | |
2489 | (match_operand:QI 0 "" "N"))) | |
2490 | (use (match_dup 0)) | |
2491 | (use (reg:CC 21)) | |
2492 | (clobber (reg:CC 21))] | |
2493 | "" | |
3b67042a | 2494 | "andn\\t%N0,st" |
52695ce0 HB |
2495 | [(set_attr "type" "misc") |
2496 | (set_attr "data" "not_uint16")]) | |
2497 | ||
57e5bce8 MH |
2498 | (define_split |
2499 | [(set (match_operand:QI 0 "std_reg_operand" "") | |
2500 | (and:QI (match_operand:QI 1 "src_operand" "") | |
2501 | (match_operand:QI 2 "tsrc_operand" ""))) | |
2502 | (clobber (reg:CC 21))] | |
2503 | "reload_completed" | |
2504 | [(set (match_dup 0) | |
2505 | (and:QI (match_dup 1) | |
2506 | (match_dup 2)))] | |
2507 | "") | |
2508 | ||
cb0ca284 MH |
2509 | (define_insn "*andqi3_test" |
2510 | [(set (reg:CC 21) | |
65c78c7d MH |
2511 | (compare:CC (and:QI (match_operand:QI 1 "src_operand" "%0,r,rR,rS<>") |
2512 | (match_operand:QI 2 "tsrc_operand" "N,rLm,JR,rS<>")) | |
cb0ca284 | 2513 | (const_int 0))) |
65c78c7d | 2514 | (clobber (match_scratch:QI 0 "=d,X,X,?X"))] |
cb0ca284 MH |
2515 | "valid_operands (AND, operands, QImode)" |
2516 | "@ | |
cb0ca284 | 2517 | andn\\t%N2,%0 |
65c78c7d MH |
2518 | tstb\\t%2,%1 |
2519 | tstb3\\t%2,%1 | |
2520 | tstb3\\t%2,%1" | |
cb0ca284 | 2521 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc") |
65c78c7d | 2522 | (set_attr "data" "not_uint16,uint16,int16,uint16")]) |
cb0ca284 MH |
2523 | |
2524 | (define_peephole | |
65c78c7d MH |
2525 | [(parallel [(set (match_operand:QI 0 "ext_reg_operand" "=d,d,d,?d") |
2526 | (and:QI (match_operand:QI 1 "src_operand" "%0,0,rR,rS<>") | |
2527 | (match_operand:QI 2 "tsrc_operand" "N,rLm,JR,rS<>"))) | |
cb0ca284 MH |
2528 | (clobber (reg:CC 21))]) |
2529 | (set (reg:CC 21) | |
2530 | (compare:CC (match_dup 0) (const_int 0)))] | |
2531 | "valid_operands (AND, operands, QImode)" | |
2532 | "@ | |
cb0ca284 | 2533 | andn\\t%N2,%0 |
65c78c7d MH |
2534 | and\\t%2,%0 |
2535 | and3\\t%2,%1,%0 | |
2536 | and3\\t%2,%1,%0" | |
cb0ca284 | 2537 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc") |
65c78c7d | 2538 | (set_attr "data" "not_uint16,uint16,int16,uint16")]) |
cb0ca284 MH |
2539 | |
2540 | (define_insn "*andqi3_set" | |
2541 | [(set (reg:CC 21) | |
65c78c7d MH |
2542 | (compare:CC (and:QI (match_operand:QI 1 "src_operand" "%0,0,rR,rS<>") |
2543 | (match_operand:QI 2 "tsrc_operand" "N,rLm,JR,rS<>")) | |
cb0ca284 | 2544 | (const_int 0))) |
65c78c7d | 2545 | (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d,?d") |
cb0ca284 MH |
2546 | (and:QI (match_dup 1) |
2547 | (match_dup 2)))] | |
2548 | "valid_operands (AND, operands, QImode)" | |
2549 | "@ | |
cb0ca284 | 2550 | andn\\t%N2,%0 |
65c78c7d MH |
2551 | and\\t%2,%0 |
2552 | and3\\t%2,%1,%0 | |
2553 | and3\\t%2,%1,%0" | |
cb0ca284 | 2554 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc") |
65c78c7d | 2555 | (set_attr "data" "not_uint16,uint16,int16,uint16")]) |
cb0ca284 MH |
2556 | |
2557 | ; | |
2558 | ; ANDN | |
2559 | ; | |
2560 | ; NB, this insn doesn't have commutative operands, but valid_operands | |
2561 | ; assumes that the code AND does. We might have to kludge this if | |
2562 | ; we make valid_operands stricter. | |
2563 | (define_insn "*andnqi3_clobber" | |
65c78c7d MH |
2564 | [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c") |
2565 | (and:QI (not:QI (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>,rLm,JR,rS<>")) | |
2566 | (match_operand:QI 1 "src_operand" "0,rR,rS<>,0,rR,rS<>"))) | |
cb0ca284 MH |
2567 | (clobber (reg:CC 21))] |
2568 | "valid_operands (AND, operands, QImode)" | |
2569 | "@ | |
65c78c7d | 2570 | andn\\t%2,%0 |
cb0ca284 MH |
2571 | andn3\\t%2,%1,%0 |
2572 | andn3\\t%2,%1,%0 | |
2573 | andn\\t%2,%0 | |
2574 | andn3\\t%2,%1,%0 | |
65c78c7d | 2575 | andn3\\t%2,%1,%0" |
cb0ca284 | 2576 | [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary") |
65c78c7d | 2577 | (set_attr "data" "uint16,int16,uint16,uint16,int16,uint16")]) |
cb0ca284 | 2578 | |
57e5bce8 MH |
2579 | (define_insn "*andnqi3_noclobber" |
2580 | [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c") | |
2581 | (and:QI (not:QI (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>")) | |
2582 | (match_operand:QI 1 "src_operand" "0,rR,rS<>")))] | |
2583 | "valid_operands (AND, operands, QImode)" | |
2584 | "@ | |
2585 | andn\\t%2,%0 | |
2586 | andn3\\t%2,%1,%0 | |
2587 | andn3\\t%2,%1,%0" | |
2588 | [(set_attr "type" "binary,binary,binary") | |
2589 | (set_attr "data" "uint16,int16,uint16")]) | |
2590 | ||
2591 | (define_split | |
2592 | [(set (match_operand:QI 0 "std_reg_operand" "") | |
2593 | (and:QI (not:QI (match_operand:QI 2 "lsrc_operand" "")) | |
2594 | (match_operand:QI 1 "src_operand" ""))) | |
2595 | (clobber (reg:CC 21))] | |
2596 | "reload_completed" | |
2597 | [(set (match_dup 0) | |
2598 | (and:QI (not:QI (match_dup 2)) | |
2599 | (match_dup 1)))] | |
2600 | "") | |
2601 | ||
cb0ca284 MH |
2602 | (define_insn "*andnqi3_test" |
2603 | [(set (reg:CC 21) | |
65c78c7d MH |
2604 | (compare:CC (and:QI (not:QI (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>")) |
2605 | (match_operand:QI 1 "src_operand" "0,rR,rS<>")) | |
cb0ca284 | 2606 | (const_int 0))) |
65c78c7d | 2607 | (clobber (match_scratch:QI 0 "=d,d,d"))] |
cb0ca284 MH |
2608 | "valid_operands (AND, operands, QImode)" |
2609 | "@ | |
65c78c7d | 2610 | andn\\t%2,%0 |
cb0ca284 | 2611 | andn3\\t%2,%1,%0 |
65c78c7d | 2612 | andn3\\t%2,%1,%0" |
cb0ca284 | 2613 | [(set_attr "type" "binarycc,binarycc,binarycc") |
65c78c7d | 2614 | (set_attr "data" "uint16,int16,uint16")]) |
cb0ca284 MH |
2615 | |
2616 | (define_insn "*andnqi3_set" | |
2617 | [(set (reg:CC 21) | |
65c78c7d MH |
2618 | (compare:CC (and:QI (not:QI (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>")) |
2619 | (match_operand:QI 1 "src_operand" "0,rR,rS<>")) | |
cb0ca284 | 2620 | (const_int 0))) |
65c78c7d | 2621 | (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d") |
cb0ca284 MH |
2622 | (and:QI (not:QI (match_dup 2)) |
2623 | (match_dup 1)))] | |
2624 | "valid_operands (AND, operands, QImode)" | |
2625 | "@ | |
65c78c7d | 2626 | andn\\t%2,%0 |
cb0ca284 | 2627 | andn3\\t%2,%1,%0 |
65c78c7d | 2628 | andn3\\t%2,%1,%0" |
cb0ca284 | 2629 | [(set_attr "type" "binarycc,binarycc,binarycc") |
65c78c7d | 2630 | (set_attr "data" "uint16,int16,uint16")]) |
cb0ca284 MH |
2631 | |
2632 | ; | |
2633 | ; OR | |
2634 | ; | |
2635 | (define_expand "iorqi3" | |
2636 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
2637 | (ior:QI (match_operand:QI 1 "src_operand" "") | |
2638 | (match_operand:QI 2 "lsrc_operand" ""))) | |
2639 | (clobber (reg:CC 21))])] | |
2640 | "" | |
2641 | "legitimize_operands (IOR, operands, QImode);") | |
2642 | ||
2643 | (define_insn "*iorqi3_clobber" | |
65c78c7d MH |
2644 | [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c") |
2645 | (ior:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>") | |
2646 | (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>,rLm,JR,rS<>"))) | |
cb0ca284 MH |
2647 | (clobber (reg:CC 21))] |
2648 | "valid_operands (IOR, operands, QImode)" | |
2649 | "@ | |
65c78c7d | 2650 | or\\t%2,%0 |
cb0ca284 MH |
2651 | or3\\t%2,%1,%0 |
2652 | or3\\t%2,%1,%0 | |
2653 | or\\t%2,%0 | |
2654 | or3\\t%2,%1,%0 | |
65c78c7d | 2655 | or3\\t%2,%1,%0" |
cb0ca284 | 2656 | [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary") |
65c78c7d | 2657 | (set_attr "data" "uint16,int16,uint16,uint16,int16,uint16")]) |
cb0ca284 | 2658 | |
57e5bce8 MH |
2659 | (define_split |
2660 | [(set (match_operand:QI 0 "std_reg_operand" "") | |
2661 | (ior:QI (match_operand:QI 1 "src_operand" "") | |
2662 | (match_operand:QI 2 "lsrc_operand" ""))) | |
2663 | (clobber (reg:CC 21))] | |
2664 | "reload_completed" | |
2665 | [(set (match_dup 0) | |
2666 | (ior:QI (match_dup 1) | |
2667 | (match_dup 2)))] | |
2668 | "") | |
2669 | ||
cb0ca284 MH |
2670 | (define_insn "*iorqi3_test" |
2671 | [(set (reg:CC 21) | |
65c78c7d MH |
2672 | (compare:CC (ior:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") |
2673 | (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>")) | |
cb0ca284 | 2674 | (const_int 0))) |
65c78c7d | 2675 | (clobber (match_scratch:QI 0 "=d,d,d"))] |
cb0ca284 MH |
2676 | "valid_operands (IOR, operands, QImode)" |
2677 | "@ | |
65c78c7d | 2678 | or\\t%2,%0 |
cb0ca284 | 2679 | or3\\t%2,%1,%0 |
65c78c7d | 2680 | or3\\t%2,%1,%0" |
cb0ca284 | 2681 | [(set_attr "type" "binarycc,binarycc,binarycc") |
65c78c7d | 2682 | (set_attr "data" "uint16,int16,uint16")]) |
cb0ca284 MH |
2683 | |
2684 | (define_peephole | |
65c78c7d MH |
2685 | [(parallel [(set (match_operand:QI 0 "ext_reg_operand" "=d,d,d") |
2686 | (ior:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") | |
2687 | (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>"))) | |
cb0ca284 MH |
2688 | (clobber (reg:CC 21))]) |
2689 | (set (reg:CC 21) | |
2690 | (compare:CC (match_dup 0) (const_int 0)))] | |
2691 | "valid_operands (IOR, operands, QImode)" | |
2692 | "@ | |
65c78c7d | 2693 | or\\t%2,%0 |
cb0ca284 | 2694 | or3\\t%2,%1,%0 |
65c78c7d | 2695 | or3\\t%2,%1,%0" |
cb0ca284 | 2696 | [(set_attr "type" "binarycc,binarycc,binarycc") |
65c78c7d | 2697 | (set_attr "data" "uint16,int16,uint16")]) |
cb0ca284 MH |
2698 | |
2699 | (define_insn "*iorqi3_set" | |
2700 | [(set (reg:CC 21) | |
65c78c7d MH |
2701 | (compare:CC (ior:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") |
2702 | (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>")) | |
cb0ca284 | 2703 | (const_int 0))) |
65c78c7d | 2704 | (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d") |
cb0ca284 MH |
2705 | (ior:QI (match_dup 1) |
2706 | (match_dup 2)))] | |
2707 | "valid_operands (IOR, operands, QImode)" | |
2708 | "@ | |
65c78c7d | 2709 | or\\t%2,%0 |
cb0ca284 | 2710 | or3\\t%2,%1,%0 |
65c78c7d | 2711 | or3\\t%2,%1,%0" |
cb0ca284 | 2712 | [(set_attr "type" "binarycc,binarycc,binarycc") |
65c78c7d | 2713 | (set_attr "data" "uint16,int16,uint16")]) |
cb0ca284 MH |
2714 | |
2715 | ; This pattern is used for loading symbol references in several parts. | |
2716 | (define_insn "iorqi3_noclobber" | |
65c78c7d MH |
2717 | [(set (match_operand:QI 0 "std_reg_operand" "=c,c,c") |
2718 | (ior:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") | |
2719 | (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>")))] | |
cb0ca284 MH |
2720 | "valid_operands (IOR, operands, QImode)" |
2721 | "@ | |
65c78c7d | 2722 | or\\t%2,%0 |
cb0ca284 | 2723 | or3\\t%2,%1,%0 |
65c78c7d | 2724 | or3\\t%2,%1,%0" |
cb0ca284 | 2725 | [(set_attr "type" "binary,binary,binary") |
65c78c7d | 2726 | (set_attr "data" "uint16,int16,uint16")]) |
cb0ca284 MH |
2727 | |
2728 | ; | |
2729 | ; XOR | |
2730 | ; | |
2731 | (define_expand "xorqi3" | |
2732 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
2733 | (xor:QI (match_operand:QI 1 "src_operand" "") | |
2734 | (match_operand:QI 2 "lsrc_operand" ""))) | |
2735 | (clobber (reg:CC 21))])] | |
2736 | "" | |
2737 | "legitimize_operands (XOR, operands, QImode);") | |
2738 | ||
2739 | (define_insn "*xorqi3_clobber" | |
65c78c7d MH |
2740 | [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c") |
2741 | (xor:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>") | |
2742 | (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>,rLm,JR,rS<>"))) | |
cb0ca284 MH |
2743 | (clobber (reg:CC 21))] |
2744 | "valid_operands (XOR, operands, QImode)" | |
2745 | "@ | |
65c78c7d | 2746 | xor\\t%2,%0 |
cb0ca284 MH |
2747 | xor3\\t%2,%1,%0 |
2748 | xor3\\t%2,%1,%0 | |
2749 | xor\\t%2,%0 | |
2750 | xor3\\t%2,%1,%0 | |
65c78c7d | 2751 | xor3\\t%2,%1,%0" |
cb0ca284 | 2752 | [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary") |
65c78c7d | 2753 | (set_attr "data" "uint16,int16,uint16,uint16,int16,uint16")]) |
cb0ca284 | 2754 | |
57e5bce8 MH |
2755 | (define_insn "*xorqi3_noclobber" |
2756 | [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c") | |
2757 | (xor:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") | |
2758 | (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>")))] | |
2759 | "valid_operands (XOR, operands, QImode)" | |
2760 | "@ | |
2761 | xor\\t%2,%0 | |
2762 | xor3\\t%2,%1,%0 | |
2763 | xor3\\t%2,%1,%0" | |
2764 | [(set_attr "type" "binary,binary,binary") | |
2765 | (set_attr "data" "uint16,int16,uint16")]) | |
2766 | ||
2767 | (define_split | |
2768 | [(set (match_operand:QI 0 "std_reg_operand" "") | |
2769 | (xor:QI (match_operand:QI 1 "src_operand" "") | |
2770 | (match_operand:QI 2 "lsrc_operand" ""))) | |
2771 | (clobber (reg:CC 21))] | |
2772 | "reload_completed" | |
2773 | [(set (match_dup 0) | |
2774 | (xor:QI (match_dup 1) | |
2775 | (match_dup 2)))] | |
2776 | "") | |
2777 | ||
cb0ca284 MH |
2778 | (define_insn "*xorqi3_test" |
2779 | [(set (reg:CC 21) | |
65c78c7d MH |
2780 | (compare:CC (xor:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") |
2781 | (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>")) | |
cb0ca284 | 2782 | (const_int 0))) |
65c78c7d | 2783 | (clobber (match_scratch:QI 0 "=d,d,d"))] |
cb0ca284 MH |
2784 | "valid_operands (XOR, operands, QImode)" |
2785 | "@ | |
65c78c7d | 2786 | xor\\t%2,%0 |
cb0ca284 | 2787 | xor3\\t%2,%1,%0 |
65c78c7d | 2788 | xor3\\t%2,%1,%0" |
cb0ca284 | 2789 | [(set_attr "type" "binarycc,binarycc,binarycc") |
65c78c7d | 2790 | (set_attr "data" "uint16,int16,uint16")]) |
cb0ca284 MH |
2791 | |
2792 | (define_insn "*xorqi3_set" | |
2793 | [(set (reg:CC 21) | |
65c78c7d MH |
2794 | (compare:CC (xor:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>") |
2795 | (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>")) | |
cb0ca284 | 2796 | (const_int 0))) |
65c78c7d | 2797 | (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d") |
cb0ca284 MH |
2798 | (xor:QI (match_dup 1) |
2799 | (match_dup 2)))] | |
2800 | "valid_operands (XOR, operands, QImode)" | |
2801 | "@ | |
65c78c7d | 2802 | xor\\t%2,%0 |
cb0ca284 | 2803 | xor3\\t%2,%1,%0 |
65c78c7d | 2804 | xor3\\t%2,%1,%0" |
cb0ca284 | 2805 | [(set_attr "type" "binarycc,binarycc,binarycc") |
65c78c7d | 2806 | (set_attr "data" "uint16,int16,uint16")]) |
cb0ca284 MH |
2807 | |
2808 | ; | |
2809 | ; LSH/ASH (left) | |
2810 | ; | |
2811 | ; The C3x and C4x have two shift instructions ASH and LSH | |
2812 | ; If the shift count is positive, a left shift is performed | |
2813 | ; otherwise a right shift is performed. The number of bits | |
2814 | ; shifted is determined by the seven LSBs of the shift count. | |
2815 | ; If the absolute value of the count is 32 or greater, the result | |
2816 | ; using the LSH instruction is zero; with the ASH insn the result | |
2817 | ; is zero or negative 1. Note that the ISO C standard allows | |
2818 | ; the result to be machine dependent whenever the shift count | |
2819 | ; exceeds the size of the object. | |
2820 | (define_expand "ashlqi3" | |
2821 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
2822 | (ashift:QI (match_operand:QI 1 "src_operand" "") | |
2823 | (match_operand:QI 2 "src_operand" ""))) | |
2824 | (clobber (reg:CC 21))])] | |
2825 | "" | |
2826 | "legitimize_operands (ASHIFT, operands, QImode);") | |
2827 | ||
2828 | (define_insn "*ashlqi3_clobber" | |
65c78c7d MH |
2829 | [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c") |
2830 | (ashift:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>,0,rR,rS<>") | |
2831 | (match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>"))) | |
cb0ca284 MH |
2832 | (clobber (reg:CC 21))] |
2833 | "valid_operands (ASHIFT, operands, QImode)" | |
2834 | "@ | |
65c78c7d | 2835 | ash\\t%2,%0 |
cb0ca284 MH |
2836 | ash3\\t%2,%1,%0 |
2837 | ash3\\t%2,%1,%0 | |
2838 | ash\\t%2,%0 | |
2839 | ash3\\t%2,%1,%0 | |
65c78c7d | 2840 | ash3\\t%2,%1,%0" |
cb0ca284 MH |
2841 | [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")]) |
2842 | ; Default to int16 data attr. | |
2843 | ||
2844 | (define_insn "*ashlqi3_set" | |
2845 | [(set (reg:CC 21) | |
2846 | (compare:CC | |
65c78c7d MH |
2847 | (ashift:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>") |
2848 | (match_operand:QI 2 "src_operand" "rIm,JR,rS<>")) | |
cb0ca284 | 2849 | (const_int 0))) |
65c78c7d | 2850 | (set (match_operand:QI 0 "reg_operand" "=d,d,d") |
cb0ca284 MH |
2851 | (ashift:QI (match_dup 1) |
2852 | (match_dup 2)))] | |
2853 | "valid_operands (ASHIFT, operands, QImode)" | |
2854 | "@ | |
65c78c7d | 2855 | ash\\t%2,%0 |
cb0ca284 | 2856 | ash3\\t%2,%1,%0 |
65c78c7d | 2857 | ash3\\t%2,%1,%0" |
95cb0203 | 2858 | [(set_attr "type" "binarycc,binarycc,binarycc")]) |
cb0ca284 MH |
2859 | ; Default to int16 data attr. |
2860 | ||
483dd5be MH |
2861 | (define_insn "ashlqi3_noclobber" |
2862 | [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c") | |
2863 | (ashift:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>") | |
2864 | (match_operand:QI 2 "src_operand" "rIm,JR,rS<>")))] | |
2865 | "valid_operands (ASHIFT, operands, QImode)" | |
2866 | "@ | |
2867 | ash\\t%2,%0 | |
2868 | ash3\\t%2,%1,%0 | |
2869 | ash3\\t%2,%1,%0" | |
2870 | [(set_attr "type" "binary,binary,binary")]) | |
2871 | ; Default to int16 data attr. | |
2872 | ||
57e5bce8 MH |
2873 | (define_split |
2874 | [(set (match_operand:QI 0 "std_reg_operand" "") | |
2875 | (ashift:QI (match_operand:QI 1 "src_operand" "") | |
2876 | (match_operand:QI 2 "src_operand" ""))) | |
2877 | (clobber (reg:CC 21))] | |
2878 | "reload_completed" | |
2879 | [(set (match_dup 0) | |
2880 | (ashift:QI (match_dup 1) | |
2881 | (match_dup 2)))] | |
2882 | "") | |
483dd5be | 2883 | |
cb0ca284 MH |
2884 | ; This is only used by lshrhi3_reg where we need a LSH insn that will |
2885 | ; shift both ways. | |
2886 | (define_insn "*lshlqi3_clobber" | |
65c78c7d MH |
2887 | [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c") |
2888 | (ashift:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>,0,rR,rS<>") | |
f959ff1a | 2889 | (unspec:QI [(match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>")] 3))) |
cb0ca284 MH |
2890 | (clobber (reg:CC 21))] |
2891 | "valid_operands (ASHIFT, operands, QImode)" | |
2892 | "@ | |
65c78c7d | 2893 | lsh\\t%2,%0 |
cb0ca284 MH |
2894 | lsh3\\t%2,%1,%0 |
2895 | lsh3\\t%2,%1,%0 | |
2896 | lsh\\t%2,%0 | |
2897 | lsh3\\t%2,%1,%0 | |
65c78c7d | 2898 | lsh3\\t%2,%1,%0" |
cb0ca284 MH |
2899 | [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")]) |
2900 | ; Default to int16 data attr. | |
2901 | ||
2902 | ; | |
2903 | ; LSH (right) | |
2904 | ; | |
2905 | ; Logical right shift on the C[34]x works by negating the shift count, | |
2906 | ; then emitting a right shift with the shift count negated. This means | |
2907 | ; that all actual shift counts in the RTL will be positive. | |
2908 | ; | |
2909 | (define_expand "lshrqi3" | |
2910 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
2911 | (lshiftrt:QI (match_operand:QI 1 "src_operand" "") | |
2912 | (match_operand:QI 2 "src_operand" ""))) | |
2913 | (clobber (reg:CC 21))])] | |
2914 | "" | |
2915 | "legitimize_operands (LSHIFTRT, operands, QImode);") | |
2916 | ||
d98d16b1 MH |
2917 | |
2918 | (define_insn "*lshrqi3_24_clobber" | |
2919 | [(set (match_operand:QI 0 "reg_operand" "=d,c") | |
2920 | (lshiftrt:QI (match_operand:QI 1 "src_operand" "mr,mr") | |
2921 | (const_int 24))) | |
2922 | (clobber (reg:CC 21))] | |
2923 | "! TARGET_C3X" | |
2924 | "lbu3\\t%1,%0" | |
2925 | [(set_attr "type" "unarycc")]) | |
2926 | ||
2927 | ||
2928 | (define_insn "*ashrqi3_24_clobber" | |
2929 | [(set (match_operand:QI 0 "reg_operand" "=d,c") | |
2930 | (ashiftrt:QI (match_operand:QI 1 "src_operand" "mr,mr") | |
2931 | (const_int 24))) | |
2932 | (clobber (reg:CC 21))] | |
2933 | "! TARGET_C3X" | |
2934 | "lb3\\t%1,%0" | |
2935 | [(set_attr "type" "unarycc")]) | |
2936 | ||
2937 | ||
2938 | (define_insn "lshrqi3_16_clobber" | |
2939 | [(set (match_operand:QI 0 "reg_operand" "=d,c") | |
2940 | (lshiftrt:QI (match_operand:QI 1 "src_operand" "mr,mr") | |
2941 | (const_int 16))) | |
2942 | (clobber (reg:CC 21))] | |
2943 | "! TARGET_C3X" | |
2944 | "lhu1\\t%1,%0" | |
2945 | [(set_attr "type" "unarycc")]) | |
2946 | ||
2947 | ||
2948 | (define_insn "*ashrqi3_16_clobber" | |
2949 | [(set (match_operand:QI 0 "reg_operand" "=d,c") | |
2950 | (ashiftrt:QI (match_operand:QI 1 "src_operand" "mr,mr") | |
2951 | (const_int 16))) | |
2952 | (clobber (reg:CC 21))] | |
2953 | "! TARGET_C3X" | |
2954 | "lh1\\t%1,%0" | |
2955 | [(set_attr "type" "unarycc")]) | |
2956 | ||
2957 | ||
cb0ca284 MH |
2958 | ; When the shift count is greater than the size of the word |
2959 | ; the result can be implementation specific | |
2960 | (define_insn "*lshrqi3_const_clobber" | |
2961 | [(set (match_operand:QI 0 "reg_operand" "=d,c,?d,?c") | |
2962 | (lshiftrt:QI (match_operand:QI 1 "src_operand" "0,0,r,r") | |
2963 | (match_operand:QI 2 "const_int_operand" "n,n,J,J"))) | |
2964 | (clobber (reg:CC 21))] | |
2965 | "valid_operands (LSHIFTRT, operands, QImode)" | |
2966 | "@ | |
2967 | lsh\\t%n2,%0 | |
2968 | lsh\\t%n2,%0 | |
2969 | lsh3\\t%n2,%1,%0 | |
2970 | lsh3\\t%n2,%1,%0" | |
f42850b9 MH |
2971 | [(set_attr "type" "binarycc,binary,binarycc,binary")]) |
2972 | ||
2973 | (define_insn "*lshrqi3_const_noclobber" | |
2974 | [(set (match_operand:QI 0 "std_reg_operand" "=c,?c") | |
2975 | (lshiftrt:QI (match_operand:QI 1 "src_operand" "0,r") | |
2976 | (match_operand:QI 2 "const_int_operand" "n,J")))] | |
2977 | "valid_operands (LSHIFTRT, operands, QImode)" | |
2978 | "@ | |
2979 | lsh\\t%n2,%0 | |
2980 | lsh3\\t%n2,%1,%0" | |
2981 | [(set_attr "type" "binary,binary")]) | |
cb0ca284 MH |
2982 | |
2983 | ; When the shift count is greater than the size of the word | |
2984 | ; the result can be implementation specific | |
2985 | (define_insn "*lshrqi3_const_set" | |
2986 | [(set (reg:CC 21) | |
2987 | (compare:CC | |
dfb31eec MH |
2988 | (lshiftrt:QI (match_operand:QI 1 "src_operand" "0,r") |
2989 | (match_operand:QI 2 "const_int_operand" "n,J")) | |
cb0ca284 | 2990 | (const_int 0))) |
dfb31eec | 2991 | (set (match_operand:QI 0 "reg_operand" "=?d,d") |
cb0ca284 MH |
2992 | (lshiftrt:QI (match_dup 1) |
2993 | (match_dup 2)))] | |
2994 | "valid_operands (LSHIFTRT, operands, QImode)" | |
2995 | "@ | |
2996 | lsh\\t%n2,%0 | |
cb0ca284 | 2997 | lsh3\\t%n2,%1,%0" |
dfb31eec | 2998 | [(set_attr "type" "binarycc,binarycc")]) |
cb0ca284 MH |
2999 | |
3000 | (define_insn "*lshrqi3_nonconst_clobber" | |
65c78c7d MH |
3001 | [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c") |
3002 | (lshiftrt:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>,0,rR,rS<>") | |
3003 | (neg:QI (match_operand:QI 2 "src_operand" "rm,R,rS<>,rm,R,rS<>")))) | |
cb0ca284 MH |
3004 | (clobber (reg:CC 21))] |
3005 | "valid_operands (LSHIFTRT, operands, QImode)" | |
3006 | "@ | |
65c78c7d | 3007 | lsh\\t%2,%0 |
cb0ca284 MH |
3008 | lsh3\\t%2,%1,%0 |
3009 | lsh3\\t%2,%1,%0 | |
3010 | lsh\\t%2,%0 | |
3011 | lsh3\\t%2,%1,%0 | |
65c78c7d | 3012 | lsh3\\t%2,%1,%0" |
cb0ca284 MH |
3013 | [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")]) |
3014 | ; Default to int16 data attr. | |
3015 | ||
f42850b9 MH |
3016 | (define_insn "*lshrqi3_nonconst_noclobber" |
3017 | [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c") | |
3018 | (lshiftrt:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>") | |
3019 | (neg:QI (match_operand:QI 2 "src_operand" "rm,R,rS<>"))))] | |
3020 | "valid_operands (LSHIFTRT, operands, QImode)" | |
3021 | "@ | |
3022 | lsh\\t%2,%0 | |
3023 | lsh3\\t%2,%1,%0 | |
3024 | lsh3\\t%2,%1,%0" | |
3025 | [(set_attr "type" "binary,binary,binary")]) | |
3026 | ; Default to int16 data attr. | |
3027 | ||
cb0ca284 MH |
3028 | ; |
3029 | ; ASH (right) | |
3030 | ; | |
3031 | ; Arithmetic right shift on the C[34]x works by negating the shift count, | |
3032 | ; then emitting a right shift with the shift count negated. This means | |
3033 | ; that all actual shift counts in the RTL will be positive. | |
3034 | ||
3035 | (define_expand "ashrqi3" | |
3036 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
3037 | (ashiftrt:QI (match_operand:QI 1 "src_operand" "") | |
3038 | (match_operand:QI 2 "src_operand" ""))) | |
3039 | (clobber (reg:CC 21))])] | |
3040 | "" | |
3041 | "legitimize_operands (ASHIFTRT, operands, QImode);") | |
3042 | ||
3043 | ; When the shift count is greater than the size of the word | |
3044 | ; the result can be implementation specific | |
3045 | (define_insn "*ashrqi3_const_clobber" | |
3046 | [(set (match_operand:QI 0 "reg_operand" "=d,c,?d,?c") | |
3047 | (ashiftrt:QI (match_operand:QI 1 "src_operand" "0,0,r,r") | |
3048 | (match_operand:QI 2 "const_int_operand" "n,n,J,J"))) | |
3049 | (clobber (reg:CC 21))] | |
3050 | "valid_operands (ASHIFTRT, operands, QImode)" | |
3051 | "@ | |
3052 | ash\\t%n2,%0 | |
3053 | ash\\t%n2,%0 | |
3054 | ash3\\t%n2,%1,%0 | |
3055 | ash3\\t%n2,%1,%0" | |
f42850b9 MH |
3056 | [(set_attr "type" "binarycc,binary,binarycc,binary")]) |
3057 | ||
3058 | (define_insn "*ashrqi3_const_noclobber" | |
3059 | [(set (match_operand:QI 0 "std_reg_operand" "=c,?c") | |
3060 | (ashiftrt:QI (match_operand:QI 1 "src_operand" "0,r") | |
3061 | (match_operand:QI 2 "const_int_operand" "n,J")))] | |
3062 | "valid_operands (ASHIFTRT, operands, QImode)" | |
3063 | "@ | |
3064 | ash\\t%n2,%0 | |
3065 | ash3\\t%n2,%1,%0" | |
3066 | [(set_attr "type" "binarycc,binarycc")]) | |
cb0ca284 MH |
3067 | |
3068 | ; When the shift count is greater than the size of the word | |
3069 | ; the result can be implementation specific | |
3070 | (define_insn "*ashrqi3_const_set" | |
3071 | [(set (reg:CC 21) | |
3072 | (compare:CC | |
95cb0203 MH |
3073 | (ashiftrt:QI (match_operand:QI 1 "src_operand" "0,r") |
3074 | (match_operand:QI 2 "const_int_operand" "n,J")) | |
cb0ca284 | 3075 | (const_int 0))) |
95cb0203 | 3076 | (set (match_operand:QI 0 "reg_operand" "=?d,d") |
cb0ca284 MH |
3077 | (ashiftrt:QI (match_dup 1) |
3078 | (match_dup 2)))] | |
3079 | "valid_operands (ASHIFTRT, operands, QImode)" | |
3080 | "@ | |
3081 | ash\\t%n2,%0 | |
cb0ca284 | 3082 | ash3\\t%n2,%1,%0" |
95cb0203 | 3083 | [(set_attr "type" "binarycc,binarycc")]) |
cb0ca284 MH |
3084 | |
3085 | (define_insn "*ashrqi3_nonconst_clobber" | |
65c78c7d MH |
3086 | [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c") |
3087 | (ashiftrt:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>,0,rR,rS<>") | |
3088 | (neg:QI (match_operand:QI 2 "src_operand" "rm,R,rS<>,rm,R,rS<>")))) | |
cb0ca284 MH |
3089 | (clobber (reg:CC 21))] |
3090 | "valid_operands (ASHIFTRT, operands, QImode)" | |
3091 | "@ | |
65c78c7d | 3092 | ash\\t%2,%0 |
cb0ca284 MH |
3093 | ash3\\t%2,%1,%0 |
3094 | ash3\\t%2,%1,%0 | |
3095 | ash\\t%2,%0 | |
3096 | ash3\\t%2,%1,%0 | |
65c78c7d | 3097 | ash3\\t%2,%1,%0" |
cb0ca284 MH |
3098 | [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")]) |
3099 | ; Default to int16 data attr. | |
3100 | ||
f42850b9 MH |
3101 | (define_insn "*ashrqi3_nonconst_noclobber" |
3102 | [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c") | |
3103 | (ashiftrt:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>") | |
3104 | (neg:QI (match_operand:QI 2 "src_operand" "rm,R,rS<>"))))] | |
3105 | "valid_operands (ASHIFTRT, operands, QImode)" | |
3106 | "@ | |
3107 | ash\\t%2,%0 | |
3108 | ash3\\t%2,%1,%0 | |
3109 | ash3\\t%2,%1,%0" | |
3110 | [(set_attr "type" "binary,binary,binary")]) | |
3111 | ; Default to int16 data attr. | |
3112 | ||
cb0ca284 MH |
3113 | ; |
3114 | ; CMPI | |
3115 | ; | |
3116 | ; Unfortunately the C40 doesn't allow cmpi3 7, *ar0++ so the next best | |
3117 | ; thing would be to get the small constant loaded into a register (say r0) | |
3118 | ; so that it could be hoisted out of the loop so that we only | |
3119 | ; would need to do cmpi3 *ar0++, r0. Now the loop optimisation pass | |
3120 | ; comes before the flow pass (which finds autoincrements) so we're stuck. | |
3121 | ; Ideally, GCC requires another loop optimisation pass (preferably after | |
3122 | ; reload) so that it can hoist invariants out of loops. | |
3123 | ; The current solution modifies legitimize_operands () so that small | |
3124 | ; constants are forced into a pseudo register. | |
3125 | ; | |
3126 | (define_expand "cmpqi" | |
3127 | [(set (reg:CC 21) | |
3128 | (compare:CC (match_operand:QI 0 "src_operand" "") | |
3129 | (match_operand:QI 1 "src_operand" "")))] | |
3130 | "" | |
3131 | "legitimize_operands (COMPARE, operands, QImode); | |
3132 | c4x_compare_op0 = operands[0]; | |
3133 | c4x_compare_op1 = operands[1]; | |
3134 | DONE;") | |
3135 | ||
3136 | (define_insn "*cmpqi_test" | |
3137 | [(set (reg:CC 21) | |
ccd63d90 MH |
3138 | (compare:CC (match_operand:QI 0 "src_operand" "r,rR,rS<>") |
3139 | (match_operand:QI 1 "src_operand" "rIm,JR,rS<>")))] | |
cb0ca284 MH |
3140 | "valid_operands (COMPARE, operands, QImode)" |
3141 | "@ | |
ccd63d90 | 3142 | cmpi\\t%1,%0 |
cb0ca284 | 3143 | cmpi3\\t%1,%0 |
ccd63d90 | 3144 | cmpi3\\t%1,%0" |
cb0ca284 MH |
3145 | [(set_attr "type" "compare,compare,compare")]) |
3146 | ||
3147 | (define_insn "*cmpqi_test_noov" | |
3148 | [(set (reg:CC_NOOV 21) | |
ccd63d90 MH |
3149 | (compare:CC_NOOV (match_operand:QI 0 "src_operand" "r,rR,rS<>") |
3150 | (match_operand:QI 1 "src_operand" "rIm,JR,rS<>")))] | |
cb0ca284 MH |
3151 | "valid_operands (COMPARE, operands, QImode)" |
3152 | "@ | |
ccd63d90 | 3153 | cmpi\\t%1,%0 |
cb0ca284 | 3154 | cmpi3\\t%1,%0 |
ccd63d90 | 3155 | cmpi3\\t%1,%0" |
cb0ca284 MH |
3156 | [(set_attr "type" "compare,compare,compare")]) |
3157 | ||
cb0ca284 MH |
3158 | |
3159 | ; | |
3160 | ; BIT-FIELD INSTRUCTIONS | |
3161 | ; | |
3162 | ||
3163 | ; | |
3164 | ; LBx/LHw (C4x only) | |
3165 | ; | |
3166 | (define_expand "extv" | |
3167 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
3168 | (sign_extract:QI (match_operand:QI 1 "src_operand" "") | |
3169 | (match_operand:QI 2 "const_int_operand" "") | |
3170 | (match_operand:QI 3 "const_int_operand" ""))) | |
3171 | (clobber (reg:CC 21))])] | |
4ddb3ea6 | 3172 | "! TARGET_C3X" |
cb0ca284 MH |
3173 | "if ((INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16) |
3174 | || (INTVAL (operands[3]) % INTVAL (operands[2]) != 0)) | |
3175 | FAIL; | |
3176 | ") | |
3177 | ||
3178 | (define_insn "*extv_clobber" | |
3179 | [(set (match_operand:QI 0 "reg_operand" "=d,c") | |
50c33087 | 3180 | (sign_extract:QI (match_operand:QI 1 "src_operand" "rLm,rLm") |
cb0ca284 MH |
3181 | (match_operand:QI 2 "const_int_operand" "n,n") |
3182 | (match_operand:QI 3 "const_int_operand" "n,n"))) | |
3183 | (clobber (reg:CC 21))] | |
4ddb3ea6 | 3184 | "! TARGET_C3X |
cb0ca284 MH |
3185 | && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) |
3186 | && (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)" | |
3187 | "* | |
3188 | if (INTVAL (operands[2]) == 8) | |
3189 | { | |
e27f8c8a | 3190 | operands[3] = GEN_INT (INTVAL (operands[3]) / 8); |
cb0ca284 MH |
3191 | return \"lb%3\\t%1,%0\"; |
3192 | } | |
e27f8c8a | 3193 | operands[3] = GEN_INT (INTVAL (operands[3]) / 16); |
cb0ca284 MH |
3194 | return \"lh%3\\t%1,%0\"; |
3195 | " | |
3196 | [(set_attr "type" "binarycc,binary") | |
3197 | (set_attr "data" "int16,int16")]) | |
3198 | ||
3199 | (define_insn "*extv_clobber_test" | |
3200 | [(set (reg:CC 21) | |
50c33087 | 3201 | (compare:CC (sign_extract:QI (match_operand:QI 1 "src_operand" "rLm") |
cb0ca284 MH |
3202 | (match_operand:QI 2 "const_int_operand" "n") |
3203 | (match_operand:QI 3 "const_int_operand" "n")) | |
3204 | (const_int 0))) | |
3205 | (clobber (match_scratch:QI 0 "=d"))] | |
4ddb3ea6 | 3206 | "! TARGET_C3X |
cb0ca284 MH |
3207 | && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) |
3208 | && (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)" | |
3209 | "* | |
3210 | if (INTVAL (operands[2]) == 8) | |
3211 | { | |
e27f8c8a | 3212 | operands[3] = GEN_INT (INTVAL (operands[3]) / 8); |
cb0ca284 MH |
3213 | return \"lb%3\\t%1,%0\"; |
3214 | } | |
e27f8c8a | 3215 | operands[3] = GEN_INT (INTVAL (operands[3]) / 16); |
cb0ca284 MH |
3216 | return \"lh%3\\t%1,%0\"; |
3217 | " | |
3218 | [(set_attr "type" "binarycc") | |
3219 | (set_attr "data" "int16")]) | |
3220 | ||
3221 | (define_insn "*extv_clobber_set" | |
3222 | [(set (reg:CC 21) | |
50c33087 | 3223 | (compare:CC (sign_extract:QI (match_operand:QI 1 "src_operand" "rLm") |
cb0ca284 MH |
3224 | (match_operand:QI 2 "const_int_operand" "n") |
3225 | (match_operand:QI 3 "const_int_operand" "n")) | |
3226 | (const_int 0))) | |
3227 | (set (match_operand:QI 0 "reg_operand" "=d") | |
3228 | (sign_extract:QI (match_dup 1) | |
3229 | (match_dup 2) | |
3230 | (match_dup 3)))] | |
4ddb3ea6 | 3231 | "! TARGET_C3X |
cb0ca284 MH |
3232 | && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) |
3233 | && (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)" | |
3234 | "* | |
3235 | if (INTVAL (operands[2]) == 8) | |
3236 | { | |
e27f8c8a | 3237 | operands[3] = GEN_INT (INTVAL (operands[3]) / 8); |
cb0ca284 MH |
3238 | return \"lb%3\\t%1,%0\"; |
3239 | } | |
e27f8c8a | 3240 | operands[3] = GEN_INT (INTVAL (operands[3]) / 16); |
cb0ca284 MH |
3241 | return \"lh%3\\t%1,%0\"; |
3242 | " | |
3243 | [(set_attr "type" "binarycc") | |
3244 | (set_attr "data" "int16")]) | |
3245 | ||
3246 | ; | |
3247 | ; LBUx/LHUw (C4x only) | |
3248 | ; | |
3249 | (define_expand "extzv" | |
3250 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
3251 | (zero_extract:QI (match_operand:QI 1 "src_operand" "") | |
3252 | (match_operand:QI 2 "const_int_operand" "") | |
3253 | (match_operand:QI 3 "const_int_operand" ""))) | |
3254 | (clobber (reg:CC 21))])] | |
4ddb3ea6 | 3255 | "! TARGET_C3X" |
cb0ca284 MH |
3256 | "if ((INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16) |
3257 | || (INTVAL (operands[3]) % INTVAL (operands[2]) != 0)) | |
3258 | FAIL; | |
3259 | ") | |
3260 | ||
3261 | (define_insn "*extzv_clobber" | |
3262 | [(set (match_operand:QI 0 "reg_operand" "=d,c") | |
50c33087 | 3263 | (zero_extract:QI (match_operand:QI 1 "src_operand" "rLm,rLm") |
cb0ca284 MH |
3264 | (match_operand:QI 2 "const_int_operand" "n,n") |
3265 | (match_operand:QI 3 "const_int_operand" "n,n"))) | |
3266 | (clobber (reg:CC 21))] | |
4ddb3ea6 | 3267 | "! TARGET_C3X |
cb0ca284 MH |
3268 | && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) |
3269 | && (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)" | |
3270 | "* | |
3271 | if (INTVAL (operands[2]) == 8) | |
3272 | { | |
e27f8c8a | 3273 | operands[3] = GEN_INT (INTVAL (operands[3]) / 8); |
cb0ca284 MH |
3274 | return \"lbu%3\\t%1,%0\"; |
3275 | } | |
e27f8c8a | 3276 | operands[3] = GEN_INT (INTVAL (operands[3]) / 16); |
cb0ca284 MH |
3277 | return \"lhu%3\\t%1,%0\"; |
3278 | " | |
3279 | [(set_attr "type" "binarycc,binary") | |
3280 | (set_attr "data" "uint16,uint16")]) | |
3281 | ||
3282 | (define_insn "*extzv_test" | |
3283 | [(set (reg:CC 21) | |
50c33087 | 3284 | (compare:CC (zero_extract:QI (match_operand:QI 1 "src_operand" "rLm") |
cb0ca284 MH |
3285 | (match_operand:QI 2 "const_int_operand" "n") |
3286 | (match_operand:QI 3 "const_int_operand" "n")) | |
3287 | (const_int 0))) | |
3288 | (clobber (match_scratch:QI 0 "=d"))] | |
4ddb3ea6 | 3289 | "! TARGET_C3X |
cb0ca284 MH |
3290 | && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) |
3291 | && (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)" | |
3292 | "* | |
3293 | if (INTVAL (operands[2]) == 8) | |
3294 | { | |
e27f8c8a | 3295 | operands[3] = GEN_INT (INTVAL (operands[3]) / 8); |
cb0ca284 MH |
3296 | return \"lbu%3\\t%1,%0\"; |
3297 | } | |
e27f8c8a | 3298 | operands[3] = GEN_INT (INTVAL (operands[3]) / 16); |
cb0ca284 MH |
3299 | return \"lhu%3\\t%1,%0\"; |
3300 | " | |
3301 | [(set_attr "type" "binarycc") | |
3302 | (set_attr "data" "uint16")]) | |
3303 | ||
3304 | (define_insn "*extzv_set" | |
3305 | [(set (reg:CC 21) | |
50c33087 | 3306 | (compare:CC (zero_extract:QI (match_operand:QI 1 "src_operand" "rLm") |
cb0ca284 MH |
3307 | (match_operand:QI 2 "const_int_operand" "n") |
3308 | (match_operand:QI 3 "const_int_operand" "n")) | |
3309 | (const_int 0))) | |
50c33087 | 3310 | (set (match_operand:QI 0 "ext_reg_operand" "=d") |
cb0ca284 MH |
3311 | (zero_extract:QI (match_dup 1) |
3312 | (match_dup 2) | |
3313 | (match_dup 3)))] | |
4ddb3ea6 | 3314 | "! TARGET_C3X |
cb0ca284 MH |
3315 | && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) |
3316 | && (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)" | |
3317 | "* | |
3318 | if (INTVAL (operands[2]) == 8) | |
3319 | { | |
d98d16b1 | 3320 | /* 8 bit extract. */ |
e27f8c8a | 3321 | operands[3] = GEN_INT (INTVAL (operands[3]) / 8); |
cb0ca284 MH |
3322 | return \"lbu%3\\t%1,%0\"; |
3323 | } | |
d98d16b1 | 3324 | /* 16 bit extract. */ |
e27f8c8a | 3325 | operands[3] = GEN_INT (INTVAL (operands[3]) / 16); |
cb0ca284 MH |
3326 | return \"lhu%3\\t%1,%0\"; |
3327 | " | |
3328 | [(set_attr "type" "binarycc") | |
3329 | (set_attr "data" "uint16")]) | |
3330 | ||
3331 | ; | |
3332 | ; MBx/MHw (C4x only) | |
3333 | ; | |
3334 | (define_expand "insv" | |
3335 | [(parallel [(set (zero_extract:QI (match_operand:QI 0 "reg_operand" "") | |
3336 | (match_operand:QI 1 "const_int_operand" "") | |
3337 | (match_operand:QI 2 "const_int_operand" "")) | |
3338 | (match_operand:QI 3 "src_operand" "")) | |
3339 | (clobber (reg:CC 21))])] | |
4ddb3ea6 MH |
3340 | "! TARGET_C3X" |
3341 | "if (! (((INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) | |
cb0ca284 MH |
3342 | && (INTVAL (operands[2]) % INTVAL (operands[1]) == 0)) |
3343 | || (INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8))) | |
3344 | FAIL; | |
3345 | ") | |
3346 | ||
3347 | (define_insn "*insv_clobber" | |
8a119a7d | 3348 | [(set (zero_extract:QI (match_operand:QI 0 "reg_operand" "+d,c") |
cb0ca284 MH |
3349 | (match_operand:QI 1 "const_int_operand" "n,n") |
3350 | (match_operand:QI 2 "const_int_operand" "n,n")) | |
50c33087 | 3351 | (match_operand:QI 3 "src_operand" "rLm,rLm")) |
cb0ca284 | 3352 | (clobber (reg:CC 21))] |
4ddb3ea6 | 3353 | "! TARGET_C3X |
cb0ca284 MH |
3354 | && (((INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) |
3355 | && (INTVAL (operands[2]) % INTVAL (operands[1]) == 0)) | |
3356 | || (INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8))" | |
3357 | "* | |
3358 | if (INTVAL (operands[1]) == 8) | |
3359 | { | |
d98d16b1 | 3360 | /* 8 bit insert. */ |
e27f8c8a | 3361 | operands[2] = GEN_INT (INTVAL (operands[2]) / 8); |
cb0ca284 MH |
3362 | return \"mb%2\\t%3,%0\"; |
3363 | } | |
3364 | else if (INTVAL (operands[1]) == 16) | |
3365 | { | |
d98d16b1 | 3366 | /* 16 bit insert. */ |
e27f8c8a | 3367 | operands[2] = GEN_INT (INTVAL (operands[2]) / 16); |
cb0ca284 MH |
3368 | return \"mh%2\\t%3,%0\"; |
3369 | } | |
d98d16b1 | 3370 | /* 24 bit insert. */ |
cb0ca284 MH |
3371 | return \"lwl1\\t%3,%0\"; |
3372 | " | |
3373 | [(set_attr "type" "binarycc,binary") | |
3374 | (set_attr "data" "uint16,uint16")]) | |
3375 | ||
3376 | (define_peephole | |
8a119a7d | 3377 | [(parallel [(set (zero_extract:QI (match_operand:QI 0 "ext_reg_operand" "+d") |
cb0ca284 MH |
3378 | (match_operand:QI 1 "const_int_operand" "n") |
3379 | (match_operand:QI 2 "const_int_operand" "n")) | |
50c33087 | 3380 | (match_operand:QI 3 "src_operand" "rLm")) |
cb0ca284 MH |
3381 | (clobber (reg:CC 21))]) |
3382 | (set (reg:CC 21) | |
3383 | (compare:CC (match_dup 0) (const_int 0)))] | |
4ddb3ea6 | 3384 | "! TARGET_C3X |
cb0ca284 MH |
3385 | && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) |
3386 | && (INTVAL (operands[2]) % INTVAL (operands[1]) == 0)" | |
3387 | "* | |
3388 | if (INTVAL (operands[1]) == 8) | |
3389 | { | |
e27f8c8a | 3390 | operands[2] = GEN_INT (INTVAL (operands[2]) / 8); |
cb0ca284 MH |
3391 | return \"mb%2\\t%3,%0\"; |
3392 | } | |
e27f8c8a | 3393 | operands[2] = GEN_INT (INTVAL (operands[2]) / 16); |
cb0ca284 MH |
3394 | return \"mh%2\\t%3,%0\"; |
3395 | " | |
3396 | [(set_attr "type" "binarycc") | |
3397 | (set_attr "data" "uint16")]) | |
3398 | ||
d98d16b1 | 3399 | |
cb0ca284 MH |
3400 | ; TWO OPERAND FLOAT INSTRUCTIONS |
3401 | ; | |
3402 | ||
3403 | ; | |
3404 | ; LDF/STF | |
3405 | ; | |
3406 | ; If one of the operands is not a register, then we should | |
3407 | ; emit two insns, using a scratch register. This will produce | |
3408 | ; better code in loops if the source operand is invariant, since | |
3409 | ; the source reload can be optimised out. During reload we cannot | |
3410 | ; use change_address or force_reg. | |
3411 | (define_expand "movqf" | |
3412 | [(set (match_operand:QF 0 "src_operand" "") | |
3413 | (match_operand:QF 1 "src_operand" ""))] | |
3414 | "" | |
3415 | " | |
50c33087 MH |
3416 | { |
3417 | if (c4x_emit_move_sequence (operands, QFmode)) | |
3418 | DONE; | |
3419 | }") | |
cb0ca284 | 3420 | |
ebcc44f4 MH |
3421 | ; This can generate invalid stack slot displacements |
3422 | (define_split | |
3423 | [(set (match_operand:QI 0 "reg_operand" "=r") | |
f416f18c | 3424 | (unspec:QI [(match_operand:QF 1 "reg_operand" "f")] 12))] |
ebcc44f4 MH |
3425 | "reload_completed" |
3426 | [(set (match_dup 3) (match_dup 1)) | |
3427 | (set (match_dup 0) (match_dup 2))] | |
3428 | "operands[2] = assign_stack_temp (QImode, GET_MODE_SIZE (QImode), 0); | |
3429 | operands[3] = copy_rtx (operands[2]); | |
3430 | PUT_MODE (operands[3], QFmode);") | |
3431 | ||
3432 | ||
3433 | (define_insn "storeqf_int" | |
3434 | [(set (match_operand:QI 0 "reg_operand" "=r") | |
f416f18c | 3435 | (unspec:QI [(match_operand:QF 1 "reg_operand" "f")] 12))] |
ebcc44f4 MH |
3436 | "" |
3437 | "#" | |
3438 | [(set_attr "type" "multi")]) | |
3439 | ||
3440 | (define_split | |
3441 | [(parallel [(set (match_operand:QI 0 "reg_operand" "=r") | |
f416f18c | 3442 | (unspec:QI [(match_operand:QF 1 "reg_operand" "f")] 12)) |
ebcc44f4 MH |
3443 | (clobber (reg:CC 21))])] |
3444 | "reload_completed" | |
3445 | [(set (mem:QF (pre_inc:QI (reg:QI 20))) | |
3446 | (match_dup 1)) | |
3447 | (parallel [(set (match_dup 0) | |
3448 | (mem:QI (post_dec:QI (reg:QI 20)))) | |
3449 | (clobber (reg:CC 21))])] | |
3450 | "") | |
3451 | ||
3452 | ||
3453 | ; We need accurate death notes for this... | |
3454 | ;(define_peephole | |
3455 | ; [(set (match_operand:QF 0 "reg_operand" "=f") | |
3456 | ; (match_operand:QF 1 "memory_operand" "m")) | |
3457 | ; (set (mem:QF (pre_inc:QI (reg:QI 20))) | |
3458 | ; (match_dup 0)) | |
3459 | ; (parallel [(set (match_operand:QI 2 "reg_operand" "r") | |
3460 | ; (mem:QI (post_dec:QI (reg:QI 20)))) | |
3461 | ; (clobber (reg:CC 21))])] | |
3462 | ; "" | |
3463 | ; "ldiu\\t%1,%0") | |
3464 | ||
3465 | (define_insn "storeqf_int_clobber" | |
3466 | [(parallel [(set (match_operand:QI 0 "reg_operand" "=r") | |
f416f18c | 3467 | (unspec:QI [(match_operand:QF 1 "reg_operand" "f")] 12)) |
ebcc44f4 MH |
3468 | (clobber (reg:CC 21))])] |
3469 | "" | |
3470 | "#" | |
3471 | [(set_attr "type" "multi")]) | |
3472 | ||
f475349b | 3473 | |
ebcc44f4 MH |
3474 | ; This can generate invalid stack slot displacements |
3475 | (define_split | |
3476 | [(set (match_operand:QF 0 "reg_operand" "=f") | |
f416f18c | 3477 | (unspec:QF [(match_operand:QI 1 "reg_operand" "r")] 11))] |
ebcc44f4 MH |
3478 | "reload_completed" |
3479 | [(set (match_dup 2) (match_dup 1)) | |
3480 | (set (match_dup 0) (match_dup 3))] | |
3481 | "operands[2] = assign_stack_temp (QImode, GET_MODE_SIZE (QImode), 0); | |
3482 | operands[3] = copy_rtx (operands[2]); | |
3483 | PUT_MODE (operands[3], QFmode);") | |
3484 | ||
3485 | ||
3486 | (define_insn "loadqf_int" | |
3487 | [(set (match_operand:QF 0 "reg_operand" "=f") | |
f416f18c | 3488 | (unspec:QF [(match_operand:QI 1 "reg_operand" "r")] 11))] |
ebcc44f4 MH |
3489 | "" |
3490 | "#" | |
3491 | [(set_attr "type" "multi")]) | |
3492 | ||
3493 | (define_split | |
3494 | [(parallel [(set (match_operand:QF 0 "reg_operand" "=f") | |
f416f18c | 3495 | (unspec:QF [(match_operand:QI 1 "reg_operand" "r")] 11)) |
ebcc44f4 MH |
3496 | (clobber (reg:CC 21))])] |
3497 | "reload_completed" | |
3498 | [(set (mem:QI (pre_inc:QI (reg:QI 20))) | |
3499 | (match_dup 1)) | |
3500 | (parallel [(set (match_dup 0) | |
3501 | (mem:QF (post_dec:QI (reg:QI 20)))) | |
3502 | (clobber (reg:CC 21))])] | |
3503 | "") | |
3504 | ||
3505 | (define_insn "loadqf_int_clobber" | |
3506 | [(parallel [(set (match_operand:QF 0 "reg_operand" "=f") | |
f416f18c | 3507 | (unspec:QF [(match_operand:QI 1 "reg_operand" "r")] 11)) |
ebcc44f4 MH |
3508 | (clobber (reg:CC 21))])] |
3509 | "" | |
3510 | "#" | |
3511 | [(set_attr "type" "multi")]) | |
3512 | ||
cb0ca284 MH |
3513 | ; We must provide an alternative to store to memory in case we have to |
3514 | ; spill a register. | |
50c33087 | 3515 | (define_insn "movqf_noclobber" |
f416f18c | 3516 | [(set (match_operand:QF 0 "dst_operand" "=f,m") |
50c33087 MH |
3517 | (match_operand:QF 1 "src_operand" "fHm,f"))] |
3518 | "REG_P (operands[0]) || REG_P (operands[1])" | |
cb0ca284 MH |
3519 | "@ |
3520 | ldfu\\t%1,%0 | |
3521 | stf\\t%1,%0" | |
3522 | [(set_attr "type" "unary,store")]) | |
3523 | ||
3524 | ;(define_insn "*movqf_clobber" | |
3525 | ; [(set (match_operand:QF 0 "reg_operand" "=f") | |
50c33087 | 3526 | ; (match_operand:QF 1 "src_operand" "fHm")) |
cb0ca284 MH |
3527 | ; (clobber (reg:CC 21))] |
3528 | ; "0" | |
3529 | ; "ldf\\t%1,%0" | |
3530 | ; [(set_attr "type" "unarycc")]) | |
3531 | ||
3532 | (define_insn "*movqf_test" | |
3533 | [(set (reg:CC 21) | |
50c33087 | 3534 | (compare:CC (match_operand:QF 1 "src_operand" "fHm") |
cb0ca284 MH |
3535 | (const_int 0))) |
3536 | (clobber (match_scratch:QF 0 "=f"))] | |
3537 | "" | |
3538 | "ldf\\t%1,%0" | |
3539 | [(set_attr "type" "unarycc")]) | |
3540 | ||
3541 | (define_insn "*movqf_set" | |
3542 | [(set (reg:CC 21) | |
50c33087 | 3543 | (compare:CC (match_operand:QF 1 "src_operand" "fHm") |
cb0ca284 MH |
3544 | (match_operand:QF 2 "fp_zero_operand" "G"))) |
3545 | (set (match_operand:QF 0 "reg_operand" "=f") | |
3546 | (match_dup 1))] | |
3547 | "" | |
3548 | "ldf\\t%1,%0" | |
3549 | [(set_attr "type" "unarycc")]) | |
3550 | ||
cb0ca284 MH |
3551 | |
3552 | (define_insn "*movqf_parallel" | |
1f7c7f6f MH |
3553 | [(set (match_operand:QF 0 "parallel_operand" "=q,S<>!V,q,S<>!V") |
3554 | (match_operand:QF 1 "parallel_operand" "S<>!V,q,S<>!V,q")) | |
3555 | (set (match_operand:QF 2 "parallel_operand" "=q,S<>!V,S<>!V,q") | |
3556 | (match_operand:QF 3 "parallel_operand" "S<>!V,q,q,S<>!V"))] | |
3557 | "TARGET_PARALLEL && valid_parallel_load_store (operands, QFmode)" | |
cb0ca284 MH |
3558 | "@ |
3559 | ldf1\\t%1,%0\\n||\\tldf2\\t%3,%2 | |
3560 | stf1\\t%1,%0\\n||\\tstf2\\t%3,%2 | |
3561 | ldf\\t%1,%0\\n||\\tstf\\t%3,%2 | |
3562 | ldf\\t%3,%2\\n||\\tstf\\t%1,%0" | |
3563 | [(set_attr "type" "load_load,store_store,load_store,store_load")]) | |
3564 | ||
3565 | ||
3566 | ; | |
3567 | ; PUSH/POP | |
3568 | ; | |
52695ce0 | 3569 | (define_insn "pushqf" |
cb0ca284 MH |
3570 | [(set (mem:QF (pre_inc:QI (reg:QI 20))) |
3571 | (match_operand:QF 0 "reg_operand" "f"))] | |
3572 | "" | |
3573 | "pushf\\t%0" | |
3574 | [(set_attr "type" "push")]) | |
3575 | ||
52695ce0 | 3576 | (define_insn "popqf" |
cb0ca284 MH |
3577 | [(set (match_operand:QF 0 "reg_operand" "=f") |
3578 | (mem:QF (post_dec:QI (reg:QI 20)))) | |
3579 | (clobber (reg:CC 21))] | |
3580 | "" | |
3581 | "popf\\t%0" | |
3582 | [(set_attr "type" "pop")]) | |
3583 | ||
52695ce0 HB |
3584 | (define_insn "popqf_unspec" |
3585 | [(set (unspec:QF [(match_operand:QF 0 "reg_operand" "=f")] 19) | |
3586 | (mem:QF (post_dec:QI (reg:QI 20)))) | |
3587 | (clobber (match_dup 0)) | |
3588 | (clobber (reg:CC 21))] | |
3589 | "" | |
3590 | "popf\\t%0" | |
3591 | [(set_attr "type" "pop")]) | |
cb0ca284 MH |
3592 | |
3593 | ; | |
3594 | ; ABSF | |
3595 | ; | |
3596 | (define_expand "absqf2" | |
3597 | [(parallel [(set (match_operand:QF 0 "reg_operand" "") | |
3598 | (abs:QF (match_operand:QF 1 "src_operand" ""))) | |
3599 | (clobber (reg:CC_NOOV 21))])] | |
3600 | "" | |
3601 | "") | |
3602 | ||
3603 | (define_insn "*absqf2_clobber" | |
3604 | [(set (match_operand:QF 0 "reg_operand" "=f") | |
50c33087 | 3605 | (abs:QF (match_operand:QF 1 "src_operand" "fHm"))) |
cb0ca284 MH |
3606 | (clobber (reg:CC_NOOV 21))] |
3607 | "" | |
3608 | "absf\\t%1,%0" | |
3609 | [(set_attr "type" "unarycc")]) | |
3610 | ||
3611 | (define_insn "*absqf2_test" | |
3612 | [(set (reg:CC_NOOV 21) | |
50c33087 | 3613 | (compare:CC_NOOV (abs:QF (match_operand:QF 1 "src_operand" "fHm")) |
cb0ca284 MH |
3614 | (match_operand:QF 2 "fp_zero_operand" "G"))) |
3615 | (clobber (match_scratch:QF 0 "=f"))] | |
3616 | "" | |
3617 | "absf\\t%1,%0" | |
3618 | [(set_attr "type" "unarycc")]) | |
3619 | ||
3620 | (define_insn "*absqf2_set" | |
3621 | [(set (reg:CC_NOOV 21) | |
50c33087 | 3622 | (compare:CC_NOOV (abs:QF (match_operand:QF 1 "src_operand" "fHm")) |
cb0ca284 MH |
3623 | (match_operand:QF 2 "fp_zero_operand" "G"))) |
3624 | (set (match_operand:QF 0 "reg_operand" "=f") | |
3625 | (abs:QF (match_dup 1)))] | |
3626 | ||
3627 | "" | |
3628 | "absf\\t%1,%0" | |
3629 | [(set_attr "type" "unarycc")]) | |
3630 | ||
3631 | ; | |
3632 | ; NEGF | |
3633 | ; | |
3634 | (define_expand "negqf2" | |
3635 | [(parallel [(set (match_operand:QF 0 "reg_operand" "") | |
3636 | (neg:QF (match_operand:QF 1 "src_operand" ""))) | |
3637 | (clobber (reg:CC_NOOV 21))])] | |
3638 | "" | |
3639 | "") | |
3640 | ||
3641 | (define_insn "*negqf2_clobber" | |
3642 | [(set (match_operand:QF 0 "reg_operand" "=f") | |
50c33087 | 3643 | (neg:QF (match_operand:QF 1 "src_operand" "fHm"))) |
cb0ca284 MH |
3644 | (clobber (reg:CC_NOOV 21))] |
3645 | "" | |
3646 | "negf\\t%1,%0" | |
3647 | [(set_attr "type" "unarycc")]) | |
3648 | ||
3649 | (define_insn "*negqf2_test" | |
3650 | [(set (reg:CC_NOOV 21) | |
50c33087 | 3651 | (compare:CC_NOOV (neg:QF (match_operand:QF 1 "src_operand" "fHm")) |
cb0ca284 MH |
3652 | (match_operand:QF 2 "fp_zero_operand" "G"))) |
3653 | (clobber (match_scratch:QF 0 "=f"))] | |
3654 | "" | |
3655 | "negf\\t%1,%0" | |
3656 | [(set_attr "type" "unarycc")]) | |
3657 | ||
3658 | (define_insn "*negqf2_set" | |
3659 | [(set (reg:CC_NOOV 21) | |
50c33087 | 3660 | (compare:CC_NOOV (neg:QF (match_operand:QF 1 "src_operand" "fHm")) |
cb0ca284 MH |
3661 | (match_operand:QF 2 "fp_zero_operand" "G"))) |
3662 | (set (match_operand:QF 0 "reg_operand" "=f") | |
3663 | (neg:QF (match_dup 1)))] | |
3664 | "" | |
3665 | "negf\\t%1,%0" | |
3666 | [(set_attr "type" "unarycc")]) | |
3667 | ||
3668 | ; | |
3669 | ; FLOAT | |
3670 | ; | |
3671 | (define_insn "floatqiqf2" | |
3672 | [(set (match_operand:QF 0 "reg_operand" "=f") | |
50c33087 | 3673 | (float:QF (match_operand:QI 1 "src_operand" "rIm"))) |
cb0ca284 MH |
3674 | (clobber (reg:CC 21))] |
3675 | "" | |
3676 | "float\\t%1,%0" | |
3677 | [(set_attr "type" "unarycc")]) | |
3678 | ||
3679 | (define_insn "*floatqiqf2_set" | |
3680 | [(set (reg:CC 21) | |
50c33087 | 3681 | (compare:CC (float:QF (match_operand:QI 1 "src_operand" "rIm")) |
cb0ca284 MH |
3682 | (match_operand:QF 2 "fp_zero_operand" "G"))) |
3683 | (set (match_operand:QF 0 "reg_operand" "=f") | |
3684 | (float:QF (match_dup 1)))] | |
cb0ca284 MH |
3685 | "" |
3686 | "float\\t%1,%0" | |
3687 | [(set_attr "type" "unarycc")]) | |
3688 | ||
3689 | ; Unsigned conversions are a little tricky because we need to | |
3690 | ; add the value for the high bit if necessary. | |
50c33087 | 3691 | ; |
cb0ca284 MH |
3692 | ; |
3693 | (define_expand "floatunsqiqf2" | |
3694 | [(set (match_dup 2) (match_dup 3)) | |
3695 | (parallel [(set (reg:CC 21) | |
3696 | (compare:CC (float:QF (match_operand:QI 1 "src_operand" "")) | |
3697 | (match_dup 3))) | |
3698 | (set (match_dup 4) | |
3699 | (float:QF (match_dup 1)))]) | |
50c33087 | 3700 | (set (match_dup 6) |
cb0ca284 | 3701 | (if_then_else:QF (lt (reg:CC 21) (const_int 0)) |
50c33087 | 3702 | (match_dup 5) |
cb0ca284 MH |
3703 | (match_dup 2))) |
3704 | (parallel [(set (match_operand:QF 0 "reg_operand" "") | |
50c33087 | 3705 | (plus:QF (match_dup 6) (match_dup 4))) |
cb0ca284 MH |
3706 | (clobber (reg:CC_NOOV 21))])] |
3707 | "" | |
3708 | "operands[2] = gen_reg_rtx (QFmode); | |
3709 | operands[3] = CONST0_RTX (QFmode); | |
3710 | operands[4] = gen_reg_rtx (QFmode); | |
50c33087 MH |
3711 | operands[5] = gen_reg_rtx (QFmode); |
3712 | operands[6] = gen_reg_rtx (QFmode); | |
3713 | emit_move_insn (operands[5], | |
3714 | immed_real_const_1 (REAL_VALUE_ATOF (\"4294967296.0\", QFmode), QFmode));") | |
cb0ca284 | 3715 | |
8a119a7d MH |
3716 | (define_expand "floatunsqihf2" |
3717 | [(set (match_dup 2) (match_dup 3)) | |
3718 | (parallel [(set (reg:CC 21) | |
3719 | (compare:CC (float:HF (match_operand:QI 1 "src_operand" "")) | |
3720 | (match_dup 3))) | |
3721 | (set (match_dup 4) | |
3722 | (float:HF (match_dup 1)))]) | |
3723 | (set (match_dup 6) | |
3724 | (if_then_else:HF (lt (reg:CC 21) (const_int 0)) | |
3725 | (match_dup 5) | |
3726 | (match_dup 2))) | |
3727 | (parallel [(set (match_operand:HF 0 "reg_operand" "") | |
3728 | (plus:HF (match_dup 6) (match_dup 4))) | |
3729 | (clobber (reg:CC_NOOV 21))])] | |
3730 | "" | |
3731 | "operands[2] = gen_reg_rtx (HFmode); | |
3732 | operands[3] = CONST0_RTX (HFmode); | |
3733 | operands[4] = gen_reg_rtx (HFmode); | |
3734 | operands[5] = gen_reg_rtx (HFmode); | |
3735 | operands[6] = gen_reg_rtx (HFmode); | |
3736 | emit_move_insn (operands[5], | |
3737 | immed_real_const_1 (REAL_VALUE_ATOF (\"4294967296.0\", HFmode), HFmode));") | |
3738 | ||
cb0ca284 MH |
3739 | (define_insn "floatqihf2" |
3740 | [(set (match_operand:HF 0 "reg_operand" "=h") | |
50c33087 | 3741 | (float:HF (match_operand:QI 1 "src_operand" "rIm"))) |
cb0ca284 MH |
3742 | (clobber (reg:CC 21))] |
3743 | "" | |
3744 | "float\\t%1,%0" | |
3745 | [(set_attr "type" "unarycc")]) | |
3746 | ||
8a119a7d MH |
3747 | (define_insn "*floatqihf2_set" |
3748 | [(set (reg:CC 21) | |
3749 | (compare:CC (float:HF (match_operand:QI 1 "src_operand" "rIm")) | |
3750 | (match_operand:QF 2 "fp_zero_operand" "G"))) | |
3751 | (set (match_operand:HF 0 "reg_operand" "=h") | |
3752 | (float:HF (match_dup 1)))] | |
3753 | "" | |
3754 | "float\\t%1,%0" | |
3755 | [(set_attr "type" "unarycc")]) | |
3756 | ||
cb0ca284 MH |
3757 | ; |
3758 | ; FIX | |
3759 | ; | |
3760 | (define_insn "fixqfqi_clobber" | |
3761 | [(set (match_operand:QI 0 "reg_operand" "=d,c") | |
50c33087 | 3762 | (fix:QI (match_operand:QF 1 "src_operand" "fHm,fHm"))) |
cb0ca284 MH |
3763 | (clobber (reg:CC 21))] |
3764 | "" | |
3765 | "fix\\t%1,%0" | |
3766 | [(set_attr "type" "unarycc")]) | |
3767 | ||
3768 | (define_insn "*fixqfqi_set" | |
3769 | [(set (reg:CC 21) | |
50c33087 | 3770 | (compare:CC (fix:QI (match_operand:QF 1 "src_operand" "fHm")) |
cb0ca284 | 3771 | (const_int 0))) |
50c33087 | 3772 | (set (match_operand:QI 0 "ext_reg_operand" "=d") |
cb0ca284 MH |
3773 | (fix:QI (match_dup 1)))] |
3774 | "" | |
3775 | "fix\\t%1,%0" | |
3776 | [(set_attr "type" "unarycc")]) | |
3777 | ||
8a119a7d MH |
3778 | (define_insn "*fixhfqi_set" |
3779 | [(set (reg:CC 21) | |
3780 | (compare:CC (fix:QI (match_operand:HF 1 "src_operand" "fH")) | |
3781 | (const_int 0))) | |
3782 | (set (match_operand:QI 0 "ext_reg_operand" "=d") | |
3783 | (fix:QI (match_dup 1)))] | |
3784 | "" | |
3785 | "fix\\t%1,%0" | |
3786 | [(set_attr "type" "unarycc")]) | |
3787 | ||
cb0ca284 MH |
3788 | ; |
3789 | ; The C[34]x fix instruction implements a floor, not a straight trunc, | |
3790 | ; so we have to invert the number, fix it, and reinvert it if negative | |
3791 | ; | |
3792 | (define_expand "fix_truncqfqi2" | |
3793 | [(parallel [(set (match_dup 2) | |
3794 | (fix:QI (match_operand:QF 1 "src_operand" ""))) | |
3795 | (clobber (reg:CC 21))]) | |
3796 | (parallel [(set (match_dup 3) (neg:QF (match_dup 1))) | |
3797 | (clobber (reg:CC_NOOV 21))]) | |
3798 | (parallel [(set (match_dup 4) (fix:QI (match_dup 3))) | |
3799 | (clobber (reg:CC 21))]) | |
3800 | (parallel [(set (reg:CC_NOOV 21) | |
3801 | (compare:CC_NOOV (neg:QI (match_dup 4)) (const_int 0))) | |
3802 | (set (match_dup 5) (neg:QI (match_dup 4)))]) | |
3803 | (set (match_dup 2) | |
3804 | (if_then_else:QI (le (reg:CC 21) (const_int 0)) | |
3805 | (match_dup 5) | |
3806 | (match_dup 2))) | |
3807 | (set (match_operand:QI 0 "reg_operand" "=r") (match_dup 2))] | |
3808 | "" | |
3809 | "if (TARGET_FAST_FIX) | |
3810 | { | |
3811 | emit_insn (gen_fixqfqi_clobber (operands[0], operands[1])); | |
3812 | DONE; | |
3813 | } | |
3814 | operands[2] = gen_reg_rtx (QImode); | |
3815 | operands[3] = gen_reg_rtx (QFmode); | |
3816 | operands[4] = gen_reg_rtx (QImode); | |
3817 | operands[5] = gen_reg_rtx (QImode); | |
3818 | ") | |
3819 | ||
8a119a7d MH |
3820 | (define_expand "fix_trunchfqi2" |
3821 | [(parallel [(set (match_dup 2) | |
3822 | (fix:QI (match_operand:HF 1 "src_operand" ""))) | |
3823 | (clobber (reg:CC 21))]) | |
3824 | (parallel [(set (match_dup 3) (neg:HF (match_dup 1))) | |
3825 | (clobber (reg:CC_NOOV 21))]) | |
3826 | (parallel [(set (match_dup 4) (fix:QI (match_dup 3))) | |
3827 | (clobber (reg:CC 21))]) | |
3828 | (parallel [(set (reg:CC_NOOV 21) | |
3829 | (compare:CC_NOOV (neg:QI (match_dup 4)) (const_int 0))) | |
3830 | (set (match_dup 5) (neg:QI (match_dup 4)))]) | |
3831 | (set (match_dup 2) | |
3832 | (if_then_else:QI (le (reg:CC 21) (const_int 0)) | |
3833 | (match_dup 5) | |
3834 | (match_dup 2))) | |
3835 | (set (match_operand:QI 0 "reg_operand" "=r") (match_dup 2))] | |
3836 | "" | |
3837 | "if (TARGET_FAST_FIX) | |
3838 | { | |
3839 | emit_insn (gen_fixhfqi_clobber (operands[0], operands[1])); | |
3840 | DONE; | |
3841 | } | |
3842 | operands[2] = gen_reg_rtx (QImode); | |
3843 | operands[3] = gen_reg_rtx (HFmode); | |
3844 | operands[4] = gen_reg_rtx (QImode); | |
3845 | operands[5] = gen_reg_rtx (QImode); | |
3846 | ") | |
3847 | ||
cb0ca284 MH |
3848 | (define_expand "fix_truncqfhi2" |
3849 | [(parallel [(set (match_operand:HI 0 "reg_operand" "") | |
3850 | (fix:HI (match_operand:QF 1 "src_operand" ""))) | |
3851 | (clobber (reg:CC 21))])] | |
3852 | "" | |
4fda2521 | 3853 | "c4x_emit_libcall (fix_truncqfhi2_libfunc, FIX, HImode, QFmode, 2, operands); |
cb0ca284 MH |
3854 | DONE;") |
3855 | ||
3856 | (define_expand "fixuns_truncqfqi2" | |
b027470f MH |
3857 | [(parallel [(set (match_dup 2) |
3858 | (fix:QI (match_operand:QF 1 "src_operand" "fHm"))) | |
3859 | (clobber (reg:CC 21))]) | |
3860 | (parallel [(set (match_dup 3) | |
3861 | (minus:QF (match_dup 1) (match_dup 5))) | |
a5fa6484 | 3862 | (clobber (reg:CC_NOOV 21))]) |
b027470f MH |
3863 | (parallel [(set (reg:CC 21) |
3864 | (compare:CC (fix:QI (match_dup 3)) | |
3865 | (const_int 0))) | |
3866 | (set (match_dup 4) | |
3867 | (fix:QI (match_dup 3)))]) | |
3868 | (parallel [(set (match_dup 4) (unspec:QI [(match_dup 2)] 13)) | |
3869 | (use (reg:CC 21))]) | |
3870 | (set (match_operand:QI 0 "reg_operand" "=r") (match_dup 4))] | |
cb0ca284 | 3871 | "" |
b027470f | 3872 | "operands[2] = gen_reg_rtx (QImode); |
a5fa6484 | 3873 | operands[3] = gen_reg_rtx (QFmode); |
b027470f | 3874 | operands[4] = gen_reg_rtx (QImode); |
a5fa6484 | 3875 | operands[5] = gen_reg_rtx (QFmode); |
a5fa6484 | 3876 | emit_move_insn (operands[5], |
b027470f | 3877 | immed_real_const_1 (REAL_VALUE_ATOF (\"4294967296.0\", QFmode), QFmode));") |
cb0ca284 | 3878 | |
8a119a7d MH |
3879 | (define_expand "fixuns_trunchfqi2" |
3880 | [(parallel [(set (match_dup 2) | |
3881 | (fix:QI (match_operand:HF 1 "src_operand" "hH"))) | |
3882 | (clobber (reg:CC 21))]) | |
3883 | (parallel [(set (match_dup 3) | |
3884 | (minus:HF (match_dup 1) (match_dup 5))) | |
3885 | (clobber (reg:CC_NOOV 21))]) | |
3886 | (parallel [(set (reg:CC 21) | |
3887 | (compare:CC (fix:QI (match_dup 3)) | |
3888 | (const_int 0))) | |
3889 | (set (match_dup 4) | |
3890 | (fix:QI (match_dup 3)))]) | |
3891 | (parallel [(set (match_dup 4) (unspec:QI [(match_dup 2)] 13)) | |
3892 | (use (reg:CC 21))]) | |
3893 | (set (match_operand:QI 0 "reg_operand" "=r") (match_dup 4))] | |
3894 | "" | |
3895 | "operands[2] = gen_reg_rtx (QImode); | |
3896 | operands[3] = gen_reg_rtx (HFmode); | |
3897 | operands[4] = gen_reg_rtx (QImode); | |
3898 | operands[5] = gen_reg_rtx (HFmode); | |
3899 | emit_move_insn (operands[5], | |
3900 | immed_real_const_1 (REAL_VALUE_ATOF (\"4294967296.0\", HFmode), HFmode));") | |
3901 | ||
cb0ca284 MH |
3902 | (define_expand "fixuns_truncqfhi2" |
3903 | [(parallel [(set (match_operand:HI 0 "reg_operand" "") | |
3904 | (unsigned_fix:HI (match_operand:QF 1 "src_operand" ""))) | |
3905 | (clobber (reg:CC 21))])] | |
3906 | "" | |
4fda2521 | 3907 | "c4x_emit_libcall (fixuns_truncqfhi2_libfunc, UNSIGNED_FIX, |
cb0ca284 MH |
3908 | HImode, QFmode, 2, operands); |
3909 | DONE;") | |
3910 | ||
3911 | ; | |
3912 | ; RCPF | |
3913 | ; | |
8a119a7d | 3914 | (define_insn "rcpfqf_clobber" |
cb0ca284 | 3915 | [(set (match_operand:QF 0 "reg_operand" "=f") |
f416f18c | 3916 | (unspec:QF [(match_operand:QF 1 "src_operand" "fHm")] 5)) |
cb0ca284 | 3917 | (clobber (reg:CC_NOOV 21))] |
4ddb3ea6 | 3918 | "! TARGET_C3X" |
cb0ca284 MH |
3919 | "rcpf\\t%1,%0" |
3920 | [(set_attr "type" "unarycc")]) | |
3921 | ||
3922 | ; | |
3923 | ; RSQRF | |
3924 | ; | |
3925 | (define_insn "*rsqrfqf_clobber" | |
3926 | [(set (match_operand:QF 0 "reg_operand" "=f") | |
f416f18c | 3927 | (unspec:QF [(match_operand:QF 1 "src_operand" "fHm")] 10)) |
cb0ca284 | 3928 | (clobber (reg:CC_NOOV 21))] |
4ddb3ea6 | 3929 | "! TARGET_C3X" |
cb0ca284 MH |
3930 | "rsqrf\\t%1,%0" |
3931 | [(set_attr "type" "unarycc")]) | |
3932 | ||
3933 | ; | |
3934 | ; RNDF | |
3935 | ; | |
3936 | (define_insn "*rndqf_clobber" | |
3937 | [(set (match_operand:QF 0 "reg_operand" "=f") | |
f416f18c | 3938 | (unspec:QF [(match_operand:QF 1 "src_operand" "fHm")] 6)) |
cb0ca284 | 3939 | (clobber (reg:CC_NOOV 21))] |
4ddb3ea6 | 3940 | "! TARGET_C3X" |
cb0ca284 MH |
3941 | "rnd\\t%1,%0" |
3942 | [(set_attr "type" "unarycc")]) | |
3943 | ||
3944 | ||
3945 | ; Inlined float square root for C4x | |
3946 | (define_expand "sqrtqf2_inline" | |
3947 | [(parallel [(set (match_dup 2) | |
f959ff1a | 3948 | (unspec:QF [(match_operand:QF 1 "src_operand" "")] 10)) |
cb0ca284 MH |
3949 | (clobber (reg:CC_NOOV 21))]) |
3950 | (parallel [(set (match_dup 3) (mult:QF (match_dup 5) (match_dup 1))) | |
3951 | (clobber (reg:CC_NOOV 21))]) | |
3952 | (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 3))) | |
3953 | (clobber (reg:CC_NOOV 21))]) | |
3954 | (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 4))) | |
3955 | (clobber (reg:CC_NOOV 21))]) | |
3956 | (parallel [(set (match_dup 4) (minus:QF (match_dup 6) (match_dup 4))) | |
3957 | (clobber (reg:CC_NOOV 21))]) | |
3958 | (parallel [(set (match_dup 2) (mult:QF (match_dup 2) (match_dup 4))) | |
3959 | (clobber (reg:CC_NOOV 21))]) | |
3960 | (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 3))) | |
3961 | (clobber (reg:CC_NOOV 21))]) | |
3962 | (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 4))) | |
3963 | (clobber (reg:CC_NOOV 21))]) | |
3964 | (parallel [(set (match_dup 4) (minus:QF (match_dup 6) (match_dup 4))) | |
3965 | (clobber (reg:CC_NOOV 21))]) | |
3966 | (parallel [(set (match_dup 2) (mult:QF (match_dup 2) (match_dup 4))) | |
3967 | (clobber (reg:CC_NOOV 21))]) | |
3968 | (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 1))) | |
3969 | (clobber (reg:CC_NOOV 21))]) | |
3970 | (parallel [(set (match_operand:QF 0 "reg_operand" "") | |
f959ff1a | 3971 | (unspec:QF [(match_dup 4)] 6)) |
cb0ca284 | 3972 | (clobber (reg:CC_NOOV 21))])] |
4ddb3ea6 MH |
3973 | "! TARGET_C3X" |
3974 | "if (! reload_in_progress | |
3975 | && ! reg_operand (operands[1], QFmode)) | |
cb0ca284 MH |
3976 | operands[1] = force_reg (QFmode, operands[1]); |
3977 | operands[2] = gen_reg_rtx (QFmode); | |
3978 | operands[3] = gen_reg_rtx (QFmode); | |
3979 | operands[4] = gen_reg_rtx (QFmode); | |
3980 | operands[5] = immed_real_const_1 (REAL_VALUE_ATOF (\"0.5\", QFmode), | |
3981 | QFmode); | |
3982 | operands[6] = immed_real_const_1 (REAL_VALUE_ATOF (\"1.5\", QFmode), | |
3983 | QFmode);") | |
3984 | ||
3985 | (define_expand "sqrtqf2" | |
3986 | [(parallel [(set (match_operand:QF 0 "reg_operand" "") | |
3987 | (sqrt:QF (match_operand:QF 1 "src_operand" ""))) | |
3988 | (clobber (reg:CC 21))])] | |
f42850b9 MH |
3989 | "! TARGET_C3X && TARGET_INLINE" |
3990 | "emit_insn (gen_sqrtqf2_inline (operands[0], operands[1])); | |
3991 | DONE;") | |
cb0ca284 | 3992 | |
8a119a7d MH |
3993 | ; |
3994 | ; TOIEEE / FRIEEE | |
3995 | ; | |
3996 | (define_insn "toieee" | |
3997 | [(set (match_operand:QF 0 "reg_operand" "=f") | |
3998 | (unspec:QF [(match_operand:QF 1 "src_operand" "fHm")] 23)) | |
3999 | (clobber (reg:CC 21))] | |
4000 | "" | |
4001 | "toieee\\t%1,%0") | |
4002 | ||
4003 | (define_insn "frieee" | |
4004 | [(set (match_operand:QF 0 "reg_operand" "=f") | |
4005 | (unspec:QF [(match_operand:QF 1 "memory_operand" "m")] 24)) | |
4006 | (clobber (reg:CC 21))] | |
4007 | "" | |
4008 | "frieee\\t%1,%0") | |
4009 | ||
cb0ca284 MH |
4010 | ; |
4011 | ; THREE OPERAND FLOAT INSTRUCTIONS | |
4012 | ; | |
4013 | ||
4014 | ; | |
4015 | ; ADDF | |
4016 | ; | |
4017 | (define_expand "addqf3" | |
4018 | [(parallel [(set (match_operand:QF 0 "reg_operand" "") | |
4019 | (plus:QF (match_operand:QF 1 "src_operand" "") | |
4020 | (match_operand:QF 2 "src_operand" ""))) | |
4021 | (clobber (reg:CC_NOOV 21))])] | |
4022 | "" | |
4023 | "legitimize_operands (PLUS, operands, QFmode);") | |
4024 | ||
4025 | (define_insn "*addqf3_clobber" | |
65c78c7d MH |
4026 | [(set (match_operand:QF 0 "reg_operand" "=f,f,?f") |
4027 | (plus:QF (match_operand:QF 1 "src_operand" "%0,fR,fS<>") | |
4028 | (match_operand:QF 2 "src_operand" "fHm,R,fS<>"))) | |
cb0ca284 MH |
4029 | (clobber (reg:CC_NOOV 21))] |
4030 | "valid_operands (PLUS, operands, QFmode)" | |
4031 | "@ | |
65c78c7d | 4032 | addf\\t%2,%0 |
cb0ca284 | 4033 | addf3\\t%2,%1,%0 |
65c78c7d | 4034 | addf3\\t%2,%1,%0" |
cb0ca284 MH |
4035 | [(set_attr "type" "binarycc,binarycc,binarycc")]) |
4036 | ||
4037 | (define_insn "*addqf3_test" | |
4038 | [(set (reg:CC_NOOV 21) | |
65c78c7d MH |
4039 | (compare:CC_NOOV (plus:QF (match_operand:QF 1 "src_operand" "%0,fR,fS<>") |
4040 | (match_operand:QF 2 "src_operand" "fHm,R,fS<>")) | |
cb0ca284 | 4041 | (match_operand:QF 3 "fp_zero_operand" "G,G,G"))) |
65c78c7d | 4042 | (clobber (match_scratch:QF 0 "=f,f,?f"))] |
cb0ca284 MH |
4043 | "valid_operands (PLUS, operands, QFmode)" |
4044 | "@ | |
65c78c7d | 4045 | addf\\t%2,%0 |
cb0ca284 | 4046 | addf3\\t%2,%1,%0 |
65c78c7d | 4047 | addf3\\t%2,%1,%0" |
cb0ca284 MH |
4048 | [(set_attr "type" "binarycc,binarycc,binarycc")]) |
4049 | ||
4050 | (define_insn "*addqf3_set" | |
4051 | [(set (reg:CC_NOOV 21) | |
65c78c7d MH |
4052 | (compare:CC_NOOV (plus:QF (match_operand:QF 1 "src_operand" "%0,fR,fS<>") |
4053 | (match_operand:QF 2 "src_operand" "fHm,R,fS<>")) | |
cb0ca284 | 4054 | (match_operand:QF 3 "fp_zero_operand" "G,G,G"))) |
65c78c7d | 4055 | (set (match_operand:QF 0 "reg_operand" "=f,f,?f") |
cb0ca284 MH |
4056 | (plus:QF (match_dup 1) |
4057 | (match_dup 2)))] | |
4058 | "valid_operands (PLUS, operands, QFmode)" | |
4059 | "@ | |
65c78c7d | 4060 | addf\\t%2,%0 |
cb0ca284 | 4061 | addf3\\t%2,%1,%0 |
65c78c7d | 4062 | addf3\\t%2,%1,%0" |
cb0ca284 MH |
4063 | [(set_attr "type" "binarycc,binarycc,binarycc")]) |
4064 | ||
4065 | ; | |
4066 | ; SUBF/SUBRF | |
4067 | ; | |
4068 | (define_expand "subqf3" | |
4069 | [(parallel [(set (match_operand:QF 0 "reg_operand" "") | |
4070 | (minus:QF (match_operand:QF 1 "src_operand" "") | |
4071 | (match_operand:QF 2 "src_operand" ""))) | |
4072 | (clobber (reg:CC_NOOV 21))])] | |
4073 | "" | |
4074 | "legitimize_operands (MINUS, operands, QFmode);") | |
4075 | ||
4076 | (define_insn "*subqf3_clobber" | |
65c78c7d MH |
4077 | [(set (match_operand:QF 0 "reg_operand" "=f,f,f,?f") |
4078 | (minus:QF (match_operand:QF 1 "src_operand" "0,fHm,fR,fS<>") | |
4079 | (match_operand:QF 2 "src_operand" "fHm,0,R,fS<>"))) | |
cb0ca284 MH |
4080 | (clobber (reg:CC_NOOV 21))] |
4081 | "valid_operands (MINUS, operands, QFmode)" | |
4082 | "@ | |
cb0ca284 | 4083 | subf\\t%2,%0 |
65c78c7d MH |
4084 | subrf\\t%1,%0 |
4085 | subf3\\t%2,%1,%0 | |
4086 | subf3\\t%2,%1,%0" | |
cb0ca284 MH |
4087 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")]) |
4088 | ||
4089 | (define_insn "*subqf3_test" | |
4090 | [(set (reg:CC_NOOV 21) | |
65c78c7d MH |
4091 | (compare:CC_NOOV (minus:QF (match_operand:QF 1 "src_operand" "0,fHm,fR,fS<>") |
4092 | (match_operand:QF 2 "src_operand" "fHm,0,R,fS<>")) | |
cb0ca284 | 4093 | (match_operand:QF 3 "fp_zero_operand" "G,G,G,G"))) |
65c78c7d | 4094 | (clobber (match_scratch:QF 0 "=f,f,f,?f"))] |
cb0ca284 MH |
4095 | "valid_operands (MINUS, operands, QFmode)" |
4096 | "@ | |
cb0ca284 | 4097 | subf\\t%2,%0 |
65c78c7d MH |
4098 | subrf\\t%1,%0 |
4099 | subf3\\t%2,%1,%0 | |
4100 | subf3\\t%2,%1,%0" | |
cb0ca284 MH |
4101 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")]) |
4102 | ||
4103 | (define_insn "*subqf3_set" | |
4104 | [(set (reg:CC_NOOV 21) | |
65c78c7d | 4105 | (compare:CC_NOOV (minus:QF (match_operand:QF 1 "src_operand" "0,fHm,fR,fS<>") |
8421850f | 4106 | (match_operand:QF 2 "src_operand" "fHm,0,R,fS<>")) |
cb0ca284 | 4107 | (match_operand:QF 3 "fp_zero_operand" "G,G,G,G"))) |
65c78c7d | 4108 | (set (match_operand:QF 0 "reg_operand" "=f,f,f,?f") |
cb0ca284 | 4109 | (minus:QF (match_dup 1) |
8421850f | 4110 | (match_dup 2)))] |
cb0ca284 MH |
4111 | "valid_operands (MINUS, operands, QFmode)" |
4112 | "@ | |
cb0ca284 | 4113 | subf\\t%2,%0 |
65c78c7d MH |
4114 | subrf\\t%1,%0 |
4115 | subf3\\t%2,%1,%0 | |
4116 | subf3\\t%2,%1,%0" | |
cb0ca284 MH |
4117 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")]) |
4118 | ||
4119 | ; | |
4120 | ; MPYF | |
4121 | ; | |
4122 | (define_expand "mulqf3" | |
4123 | [(parallel [(set (match_operand:QF 0 "reg_operand" "") | |
4124 | (mult:QF (match_operand:QF 1 "src_operand" "") | |
4125 | (match_operand:QF 2 "src_operand" ""))) | |
4126 | (clobber (reg:CC_NOOV 21))])] | |
4127 | "" | |
4128 | "legitimize_operands (MULT, operands, QFmode);") | |
4129 | ||
4130 | (define_insn "*mulqf3_clobber" | |
65c78c7d MH |
4131 | [(set (match_operand:QF 0 "reg_operand" "=f,f,?f") |
4132 | (mult:QF (match_operand:QF 1 "src_operand" "%0,fR,fS<>") | |
4133 | (match_operand:QF 2 "src_operand" "fHm,R,fS<>"))) | |
cb0ca284 MH |
4134 | (clobber (reg:CC_NOOV 21))] |
4135 | "valid_operands (MULT, operands, QFmode)" | |
4136 | "@ | |
65c78c7d | 4137 | mpyf\\t%2,%0 |
cb0ca284 | 4138 | mpyf3\\t%2,%1,%0 |
65c78c7d | 4139 | mpyf3\\t%2,%1,%0" |
cb0ca284 MH |
4140 | [(set_attr "type" "binarycc,binarycc,binarycc")]) |
4141 | ||
4142 | (define_insn "*mulqf3_test" | |
4143 | [(set (reg:CC_NOOV 21) | |
65c78c7d MH |
4144 | (compare:CC_NOOV (mult:QF (match_operand:QF 1 "src_operand" "%0,fR,fS<>") |
4145 | (match_operand:QF 2 "src_operand" "fHm,R,fS<>")) | |
cb0ca284 | 4146 | (match_operand:QF 3 "fp_zero_operand" "G,G,G"))) |
65c78c7d | 4147 | (clobber (match_scratch:QF 0 "=f,f,?f"))] |
cb0ca284 MH |
4148 | "valid_operands (MULT, operands, QFmode)" |
4149 | "@ | |
65c78c7d | 4150 | mpyf\\t%2,%0 |
cb0ca284 | 4151 | mpyf3\\t%2,%1,%0 |
65c78c7d | 4152 | mpyf3\\t%2,%1,%0" |
cb0ca284 MH |
4153 | [(set_attr "type" "binarycc,binarycc,binarycc")]) |
4154 | ||
4155 | (define_insn "*mulqf3_set" | |
4156 | [(set (reg:CC_NOOV 21) | |
65c78c7d MH |
4157 | (compare:CC_NOOV (mult:QF (match_operand:QF 1 "src_operand" "%0,fR,fS<>") |
4158 | (match_operand:QF 2 "src_operand" "fHm,R,fS<>")) | |
cb0ca284 | 4159 | (match_operand:QF 3 "fp_zero_operand" "G,G,G"))) |
65c78c7d | 4160 | (set (match_operand:QF 0 "reg_operand" "=f,f,?f") |
cb0ca284 MH |
4161 | (mult:QF (match_dup 1) |
4162 | (match_dup 2)))] | |
4163 | "valid_operands (MULT, operands, QFmode)" | |
4164 | "@ | |
65c78c7d | 4165 | mpyf\\t%2,%0 |
cb0ca284 | 4166 | mpyf3\\t%2,%1,%0 |
65c78c7d | 4167 | mpyf3\\t%2,%1,%0" |
cb0ca284 MH |
4168 | [(set_attr "type" "binarycc,binarycc,binarycc")]) |
4169 | ||
4170 | ; | |
4171 | ; CMPF | |
4172 | ; | |
4173 | (define_expand "cmpqf" | |
4174 | [(set (reg:CC 21) | |
4175 | (compare:CC (match_operand:QF 0 "src_operand" "") | |
4176 | (match_operand:QF 1 "src_operand" "")))] | |
4177 | "" | |
4178 | "legitimize_operands (COMPARE, operands, QFmode); | |
4179 | c4x_compare_op0 = operands[0]; | |
4180 | c4x_compare_op1 = operands[1]; | |
4181 | DONE;") | |
4182 | ||
4183 | (define_insn "*cmpqf" | |
4184 | [(set (reg:CC 21) | |
ccd63d90 | 4185 | (compare:CC (match_operand:QF 0 "src_operand" "f,fR,fS<>") |
65c78c7d | 4186 | (match_operand:QF 1 "src_operand" "fHm,R,fS<>")))] |
cb0ca284 MH |
4187 | "valid_operands (COMPARE, operands, QFmode)" |
4188 | "@ | |
65c78c7d | 4189 | cmpf\\t%1,%0 |
cb0ca284 | 4190 | cmpf3\\t%1,%0 |
65c78c7d | 4191 | cmpf3\\t%1,%0" |
cb0ca284 MH |
4192 | [(set_attr "type" "compare,compare,compare")]) |
4193 | ||
4194 | (define_insn "*cmpqf_noov" | |
4195 | [(set (reg:CC_NOOV 21) | |
ccd63d90 | 4196 | (compare:CC_NOOV (match_operand:QF 0 "src_operand" "f,fR,fS<>") |
65c78c7d | 4197 | (match_operand:QF 1 "src_operand" "fHm,R,fS<>")))] |
cb0ca284 MH |
4198 | "valid_operands (COMPARE, operands, QFmode)" |
4199 | "@ | |
65c78c7d | 4200 | cmpf\\t%1,%0 |
cb0ca284 | 4201 | cmpf3\\t%1,%0 |
65c78c7d | 4202 | cmpf3\\t%1,%0" |
cb0ca284 MH |
4203 | [(set_attr "type" "compare,compare,compare")]) |
4204 | ||
4205 | ; Inlined float divide for C4x | |
4206 | (define_expand "divqf3_inline" | |
4207 | [(parallel [(set (match_dup 3) | |
f959ff1a | 4208 | (unspec:QF [(match_operand:QF 2 "src_operand" "")] 5)) |
cb0ca284 MH |
4209 | (clobber (reg:CC_NOOV 21))]) |
4210 | (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 3))) | |
4211 | (clobber (reg:CC_NOOV 21))]) | |
4212 | (parallel [(set (match_dup 4) (minus:QF (match_dup 5) (match_dup 4))) | |
4213 | (clobber (reg:CC_NOOV 21))]) | |
4214 | (parallel [(set (match_dup 3) (mult:QF (match_dup 3) (match_dup 4))) | |
4215 | (clobber (reg:CC_NOOV 21))]) | |
4216 | (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 3))) | |
4217 | (clobber (reg:CC_NOOV 21))]) | |
4218 | (parallel [(set (match_dup 4) (minus:QF (match_dup 5) (match_dup 4))) | |
4219 | (clobber (reg:CC_NOOV 21))]) | |
4220 | (parallel [(set (match_dup 3) (mult:QF (match_dup 3) (match_dup 4))) | |
4221 | (clobber (reg:CC_NOOV 21))]) | |
4222 | (parallel [(set (match_dup 3) | |
4223 | (mult:QF (match_operand:QF 1 "src_operand" "") | |
4224 | (match_dup 3))) | |
4225 | (clobber (reg:CC_NOOV 21))]) | |
4226 | (parallel [(set (match_operand:QF 0 "reg_operand" "") | |
f959ff1a | 4227 | (unspec:QF [(match_dup 3)] 6)) |
cb0ca284 | 4228 | (clobber (reg:CC_NOOV 21))])] |
4ddb3ea6 MH |
4229 | "! TARGET_C3X" |
4230 | "if (! reload_in_progress | |
4231 | && ! reg_operand (operands[2], QFmode)) | |
cb0ca284 MH |
4232 | operands[2] = force_reg (QFmode, operands[2]); |
4233 | operands[3] = gen_reg_rtx (QFmode); | |
4234 | operands[4] = gen_reg_rtx (QFmode); | |
4235 | operands[5] = CONST2_RTX (QFmode);") | |
4236 | ||
4237 | (define_expand "divqf3" | |
4238 | [(parallel [(set (match_operand:QF 0 "reg_operand" "") | |
4239 | (div:QF (match_operand:QF 1 "src_operand" "") | |
4240 | (match_operand:QF 2 "src_operand" ""))) | |
4241 | (clobber (reg:CC 21))])] | |
f42850b9 MH |
4242 | "! TARGET_C3X && TARGET_INLINE" |
4243 | "emit_insn (gen_divqf3_inline (operands[0], operands[1], operands[2])); | |
4244 | DONE;") | |
cb0ca284 MH |
4245 | |
4246 | ; | |
4247 | ; CONDITIONAL MOVES | |
4248 | ; | |
4249 | ||
57e5bce8 MH |
4250 | ; ??? We should make these pattern fail if the src operand combination |
4251 | ; is not valid. Although reload will fix things up, it will introduce | |
4252 | ; extra load instructions that won't be hoisted out of a loop. | |
4253 | ||
cb0ca284 MH |
4254 | (define_insn "*ldi_conditional" |
4255 | [(set (match_operand:QI 0 "reg_operand" "=r,r") | |
4256 | (if_then_else:QI (match_operator 1 "comparison_operator" | |
4257 | [(reg:CC 21) (const_int 0)]) | |
50c33087 MH |
4258 | (match_operand:QI 2 "src_operand" "rIm,0") |
4259 | (match_operand:QI 3 "src_operand" "0,rIm")))] | |
cb0ca284 MH |
4260 | "" |
4261 | "@ | |
4262 | ldi%1\\t%2,%0 | |
4263 | ldi%I1\\t%3,%0" | |
4264 | [(set_attr "type" "binary")]) | |
4265 | ||
4266 | (define_insn "*ldi_conditional_noov" | |
4267 | [(set (match_operand:QI 0 "reg_operand" "=r,r") | |
4268 | (if_then_else:QI (match_operator 1 "comparison_operator" | |
4269 | [(reg:CC_NOOV 21) (const_int 0)]) | |
50c33087 MH |
4270 | (match_operand:QI 2 "src_operand" "rIm,0") |
4271 | (match_operand:QI 3 "src_operand" "0,rIm")))] | |
959e0a76 MH |
4272 | "GET_CODE (operands[1]) != LE |
4273 | && GET_CODE (operands[1]) != GE | |
4274 | && GET_CODE (operands[1]) != LT | |
4275 | && GET_CODE (operands[1]) != GT" | |
cb0ca284 MH |
4276 | "@ |
4277 | ldi%1\\t%2,%0 | |
4278 | ldi%I1\\t%3,%0" | |
4279 | [(set_attr "type" "binary")]) | |
4280 | ||
b027470f MH |
4281 | (define_insn "*ldi_on_overflow" |
4282 | [(set (match_operand:QI 0 "reg_operand" "=r") | |
4283 | (unspec:QI [(match_operand:QI 1 "src_operand" "rIm")] 13)) | |
4284 | (use (reg:CC 21))] | |
4285 | "" | |
3b67042a | 4286 | "ldiv\\t%1,%0" |
52695ce0 | 4287 | [(set_attr "type" "unary")]) |
b027470f | 4288 | |
cb0ca284 MH |
4289 | ; Move operand 2 to operand 0 if condition (operand 1) is true |
4290 | ; else move operand 3 to operand 0. | |
4291 | ; The temporary register is required below because some of the operands | |
4292 | ; might be identical (namely 0 and 2). | |
4293 | ; | |
4294 | (define_expand "movqicc" | |
4295 | [(set (match_operand:QI 0 "reg_operand" "") | |
4296 | (if_then_else:QI (match_operand 1 "comparison_operator" "") | |
4297 | (match_operand:QI 2 "src_operand" "") | |
4298 | (match_operand:QI 3 "src_operand" "")))] | |
4299 | "" | |
4300 | "{ | |
4301 | enum rtx_code code = GET_CODE (operands[1]); | |
4302 | rtx ccreg = c4x_gen_compare_reg (code, c4x_compare_op0, c4x_compare_op1); | |
4303 | if (ccreg == NULL_RTX) FAIL; | |
d5e4ff48 MH |
4304 | emit_insn (gen_rtx_SET (QImode, operands[0], |
4305 | gen_rtx_IF_THEN_ELSE (QImode, | |
cb0ca284 MH |
4306 | gen_rtx (code, VOIDmode, ccreg, const0_rtx), |
4307 | operands[2], operands[3]))); | |
4308 | DONE;}") | |
4309 | ||
4310 | (define_insn "*ldf_conditional" | |
4311 | [(set (match_operand:QF 0 "reg_operand" "=f,f") | |
4312 | (if_then_else:QF (match_operator 1 "comparison_operator" | |
4313 | [(reg:CC 21) (const_int 0)]) | |
50c33087 MH |
4314 | (match_operand:QF 2 "src_operand" "fHm,0") |
4315 | (match_operand:QF 3 "src_operand" "0,fHm")))] | |
cb0ca284 MH |
4316 | "" |
4317 | "@ | |
4318 | ldf%1\\t%2,%0 | |
4319 | ldf%I1\\t%3,%0" | |
4320 | [(set_attr "type" "binary")]) | |
4321 | ||
4322 | (define_insn "*ldf_conditional_noov" | |
4323 | [(set (match_operand:QF 0 "reg_operand" "=f,f") | |
4324 | (if_then_else:QF (match_operator 1 "comparison_operator" | |
4325 | [(reg:CC_NOOV 21) (const_int 0)]) | |
50c33087 MH |
4326 | (match_operand:QF 2 "src_operand" "fHm,0") |
4327 | (match_operand:QF 3 "src_operand" "0,fHm")))] | |
959e0a76 MH |
4328 | "GET_CODE (operands[1]) != LE |
4329 | && GET_CODE (operands[1]) != GE | |
4330 | && GET_CODE (operands[1]) != LT | |
4331 | && GET_CODE (operands[1]) != GT" | |
cb0ca284 MH |
4332 | "@ |
4333 | ldf%1\\t%2,%0 | |
4334 | ldf%I1\\t%3,%0" | |
4335 | [(set_attr "type" "binary")]) | |
4336 | ||
4337 | (define_expand "movqfcc" | |
4338 | [(set (match_operand:QF 0 "reg_operand" "") | |
4339 | (if_then_else:QF (match_operand 1 "comparison_operator" "") | |
4340 | (match_operand:QF 2 "src_operand" "") | |
4341 | (match_operand:QF 3 "src_operand" "")))] | |
4342 | "" | |
4343 | "{ | |
4344 | enum rtx_code code = GET_CODE (operands[1]); | |
4345 | rtx ccreg = c4x_gen_compare_reg (code, c4x_compare_op0, c4x_compare_op1); | |
4346 | if (ccreg == NULL_RTX) FAIL; | |
d5e4ff48 MH |
4347 | emit_insn (gen_rtx_SET (QFmode, operands[0], |
4348 | gen_rtx_IF_THEN_ELSE (QFmode, | |
cb0ca284 MH |
4349 | gen_rtx (code, VOIDmode, ccreg, const0_rtx), |
4350 | operands[2], operands[3]))); | |
4351 | DONE;}") | |
4352 | ||
8a119a7d MH |
4353 | (define_insn "*ldhf_conditional" |
4354 | [(set (match_operand:HF 0 "reg_operand" "=h,h") | |
4355 | (if_then_else:HF (match_operator 1 "comparison_operator" | |
4356 | [(reg:CC 21) (const_int 0)]) | |
4357 | (match_operand:HF 2 "src_operand" "hH,0") | |
4358 | (match_operand:HF 3 "src_operand" "0,hH")))] | |
4359 | "" | |
4360 | "@ | |
4361 | ldf%1\\t%2,%0 | |
4362 | ldf%I1\\t%3,%0" | |
4363 | [(set_attr "type" "binary")]) | |
4364 | ||
4365 | (define_insn "*ldhf_conditional_noov" | |
4366 | [(set (match_operand:HF 0 "reg_operand" "=h,h") | |
4367 | (if_then_else:HF (match_operator 1 "comparison_operator" | |
4368 | [(reg:CC_NOOV 21) (const_int 0)]) | |
4369 | (match_operand:HF 2 "src_operand" "hH,0") | |
4370 | (match_operand:HF 3 "src_operand" "0,hH")))] | |
4371 | "GET_CODE (operands[1]) != LE | |
4372 | && GET_CODE (operands[1]) != GE | |
4373 | && GET_CODE (operands[1]) != LT | |
4374 | && GET_CODE (operands[1]) != GT" | |
4375 | "@ | |
4376 | ldf%1\\t%2,%0 | |
4377 | ldf%I1\\t%3,%0" | |
4378 | [(set_attr "type" "binary")]) | |
4379 | ||
4380 | (define_expand "movhfcc" | |
4381 | [(set (match_operand:HF 0 "reg_operand" "") | |
4382 | (if_then_else:HF (match_operand 1 "comparison_operator" "") | |
4383 | (match_operand:HF 2 "src_operand" "") | |
4384 | (match_operand:HF 3 "src_operand" "")))] | |
4385 | "" | |
4386 | "{ | |
4387 | enum rtx_code code = GET_CODE (operands[1]); | |
4388 | rtx ccreg = c4x_gen_compare_reg (code, c4x_compare_op0, c4x_compare_op1); | |
4389 | if (ccreg == NULL_RTX) FAIL; | |
4390 | emit_insn (gen_rtx_SET (HFmode, operands[0], | |
4391 | gen_rtx_IF_THEN_ELSE (HFmode, | |
4392 | gen_rtx (code, VOIDmode, ccreg, const0_rtx), | |
4393 | operands[2], operands[3]))); | |
4394 | DONE;}") | |
4395 | ||
cb0ca284 MH |
4396 | (define_expand "seq" |
4397 | [(set (match_operand:QI 0 "reg_operand" "") | |
4398 | (const_int 0)) | |
4399 | (set (match_dup 0) | |
4400 | (if_then_else:QI (eq (match_dup 1) (const_int 0)) | |
4401 | (const_int 1) | |
4402 | (match_dup 0)))] | |
4403 | "" | |
4404 | "operands[1] = c4x_gen_compare_reg (EQ, c4x_compare_op0, c4x_compare_op1);") | |
4405 | ||
4406 | (define_expand "sne" | |
4407 | [(set (match_operand:QI 0 "reg_operand" "") | |
4408 | (const_int 0)) | |
4409 | (set (match_dup 0) | |
4410 | (if_then_else:QI (ne (match_dup 1) (const_int 0)) | |
4411 | (const_int 1) | |
4412 | (match_dup 0)))] | |
4413 | "" | |
4414 | "operands[1] = c4x_gen_compare_reg (NE, c4x_compare_op0, c4x_compare_op1);") | |
4415 | ||
4416 | (define_expand "slt" | |
4417 | [(set (match_operand:QI 0 "reg_operand" "") | |
4418 | (const_int 0)) | |
4419 | (set (match_dup 0) | |
4420 | (if_then_else:QI (lt (match_dup 1) (const_int 0)) | |
4421 | (const_int 1) | |
4422 | (match_dup 0)))] | |
4423 | "" | |
4424 | "operands[1] = c4x_gen_compare_reg (LT, c4x_compare_op0, c4x_compare_op1); | |
4425 | if (operands[1] == NULL_RTX) FAIL;") | |
4426 | ||
4427 | (define_expand "sltu" | |
4428 | [(set (match_operand:QI 0 "reg_operand" "") | |
4429 | (const_int 0)) | |
4430 | (set (match_dup 0) | |
4431 | (if_then_else:QI (ltu (match_dup 1) (const_int 0)) | |
4432 | (const_int 1) | |
4433 | (match_dup 0)))] | |
4434 | "" | |
4435 | "operands[1] = c4x_gen_compare_reg (LTU, c4x_compare_op0, c4x_compare_op1);") | |
4436 | ||
4437 | (define_expand "sgt" | |
4438 | [(set (match_operand:QI 0 "reg_operand" "") | |
4439 | (const_int 0)) | |
4440 | (set (match_dup 0) | |
4441 | (if_then_else:QI (gt (match_dup 1) (const_int 0)) | |
4442 | (const_int 1) | |
4443 | (match_dup 0)))] | |
4444 | "" | |
4445 | "operands[1] = c4x_gen_compare_reg (GT, c4x_compare_op0, c4x_compare_op1); | |
4446 | if (operands[1] == NULL_RTX) FAIL;") | |
4447 | ||
4448 | (define_expand "sgtu" | |
4449 | [(set (match_operand:QI 0 "reg_operand" "") | |
4450 | (const_int 0)) | |
4451 | (set (match_dup 0) | |
4452 | (if_then_else:QI (gtu (match_dup 1) (const_int 0)) | |
4453 | (const_int 1) | |
4454 | (match_dup 0)))] | |
4455 | "" | |
4456 | "operands[1] = c4x_gen_compare_reg (GTU, c4x_compare_op0, c4x_compare_op1);") | |
4457 | ||
4458 | (define_expand "sle" | |
4459 | [(set (match_operand:QI 0 "reg_operand" "") | |
4460 | (const_int 0)) | |
4461 | (set (match_dup 0) | |
4462 | (if_then_else:QI (le (match_dup 1) (const_int 0)) | |
4463 | (const_int 1) | |
4464 | (match_dup 0)))] | |
4465 | "" | |
4466 | "operands[1] = c4x_gen_compare_reg (LE, c4x_compare_op0, c4x_compare_op1); | |
4467 | if (operands[1] == NULL_RTX) FAIL;") | |
4468 | ||
4469 | (define_expand "sleu" | |
4470 | [(set (match_operand:QI 0 "reg_operand" "") | |
4471 | (const_int 0)) | |
4472 | (set (match_dup 0) | |
4473 | (if_then_else:QI (leu (match_dup 1) (const_int 0)) | |
4474 | (const_int 1) | |
4475 | (match_dup 0)))] | |
4476 | "" | |
4477 | "operands[1] = c4x_gen_compare_reg (LEU, c4x_compare_op0, c4x_compare_op1);") | |
4478 | ||
4479 | (define_expand "sge" | |
4480 | [(set (match_operand:QI 0 "reg_operand" "") | |
4481 | (const_int 0)) | |
4482 | (set (match_dup 0) | |
4483 | (if_then_else:QI (ge (match_dup 1) (const_int 0)) | |
4484 | (const_int 1) | |
4485 | (match_dup 0)))] | |
4486 | "" | |
4487 | "operands[1] = c4x_gen_compare_reg (GE, c4x_compare_op0, c4x_compare_op1); | |
4488 | if (operands[1] == NULL_RTX) FAIL;") | |
4489 | ||
4490 | (define_expand "sgeu" | |
4491 | [(set (match_operand:QI 0 "reg_operand" "") | |
4492 | (const_int 0)) | |
4493 | (set (match_dup 0) | |
4494 | (if_then_else:QI (geu (match_dup 1) (const_int 0)) | |
4495 | (const_int 1) | |
4496 | (match_dup 0)))] | |
4497 | "" | |
4498 | "operands[1] = c4x_gen_compare_reg (GEU, c4x_compare_op0, c4x_compare_op1);") | |
4499 | ||
4500 | (define_split | |
4501 | [(set (match_operand:QI 0 "reg_operand" "") | |
f416f18c | 4502 | (match_operator:QI 1 "comparison_operator" [(reg:CC 21) (const_int 0)]))] |
cb0ca284 MH |
4503 | "reload_completed" |
4504 | [(set (match_dup 0) (const_int 0)) | |
4505 | (set (match_dup 0) | |
4506 | (if_then_else:QI (match_op_dup 1 [(reg:CC 21) (const_int 0)]) | |
4507 | (const_int 1) | |
4508 | (match_dup 0)))] | |
4509 | "") | |
4510 | ||
4511 | (define_split | |
4512 | [(set (match_operand:QI 0 "reg_operand" "") | |
f416f18c | 4513 | (match_operator:QI 1 "comparison_operator" [(reg:CC_NOOV 21) (const_int 0)]))] |
cb0ca284 MH |
4514 | "reload_completed" |
4515 | [(set (match_dup 0) (const_int 0)) | |
4516 | (set (match_dup 0) | |
4517 | (if_then_else:QI (match_op_dup 1 [(reg:CC_NOOV 21) (const_int 0)]) | |
4518 | (const_int 1) | |
4519 | (match_dup 0)))] | |
4520 | "") | |
4521 | ||
4522 | (define_insn "*bu" | |
4523 | [(set (pc) | |
4524 | (unspec [(match_operand:QI 0 "reg_operand" "r")] 1))] | |
4525 | "" | |
4526 | "bu%#\\t%0" | |
4527 | [(set_attr "type" "jump")]) | |
4528 | ||
4529 | (define_expand "caseqi" | |
4530 | [(parallel [(set (match_dup 5) | |
4531 | (minus:QI (match_operand:QI 0 "reg_operand" "") | |
4532 | (match_operand:QI 1 "src_operand" ""))) | |
4533 | (clobber (reg:CC_NOOV 21))]) | |
4534 | (set (reg:CC 21) | |
4535 | (compare:CC (match_dup 5) | |
4536 | (match_operand:QI 2 "src_operand" ""))) | |
4537 | (set (pc) | |
4538 | (if_then_else (gtu (reg:CC 21) | |
4539 | (const_int 0)) | |
4540 | (label_ref (match_operand 4 "" "")) | |
4541 | (pc))) | |
4542 | (parallel [(set (match_dup 6) | |
4543 | (plus:QI (match_dup 5) | |
4544 | (label_ref:QI (match_operand 3 "" "")))) | |
4545 | (clobber (reg:CC_NOOV 21))]) | |
4546 | (set (match_dup 7) | |
4547 | (mem:QI (match_dup 6))) | |
4548 | (set (pc) (match_dup 7))] | |
4549 | "" | |
4550 | "operands[5] = gen_reg_rtx (QImode); | |
4551 | operands[6] = gen_reg_rtx (QImode); | |
4552 | operands[7] = gen_reg_rtx (QImode);") | |
4553 | ||
4554 | ; | |
4555 | ; PARALLEL FLOAT INSTRUCTIONS | |
4556 | ; | |
4557 | ; This patterns are under development | |
4558 | ||
4559 | ; | |
4560 | ; ABSF/STF | |
4561 | ; | |
4562 | ||
4563 | (define_insn "*absqf2_movqf_clobber" | |
4564 | [(set (match_operand:QF 0 "ext_low_reg_operand" "=q") | |
4565 | (abs:QF (match_operand:QF 1 "par_ind_operand" "S<>"))) | |
4566 | (set (match_operand:QF 2 "par_ind_operand" "=S<>") | |
4567 | (match_operand:QF 3 "ext_low_reg_operand" "q")) | |
4568 | (clobber (reg:CC_NOOV 21))] | |
e868a840 | 4569 | "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)" |
cb0ca284 MH |
4570 | "absf\\t%1,%0\\n||\\tstf\\t%3,%2" |
4571 | [(set_attr "type" "binarycc")]) | |
4572 | ||
4573 | ; | |
4574 | ; ADDF/STF | |
4575 | ; | |
4576 | ||
4577 | (define_insn "*addqf3_movqf_clobber" | |
1f7c7f6f MH |
4578 | [(set (match_operand:QF 0 "ext_low_reg_operand" "=q,q") |
4579 | (plus:QF (match_operand:QF 1 "parallel_operand" "%q,S<>") | |
4580 | (match_operand:QF 2 "parallel_operand" "S<>,q"))) | |
4581 | (set (match_operand:QF 3 "par_ind_operand" "=S<>,S<>") | |
4582 | (match_operand:QF 4 "ext_low_reg_operand" "q,q")) | |
cb0ca284 MH |
4583 | (clobber (reg:CC 21))] |
4584 | "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QFmode)" | |
4585 | "addf3\\t%2,%1,%0\\n||\\tstf\\t%4,%3" | |
1f7c7f6f | 4586 | [(set_attr "type" "binarycc,binarycc")]) |
cb0ca284 MH |
4587 | |
4588 | ; | |
4589 | ; FLOAT/STF | |
4590 | ; | |
4591 | ||
e868a840 | 4592 | (define_insn "*floatqiqf2_movqf_clobber" |
cb0ca284 MH |
4593 | [(set (match_operand:QF 0 "ext_low_reg_operand" "=q") |
4594 | (float:QF (match_operand:QI 1 "par_ind_operand" "S<>"))) | |
4595 | (set (match_operand:QF 2 "par_ind_operand" "=S<>") | |
4596 | (match_operand:QF 3 "ext_low_reg_operand" "q")) | |
4597 | (clobber (reg:CC 21))] | |
e868a840 | 4598 | "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)" |
cb0ca284 MH |
4599 | "float\\t%1,%0\\n||\\tstf\\t%3,%2" |
4600 | [(set_attr "type" "binarycc")]) | |
4601 | ||
4602 | ; | |
4603 | ; MPYF/ADDF | |
4604 | ; | |
4605 | ||
4606 | (define_insn "*mulqf3_addqf3_clobber" | |
1f7c7f6f MH |
4607 | [(set (match_operand:QF 0 "r0r1_reg_operand" "=t,t,t,t") |
4608 | (mult:QF (match_operand:QF 1 "parallel_operand" "%S<>!V,q,S<>!V,q") | |
4609 | (match_operand:QF 2 "parallel_operand" "q,S<>!V,S<>!V,q"))) | |
4610 | (set (match_operand:QF 3 "r2r3_reg_operand" "=u,u,u,u") | |
4611 | (plus:QF (match_operand:QF 4 "parallel_operand" "%S<>!V,q,q,S<>!V") | |
4612 | (match_operand:QF 5 "parallel_operand" "q,S<>!V,q,S<>!V"))) | |
4613 | (clobber (reg:CC_NOOV 21))] | |
cb0ca284 MH |
4614 | "TARGET_PARALLEL_MPY && valid_parallel_operands_6 (operands, QFmode)" |
4615 | "mpyf3\\t%2,%1,%0\\n||\\taddf3\\t%5,%4,%3" | |
1f7c7f6f | 4616 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")]) |
cb0ca284 MH |
4617 | |
4618 | ||
4619 | ; | |
4620 | ; MPYF/STF | |
4621 | ; | |
4622 | ||
4623 | (define_insn "*mulqf3_movqf_clobber" | |
1f7c7f6f MH |
4624 | [(set (match_operand:QF 0 "ext_low_reg_operand" "=q,q") |
4625 | (mult:QF (match_operand:QF 1 "parallel_operand" "%q,S<>") | |
4626 | (match_operand:QF 2 "parallel_operand" "S<>,q"))) | |
4627 | (set (match_operand:QF 3 "par_ind_operand" "=S<>,S<>") | |
4628 | (match_operand:QF 4 "ext_low_reg_operand" "q,q")) | |
cb0ca284 MH |
4629 | (clobber (reg:CC 21))] |
4630 | "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QFmode)" | |
4631 | "mpyf3\\t%2,%1,%0\\n||\\tstf\\t%4,%3" | |
1f7c7f6f | 4632 | [(set_attr "type" "binarycc,binarycc")]) |
cb0ca284 MH |
4633 | |
4634 | ; | |
4635 | ; MPYF/SUBF | |
4636 | ; | |
4637 | ||
4638 | (define_insn "*mulqf3_subqf3_clobber" | |
1f7c7f6f MH |
4639 | [(set (match_operand:QF 0 "r0r1_reg_operand" "=t,t") |
4640 | (mult:QF (match_operand:QF 1 "parallel_operand" "S<>,q") | |
4641 | (match_operand:QF 2 "parallel_operand" "q,S<>"))) | |
4642 | (set (match_operand:QF 3 "r2r3_reg_operand" "=u,u") | |
4643 | (minus:QF (match_operand:QF 4 "parallel_operand" "S<>,q") | |
4644 | (match_operand:QF 5 "parallel_operand" "q,S<>"))) | |
cb0ca284 MH |
4645 | (clobber (reg:CC 21))] |
4646 | "TARGET_PARALLEL_MPY && valid_parallel_operands_6 (operands, QFmode)" | |
4647 | "mpyf3\\t%2,%1,%0\\n||\\tsubf3\\t%5,%4,%3" | |
1f7c7f6f | 4648 | [(set_attr "type" "binarycc,binarycc")]) |
cb0ca284 | 4649 | |
d8b173bb MH |
4650 | ; |
4651 | ; MPYF/LDF 0 | |
4652 | ; | |
4653 | ||
4654 | (define_insn "*mulqf3_clrqf_clobber" | |
4655 | [(set (match_operand:QF 0 "r0r1_reg_operand" "=t") | |
1f7c7f6f | 4656 | (mult:QF (match_operand:QF 1 "par_ind_operand" "%S<>") |
d8b173bb MH |
4657 | (match_operand:QF 2 "par_ind_operand" "S<>"))) |
4658 | (set (match_operand:QF 3 "r2r3_reg_operand" "=u") | |
4659 | (match_operand:QF 4 "fp_zero_operand" "G")) | |
4660 | (clobber (reg:CC 21))] | |
4661 | "TARGET_PARALLEL_MPY" | |
4662 | "mpyf3\\t%2,%1,%0\\n||\\tsubf3\\t%3,%3,%3" | |
4663 | [(set_attr "type" "binarycc")]) | |
4664 | ||
cb0ca284 MH |
4665 | ; |
4666 | ; NEGF/STF | |
4667 | ; | |
4668 | ||
4669 | (define_insn "*negqf2_movqf_clobber" | |
4670 | [(set (match_operand:QF 0 "ext_low_reg_operand" "=q") | |
4671 | (neg:QF (match_operand:QF 1 "par_ind_operand" "S<>"))) | |
4672 | (set (match_operand:QF 2 "par_ind_operand" "=S<>") | |
4673 | (match_operand:QF 3 "ext_low_reg_operand" "q")) | |
4674 | (clobber (reg:CC 21))] | |
e868a840 | 4675 | "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)" |
cb0ca284 MH |
4676 | "negf\\t%1,%0\\n||\\tstf\\t%3,%2" |
4677 | [(set_attr "type" "binarycc")]) | |
4678 | ||
4679 | ; | |
4680 | ; SUBF/STF | |
4681 | ; | |
4682 | ||
4683 | (define_insn "*subqf3_movqf_clobber" | |
4684 | [(set (match_operand:QF 0 "ext_low_reg_operand" "=q") | |
4685 | (minus:QF (match_operand:QF 1 "ext_low_reg_operand" "q") | |
e868a840 | 4686 | (match_operand:QF 2 "par_ind_operand" "S<>"))) |
cb0ca284 MH |
4687 | (set (match_operand:QF 3 "par_ind_operand" "=S<>") |
4688 | (match_operand:QF 4 "ext_low_reg_operand" "q")) | |
4689 | (clobber (reg:CC 21))] | |
e868a840 | 4690 | "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QFmode)" |
cb0ca284 MH |
4691 | "subf3\\t%2,%1,%0\\n||\\tstf\\t%4,%3" |
4692 | [(set_attr "type" "binarycc")]) | |
4693 | ||
8a119a7d MH |
4694 | ; |
4695 | ; TOIEEE/STF | |
4696 | ; | |
4697 | ||
4698 | (define_insn "*toieee_movqf_clobber" | |
4699 | [(set (match_operand:QF 0 "ext_low_reg_operand" "=q") | |
4700 | (unspec:QF [(match_operand:QF 1 "par_ind_operand" "S<>")] 23)) | |
4701 | (set (match_operand:QF 2 "par_ind_operand" "=S<>") | |
4702 | (match_operand:QF 3 "ext_low_reg_operand" "q")) | |
4703 | (clobber (reg:CC 21))] | |
4704 | "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)" | |
4705 | "toieee\\t%1,%0\\n||\\tstf\\t%3,%2" | |
4706 | [(set_attr "type" "binarycc")]) | |
4707 | ||
4708 | ; | |
4709 | ; FRIEEE/STF | |
4710 | ; | |
4711 | ||
4712 | (define_insn "*frieee_movqf_clobber" | |
4713 | [(set (match_operand:QF 0 "ext_low_reg_operand" "=q") | |
4714 | (unspec:QF [(match_operand:QF 1 "par_ind_operand" "S<>")] 24)) | |
4715 | (set (match_operand:QF 2 "par_ind_operand" "=S<>") | |
4716 | (match_operand:QF 3 "ext_low_reg_operand" "q")) | |
4717 | (clobber (reg:CC 21))] | |
4718 | "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)" | |
4719 | "frieee\\t%1,%0\\n||\\tstf\\t%3,%2" | |
4720 | [(set_attr "type" "binarycc")]) | |
4721 | ||
cb0ca284 MH |
4722 | ; |
4723 | ; PARALLEL INTEGER INSTRUCTIONS | |
4724 | ; | |
cb0ca284 MH |
4725 | |
4726 | ; | |
4727 | ; ABSI/STI | |
4728 | ; | |
4729 | ||
4730 | (define_insn "*absqi2_movqi_clobber" | |
4731 | [(set (match_operand:QI 0 "ext_low_reg_operand" "=q") | |
4732 | (abs:QI (match_operand:QI 1 "par_ind_operand" "S<>"))) | |
4733 | (set (match_operand:QI 2 "par_ind_operand" "=S<>") | |
4734 | (match_operand:QI 3 "ext_low_reg_operand" "q")) | |
4735 | (clobber (reg:CC_NOOV 21))] | |
e868a840 | 4736 | "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QImode)" |
cb0ca284 MH |
4737 | "absi\\t%1,%0\\n||\\tsti\\t%3,%2" |
4738 | [(set_attr "type" "binarycc")]) | |
4739 | ||
4740 | ; | |
4741 | ; ADDI/STI | |
4742 | ; | |
4743 | ||
4744 | (define_insn "*addqi3_movqi_clobber" | |
1f7c7f6f MH |
4745 | [(set (match_operand:QI 0 "ext_low_reg_operand" "=q,q") |
4746 | (plus:QI (match_operand:QI 1 "parallel_operand" "%q,S<>") | |
4747 | (match_operand:QI 2 "parallel_operand" "S<>,q"))) | |
4748 | (set (match_operand:QI 3 "par_ind_operand" "=S<>,S<>") | |
4749 | (match_operand:QI 4 "ext_low_reg_operand" "q,q")) | |
cb0ca284 MH |
4750 | (clobber (reg:CC 21))] |
4751 | "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)" | |
4752 | "addi3\\t%2,%1,%0\\n||\\tsti\\t%4,%3" | |
1f7c7f6f | 4753 | [(set_attr "type" "binarycc,binarycc")]) |
cb0ca284 MH |
4754 | |
4755 | ; | |
4756 | ; AND/STI | |
4757 | ; | |
4758 | ||
4759 | (define_insn "*andqi3_movqi_clobber" | |
1f7c7f6f MH |
4760 | [(set (match_operand:QI 0 "ext_low_reg_operand" "=q,q") |
4761 | (and:QI (match_operand:QI 1 "parallel_operand" "%q,S<>") | |
4762 | (match_operand:QI 2 "parallel_operand" "S<>,q"))) | |
4763 | (set (match_operand:QI 3 "par_ind_operand" "=S<>,S<>") | |
4764 | (match_operand:QI 4 "ext_low_reg_operand" "q,q")) | |
cb0ca284 MH |
4765 | (clobber (reg:CC 21))] |
4766 | "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)" | |
4767 | "and3\\t%2,%1,%0\\n||\\tsti\\t%4,%3" | |
1f7c7f6f | 4768 | [(set_attr "type" "binarycc,binarycc")]) |
cb0ca284 MH |
4769 | |
4770 | ; | |
4771 | ; ASH(left)/STI | |
4772 | ; | |
4773 | ||
4774 | (define_insn "*ashlqi3_movqi_clobber" | |
4775 | [(set (match_operand:QI 0 "ext_low_reg_operand" "=q") | |
4776 | (ashift:QI (match_operand:QI 1 "par_ind_operand" "S<>") | |
4777 | (match_operand:QI 2 "ext_low_reg_operand" "q"))) | |
4778 | (set (match_operand:QI 3 "par_ind_operand" "=S<>") | |
4779 | (match_operand:QI 4 "ext_low_reg_operand" "q")) | |
4780 | (clobber (reg:CC 21))] | |
e868a840 | 4781 | "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)" |
cb0ca284 MH |
4782 | "ash3\\t%2,%1,%0\\n||\\tsti\\t%4,%3" |
4783 | [(set_attr "type" "binarycc")]) | |
4784 | ||
4785 | ; | |
4786 | ; ASH(right)/STI | |
4787 | ; | |
4788 | ||
e868a840 | 4789 | (define_insn "*ashrqi3_movqi_clobber" |
cb0ca284 MH |
4790 | [(set (match_operand:QI 0 "ext_low_reg_operand" "=q") |
4791 | (ashiftrt:QI (match_operand:QI 1 "par_ind_operand" "S<>") | |
4792 | (neg:QI (match_operand:QI 2 "ext_low_reg_operand" "q")))) | |
4793 | (set (match_operand:QI 3 "par_ind_operand" "=S<>") | |
4794 | (match_operand:QI 4 "ext_low_reg_operand" "q")) | |
4795 | (clobber (reg:CC 21))] | |
e868a840 | 4796 | "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)" |
cb0ca284 MH |
4797 | "ash3\\t%2,%1,%0\\n||\\tsti\\t%4,%3" |
4798 | [(set_attr "type" "binarycc")]) | |
4799 | ||
4800 | ; | |
4801 | ; FIX/STI | |
4802 | ; | |
4803 | ||
4804 | (define_insn "*fixqfqi2_movqi_clobber" | |
4805 | [(set (match_operand:QI 0 "ext_low_reg_operand" "=q") | |
4806 | (fix:QI (match_operand:QF 1 "par_ind_operand" "S<>"))) | |
4807 | (set (match_operand:QI 2 "par_ind_operand" "=S<>") | |
4808 | (match_operand:QI 3 "ext_low_reg_operand" "q")) | |
4809 | (clobber (reg:CC 21))] | |
e868a840 | 4810 | "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QImode)" |
cb0ca284 MH |
4811 | "fix\\t%1,%0\\n||\\tsti\\t%3,%2" |
4812 | [(set_attr "type" "binarycc")]) | |
4813 | ||
4814 | ; | |
4815 | ; LSH(right)/STI | |
4816 | ; | |
4817 | ||
4818 | (define_insn "*lshrqi3_movqi_clobber" | |
4819 | [(set (match_operand:QI 0 "ext_low_reg_operand" "=q") | |
4820 | (lshiftrt:QI (match_operand:QI 1 "par_ind_operand" "S<>") | |
4821 | (neg:QI (match_operand:QI 2 "ext_low_reg_operand" "q")))) | |
4822 | (set (match_operand:QI 3 "par_ind_operand" "=S<>") | |
4823 | (match_operand:QI 4 "ext_low_reg_operand" "q")) | |
4824 | (clobber (reg:CC 21))] | |
e868a840 | 4825 | "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)" |
cb0ca284 MH |
4826 | "lsh3\\t%2,%1,%0\\n||\\tsti\\t%4,%3" |
4827 | [(set_attr "type" "binarycc")]) | |
4828 | ||
4829 | ; | |
4830 | ; MPYI/ADDI | |
4831 | ; | |
4832 | ||
4833 | (define_insn "*mulqi3_addqi3_clobber" | |
1f7c7f6f MH |
4834 | [(set (match_operand:QI 0 "r0r1_reg_operand" "=t,t,t,t") |
4835 | (mult:QI (match_operand:QI 1 "parallel_operand" "%S<>!V,q,S<>!V,q") | |
4836 | (match_operand:QI 2 "parallel_operand" "q,S<>!V,S<>!V,q"))) | |
4837 | (set (match_operand:QI 3 "r2r3_reg_operand" "=u,u,u,u") | |
4838 | (plus:QI (match_operand:QI 4 "parallel_operand" "%S<>!V,q,q,S<>!V") | |
4839 | (match_operand:QI 5 "parallel_operand" "q,S<>!V,q,S<>!V"))) | |
cb0ca284 MH |
4840 | (clobber (reg:CC 21))] |
4841 | "TARGET_PARALLEL_MPY && TARGET_MPYI | |
4842 | && valid_parallel_operands_6 (operands, QImode)" | |
4843 | "mpyi3\\t%2,%1,%0\\n||\\taddi3\\t%5,%4,%3" | |
1f7c7f6f | 4844 | [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")]) |
cb0ca284 | 4845 | |
d8b173bb | 4846 | |
cb0ca284 MH |
4847 | ; |
4848 | ; MPYI/STI | |
4849 | ; | |
4850 | ||
4851 | (define_insn "*mulqi3_movqi_clobber" | |
1f7c7f6f MH |
4852 | [(set (match_operand:QI 0 "ext_low_reg_operand" "=q,q") |
4853 | (mult:QI (match_operand:QI 1 "parallel_operand" "%q,S<>") | |
4854 | (match_operand:QI 2 "parallel_operand" "S<>,q"))) | |
4855 | (set (match_operand:QI 3 "par_ind_operand" "=S<>,S<>") | |
4856 | (match_operand:QI 4 "ext_low_reg_operand" "q,q")) | |
cb0ca284 MH |
4857 | (clobber (reg:CC 21))] |
4858 | "TARGET_PARALLEL && TARGET_MPYI | |
4859 | && valid_parallel_operands_5 (operands, QImode)" | |
4860 | "mpyi3\\t%2,%1,%0\\n||\\tsti\\t%4,%3" | |
1f7c7f6f | 4861 | [(set_attr "type" "binarycc,binarycc")]) |
cb0ca284 MH |
4862 | |
4863 | ; | |
4864 | ; MPYI/SUBI | |
4865 | ; | |
4866 | ||
4867 | (define_insn "*mulqi3_subqi3_clobber" | |
1f7c7f6f MH |
4868 | [(set (match_operand:QI 0 "r0r1_reg_operand" "=t,t") |
4869 | (mult:QI (match_operand:QI 1 "parallel_operand" "S<>,q") | |
4870 | (match_operand:QI 2 "parallel_operand" "q,S<>"))) | |
4871 | (set (match_operand:QI 3 "r2r3_reg_operand" "=u,u") | |
4872 | (minus:QI (match_operand:QI 4 "parallel_operand" "S<>,q") | |
4873 | (match_operand:QI 5 "parallel_operand" "q,S<>"))) | |
cb0ca284 MH |
4874 | (clobber (reg:CC 21))] |
4875 | "TARGET_PARALLEL_MPY && TARGET_MPYI | |
4876 | && valid_parallel_operands_6 (operands, QImode)" | |
4877 | "mpyi3\\t%2,%1,%0\\n||\\tsubi3\\t%5,%4,%3" | |
1f7c7f6f | 4878 | [(set_attr "type" "binarycc,binarycc")]) |
cb0ca284 | 4879 | |
d8b173bb MH |
4880 | ; |
4881 | ; MPYI/LDI 0 | |
4882 | ; | |
4883 | ||
4884 | (define_insn "*mulqi3_clrqi_clobber" | |
4885 | [(set (match_operand:QI 0 "r0r1_reg_operand" "=t") | |
1f7c7f6f | 4886 | (mult:QI (match_operand:QI 1 "par_ind_operand" "%S<>") |
d8b173bb MH |
4887 | (match_operand:QI 2 "par_ind_operand" "S<>"))) |
4888 | (set (match_operand:QI 3 "r2r3_reg_operand" "=u") | |
4889 | (const_int 0)) | |
4890 | (clobber (reg:CC 21))] | |
4891 | "TARGET_PARALLEL_MPY && TARGET_MPYI" | |
4892 | "mpyi3\\t%2,%1,%0\\n||\\tsubi3\\t%3,%3,%3" | |
4893 | [(set_attr "type" "binarycc")]) | |
4894 | ||
cb0ca284 MH |
4895 | ; |
4896 | ; NEGI/STI | |
4897 | ; | |
4898 | ||
4899 | (define_insn "*negqi2_movqi_clobber" | |
4900 | [(set (match_operand:QI 0 "ext_low_reg_operand" "=q") | |
4901 | (neg:QI (match_operand:QI 1 "par_ind_operand" "S<>"))) | |
4902 | (set (match_operand:QI 2 "par_ind_operand" "=S<>") | |
4903 | (match_operand:QI 3 "ext_low_reg_operand" "q")) | |
4904 | (clobber (reg:CC 21))] | |
e868a840 | 4905 | "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QImode)" |
cb0ca284 MH |
4906 | "negi\\t%1,%0\\n||\\tsti\\t%3,%2" |
4907 | [(set_attr "type" "binarycc")]) | |
4908 | ||
4909 | ; | |
4910 | ; NOT/STI | |
4911 | ; | |
4912 | ||
4913 | (define_insn "*notqi2_movqi_clobber" | |
4914 | [(set (match_operand:QI 0 "ext_low_reg_operand" "=q") | |
4915 | (not:QI (match_operand:QI 1 "par_ind_operand" "S<>"))) | |
4916 | (set (match_operand:QI 2 "par_ind_operand" "=S<>") | |
4917 | (match_operand:QI 3 "ext_low_reg_operand" "q")) | |
4918 | (clobber (reg:CC 21))] | |
e868a840 | 4919 | "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QImode)" |
cb0ca284 MH |
4920 | "not\\t%1,%0\\n||\\tsti\\t%3,%2" |
4921 | [(set_attr "type" "binarycc")]) | |
4922 | ||
4923 | ; | |
4924 | ; OR/STI | |
4925 | ; | |
4926 | ||
4927 | (define_insn "*iorqi3_movqi_clobber" | |
1f7c7f6f MH |
4928 | [(set (match_operand:QI 0 "ext_low_reg_operand" "=q,q") |
4929 | (ior:QI (match_operand:QI 1 "parallel_operand" "%q,S<>") | |
4930 | (match_operand:QI 2 "parallel_operand" "S<>,q"))) | |
4931 | (set (match_operand:QI 3 "par_ind_operand" "=S<>,S<>") | |
4932 | (match_operand:QI 4 "ext_low_reg_operand" "q,q")) | |
cb0ca284 MH |
4933 | (clobber (reg:CC 21))] |
4934 | "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)" | |
4935 | "or3\\t%2,%1,%0\\n||\\tsti\\t%4,%3" | |
1f7c7f6f | 4936 | [(set_attr "type" "binarycc,binarycc")]) |
cb0ca284 MH |
4937 | |
4938 | ; | |
4939 | ; SUBI/STI | |
4940 | ; | |
4941 | ||
4942 | (define_insn "*subqi3_movqi_clobber" | |
4943 | [(set (match_operand:QI 0 "ext_low_reg_operand" "=q") | |
1f7c7f6f MH |
4944 | (minus:QI (match_operand:QI 1 "par_ind_operand" "S<>") |
4945 | (match_operand:QI 2 "ext_low_reg_operand" "q"))) | |
cb0ca284 MH |
4946 | (set (match_operand:QI 3 "par_ind_operand" "=S<>") |
4947 | (match_operand:QI 4 "ext_low_reg_operand" "q")) | |
4948 | (clobber (reg:CC 21))] | |
e868a840 | 4949 | "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)" |
cb0ca284 MH |
4950 | "subi3\\t%2,%1,%0\\n||\\tsti\\t%4,%3" |
4951 | [(set_attr "type" "binarycc")]) | |
4952 | ||
4953 | ; | |
4954 | ; XOR/STI | |
4955 | ; | |
4956 | ||
4957 | (define_insn "*xorqi3_movqi_clobber" | |
1f7c7f6f MH |
4958 | [(set (match_operand:QI 0 "ext_low_reg_operand" "=q,q") |
4959 | (xor:QI (match_operand:QI 1 "parallel_operand" "%q,S<>") | |
4960 | (match_operand:QI 2 "parallel_operand" "S<>,q"))) | |
4961 | (set (match_operand:QI 3 "par_ind_operand" "=S<>,S<>") | |
4962 | (match_operand:QI 4 "ext_low_reg_operand" "q,q")) | |
cb0ca284 MH |
4963 | (clobber (reg:CC 21))] |
4964 | "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)" | |
4965 | "xor3\\t%2,%1,%0\\n||\\tsti\\t%4,%3" | |
1f7c7f6f | 4966 | [(set_attr "type" "binarycc,binarycc")]) |
cb0ca284 MH |
4967 | |
4968 | ; | |
4969 | ; BRANCH/CALL INSTRUCTIONS | |
4970 | ; | |
4971 | ||
4972 | ; | |
4973 | ; Branch instructions | |
4974 | ; | |
4975 | (define_insn "*b" | |
4976 | [(set (pc) (if_then_else (match_operator 0 "comparison_operator" | |
4977 | [(reg:CC 21) (const_int 0)]) | |
4978 | (label_ref (match_operand 1 "" "")) | |
4979 | (pc)))] | |
4980 | "" | |
4981 | "* | |
959e0a76 | 4982 | return c4x_output_cbranch (\"b%0\", insn);" |
cb0ca284 MH |
4983 | [(set_attr "type" "jmpc")]) |
4984 | ||
4985 | (define_insn "*b_rev" | |
4986 | [(set (pc) (if_then_else (match_operator 0 "comparison_operator" | |
4987 | [(reg:CC 21) (const_int 0)]) | |
4988 | (pc) | |
4989 | (label_ref (match_operand 1 "" ""))))] | |
4990 | "" | |
4991 | "* | |
959e0a76 | 4992 | return c4x_output_cbranch (\"b%I0\", insn);" |
cb0ca284 MH |
4993 | [(set_attr "type" "jmpc")]) |
4994 | ||
4995 | (define_insn "*b_noov" | |
4996 | [(set (pc) (if_then_else (match_operator 0 "comparison_operator" | |
4997 | [(reg:CC_NOOV 21) (const_int 0)]) | |
4998 | (label_ref (match_operand 1 "" "")) | |
4999 | (pc)))] | |
959e0a76 MH |
5000 | "GET_CODE (operands[0]) != LE |
5001 | && GET_CODE (operands[0]) != GE | |
5002 | && GET_CODE (operands[0]) != LT | |
5003 | && GET_CODE (operands[0]) != GT" | |
cb0ca284 | 5004 | "* |
959e0a76 | 5005 | return c4x_output_cbranch (\"b%0\", insn);" |
cb0ca284 MH |
5006 | [(set_attr "type" "jmpc")]) |
5007 | ||
5008 | (define_insn "*b_noov_rev" | |
5009 | [(set (pc) (if_then_else (match_operator 0 "comparison_operator" | |
5010 | [(reg:CC_NOOV 21) (const_int 0)]) | |
5011 | (pc) | |
5012 | (label_ref (match_operand 1 "" ""))))] | |
959e0a76 MH |
5013 | "GET_CODE (operands[0]) != LE |
5014 | && GET_CODE (operands[0]) != GE | |
5015 | && GET_CODE (operands[0]) != LT | |
5016 | && GET_CODE (operands[0]) != GT" | |
cb0ca284 | 5017 | "* |
959e0a76 | 5018 | return c4x_output_cbranch (\"b%I0\", insn);" |
cb0ca284 MH |
5019 | [(set_attr "type" "jmpc")]) |
5020 | ||
5021 | (define_expand "beq" | |
5022 | [(set (pc) (if_then_else (eq (match_dup 1) (const_int 0)) | |
5023 | (label_ref (match_operand 0 "" "")) | |
5024 | (pc)))] | |
5025 | "" | |
5026 | "operands[1] = c4x_gen_compare_reg (EQ, c4x_compare_op0, c4x_compare_op1);") | |
5027 | ||
5028 | (define_expand "bne" | |
5029 | [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) | |
5030 | (label_ref (match_operand 0 "" "")) | |
5031 | (pc)))] | |
5032 | "" | |
5033 | "operands[1] = c4x_gen_compare_reg (NE, c4x_compare_op0, c4x_compare_op1);") | |
5034 | ||
5035 | (define_expand "blt" | |
5036 | [(set (pc) (if_then_else (lt (match_dup 1) (const_int 0)) | |
5037 | (label_ref (match_operand 0 "" "")) | |
5038 | (pc)))] | |
5039 | "" | |
5040 | "operands[1] = c4x_gen_compare_reg (LT, c4x_compare_op0, c4x_compare_op1); | |
5041 | if (operands[1] == NULL_RTX) FAIL;") | |
5042 | ||
5043 | (define_expand "bltu" | |
5044 | [(set (pc) (if_then_else (ltu (match_dup 1) (const_int 0)) | |
5045 | (label_ref (match_operand 0 "" "")) | |
5046 | (pc)))] | |
5047 | "" | |
5048 | "operands[1] = c4x_gen_compare_reg (LTU, c4x_compare_op0, c4x_compare_op1);") | |
5049 | ||
5050 | (define_expand "bgt" | |
5051 | [(set (pc) (if_then_else (gt (match_dup 1) (const_int 0)) | |
5052 | (label_ref (match_operand 0 "" "")) | |
5053 | (pc)))] | |
5054 | "" | |
5055 | "operands[1] = c4x_gen_compare_reg (GT, c4x_compare_op0, c4x_compare_op1); | |
5056 | if (operands[1] == NULL_RTX) FAIL;") | |
5057 | ||
5058 | (define_expand "bgtu" | |
5059 | [(set (pc) (if_then_else (gtu (match_dup 1) (const_int 0)) | |
5060 | (label_ref (match_operand 0 "" "")) | |
5061 | (pc)))] | |
5062 | "" | |
5063 | "operands[1] = c4x_gen_compare_reg (GTU, c4x_compare_op0, c4x_compare_op1);") | |
5064 | ||
5065 | (define_expand "ble" | |
5066 | [(set (pc) (if_then_else (le (match_dup 1) (const_int 0)) | |
5067 | (label_ref (match_operand 0 "" "")) | |
5068 | (pc)))] | |
5069 | "" | |
5070 | "operands[1] = c4x_gen_compare_reg (LE, c4x_compare_op0, c4x_compare_op1); | |
5071 | if (operands[1] == NULL_RTX) FAIL;") | |
5072 | ||
5073 | (define_expand "bleu" | |
5074 | [(set (pc) (if_then_else (leu (match_dup 1) (const_int 0)) | |
5075 | (label_ref (match_operand 0 "" "")) | |
5076 | (pc)))] | |
5077 | "" | |
5078 | "operands[1] = c4x_gen_compare_reg (LEU, c4x_compare_op0, c4x_compare_op1);") | |
5079 | ||
5080 | (define_expand "bge" | |
5081 | [(set (pc) (if_then_else (ge (match_dup 1) (const_int 0)) | |
5082 | (label_ref (match_operand 0 "" "")) | |
5083 | (pc)))] | |
5084 | "" | |
5085 | "operands[1] = c4x_gen_compare_reg (GE, c4x_compare_op0, c4x_compare_op1); | |
5086 | if (operands[1] == NULL_RTX) FAIL;") | |
5087 | ||
5088 | (define_expand "bgeu" | |
5089 | [(set (pc) (if_then_else (geu (match_dup 1) (const_int 0)) | |
5090 | (label_ref (match_operand 0 "" "")) | |
5091 | (pc)))] | |
5092 | "" | |
5093 | "operands[1] = c4x_gen_compare_reg (GEU, c4x_compare_op0, c4x_compare_op1);") | |
5094 | ||
5095 | (define_insn "*b_reg" | |
5096 | [(set (pc) (match_operand:QI 0 "reg_operand" "r"))] | |
5097 | "" | |
5098 | "bu%#\\t%0" | |
5099 | [(set_attr "type" "jump")]) | |
5100 | ||
5101 | (define_expand "indirect_jump" | |
5102 | [(set (pc) (match_operand:QI 0 "reg_operand" ""))] | |
5103 | "" | |
5104 | "") | |
5105 | ||
5106 | (define_insn "tablejump" | |
5107 | [(set (pc) (match_operand:QI 0 "src_operand" "r")) | |
5108 | (use (label_ref (match_operand 1 "" "")))] | |
5109 | "" | |
5110 | "bu%#\\t%0" | |
5111 | [(set_attr "type" "jump")]) | |
5112 | ||
5113 | ; | |
5114 | ; CALL | |
5115 | ; | |
5116 | (define_insn "*call_c3x" | |
b2e9a2fd | 5117 | [(call (mem:QI (match_operand:QI 0 "call_address_operand" "Ur")) |
cb0ca284 MH |
5118 | (match_operand:QI 1 "general_operand" "")) |
5119 | (clobber (reg:QI 31))] | |
5120 | ;; Operand 1 not really used on the C4x. The C30 doesn't have reg 31. | |
5121 | ||
5122 | "TARGET_C3X" | |
50c33087 MH |
5123 | "call%U0\\t%C0" |
5124 | [(set_attr "type" "call")]) | |
cb0ca284 MH |
5125 | |
5126 | ; LAJ requires R11 (31) for the return address | |
5127 | (define_insn "*laj" | |
b2e9a2fd | 5128 | [(call (mem:QI (match_operand:QI 0 "call_address_operand" "Ur")) |
cb0ca284 MH |
5129 | (match_operand:QI 1 "general_operand" "")) |
5130 | (clobber (reg:QI 31))] | |
5131 | ;; Operand 1 not really used on the C4x. | |
5132 | ||
4ddb3ea6 | 5133 | "! TARGET_C3X" |
cb0ca284 | 5134 | "* |
50c33087 | 5135 | if (final_sequence) |
5078f5eb HB |
5136 | return c4x_check_laj_p (insn) |
5137 | ? \"nop\\n\\tlaj%U0\\t%C0\" : \"laj%U0\\t%C0\"; | |
d5e4ff48 | 5138 | else |
50c33087 MH |
5139 | return \"call%U0\\t%C0\";" |
5140 | [(set_attr "type" "laj")]) | |
cb0ca284 MH |
5141 | |
5142 | (define_expand "call" | |
b2e9a2fd | 5143 | [(parallel [(call (match_operand:QI 0 "" "") |
cb0ca284 MH |
5144 | (match_operand:QI 1 "general_operand" "")) |
5145 | (clobber (reg:QI 31))])] | |
5146 | "" | |
b2e9a2fd MH |
5147 | " |
5148 | { | |
5149 | if (GET_CODE (operands[0]) == MEM | |
5150 | && ! call_address_operand (XEXP (operands[0], 0), Pmode)) | |
5151 | operands[0] = gen_rtx_MEM (GET_MODE (operands[0]), | |
5152 | force_reg (Pmode, XEXP (operands[0], 0))); | |
5153 | }") | |
cb0ca284 | 5154 | |
52695ce0 HB |
5155 | (define_insn "nodb_call" |
5156 | [(call (mem:QI (match_operand:QI 0 "call_address_operand" "Ur")) | |
5157 | (const_int 0))] | |
5158 | "" | |
5159 | "call%U0\\t%C0" | |
5160 | [(set_attr "type" "call")]) | |
5161 | ||
cb0ca284 | 5162 | (define_insn "*callv_c3x" |
50c33087 | 5163 | [(set (match_operand 0 "" "=r") |
b2e9a2fd | 5164 | (call (mem:QI (match_operand:QI 1 "call_address_operand" "Ur")) |
cb0ca284 MH |
5165 | (match_operand:QI 2 "general_operand" ""))) |
5166 | (clobber (reg:QI 31))] | |
5167 | ;; Operand 0 and 2 not really used for the C4x. | |
5168 | ;; The C30 doesn't have reg 31. | |
5169 | ||
5170 | "TARGET_C3X" | |
50c33087 MH |
5171 | "call%U1\\t%C1" |
5172 | [(set_attr "type" "call")]) | |
cb0ca284 MH |
5173 | |
5174 | ; LAJ requires R11 (31) for the return address | |
5175 | (define_insn "*lajv" | |
50c33087 | 5176 | [(set (match_operand 0 "" "=r") |
b2e9a2fd | 5177 | (call (mem:QI (match_operand:QI 1 "call_address_operand" "Ur")) |
cb0ca284 MH |
5178 | (match_operand:QI 2 "general_operand" ""))) |
5179 | (clobber (reg:QI 31))] | |
5180 | ;; Operand 0 and 2 not really used in the C30 instruction. | |
5181 | ||
4ddb3ea6 | 5182 | "! TARGET_C3X" |
cb0ca284 | 5183 | "* |
50c33087 | 5184 | if (final_sequence) |
5078f5eb HB |
5185 | return c4x_check_laj_p (insn) |
5186 | ? \"nop\\n\\tlaj%U1\\t%C1\" : \"laj%U1\\t%C1\"; | |
d5e4ff48 | 5187 | else |
50c33087 MH |
5188 | return \"call%U1\\t%C1\";" |
5189 | [(set_attr "type" "laj")]) | |
cb0ca284 MH |
5190 | |
5191 | (define_expand "call_value" | |
5192 | [(parallel [(set (match_operand 0 "" "") | |
b2e9a2fd | 5193 | (call (match_operand:QI 1 "" "") |
cb0ca284 MH |
5194 | (match_operand:QI 2 "general_operand" ""))) |
5195 | (clobber (reg:QI 31))])] | |
5196 | "" | |
b2e9a2fd MH |
5197 | " |
5198 | { | |
5199 | if (GET_CODE (operands[0]) == MEM | |
5200 | && ! call_address_operand (XEXP (operands[1], 0), Pmode)) | |
5201 | operands[0] = gen_rtx_MEM (GET_MODE (operands[1]), | |
5202 | force_reg (Pmode, XEXP (operands[1], 0))); | |
5203 | }") | |
cb0ca284 MH |
5204 | |
5205 | (define_insn "return" | |
5206 | [(return)] | |
5207 | "c4x_null_epilogue_p ()" | |
5208 | "rets" | |
5209 | [(set_attr "type" "rets")]) | |
5210 | ||
52695ce0 HB |
5211 | (define_insn "return_from_epilogue" |
5212 | [(return)] | |
5213 | "reload_completed && ! c4x_interrupt_function_p ()" | |
5214 | "rets" | |
5215 | [(set_attr "type" "rets")]) | |
5216 | ||
5217 | (define_insn "return_from_interrupt_epilogue" | |
5218 | [(return)] | |
5219 | "reload_completed && c4x_interrupt_function_p ()" | |
5220 | "reti" | |
5221 | [(set_attr "type" "rets")]) | |
5222 | ||
cb0ca284 MH |
5223 | (define_insn "*return_cc" |
5224 | [(set (pc) | |
5225 | (if_then_else (match_operator 0 "comparison_operator" | |
5226 | [(reg:CC 21) (const_int 0)]) | |
5227 | (return) | |
5228 | (pc)))] | |
5229 | "c4x_null_epilogue_p ()" | |
5230 | "rets%0" | |
5231 | [(set_attr "type" "rets")]) | |
5232 | ||
5233 | (define_insn "*return_cc_noov" | |
5234 | [(set (pc) | |
5235 | (if_then_else (match_operator 0 "comparison_operator" | |
5236 | [(reg:CC_NOOV 21) (const_int 0)]) | |
5237 | (return) | |
5238 | (pc)))] | |
959e0a76 MH |
5239 | "GET_CODE (operands[0]) != LE |
5240 | && GET_CODE (operands[0]) != GE | |
5241 | && GET_CODE (operands[0]) != LT | |
5242 | && GET_CODE (operands[0]) != GT | |
cb0ca284 MH |
5243 | && c4x_null_epilogue_p ()" |
5244 | "rets%0" | |
5245 | [(set_attr "type" "rets")]) | |
5246 | ||
5247 | (define_insn "*return_cc_inverse" | |
5248 | [(set (pc) | |
5249 | (if_then_else (match_operator 0 "comparison_operator" | |
5250 | [(reg:CC 21) (const_int 0)]) | |
5251 | (pc) | |
5252 | (return)))] | |
5253 | "c4x_null_epilogue_p ()" | |
5254 | "rets%I0" | |
5255 | [(set_attr "type" "rets")]) | |
5256 | ||
5257 | (define_insn "*return_cc_noov_inverse" | |
5258 | [(set (pc) | |
5259 | (if_then_else (match_operator 0 "comparison_operator" | |
5260 | [(reg:CC_NOOV 21) (const_int 0)]) | |
5261 | (pc) | |
5262 | (return)))] | |
959e0a76 MH |
5263 | "GET_CODE (operands[0]) != LE |
5264 | && GET_CODE (operands[0]) != GE | |
5265 | && GET_CODE (operands[0]) != LT | |
5266 | && GET_CODE (operands[0]) != GT | |
cb0ca284 MH |
5267 | && c4x_null_epilogue_p ()" |
5268 | "rets%I0" | |
5269 | [(set_attr "type" "rets")]) | |
5270 | ||
5271 | (define_insn "jump" | |
5272 | [(set (pc) (label_ref (match_operand 0 "" "")))] | |
5273 | "" | |
5274 | "br%#\\t%l0" | |
5275 | [(set_attr "type" "jump")]) | |
5276 | ||
8a119a7d MH |
5277 | (define_insn "trap" |
5278 | [(trap_if (const_int 1) (const_int 31))] | |
5279 | "" | |
5280 | "trapu\\t31" | |
5281 | [(set_attr "type" "call")]) | |
5282 | ||
5283 | (define_expand "conditional_trap" | |
5284 | [(trap_if (match_operand 0 "comparison_operator" "") | |
5285 | (match_operand 1 "const_int_operand" ""))] | |
5286 | "" | |
5287 | "{ | |
5288 | enum rtx_code code = GET_CODE (operands[1]); | |
5289 | rtx ccreg = c4x_gen_compare_reg (code, c4x_compare_op0, c4x_compare_op1); | |
5290 | if (ccreg == NULL_RTX) FAIL; | |
5291 | if (GET_MODE (ccreg) == CCmode) | |
5292 | emit_insn (gen_cond_trap_cc (operands[0], operands[1])); | |
5293 | else | |
5294 | emit_insn (gen_cond_trap_cc_noov (operands[0], operands[1])); | |
5295 | DONE;}") | |
5296 | ||
5297 | (define_insn "cond_trap_cc" | |
5298 | [(trap_if (match_operator 0 "comparison_operator" | |
5299 | [(reg:CC 21) (const_int 0)]) | |
5300 | (match_operand 1 "const_int_operand" ""))] | |
5301 | "" | |
5302 | "trap%0\\t31" | |
5303 | [(set_attr "type" "call")]) | |
5304 | ||
5305 | (define_insn "cond_trap_cc_noov" | |
5306 | [(trap_if (match_operator 0 "comparison_operator" | |
5307 | [(reg:CC_NOOV 21) (const_int 0)]) | |
5308 | (match_operand 1 "const_int_operand" ""))] | |
5309 | "GET_CODE (operands[0]) != LE | |
5310 | && GET_CODE (operands[0]) != GE | |
5311 | && GET_CODE (operands[0]) != LT | |
5312 | && GET_CODE (operands[0]) != GT" | |
5313 | "trap%0\\t31" | |
5314 | [(set_attr "type" "call")]) | |
5315 | ||
cb0ca284 MH |
5316 | ; |
5317 | ; DBcond | |
5318 | ; | |
5319 | ; Note we have to emit a dbu instruction if there are no delay slots | |
5320 | ; to fill. | |
5321 | ; Also note that GCC will try to reverse a loop to see if it can | |
5322 | ; utilise this instruction. However, if there are more than one | |
5323 | ; memory reference in the loop, it cannot guarantee that reversing | |
5324 | ; the loop will work :( (see check_dbra_loop() in loop.c) | |
5325 | ; Note that the C3x only decrements the 24 LSBs of the address register | |
5326 | ; and the 8 MSBs are untouched. The C4x uses all 32-bits. We thus | |
5327 | ; have an option to disable this instruction. | |
5328 | (define_insn "*db" | |
5329 | [(set (pc) | |
5e6a42d9 | 5330 | (if_then_else (ne (match_operand:QI 0 "addr_reg_operand" "+a,?*d,??*r,!m") |
cb0ca284 MH |
5331 | (const_int 0)) |
5332 | (label_ref (match_operand 1 "" "")) | |
5333 | (pc))) | |
5e6a42d9 | 5334 | (set (match_dup 0) |
cb0ca284 | 5335 | (plus:QI (match_dup 0) |
959e0a76 | 5336 | (const_int -1))) |
52695ce0 | 5337 | (use (reg:QI 20)) |
959e0a76 | 5338 | (clobber (reg:CC_NOOV 21))] |
cb0ca284 MH |
5339 | "TARGET_DB && TARGET_LOOP_UNSIGNED" |
5340 | "* | |
959e0a76 MH |
5341 | if (which_alternative == 0) |
5342 | return \"dbu%#\\t%0,%l1\"; | |
5343 | else if (which_alternative == 1) | |
5344 | return c4x_output_cbranch (\"subi\\t1,%0\\n\\tbge\", insn); | |
5345 | else if (which_alternative == 2) | |
5346 | return c4x_output_cbranch (\"subi\\t1,%0\\n\\tcmpi\\t0,%0\\n\\tbge\", insn); | |
cb0ca284 | 5347 | else |
959e0a76 | 5348 | return c4x_output_cbranch (\"push\\tr0\\n\\tldi\\t%0,r0\\n\\tsubi\\t1,r0\\n\\tsti\\tr0,%0\\n\\tpop\\tr0\\n\\tbhs\", insn); |
cb0ca284 | 5349 | " |
959e0a76 | 5350 | [(set_attr "type" "db,jmpc,jmpc,jmpc")]) |
cb0ca284 | 5351 | |
37641f7d MH |
5352 | (define_insn "*db_noclobber" |
5353 | [(set (pc) | |
5354 | (if_then_else (ne (match_operand:QI 0 "addr_reg_operand" "+a") | |
5355 | (const_int 0)) | |
5356 | (label_ref (match_operand 1 "" "")) | |
5357 | (pc))) | |
5358 | (set (match_dup 0) | |
5359 | (plus:QI (match_dup 0) | |
5360 | (const_int -1)))] | |
5361 | "reload_completed && TARGET_DB && TARGET_LOOP_UNSIGNED" | |
5362 | "dbu%#\\t%0,%l1" | |
5363 | [(set_attr "type" "db")]) | |
5364 | ||
5365 | (define_split | |
5366 | [(set (pc) | |
5367 | (if_then_else (ne (match_operand:QI 0 "addr_reg_operand" "") | |
5368 | (const_int 0)) | |
5369 | (label_ref (match_operand 1 "" "")) | |
5370 | (pc))) | |
5371 | (set (match_dup 0) | |
5372 | (plus:QI (match_dup 0) | |
5373 | (const_int -1))) | |
52695ce0 | 5374 | (use (reg:QI 20)) |
37641f7d MH |
5375 | (clobber (reg:CC_NOOV 21))] |
5376 | "reload_completed && TARGET_DB && TARGET_LOOP_UNSIGNED" | |
5377 | [(parallel [(set (pc) | |
5378 | (if_then_else (ne (match_dup 0) | |
5379 | (const_int 0)) | |
5380 | (label_ref (match_dup 1)) | |
5381 | (pc))) | |
5382 | (set (match_dup 0) | |
5383 | (plus:QI (match_dup 0) | |
5384 | (const_int -1)))])] | |
5385 | "") | |
5386 | ||
5e6a42d9 MH |
5387 | |
5388 | ; This insn is used for some loop tests, typically loops reversed when | |
5389 | ; strength reduction is used. It is actually created when the instruction | |
5390 | ; combination phase combines the special loop test. Since this insn | |
5391 | ; is both a jump insn and has an output, it must deal with its own | |
5392 | ; reloads, hence the `m' constraints. | |
5393 | ||
5394 | ; The C4x does the decrement and then compares the result against zero. | |
5395 | ; It branches if the result was greater than or equal to zero. | |
5396 | ; In the RTL the comparison and decrement are assumed to happen | |
5397 | ; at the same time so we bias the iteration counter with by -1 | |
5398 | ; when we make the test. | |
cb0ca284 MH |
5399 | (define_insn "decrement_and_branch_until_zero" |
5400 | [(set (pc) | |
5e6a42d9 | 5401 | (if_then_else (ge (plus:QI (match_operand:QI 0 "addr_reg_operand" "+a,?*d,??*r,!m") |
959e0a76 MH |
5402 | (const_int -1)) |
5403 | (const_int 0)) | |
cb0ca284 MH |
5404 | (label_ref (match_operand 1 "" "")) |
5405 | (pc))) | |
5e6a42d9 | 5406 | (set (match_dup 0) |
cb0ca284 | 5407 | (plus:QI (match_dup 0) |
959e0a76 | 5408 | (const_int -1))) |
52695ce0 | 5409 | (use (reg:QI 20)) |
959e0a76 | 5410 | (clobber (reg:CC_NOOV 21))] |
8de858c0 | 5411 | "TARGET_DB && (find_reg_note (insn, REG_NONNEG, 0) || TARGET_LOOP_UNSIGNED)" |
cb0ca284 | 5412 | "* |
959e0a76 MH |
5413 | if (which_alternative == 0) |
5414 | return \"dbu%#\\t%0,%l1\"; | |
5415 | else if (which_alternative == 1) | |
5416 | return c4x_output_cbranch (\"subi\\t1,%0\\n\\tbge\", insn); | |
5417 | else if (which_alternative == 2) | |
5418 | return c4x_output_cbranch (\"subi\\t1,%0\\n\\tcmpi\\t0,%0\\n\\tbge\", insn); | |
cb0ca284 | 5419 | else |
959e0a76 | 5420 | return c4x_output_cbranch (\"push\\tr0\\n\\tldi\\t%0,r0\\n\\tsubi\\t1,r0\\n\\tsti\\tr0,%0\\n\\tpop\\tr0\\n\\tbhs\", insn); |
cb0ca284 | 5421 | " |
959e0a76 | 5422 | [(set_attr "type" "db,jmpc,jmpc,jmpc")]) |
cb0ca284 | 5423 | |
37641f7d MH |
5424 | (define_insn "*decrement_and_branch_until_zero_noclobber" |
5425 | [(set (pc) | |
5426 | (if_then_else (ge (plus:QI (match_operand:QI 0 "addr_reg_operand" "+a") | |
5427 | (const_int -1)) | |
5428 | (const_int 0)) | |
5429 | (label_ref (match_operand 1 "" "")) | |
5430 | (pc))) | |
5431 | (set (match_dup 0) | |
5432 | (plus:QI (match_dup 0) | |
5433 | (const_int -1)))] | |
f475349b | 5434 | "reload_completed && TARGET_DB && TARGET_LOOP_UNSIGNED" |
37641f7d MH |
5435 | "dbu%#\\t%0,%l1" |
5436 | [(set_attr "type" "db")]) | |
5437 | ||
5438 | (define_split | |
5439 | [(set (pc) | |
5440 | (if_then_else (ge (plus:QI (match_operand:QI 0 "addr_reg_operand" "") | |
5441 | (const_int -1)) | |
5442 | (const_int 0)) | |
5443 | (label_ref (match_operand 1 "" "")) | |
5444 | (pc))) | |
5445 | (set (match_dup 0) | |
5446 | (plus:QI (match_dup 0) | |
5447 | (const_int -1))) | |
52695ce0 | 5448 | (use (reg:QI 20)) |
37641f7d | 5449 | (clobber (reg:CC_NOOV 21))] |
f475349b | 5450 | "reload_completed && TARGET_DB && TARGET_LOOP_UNSIGNED" |
37641f7d MH |
5451 | [(parallel [(set (pc) |
5452 | (if_then_else (ge (plus:QI (match_dup 0) | |
5453 | (const_int -1)) | |
5454 | (const_int 0)) | |
5455 | (label_ref (match_dup 1)) | |
5456 | (pc))) | |
5457 | (set (match_dup 0) | |
5458 | (plus:QI (match_dup 0) | |
5459 | (const_int -1)))])] | |
5460 | "") | |
5461 | ||
cb0ca284 MH |
5462 | ; |
5463 | ; MISC INSTRUCTIONS | |
5464 | ; | |
5465 | ||
5466 | ; | |
5467 | ; NOP | |
5468 | ; | |
5469 | (define_insn "nop" | |
5470 | [(const_int 0)] | |
5471 | "" | |
5472 | "nop") | |
5473 | ; Default to misc type attr. | |
5474 | ||
39c1728e HB |
5475 | (define_insn "return_indirect_internal" |
5476 | [(return) | |
5477 | (use (match_operand:QI 0 "reg_operand" ""))] | |
5478 | "reload_completed" | |
5479 | "bu%#\\t%0" | |
5480 | [(set_attr "type" "jump")]) | |
5481 | ||
52695ce0 HB |
5482 | (define_expand "prologue" |
5483 | [(const_int 1)] | |
5484 | "" | |
5485 | "c4x_expand_prologue (); DONE;") | |
5486 | ||
5487 | (define_expand "epilogue" | |
5488 | [(const_int 1)] | |
5489 | "" | |
5490 | "c4x_expand_epilogue (); DONE;") | |
cb0ca284 MH |
5491 | |
5492 | ; | |
5493 | ; RPTB | |
5494 | ; | |
5495 | (define_insn "rptb_top" | |
959e0a76 | 5496 | [(use (label_ref (match_operand 0 "" ""))) |
f475349b MH |
5497 | (use (label_ref (match_operand 1 "" ""))) |
5498 | (clobber (reg:QI 25)) | |
5499 | (clobber (reg:QI 26))] | |
cb0ca284 MH |
5500 | "" |
5501 | "* | |
4ddb3ea6 | 5502 | return ! final_sequence && c4x_rptb_rpts_p (insn, operands[0]) |
cb0ca284 MH |
5503 | ? \"rpts\\trc\" : \"rptb%#\\t%l1-1\"; |
5504 | " | |
5505 | [(set_attr "type" "repeat_top")]) | |
5506 | ||
3b5e8a16 MH |
5507 | (define_insn "rpts_top" |
5508 | [(unspec [(use (label_ref (match_operand 0 "" ""))) | |
f475349b MH |
5509 | (use (label_ref (match_operand 1 "" "")))] 2) |
5510 | (clobber (reg:QI 25)) | |
5511 | (clobber (reg:QI 26))] | |
3b5e8a16 MH |
5512 | "" |
5513 | "* | |
5514 | return ! final_sequence && c4x_rptb_rpts_p (insn, operands[0]) | |
5515 | ? \"rpts\\trc\" : \"rptb%#\\t%l1-1\"; | |
5516 | " | |
5517 | [(set_attr "type" "repeat")]) | |
5518 | ||
959e0a76 MH |
5519 | ; This pattern needs to be emitted at the start of the loop to |
5520 | ; say that RS and RE are loaded. | |
f0cae6c7 | 5521 | (define_insn "rptb_init" |
3b5e8a16 | 5522 | [(unspec [(match_operand:QI 0 "register_operand" "va")] 22) |
959e0a76 MH |
5523 | (clobber (reg:QI 25)) |
5524 | (clobber (reg:QI 26))] | |
5525 | "" | |
5526 | "" | |
5527 | [(set_attr "type" "repeat")]) | |
cb0ca284 | 5528 | |
4a6330ac | 5529 | |
f0cae6c7 MH |
5530 | ; operand 0 is the loop count pseudo register |
5531 | ; operand 1 is the number of loop iterations or 0 if it is unknown | |
5532 | ; operand 2 is the maximum number of loop iterations | |
5533 | ; operand 3 is the number of levels of enclosed loops | |
152d5997 | 5534 | (define_expand "doloop_begin" |
f0cae6c7 MH |
5535 | [(use (match_operand 0 "register_operand" "")) |
5536 | (use (match_operand:QI 1 "const_int_operand" "")) | |
5537 | (use (match_operand:QI 2 "const_int_operand" "")) | |
5538 | (use (match_operand:QI 3 "const_int_operand" ""))] | |
152d5997 MH |
5539 | "" |
5540 | "if (INTVAL (operands[3]) > 1 || ! TARGET_RPTB) | |
f0cae6c7 | 5541 | FAIL; |
f475349b | 5542 | emit_insn (gen_rptb_init (operands[0])); |
f0cae6c7 MH |
5543 | DONE; |
5544 | ") | |
152d5997 MH |
5545 | |
5546 | ||
959e0a76 MH |
5547 | ; The RS (25) and RE (26) registers must be unviolate from the top of the loop |
5548 | ; to here. | |
d5e4ff48 MH |
5549 | (define_insn "rptb_end" |
5550 | [(set (pc) | |
4a6330ac | 5551 | (if_then_else (ge (match_operand:QI 0 "register_operand" "+v,?a,!*d,!*x*k,!m") |
d5e4ff48 MH |
5552 | (const_int 0)) |
5553 | (label_ref (match_operand 1 "" "")) | |
5554 | (pc))) | |
4a6330ac | 5555 | (set (match_dup 0) |
d5e4ff48 | 5556 | (plus:QI (match_dup 0) |
e27f8c8a | 5557 | (const_int -1))) |
959e0a76 MH |
5558 | (use (reg:QI 25)) |
5559 | (use (reg:QI 26)) | |
52695ce0 | 5560 | (use (reg:QI 20)) |
959e0a76 | 5561 | (clobber (reg:CC_NOOV 21))] |
d5e4ff48 MH |
5562 | "" |
5563 | "* | |
959e0a76 MH |
5564 | if (which_alternative == 0) |
5565 | return c4x_rptb_nop_p (insn) ? \"nop\" : \"\"; | |
4a6330ac | 5566 | else if (which_alternative == 1 && TARGET_DB) |
959e0a76 MH |
5567 | return \"dbu%#\\t%0,%l1\"; |
5568 | else if (which_alternative == 2) | |
5569 | return c4x_output_cbranch (\"subi\\t1,%0\\n\\tbge\", insn); | |
4a6330ac | 5570 | else if (which_alternative == 3 || (which_alternative == 1 && ! TARGET_DB)) |
959e0a76 MH |
5571 | return c4x_output_cbranch (\"subi\\t1,%0\\n\\tcmpi\\t0,%0\\n\\tbge\", insn); |
5572 | else | |
5573 | return c4x_output_cbranch (\"push\\tr0\\n\\tldi\\t%0,r0\\n\\tsubi\\t1,r0\\n\\tsti\\tr0,%0\\n\\tpop\\tr0\\n\\tbhs\", insn); | |
5574 | " | |
5575 | [(set_attr "type" "repeat,db,jmpc,jmpc,jmpc")]) | |
d5e4ff48 | 5576 | |
3b5e8a16 MH |
5577 | (define_split |
5578 | [(set (pc) | |
5579 | (if_then_else (ge (match_operand:QI 0 "addr_reg_operand" "") | |
5580 | (const_int 0)) | |
5581 | (label_ref (match_operand 1 "" "")) | |
5582 | (pc))) | |
5583 | (set (match_dup 0) | |
5584 | (plus:QI (match_dup 0) | |
5585 | (const_int -1))) | |
5586 | (use (match_operand:QI 2 "const_int_operand" "")) | |
5587 | (use (match_operand:QI 3 "const_int_operand" "")) | |
5588 | (use (match_operand:QI 4 "const_int_operand" "")) | |
5589 | (use (reg:QI 25)) | |
5590 | (use (reg:QI 26)) | |
52695ce0 | 5591 | (use (reg:QI 20)) |
3b5e8a16 MH |
5592 | (clobber (reg:CC_NOOV 21))] |
5593 | "reload_completed" | |
5594 | [(parallel [(set (pc) | |
5595 | (if_then_else (ge (match_dup 0) | |
5596 | (const_int 0)) | |
5597 | (label_ref (match_dup 1)) | |
5598 | (pc))) | |
5599 | (set (match_dup 0) | |
5600 | (plus:QI (match_dup 0) | |
5601 | (const_int -1)))])] | |
5602 | "") | |
5603 | ||
f0cae6c7 MH |
5604 | ; operand 0 is the loop count pseudo register |
5605 | ; operand 1 is the number of loop iterations or 0 if it is unknown | |
5606 | ; operand 2 is the maximum number of loop iterations | |
5607 | ; operand 3 is the number of levels of enclosed loops | |
5608 | ; operand 4 is the label to jump to at the top of the loop | |
152d5997 | 5609 | (define_expand "doloop_end" |
f0cae6c7 MH |
5610 | [(use (match_operand 0 "register_operand" "")) |
5611 | (use (match_operand:QI 1 "const_int_operand" "")) | |
5612 | (use (match_operand:QI 2 "const_int_operand" "")) | |
5613 | (use (match_operand:QI 3 "const_int_operand" "")) | |
5614 | (use (label_ref (match_operand 4 "" "")))] | |
d5e4ff48 | 5615 | "" |
152d5997 | 5616 | "if (! TARGET_LOOP_UNSIGNED |
1943c2c1 | 5617 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > ((unsigned) 1 << 31)) |
152d5997 | 5618 | FAIL; |
f0cae6c7 | 5619 | if (INTVAL (operands[3]) > 1 || ! TARGET_RPTB) |
4a6330ac MH |
5620 | { |
5621 | /* The C30 maximum iteration count for DB is 2^24. */ | |
152d5997 MH |
5622 | if (! TARGET_DB) |
5623 | FAIL; | |
f0cae6c7 MH |
5624 | emit_jump_insn (gen_decrement_and_branch_until_zero (operands[0], |
5625 | operands[4])); | |
4a6330ac | 5626 | DONE; |
f0cae6c7 MH |
5627 | } |
5628 | emit_jump_insn (gen_rptb_end (operands[0], operands[4])); | |
5629 | DONE; | |
5630 | ") | |
d5e4ff48 | 5631 | |
152d5997 MH |
5632 | ; The current low overhead looping code is naff and is not failsafe |
5633 | ; If you want RTPB instructions to be generated, apply the patches | |
5634 | ; from www.elec.canterbury.ac.nz/c4x. This will utilise the | |
5635 | ; doloop_begin and doloop_end patterns in this MD. | |
5636 | (define_expand "decrement_and_branch_on_count" | |
5637 | [(parallel [(set (pc) | |
5638 | (if_then_else (ge (match_operand:QI 0 "register_operand" "") | |
5639 | (const_int 0)) | |
5640 | (label_ref (match_operand 1 "" "")) | |
5641 | (pc))) | |
5642 | (set (match_dup 0) | |
5643 | (plus:QI (match_dup 0) | |
5644 | (const_int -1))) | |
5645 | (use (reg:QI 25)) | |
5646 | (use (reg:QI 26)) | |
5647 | (clobber (reg:CC_NOOV 21))])] | |
5648 | "0" | |
5649 | "") | |
5650 | ||
cb0ca284 MH |
5651 | (define_expand "movstrqi_small2" |
5652 | [(parallel [(set (mem:BLK (match_operand:BLK 0 "src_operand" "")) | |
5653 | (mem:BLK (match_operand:BLK 1 "src_operand" ""))) | |
5654 | (use (match_operand:QI 2 "immediate_operand" "")) | |
5655 | (use (match_operand:QI 3 "immediate_operand" "")) | |
5656 | (clobber (match_operand:QI 4 "ext_low_reg_operand" ""))])] | |
5657 | "" | |
5658 | " | |
5659 | { | |
5660 | rtx src, dst, tmp; | |
5661 | rtx src_mem, dst_mem; | |
5662 | int len; | |
5663 | int i; | |
5664 | ||
5665 | dst = operands[0]; | |
5666 | src = operands[1]; | |
5667 | len = INTVAL (operands[2]); | |
5668 | tmp = operands[4]; | |
5669 | ||
d5e4ff48 MH |
5670 | src_mem = gen_rtx_MEM (QImode, src); |
5671 | dst_mem = gen_rtx_MEM (QImode, dst); | |
cb0ca284 | 5672 | |
0dced2c7 | 5673 | if (TARGET_PARALLEL) |
cb0ca284 | 5674 | { |
0dced2c7 MH |
5675 | emit_insn (gen_movqi (tmp, src_mem)); |
5676 | emit_insn (gen_addqi3_noclobber (src, src, const1_rtx)); | |
5677 | for (i = 1; i < len; i++) | |
5678 | { | |
5679 | emit_insn (gen_movqi_parallel (tmp, src_mem, dst_mem, tmp)); | |
5680 | emit_insn (gen_addqi3_noclobber (src, src, const1_rtx)); | |
5681 | emit_insn (gen_addqi3_noclobber (dst, dst, const1_rtx)); | |
5682 | } | |
5683 | emit_insn (gen_movqi (dst_mem, tmp)); | |
5684 | emit_insn (gen_addqi3_noclobber (dst, dst, const1_rtx)); | |
5685 | } | |
5686 | else | |
5687 | { | |
5688 | for (i = 0; i < len; i++) | |
5689 | { | |
5690 | emit_insn (gen_movqi (tmp, src_mem)); | |
5691 | emit_insn (gen_movqi (dst_mem, tmp)); | |
5692 | emit_insn (gen_addqi3_noclobber (src, src, const1_rtx)); | |
5693 | emit_insn (gen_addqi3_noclobber (dst, dst, const1_rtx)); | |
5694 | } | |
cb0ca284 | 5695 | } |
cb0ca284 MH |
5696 | DONE; |
5697 | } | |
5698 | ") | |
5699 | ||
5700 | ||
5701 | ; | |
5702 | ; BLOCK MOVE | |
5703 | ; We should probably get RC loaded when using RPTB automagically... | |
5704 | ; There's probably no need to call _memcpy() if we don't get | |
e03f5d43 | 5705 | ; an immediate operand for the size. We could do a better job here |
cb0ca284 MH |
5706 | ; than most memcpy() implementations. |
5707 | ; operand 2 is the number of bytes | |
5708 | ; operand 3 is the shared alignment | |
5709 | ; operand 4 is a scratch register | |
5710 | ||
5711 | (define_insn "movstrqi_small" | |
8de858c0 MH |
5712 | [(set (mem:BLK (match_operand:QI 0 "addr_reg_operand" "+a")) |
5713 | (mem:BLK (match_operand:QI 1 "addr_reg_operand" "+a"))) | |
cb0ca284 MH |
5714 | (use (match_operand:QI 2 "immediate_operand" "i")) |
5715 | (use (match_operand:QI 3 "immediate_operand" "")) | |
5716 | (clobber (match_operand:QI 4 "ext_low_reg_operand" "=&q")) | |
5717 | (clobber (match_dup 0)) | |
5718 | (clobber (match_dup 1))] | |
5719 | "" | |
5720 | "* | |
5721 | { | |
5722 | int i; | |
5723 | int len = INTVAL (operands[2]); | |
5724 | int first = 1; | |
5725 | ||
5726 | for (i = 0; i < len; i++) | |
5727 | { | |
5728 | if (first) | |
5729 | output_asm_insn (\"ldiu\\t*%1++,%4\", operands); | |
5730 | else | |
5731 | output_asm_insn (\"|| ldi\\t*%1++,%4\", operands); | |
5732 | output_asm_insn (\"sti\\t%4,*%0++\", operands); | |
5733 | first = 0; | |
5734 | } | |
5735 | return \"\"; | |
5736 | } | |
5737 | " | |
5738 | [(set_attr "type" "multi")]) | |
5739 | ||
5740 | (define_insn "movstrqi_large" | |
8de858c0 MH |
5741 | [(set (mem:BLK (match_operand:QI 0 "addr_reg_operand" "+a")) |
5742 | (mem:BLK (match_operand:QI 1 "addr_reg_operand" "+a"))) | |
cb0ca284 MH |
5743 | (use (match_operand:QI 2 "immediate_operand" "i")) |
5744 | (use (match_operand:QI 3 "immediate_operand" "")) | |
5745 | (clobber (match_operand:QI 4 "ext_low_reg_operand" "=&q")) | |
5746 | (clobber (match_dup 0)) | |
5747 | (clobber (match_dup 1)) | |
5748 | (clobber (reg:QI 25)) | |
5749 | (clobber (reg:QI 26)) | |
5750 | (clobber (reg:QI 27))] | |
5751 | "" | |
5752 | "* | |
5753 | { | |
5754 | int len = INTVAL (operands[2]); | |
5755 | ||
5756 | output_asm_insn (\"ldiu\\t*%1++,%4\", operands); | |
959e0a76 | 5757 | if (TARGET_RPTS_CYCLES (len)) |
cb0ca284 MH |
5758 | { |
5759 | output_asm_insn (\"rpts\\t%2-2\", operands); | |
5760 | output_asm_insn (\"sti\\t%4,*%0++\", operands); | |
5761 | output_asm_insn (\"|| ldi\\t*%1++,%4\", operands); | |
5762 | return \"sti\\t%4,*%0++\"; | |
5763 | } | |
5764 | else | |
5765 | { | |
5766 | output_asm_insn (\"ldiu\\t%2-2,rc\", operands); | |
5767 | output_asm_insn (\"rptb\\t$+1\", operands); | |
5768 | output_asm_insn (\"sti\\t%4,*%0++\", operands); | |
5769 | output_asm_insn (\"|| ldi\\t*%1++,%4\", operands); | |
5770 | ||
5771 | return \"sti\\t%4,*%0++\"; | |
5772 | } | |
5773 | } | |
5774 | " | |
959e0a76 | 5775 | [(set_attr "type" "multi")]) |
cb0ca284 MH |
5776 | |
5777 | ; Operand 2 is the count, operand 3 is the alignment. | |
5778 | (define_expand "movstrqi" | |
5779 | [(parallel [(set (mem:BLK (match_operand:BLK 0 "src_operand" "")) | |
5780 | (mem:BLK (match_operand:BLK 1 "src_operand" ""))) | |
5781 | (use (match_operand:QI 2 "immediate_operand" "")) | |
5782 | (use (match_operand:QI 3 "immediate_operand" ""))])] | |
5783 | "" | |
5784 | " | |
5785 | { | |
5786 | rtx tmp; | |
5787 | if (GET_CODE (operands[2]) != CONST_INT | |
5788 | || INTVAL (operands[2]) > 32767 | |
5789 | || INTVAL (operands[2]) <= 0) | |
5790 | { | |
5791 | FAIL; /* Try to call _memcpy */ | |
5792 | } | |
5793 | ||
959e0a76 MH |
5794 | operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); |
5795 | operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); | |
cb0ca284 MH |
5796 | tmp = gen_reg_rtx (QImode); |
5797 | if (INTVAL (operands[2]) < 8) | |
0dced2c7 | 5798 | emit_insn (gen_movstrqi_small2 (operands[0], operands[1], operands[2], |
cb0ca284 MH |
5799 | operands[3], tmp)); |
5800 | else | |
5801 | { | |
5802 | emit_insn (gen_movstrqi_large (operands[0], operands[1], operands[2], | |
5803 | operands[3], tmp)); | |
5804 | } | |
5805 | DONE; | |
5806 | }") | |
5807 | ||
5808 | ||
5809 | (define_insn "*cmpstrqi" | |
50c33087 | 5810 | [(set (match_operand:QI 0 "ext_reg_operand" "=d") |
8de858c0 MH |
5811 | (compare:QI (mem:BLK (match_operand:QI 1 "addr_reg_operand" "+a")) |
5812 | (mem:BLK (match_operand:QI 2 "addr_reg_operand" "+a")))) | |
cb0ca284 MH |
5813 | (use (match_operand:QI 3 "immediate_operand" "i")) |
5814 | (use (match_operand:QI 4 "immediate_operand" "")) | |
5815 | (clobber (match_operand:QI 5 "std_reg_operand" "=&c")) | |
5816 | (clobber (reg:QI 21))] | |
5817 | "" | |
5818 | "* | |
5819 | { | |
5820 | output_asm_insn (\"ldi\\t%3-1,%5\", operands); | |
5821 | output_asm_insn (\"$1:\tsubi3\\t*%1++,*%2++,%0\", operands); | |
5822 | output_asm_insn (\"dbeq\\t%5,$1\", operands); | |
d5e4ff48 | 5823 | return \"\"; |
cb0ca284 MH |
5824 | }") |
5825 | ||
5826 | (define_expand "cmpstrqi" | |
5827 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
5828 | (compare:QI (match_operand:BLK 1 "general_operand" "") | |
5829 | (match_operand:BLK 2 "general_operand" ""))) | |
5830 | (use (match_operand:QI 3 "immediate_operand" "")) | |
5831 | (use (match_operand:QI 4 "immediate_operand" "")) | |
5832 | (clobber (match_dup 5)) | |
5833 | (clobber (reg:QI 21))])] | |
5834 | "" | |
5835 | " | |
5836 | { | |
5837 | if (GET_CODE (operands[3]) != CONST_INT | |
5838 | || INTVAL (operands[3]) > 32767 | |
5839 | || INTVAL (operands[3]) <= 0) | |
5840 | { | |
5841 | FAIL; | |
5842 | } | |
959e0a76 MH |
5843 | operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); |
5844 | operands[2] = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); | |
cb0ca284 MH |
5845 | operands[5] = gen_reg_rtx (QImode); |
5846 | }") | |
5847 | ||
5848 | ; | |
5849 | ; TWO OPERAND LONG DOUBLE INSTRUCTIONS | |
5850 | ; | |
5851 | ||
5852 | (define_expand "movhf" | |
5853 | [(set (match_operand:HF 0 "src_operand" "") | |
5854 | (match_operand:HF 1 "src_operand" ""))] | |
5855 | "" | |
50c33087 MH |
5856 | "if (c4x_emit_move_sequence (operands, HFmode)) |
5857 | DONE;") | |
cb0ca284 MH |
5858 | |
5859 | (define_insn "*movhf_noclobber_reg" | |
5860 | [(set (match_operand:HF 0 "reg_operand" "=h") | |
50c33087 MH |
5861 | (match_operand:HF 1 "src_operand" "Hh"))] |
5862 | "GET_CODE (operands[1]) != MEM" | |
cb0ca284 MH |
5863 | "ldfu\\t%1,%0" |
5864 | [(set_attr "type" "unary")]) | |
5865 | ||
cb0ca284 | 5866 | (define_insn "*movhf_noclobber" |
f416f18c | 5867 | [(set (match_operand:HF 0 "dst_operand" "=h,m") |
95d62815 | 5868 | (match_operand:HF 1 "src_operand" "Hm,h"))] |
cb0ca284 MH |
5869 | "reg_operand (operands[0], HFmode) ^ reg_operand (operands[1], HFmode)" |
5870 | "#" | |
5871 | [(set_attr "type" "multi,multi")]) | |
5872 | ||
5873 | (define_insn "*movhf_test" | |
5874 | [(set (reg:CC 21) | |
5875 | (compare:CC (match_operand:HF 1 "reg_operand" "h") | |
5876 | (const_int 0))) | |
5877 | (clobber (match_scratch:HF 0 "=h"))] | |
5878 | "" | |
5879 | "ldf\\t%1,%0" | |
5880 | [(set_attr "type" "unarycc")]) | |
5881 | ||
5882 | (define_insn "*movhf_set" | |
5883 | [(set (reg:CC 21) | |
5884 | (compare:CC (match_operand:HF 1 "reg_operand" "h") | |
5885 | (match_operand:HF 2 "fp_zero_operand" "G"))) | |
5886 | (set (match_operand:HF 0 "reg_operand" "=h") | |
5887 | (match_dup 1))] | |
5888 | "" | |
5889 | "ldf\\t%1,%0" | |
5890 | [(set_attr "type" "unarycc")]) | |
5891 | ||
5892 | (define_split | |
5893 | [(set (match_operand:HF 0 "reg_operand" "") | |
5894 | (match_operand:HF 1 "memory_operand" ""))] | |
5895 | "reload_completed" | |
5896 | [(set (match_dup 0) (float_extend:HF (match_dup 2))) | |
a9d3cc3f MH |
5897 | (set (match_dup 0) (unspec:HF [(subreg:QI (match_dup 0) 0) |
5898 | (match_dup 3)] 8))] | |
cb0ca284 MH |
5899 | "operands[2] = c4x_operand_subword (operands[1], 0, 1, HFmode); |
5900 | operands[3] = c4x_operand_subword (operands[1], 1, 1, HFmode); | |
5901 | PUT_MODE (operands[2], QFmode); | |
5902 | PUT_MODE (operands[3], QImode);") | |
5903 | ||
5904 | (define_split | |
5905 | [(set (match_operand:HF 0 "reg_operand" "") | |
5906 | (match_operand:HF 1 "const_operand" ""))] | |
5907 | "reload_completed && 0" | |
5908 | [(set (match_dup 0) (float_extend:HF (match_dup 2))) | |
a9d3cc3f MH |
5909 | (set (match_dup 0) (unspec:HF [(subreg:QI (match_dup 0) 0) |
5910 | (match_dup 3)] 8))] | |
cb0ca284 MH |
5911 | "operands[2] = c4x_operand_subword (operands[1], 0, 1, HFmode); |
5912 | operands[3] = c4x_operand_subword (operands[1], 1, 1, HFmode); | |
5913 | PUT_MODE (operands[2], QFmode); | |
5914 | PUT_MODE (operands[3], QImode);") | |
5915 | ||
5916 | (define_split | |
5917 | [(set (match_operand:HF 0 "memory_operand" "") | |
5918 | (match_operand:HF 1 "reg_operand" ""))] | |
5919 | "reload_completed" | |
5920 | [(set (match_dup 2) (float_truncate:QF (match_dup 1))) | |
f959ff1a | 5921 | (set (match_dup 3) (unspec:QI [(match_dup 1)] 9))] |
cb0ca284 MH |
5922 | "operands[2] = c4x_operand_subword (operands[0], 0, 1, HFmode); |
5923 | operands[3] = c4x_operand_subword (operands[0], 1, 1, HFmode); | |
5924 | PUT_MODE (operands[2], QFmode); | |
5925 | PUT_MODE (operands[3], QImode);") | |
5926 | ||
5927 | (define_insn "*loadhf_float" | |
5928 | [(set (match_operand:HF 0 "reg_operand" "=h") | |
50c33087 | 5929 | (float_extend:HF (match_operand:QF 1 "src_operand" "fHm")))] |
cb0ca284 | 5930 | "" |
3b67042a | 5931 | "ldfu\\t%1,%0" |
cb0ca284 MH |
5932 | [(set_attr "type" "unary")]) |
5933 | ||
5934 | (define_insn "*loadhf_int" | |
8a119a7d | 5935 | [(set (match_operand:HF 0 "reg_operand" "+h") |
f416f18c | 5936 | (unspec:HF [(subreg:QI (match_dup 0) 0) |
a9d3cc3f | 5937 | (match_operand:QI 1 "src_operand" "rIm")] 8))] |
cb0ca284 | 5938 | "" |
3b67042a | 5939 | "ldiu\\t%1,%0" |
cb0ca284 MH |
5940 | [(set_attr "type" "unary")]) |
5941 | ||
5942 | (define_insn "*storehf_float" | |
5943 | [(set (match_operand:QF 0 "memory_operand" "=m") | |
5944 | (float_truncate:QF (match_operand:HF 1 "reg_operand" "h")))] | |
5945 | "" | |
5946 | "stf\\t%1,%0" | |
5947 | [(set_attr "type" "store")]) | |
5948 | ||
5949 | (define_insn "*storehf_int" | |
5950 | [(set (match_operand:QI 0 "memory_operand" "=m") | |
f416f18c | 5951 | (unspec:QI [(match_operand:HF 1 "reg_operand" "h")] 9))] |
cb0ca284 | 5952 | "" |
3b67042a | 5953 | "sti\\t%1,%0" |
cb0ca284 MH |
5954 | [(set_attr "type" "store")]) |
5955 | ||
5956 | (define_insn "extendqfhf2" | |
5957 | [(set (match_operand:HF 0 "reg_operand" "=h") | |
5958 | (float_extend:HF (match_operand:QF 1 "reg_operand" "h")))] | |
5959 | "" | |
5960 | "ldfu\\t%1,%0" | |
5961 | [(set_attr "type" "unarycc")]) | |
5962 | ||
5963 | (define_insn "trunchfqf2" | |
5964 | [(set (match_operand:QF 0 "reg_operand" "=h") | |
5965 | (float_truncate:QF (match_operand:HF 1 "reg_operand" "0"))) | |
5966 | (clobber (reg:CC 21))] | |
5967 | "" | |
5968 | "andn\\t0ffh,%0" | |
5969 | [(set_attr "type" "unarycc")]) | |
5970 | ||
5971 | ; | |
5972 | ; PUSH/POP | |
5973 | ; | |
52695ce0 | 5974 | (define_insn "pushhf" |
cb0ca284 MH |
5975 | [(set (mem:HF (pre_inc:QI (reg:QI 20))) |
5976 | (match_operand:HF 0 "reg_operand" "h"))] | |
5977 | "" | |
5978 | "#" | |
5979 | [(set_attr "type" "multi")]) | |
5980 | ||
5981 | (define_split | |
5982 | [(set (mem:HF (pre_inc:QI (reg:QI 20))) | |
5983 | (match_operand:HF 0 "reg_operand" ""))] | |
5984 | "reload_completed" | |
5985 | [(set (mem:QF (pre_inc:QI (reg:QI 20))) | |
5986 | (float_truncate:QF (match_dup 0))) | |
5987 | (set (mem:QI (pre_inc:QI (reg:QI 20))) | |
f959ff1a | 5988 | (unspec:QI [(match_dup 0)] 9))] |
cb0ca284 MH |
5989 | "") |
5990 | ||
5991 | (define_insn "pushhf_trunc" | |
5992 | [(set (mem:QF (pre_inc:QI (reg:QI 20))) | |
5993 | (float_truncate:QF (match_operand:HF 0 "reg_operand" "h")))] | |
5994 | "" | |
5995 | "pushf\\t%0" | |
5996 | [(set_attr "type" "push")]) | |
5997 | ||
5998 | (define_insn "pushhf_int" | |
5999 | [(set (mem:QI (pre_inc:QI (reg:QI 20))) | |
f416f18c | 6000 | (unspec:QI [(match_operand:HF 0 "reg_operand" "h")] 9))] |
cb0ca284 MH |
6001 | "" |
6002 | "push\\t%0" | |
6003 | [(set_attr "type" "push")]) | |
6004 | ||
6005 | ; we can not use this because the popf will destroy the low 8 bits | |
52695ce0 | 6006 | ;(define_insn "pophf" |
cb0ca284 MH |
6007 | ; [(set (match_operand:HF 0 "reg_operand" "=h") |
6008 | ; (mem:HF (post_dec:QI (reg:QI 20)))) | |
6009 | ; (clobber (reg:CC 21))] | |
6010 | ; "" | |
6011 | ; "#" | |
6012 | ; [(set_attr "type" "multi")]) | |
6013 | ||
6014 | (define_split | |
6015 | [(set (match_operand:HF 0 "reg_operand" "") | |
6016 | (mem:HF (post_dec:QI (reg:QI 20)))) | |
6017 | (clobber (reg:CC 21))] | |
6018 | "reload_completed" | |
6019 | [(parallel [(set (match_operand:HF 0 "reg_operand" "=h") | |
6020 | (float_extend:HF (mem:QF (post_dec:QI (reg:QI 20))))) | |
6021 | (clobber (reg:CC 21))]) | |
6022 | (parallel [(set (match_dup 0) | |
a9d3cc3f | 6023 | (unspec:HF [(subreg:QI (match_dup 0) 0) |
cb0ca284 MH |
6024 | (mem:QI (post_dec:QI (reg:QI 20)))] 8)) |
6025 | (clobber (reg:CC 21))])] | |
6026 | "") | |
6027 | ||
6028 | (define_insn "*pophf_int" | |
8a119a7d | 6029 | [(set (match_operand:HF 0 "reg_operand" "+h") |
f416f18c | 6030 | (unspec:HF [(subreg:QI (match_dup 0) 0) |
a9d3cc3f | 6031 | (mem:QI (post_dec:QI (reg:QI 20)))] 8)) |
cb0ca284 MH |
6032 | (clobber (reg:CC 21))] |
6033 | "" | |
3b67042a | 6034 | "pop\\t%0" |
cb0ca284 MH |
6035 | [(set_attr "type" "pop")]) |
6036 | ||
6037 | (define_insn "*pophf_float" | |
6038 | [(set (match_operand:HF 0 "reg_operand" "=h") | |
6039 | (float_extend:HF (mem:QF (post_dec:QI (reg:QI 20))))) | |
6040 | (clobber (reg:CC 21))] | |
6041 | "" | |
3b67042a | 6042 | "popf\\t%0" |
52695ce0 | 6043 | [(set_attr "type" "pop")]) |
cb0ca284 MH |
6044 | |
6045 | ; | |
6046 | ; FIX | |
6047 | ; | |
6048 | (define_insn "fixhfqi_clobber" | |
6049 | [(set (match_operand:QI 0 "reg_operand" "=dc") | |
6050 | (fix:QI (match_operand:HF 1 "reg_or_const_operand" "hH"))) | |
6051 | (clobber (reg:CC 21))] | |
6052 | "" | |
6053 | "fix\\t%1,%0" | |
6054 | [(set_attr "type" "unarycc")]) | |
6055 | ||
6056 | ; | |
6057 | ; ABSF | |
6058 | ; | |
6059 | (define_expand "abshf2" | |
6060 | [(parallel [(set (match_operand:HF 0 "reg_operand" "") | |
6061 | (abs:HF (match_operand:HF 1 "reg_or_const_operand" ""))) | |
6062 | (clobber (reg:CC_NOOV 21))])] | |
6063 | "" | |
6064 | "") | |
6065 | ||
6066 | (define_insn "*abshf2_clobber" | |
6067 | [(set (match_operand:HF 0 "reg_operand" "=h") | |
6068 | (abs:HF (match_operand:HF 1 "reg_or_const_operand" "hH"))) | |
6069 | (clobber (reg:CC_NOOV 21))] | |
6070 | "" | |
6071 | "absf\\t%1,%0" | |
6072 | [(set_attr "type" "unarycc")]) | |
6073 | ||
6074 | (define_insn "*abshf2_test" | |
6075 | [(set (reg:CC_NOOV 21) | |
6076 | (compare:CC_NOOV (abs:HF (match_operand:HF 1 "reg_operand" "h")) | |
6077 | (match_operand:HF 2 "fp_zero_operand" "G"))) | |
6078 | (clobber (match_scratch:HF 0 "=h"))] | |
6079 | "" | |
6080 | "absf\\t%1,%0" | |
6081 | [(set_attr "type" "unarycc")]) | |
6082 | ||
6083 | (define_insn "*abshf2_set" | |
6084 | [(set (reg:CC_NOOV 21) | |
6085 | (compare:CC_NOOV (abs:HF (match_operand:HF 1 "reg_or_const_operand" "hH")) | |
6086 | (match_operand:HF 2 "fp_zero_operand" "G"))) | |
6087 | (set (match_operand:HF 0 "reg_operand" "=h") | |
6088 | (abs:HF (match_dup 1)))] | |
6089 | ||
6090 | "" | |
6091 | "absf\\t%1,%0" | |
6092 | [(set_attr "type" "unarycc")]) | |
6093 | ||
6094 | ; | |
6095 | ; NEGF | |
6096 | ; | |
6097 | (define_expand "neghf2" | |
6098 | [(parallel [(set (match_operand:HF 0 "reg_operand" "") | |
6099 | (neg:HF (match_operand:HF 1 "reg_or_const_operand" ""))) | |
8a119a7d | 6100 | (clobber (reg:CC_NOOV 21))])] |
cb0ca284 MH |
6101 | "" |
6102 | "") | |
6103 | ||
6104 | (define_insn "*neghf2_clobber" | |
6105 | [(set (match_operand:HF 0 "reg_operand" "=h") | |
6106 | (neg:HF (match_operand:HF 1 "reg_or_const_operand" "hH"))) | |
8a119a7d | 6107 | (clobber (reg:CC_NOOV 21))] |
cb0ca284 MH |
6108 | "" |
6109 | "negf\\t%1,%0" | |
6110 | [(set_attr "type" "unarycc")]) | |
6111 | ||
6112 | (define_insn "*neghf2_test" | |
8a119a7d MH |
6113 | [(set (reg:CC_NOOV 21) |
6114 | (compare:CC_NOOV (neg:HF (match_operand:HF 1 "reg_or_const_operand" "hH")) | |
6115 | (match_operand:HF 2 "fp_zero_operand" "G"))) | |
cb0ca284 MH |
6116 | (clobber (match_scratch:HF 0 "=h"))] |
6117 | "" | |
6118 | "negf\\t%1,%0" | |
6119 | [(set_attr "type" "unarycc")]) | |
6120 | ||
6121 | (define_insn "*neghf2_set" | |
8a119a7d MH |
6122 | [(set (reg:CC_NOOV 21) |
6123 | (compare:CC_NOOV (neg:HF (match_operand:HF 1 "reg_or_const_operand" "hH")) | |
6124 | (match_operand:HF 2 "fp_zero_operand" "G"))) | |
cb0ca284 MH |
6125 | (set (match_operand:HF 0 "reg_operand" "=h") |
6126 | (neg:HF (match_dup 1)))] | |
6127 | "" | |
6128 | "negf\\t%1,%0" | |
6129 | [(set_attr "type" "unarycc")]) | |
6130 | ||
6131 | ; | |
6132 | ; RCPF | |
6133 | ; | |
6134 | (define_insn "*rcpfhf_clobber" | |
6135 | [(set (match_operand:HF 0 "reg_operand" "=h") | |
f416f18c | 6136 | (unspec:HF [(match_operand:HF 1 "reg_or_const_operand" "hH")] 5)) |
cb0ca284 | 6137 | (clobber (reg:CC_NOOV 21))] |
4ddb3ea6 | 6138 | "! TARGET_C3X" |
cb0ca284 MH |
6139 | "rcpf\\t%1,%0" |
6140 | [(set_attr "type" "unarycc")]) | |
6141 | ||
6142 | ; | |
6143 | ; RSQRF | |
6144 | ; | |
6145 | (define_insn "*rsqrfhf_clobber" | |
6146 | [(set (match_operand:HF 0 "reg_operand" "=h") | |
f416f18c | 6147 | (unspec:HF [(match_operand:HF 1 "reg_or_const_operand" "hH")] 10)) |
cb0ca284 | 6148 | (clobber (reg:CC_NOOV 21))] |
4ddb3ea6 | 6149 | "! TARGET_C3X" |
cb0ca284 MH |
6150 | "rsqrf\\t%1,%0" |
6151 | [(set_attr "type" "unarycc")]) | |
6152 | ||
6153 | ; | |
6154 | ; RNDF | |
6155 | ; | |
6156 | (define_insn "*rndhf_clobber" | |
6157 | [(set (match_operand:HF 0 "reg_operand" "=h") | |
f416f18c | 6158 | (unspec:HF [(match_operand:HF 1 "reg_or_const_operand" "hH")] 6)) |
cb0ca284 | 6159 | (clobber (reg:CC_NOOV 21))] |
4ddb3ea6 | 6160 | "! TARGET_C3X" |
cb0ca284 MH |
6161 | "rnd\\t%1,%0" |
6162 | [(set_attr "type" "unarycc")]) | |
6163 | ||
6164 | ||
6165 | ; Inlined float square root for C4x | |
6166 | (define_expand "sqrthf2_inline" | |
6167 | [(parallel [(set (match_dup 2) | |
f959ff1a | 6168 | (unspec:HF [(match_operand:HF 1 "reg_operand" "")] 10)) |
cb0ca284 MH |
6169 | (clobber (reg:CC_NOOV 21))]) |
6170 | (parallel [(set (match_dup 3) (mult:HF (match_dup 5) (match_dup 1))) | |
6171 | (clobber (reg:CC_NOOV 21))]) | |
6172 | (parallel [(set (match_dup 4) (mult:HF (match_dup 2) (match_dup 3))) | |
6173 | (clobber (reg:CC_NOOV 21))]) | |
6174 | (parallel [(set (match_dup 4) (mult:HF (match_dup 2) (match_dup 4))) | |
6175 | (clobber (reg:CC_NOOV 21))]) | |
6176 | (parallel [(set (match_dup 4) (minus:HF (match_dup 6) (match_dup 4))) | |
6177 | (clobber (reg:CC_NOOV 21))]) | |
6178 | (parallel [(set (match_dup 2) (mult:HF (match_dup 2) (match_dup 4))) | |
6179 | (clobber (reg:CC_NOOV 21))]) | |
6180 | (parallel [(set (match_dup 4) (mult:HF (match_dup 2) (match_dup 3))) | |
6181 | (clobber (reg:CC_NOOV 21))]) | |
6182 | (parallel [(set (match_dup 4) (mult:HF (match_dup 2) (match_dup 4))) | |
6183 | (clobber (reg:CC_NOOV 21))]) | |
6184 | (parallel [(set (match_dup 4) (minus:HF (match_dup 6) (match_dup 4))) | |
6185 | (clobber (reg:CC_NOOV 21))]) | |
6186 | (parallel [(set (match_dup 2) (mult:HF (match_dup 2) (match_dup 4))) | |
6187 | (clobber (reg:CC_NOOV 21))]) | |
6188 | (parallel [(set (match_operand:HF 0 "reg_operand" "") | |
6189 | (mult:HF (match_dup 2) (match_dup 1))) | |
6190 | (clobber (reg:CC_NOOV 21))])] | |
4ddb3ea6 | 6191 | "! TARGET_C3X" |
cb0ca284 MH |
6192 | " |
6193 | operands[2] = gen_reg_rtx (HFmode); | |
6194 | operands[3] = gen_reg_rtx (HFmode); | |
6195 | operands[4] = gen_reg_rtx (HFmode); | |
6196 | operands[5] = immed_real_const_1 (REAL_VALUE_ATOF (\"0.5\", HFmode), HFmode); | |
6197 | operands[6] = immed_real_const_1 (REAL_VALUE_ATOF (\"1.5\", HFmode), HFmode); | |
6198 | ") | |
6199 | ||
6200 | ||
6201 | (define_expand "sqrthf2" | |
6202 | [(parallel [(set (match_operand:HF 0 "reg_operand" "") | |
6203 | (sqrt:HF (match_operand:HF 1 "reg_operand" ""))) | |
6204 | (clobber (reg:CC 21))])] | |
f42850b9 MH |
6205 | "! TARGET_C3X && TARGET_INLINE" |
6206 | "emit_insn (gen_sqrthf2_inline (operands[0], operands[1])); | |
6207 | DONE;") | |
6208 | ||
cb0ca284 MH |
6209 | |
6210 | (define_expand "fix_trunchfhi2" | |
6211 | [(parallel [(set (match_operand:HI 0 "reg_operand" "") | |
6212 | (fix:HI (match_operand:HF 1 "reg_operand" ""))) | |
6213 | (clobber (reg:CC 21))])] | |
6214 | "" | |
4fda2521 | 6215 | "c4x_emit_libcall (fix_trunchfhi2_libfunc, FIX, HImode, HFmode, 2, operands); |
cb0ca284 MH |
6216 | DONE;") |
6217 | ||
6218 | (define_expand "fixuns_trunchfhi2" | |
6219 | [(parallel [(set (match_operand:HI 0 "reg_operand" "") | |
6220 | (unsigned_fix:HI (match_operand:HF 1 "reg_operand" ""))) | |
6221 | (clobber (reg:CC 21))])] | |
6222 | "" | |
4fda2521 | 6223 | "c4x_emit_libcall (fixuns_trunchfhi2_libfunc, UNSIGNED_FIX, |
cb0ca284 MH |
6224 | HImode, HFmode, 2, operands); |
6225 | DONE;") | |
6226 | ||
6227 | ; | |
6228 | ; THREE OPERAND LONG DOUBLE INSTRUCTIONS | |
6229 | ; | |
6230 | ||
6231 | ; | |
6232 | ; ADDF | |
6233 | ; | |
6234 | (define_insn "addhf3" | |
65c78c7d MH |
6235 | [(set (match_operand:HF 0 "reg_operand" "=h,?h") |
6236 | (plus:HF (match_operand:HF 1 "reg_operand" "%0,h") | |
6237 | (match_operand:HF 2 "reg_or_const_operand" "H,h"))) | |
cb0ca284 MH |
6238 | (clobber (reg:CC_NOOV 21))] |
6239 | "" | |
6240 | "@ | |
65c78c7d MH |
6241 | addf\\t%2,%0 |
6242 | addf3\\t%2,%1,%0" | |
cb0ca284 MH |
6243 | [(set_attr "type" "binarycc,binarycc")]) |
6244 | ||
6245 | ; | |
6246 | ; SUBF | |
6247 | ; | |
6248 | (define_insn "subhf3" | |
65c78c7d MH |
6249 | [(set (match_operand:HF 0 "reg_operand" "=h,h,?h") |
6250 | (minus:HF (match_operand:HF 1 "reg_or_const_operand" "0,H,h") | |
6251 | (match_operand:HF 2 "reg_or_const_operand" "H,0,h"))) | |
cb0ca284 MH |
6252 | (clobber (reg:CC_NOOV 21))] |
6253 | "" | |
6254 | "@ | |
cb0ca284 | 6255 | subf\\t%2,%0 |
65c78c7d MH |
6256 | subrf\\t%1,%0 |
6257 | subf3\\t%2,%1,%0" | |
cb0ca284 MH |
6258 | [(set_attr "type" "binarycc,binarycc,binarycc")]) |
6259 | ||
6260 | ; | |
6261 | ; MULF | |
6262 | ; | |
6263 | ; The C3x MPYF only uses 24 bit precision while the C4x uses 32 bit precison. | |
6264 | ; | |
6265 | (define_expand "mulhf3" | |
6266 | [(parallel [(set (match_operand:HF 0 "reg_operand" "=h") | |
6267 | (mult:HF (match_operand:HF 1 "reg_operand" "h") | |
6268 | (match_operand:HF 2 "reg_operand" "h"))) | |
6269 | (clobber (reg:CC_NOOV 21))])] | |
f42850b9 MH |
6270 | "! TARGET_C3X" |
6271 | "") | |
cb0ca284 MH |
6272 | |
6273 | (define_insn "*mulhf3_c40" | |
65c78c7d MH |
6274 | [(set (match_operand:HF 0 "reg_operand" "=h,?h") |
6275 | (mult:HF (match_operand:HF 1 "reg_operand" "%0,h") | |
6276 | (match_operand:HF 2 "reg_or_const_operand" "hH,h"))) | |
cb0ca284 MH |
6277 | (clobber (reg:CC_NOOV 21))] |
6278 | "" | |
6279 | "@ | |
65c78c7d MH |
6280 | mpyf\\t%2,%0 |
6281 | mpyf3\\t%2,%1,%0" | |
cb0ca284 MH |
6282 | [(set_attr "type" "binarycc,binarycc")]) |
6283 | ||
6284 | ; | |
6285 | ; CMPF | |
6286 | ; | |
6287 | (define_expand "cmphf" | |
6288 | [(set (reg:CC 21) | |
6289 | (compare:CC (match_operand:HF 0 "reg_operand" "") | |
6290 | (match_operand:HF 1 "reg_or_const_operand" "")))] | |
6291 | "" | |
6292 | "c4x_compare_op0 = operands[0]; | |
6293 | c4x_compare_op1 = operands[1]; | |
6294 | DONE;") | |
6295 | ||
6296 | (define_insn "*cmphf" | |
6297 | [(set (reg:CC 21) | |
6298 | (compare:CC (match_operand:HF 0 "reg_operand" "h") | |
6299 | (match_operand:HF 1 "reg_or_const_operand" "hH")))] | |
6300 | "" | |
6301 | "cmpf\\t%1,%0" | |
6302 | [(set_attr "type" "compare")]) | |
6303 | ||
6304 | (define_insn "*cmphf_noov" | |
6305 | [(set (reg:CC_NOOV 21) | |
6306 | (compare:CC_NOOV (match_operand:HF 0 "reg_operand" "h") | |
6307 | (match_operand:HF 1 "reg_or_const_operand" "hH")))] | |
6308 | "" | |
6309 | "cmpf\\t%1,%0" | |
6310 | [(set_attr "type" "compare")]) | |
6311 | ||
6312 | ; Inlined float divide for C4x | |
6313 | (define_expand "divhf3_inline" | |
6314 | [(parallel [(set (match_dup 3) | |
f959ff1a | 6315 | (unspec:HF [(match_operand:HF 2 "reg_operand" "")] 5)) |
cb0ca284 MH |
6316 | (clobber (reg:CC_NOOV 21))]) |
6317 | (parallel [(set (match_dup 4) (mult:HF (match_dup 2) (match_dup 3))) | |
6318 | (clobber (reg:CC_NOOV 21))]) | |
6319 | (parallel [(set (match_dup 4) (minus:HF (match_dup 5) (match_dup 4))) | |
6320 | (clobber (reg:CC_NOOV 21))]) | |
6321 | (parallel [(set (match_dup 3) (mult:HF (match_dup 3) (match_dup 4))) | |
6322 | (clobber (reg:CC_NOOV 21))]) | |
6323 | (parallel [(set (match_dup 4) (mult:HF (match_dup 2) (match_dup 3))) | |
6324 | (clobber (reg:CC_NOOV 21))]) | |
6325 | (parallel [(set (match_dup 4) (minus:HF (match_dup 5) (match_dup 4))) | |
6326 | (clobber (reg:CC_NOOV 21))]) | |
6327 | (parallel [(set (match_dup 3) (mult:HF (match_dup 3) (match_dup 4))) | |
6328 | (clobber (reg:CC_NOOV 21))]) | |
6329 | (parallel [(set (match_operand:HF 0 "reg_operand" "") | |
6330 | (mult:HF (match_operand:HF 1 "reg_operand" "") | |
6331 | (match_dup 3))) | |
6332 | (clobber (reg:CC_NOOV 21))])] | |
4ddb3ea6 | 6333 | "! TARGET_C3X" |
cb0ca284 MH |
6334 | " |
6335 | operands[3] = gen_reg_rtx (HFmode); | |
6336 | operands[4] = gen_reg_rtx (HFmode); | |
6337 | operands[5] = CONST2_RTX (HFmode); | |
6338 | ") | |
6339 | ||
6340 | (define_expand "divhf3" | |
6341 | [(parallel [(set (match_operand:HF 0 "reg_operand" "") | |
6342 | (div:HF (match_operand:HF 1 "reg_operand" "") | |
6343 | (match_operand:HF 2 "reg_operand" ""))) | |
6344 | (clobber (reg:CC 21))])] | |
f42850b9 MH |
6345 | "! TARGET_C3X && TARGET_INLINE" |
6346 | "emit_insn (gen_divhf3_inline (operands[0], operands[1], operands[2])); | |
6347 | DONE;") | |
cb0ca284 MH |
6348 | |
6349 | ||
6350 | ; | |
6351 | ; TWO OPERAND LONG LONG INSTRUCTIONS | |
6352 | ; | |
6353 | ||
e42efef5 MH |
6354 | (define_insn "*movhi_stik" |
6355 | [(set (match_operand:HI 0 "memory_operand" "=m") | |
6356 | (match_operand:HI 1 "stik_const_operand" "K"))] | |
6357 | "! TARGET_C3X" | |
6358 | "#" | |
6359 | [(set_attr "type" "multi")]) | |
6360 | ||
cb0ca284 MH |
6361 | ; We could load some constants using define_splits for the C30 |
6362 | ; in the large memory model---these would emit shift and or insns. | |
6363 | (define_expand "movhi" | |
6364 | [(set (match_operand:HI 0 "src_operand" "") | |
6365 | (match_operand:HI 1 "src_operand" ""))] | |
6366 | "" | |
50c33087 MH |
6367 | "if (c4x_emit_move_sequence (operands, HImode)) |
6368 | DONE;") | |
cb0ca284 MH |
6369 | |
6370 | ; The constraints for movhi must include 'r' if we don't | |
6371 | ; restrict HImode regnos to start on an even number, since | |
6372 | ; we can get RC, R8 allocated as a pair. We want more | |
6373 | ; votes for FP_REGS so we use dr as the constraints. | |
6374 | (define_insn "*movhi_noclobber" | |
f416f18c | 6375 | [(set (match_operand:HI 0 "dst_operand" "=dr,m") |
95d62815 | 6376 | (match_operand:HI 1 "src_operand" "drIm,r"))] |
cb0ca284 MH |
6377 | "reg_operand (operands[0], HImode) |
6378 | || reg_operand (operands[1], HImode)" | |
6379 | "#" | |
6380 | [(set_attr "type" "multi,multi")]) | |
6381 | ||
8de858c0 MH |
6382 | ; This will fail miserably if the destination register is used in the |
6383 | ; source memory address. | |
6384 | ; The usual strategy in this case is to swap the order of insns we emit, | |
6385 | ; however, this will fail if we have an autoincrement memory address. | |
6386 | ; For example: | |
6387 | ; ldi *ar0++, ar0 | |
6388 | ; ldi *ar0++, ar1 | |
6389 | ; | |
6390 | ; We could convert this to | |
6391 | ; ldi *ar0(1), ar1 | |
6392 | ; ldi *ar0, ar0 | |
6393 | ; | |
6394 | ; However, things are likely to be very screwed up if we get this. | |
6395 | ||
cb0ca284 | 6396 | (define_split |
f416f18c | 6397 | [(set (match_operand:HI 0 "dst_operand" "") |
cb0ca284 MH |
6398 | (match_operand:HI 1 "src_operand" ""))] |
6399 | "reload_completed | |
e42efef5 MH |
6400 | && (reg_operand (operands[0], HImode) |
6401 | || reg_operand (operands[1], HImode) | |
6402 | || stik_const_operand (operands[1], HImode))" | |
8de858c0 MH |
6403 | [(set (match_dup 2) (match_dup 4)) |
6404 | (set (match_dup 3) (match_dup 5))] | |
cb0ca284 | 6405 | "operands[2] = c4x_operand_subword (operands[0], 0, 1, HImode); |
8de858c0 MH |
6406 | operands[3] = c4x_operand_subword (operands[0], 1, 1, HImode); |
6407 | operands[4] = c4x_operand_subword (operands[1], 0, 1, HImode); | |
6408 | operands[5] = c4x_operand_subword (operands[1], 1, 1, HImode); | |
6409 | if (reg_overlap_mentioned_p (operands[2], operands[5])) | |
6410 | { | |
6411 | /* Swap order of move insns. */ | |
6412 | rtx tmp; | |
6413 | tmp = operands[2]; | |
6414 | operands[2] =operands[3]; | |
6415 | operands[3] = tmp; | |
6416 | tmp = operands[4]; | |
6417 | operands[4] =operands[5]; | |
6418 | operands[5] = tmp; | |
6419 | }") | |
cb0ca284 MH |
6420 | |
6421 | ||
6422 | (define_insn "extendqihi2" | |
6423 | [(set (match_operand:HI 0 "reg_operand" "=dc") | |
50c33087 | 6424 | (sign_extend:HI (match_operand:QI 1 "src_operand" "rIm"))) |
cb0ca284 MH |
6425 | (clobber (reg:CC 21))] |
6426 | "" | |
6427 | "#" | |
6428 | [(set_attr "type" "multi")]) | |
6429 | ||
6430 | (define_split | |
6431 | [(set (match_operand:HI 0 "reg_operand" "=?dc") | |
50c33087 | 6432 | (sign_extend:HI (match_operand:QI 1 "src_operand" "rIm"))) |
cb0ca284 MH |
6433 | (clobber (reg:CC 21))] |
6434 | "reload_completed && TARGET_C3X" | |
6435 | [(set (match_dup 2) (match_dup 1)) | |
6436 | (set (match_dup 3) (match_dup 2)) | |
6437 | (parallel [(set (match_dup 3) (ashiftrt:QI (match_dup 3) (const_int 31))) | |
6438 | (clobber (reg:CC 21))])] | |
6439 | "operands[2] = c4x_operand_subword (operands[0], 0, 0, HImode); | |
6440 | operands[3] = c4x_operand_subword (operands[0], 1, 0, HImode);") | |
6441 | ||
6442 | (define_split | |
6443 | [(set (match_operand:HI 0 "reg_operand" "=?dc") | |
50c33087 | 6444 | (sign_extend:HI (match_operand:QI 1 "src_operand" "rIm"))) |
cb0ca284 | 6445 | (clobber (reg:CC 21))] |
4ddb3ea6 | 6446 | "reload_completed && ! TARGET_C3X" |
cb0ca284 MH |
6447 | [(set (match_dup 2) (match_dup 1)) |
6448 | (parallel [(set (match_dup 3) (ashiftrt:QI (match_dup 2) (const_int 31))) | |
6449 | (clobber (reg:CC 21))])] | |
6450 | "operands[2] = c4x_operand_subword (operands[0], 0, 0, HImode); | |
6451 | operands[3] = c4x_operand_subword (operands[0], 1, 0, HImode);") | |
6452 | ||
6453 | (define_insn "zero_extendqihi2" | |
6454 | [(set (match_operand:HI 0 "reg_operand" "=?dc") | |
50c33087 | 6455 | (zero_extend:HI (match_operand:QI 1 "src_operand" "rIm"))) |
cb0ca284 MH |
6456 | (clobber (reg:CC 21))] |
6457 | "" | |
6458 | "#" | |
6459 | [(set_attr "type" "multi")]) | |
6460 | ||
6461 | ; If operand0 and operand1 are the same register we don't need | |
6462 | ; the first set. | |
6463 | (define_split | |
6464 | [(set (match_operand:HI 0 "reg_operand" "=?dc") | |
50c33087 | 6465 | (zero_extend:HI (match_operand:QI 1 "src_operand" "rIm"))) |
cb0ca284 MH |
6466 | (clobber (reg:CC 21))] |
6467 | "reload_completed" | |
6468 | [(set (match_dup 2) (match_dup 1)) | |
6469 | (set (match_dup 3) (const_int 0))] | |
6470 | "operands[2] = c4x_operand_subword (operands[0], 0, 0, HImode); | |
6471 | operands[3] = c4x_operand_subword (operands[0], 1, 0, HImode);") | |
6472 | ||
6473 | ; | |
6474 | ; PUSH/POP | |
6475 | ; | |
6476 | (define_insn "*pushhi" | |
6477 | [(set (mem:HI (pre_inc:QI (reg:QI 20))) | |
6478 | (match_operand:HI 0 "reg_operand" "r"))] | |
6479 | "" | |
6480 | "#" | |
6481 | [(set_attr "type" "multi")]) | |
6482 | ||
6483 | (define_split | |
6484 | [(set (mem:HI (pre_inc:QI (reg:QI 20))) | |
6485 | (match_operand:HI 0 "reg_operand" ""))] | |
6486 | "reload_completed" | |
6487 | [(set (mem:QI (pre_inc:QI (reg:QI 20))) (match_dup 2)) | |
6488 | (set (mem:QI (pre_inc:QI (reg:QI 20))) (match_dup 3))] | |
6489 | "operands[2] = c4x_operand_subword (operands[0], 0, 0, HImode); | |
6490 | operands[3] = c4x_operand_subword (operands[0], 1, 0, HImode);") | |
6491 | ||
6492 | (define_insn "*pophi" | |
6493 | [(set (match_operand:HI 0 "reg_operand" "=r") | |
6494 | (mem:HI (post_dec:QI (reg:QI 20)))) | |
6495 | (clobber (reg:CC 21))] | |
6496 | "" | |
6497 | "#" | |
6498 | [(set_attr "type" "multi")]) | |
6499 | ||
6500 | (define_split | |
6501 | [(set (match_operand:HI 0 "reg_operand" "") | |
6502 | (mem:HI (pre_inc:QI (reg:QI 20))))] | |
6503 | "reload_completed" | |
6504 | [(set (match_dup 2) (mem:QI (pre_inc:QI (reg:QI 20)))) | |
6505 | (set (match_dup 3) (mem:QI (pre_inc:QI (reg:QI 20))))] | |
6506 | "operands[2] = c4x_operand_subword (operands[0], 0, 0, HImode); | |
6507 | operands[3] = c4x_operand_subword (operands[0], 1, 0, HImode);") | |
6508 | ||
6509 | ; | |
6510 | ; NEG | |
6511 | ; | |
6512 | (define_insn "neghi2" | |
6513 | [(set (match_operand:HI 0 "ext_reg_operand" "=d") | |
6514 | (neg:HI (match_operand:HI 1 "src_operand" "rm"))) | |
6515 | (clobber (reg:CC_NOOV 21))] | |
6516 | "" | |
6517 | "#" | |
6518 | [(set_attr "type" "multi")]) | |
6519 | ||
6520 | (define_split | |
6521 | [(set (match_operand:HI 0 "ext_reg_operand" "") | |
6522 | (neg:HI (match_operand:HI 1 "src_operand" ""))) | |
6523 | (clobber (reg:CC_NOOV 21))] | |
6524 | "reload_completed" | |
6525 | [(parallel [(set (reg:CC_NOOV 21) | |
6526 | (compare:CC_NOOV (neg:QI (match_dup 3)) | |
6527 | (const_int 0))) | |
6528 | (set (match_dup 2) (neg:QI (match_dup 3)))]) | |
6529 | (parallel [(set (match_dup 4) (neg:QI (match_dup 5))) | |
6530 | (use (reg:CC_NOOV 21)) | |
6531 | (clobber (reg:CC_NOOV 21))])] | |
6532 | "operands[2] = c4x_operand_subword (operands[0], 0, 1, HImode); | |
6533 | operands[3] = c4x_operand_subword (operands[1], 0, 1, HImode); | |
6534 | operands[4] = c4x_operand_subword (operands[0], 1, 1, HImode); | |
6535 | operands[5] = c4x_operand_subword (operands[1], 1, 1, HImode);") | |
6536 | ||
6537 | (define_insn "one_cmplhi2" | |
6538 | [(set (match_operand:HI 0 "reg_operand" "=r") | |
6539 | (not:HI (match_operand:HI 1 "src_operand" "rm"))) | |
6540 | (clobber (reg:CC 21))] | |
6541 | "" | |
6542 | "#" | |
6543 | [(set_attr "type" "multi")]) | |
6544 | ||
6545 | (define_split | |
6546 | [(set (match_operand:HI 0 "reg_operand" "") | |
6547 | (not:HI (match_operand:HI 1 "src_operand" ""))) | |
6548 | (clobber (reg:CC 21))] | |
6549 | "reload_completed" | |
6550 | [(parallel [(set (match_dup 2) (not:QI (match_dup 3))) | |
6551 | (clobber (reg:CC 21))]) | |
6552 | (parallel [(set (match_dup 4) (not:QI (match_dup 5))) | |
6553 | (clobber (reg:CC 21))])] | |
6554 | "operands[2] = c4x_operand_subword (operands[0], 0, 1, HImode); | |
6555 | operands[3] = c4x_operand_subword (operands[1], 0, 1, HImode); | |
6556 | operands[4] = c4x_operand_subword (operands[0], 1, 1, HImode); | |
6557 | operands[5] = c4x_operand_subword (operands[1], 1, 1, HImode);") | |
6558 | ||
6559 | (define_expand "floathiqf2" | |
6560 | [(parallel [(set (match_operand:QF 0 "reg_operand" "") | |
6561 | (float:QF (match_operand:HI 1 "src_operand" ""))) | |
6562 | (clobber (reg:CC 21))])] | |
6563 | "" | |
4fda2521 | 6564 | "c4x_emit_libcall (floathiqf2_libfunc, FLOAT, QFmode, HImode, 2, operands); |
cb0ca284 MH |
6565 | DONE;") |
6566 | ||
6567 | (define_expand "floatunshiqf2" | |
6568 | [(parallel [(set (match_operand:QF 0 "reg_operand" "") | |
6569 | (unsigned_float:QF (match_operand:HI 1 "src_operand" ""))) | |
6570 | (clobber (reg:CC 21))])] | |
6571 | "" | |
4fda2521 | 6572 | "c4x_emit_libcall (floatunshiqf2_libfunc, UNSIGNED_FLOAT, |
cb0ca284 MH |
6573 | QFmode, HImode, 2, operands); |
6574 | DONE;") | |
6575 | ||
6576 | (define_expand "floathihf2" | |
6577 | [(parallel [(set (match_operand:HF 0 "reg_operand" "") | |
6578 | (float:HF (match_operand:HI 1 "src_operand" ""))) | |
6579 | (clobber (reg:CC 21))])] | |
6580 | "" | |
4fda2521 | 6581 | "c4x_emit_libcall (floathihf2_libfunc, FLOAT, HFmode, HImode, 2, operands); |
cb0ca284 MH |
6582 | DONE;") |
6583 | ||
6584 | (define_expand "floatunshihf2" | |
6585 | [(parallel [(set (match_operand:HF 0 "reg_operand" "") | |
6586 | (unsigned_float:HF (match_operand:HI 1 "src_operand" ""))) | |
6587 | (clobber (reg:CC 21))])] | |
6588 | "" | |
4fda2521 | 6589 | "c4x_emit_libcall (floatunshihf2_libfunc, UNSIGNED_FLOAT, |
cb0ca284 MH |
6590 | HFmode, HImode, 2, operands); |
6591 | DONE;") | |
6592 | ||
6593 | ||
6594 | ; | |
6595 | ; THREE OPERAND LONG LONG INSTRUCTIONS | |
6596 | ; | |
6597 | ||
6598 | (define_expand "addhi3" | |
6599 | [(parallel [(set (match_operand:HI 0 "ext_reg_operand" "") | |
6600 | (plus:HI (match_operand:HI 1 "src_operand" "") | |
6601 | (match_operand:HI 2 "src_operand" ""))) | |
6602 | (clobber (reg:CC_NOOV 21))])] | |
6603 | "" | |
6604 | "legitimize_operands (PLUS, operands, HImode);") | |
6605 | ||
6606 | (define_insn "*addhi3_clobber" | |
65c78c7d MH |
6607 | [(set (match_operand:HI 0 "ext_reg_operand" "=d,d,?d") |
6608 | (plus:HI (match_operand:HI 1 "src_operand" "%0,rR,rS<>") | |
6609 | (match_operand:HI 2 "src_operand" "rm,R,rS<>"))) | |
cb0ca284 MH |
6610 | (clobber (reg:CC_NOOV 21))] |
6611 | "valid_operands (PLUS, operands, HImode)" | |
6612 | "#" | |
6613 | [(set_attr "type" "multi,multi,multi")]) | |
6614 | ||
6615 | (define_split | |
6616 | [(set (match_operand:HI 0 "ext_reg_operand" "") | |
6617 | (plus:HI (match_operand:HI 1 "src_operand" "") | |
6618 | (match_operand:HI 2 "src_operand" ""))) | |
6619 | (clobber (reg:CC_NOOV 21))] | |
6620 | "reload_completed" | |
6621 | [(parallel [(set (reg:CC_NOOV 21) | |
6622 | (compare:CC_NOOV (plus:QI (match_dup 4) (match_dup 5)) | |
6623 | (const_int 0))) | |
6624 | (set (match_dup 3) (plus:QI (match_dup 4) (match_dup 5)))]) | |
6625 | (parallel [(set (match_dup 6) (plus:QI (match_dup 7) (match_dup 8))) | |
6626 | (use (reg:CC_NOOV 21)) | |
6627 | (clobber (reg:CC_NOOV 21))])] | |
6628 | "operands[3] = c4x_operand_subword (operands[0], 0, 1, HImode); | |
6629 | operands[4] = c4x_operand_subword (operands[1], 0, 1, HImode); | |
6630 | operands[5] = c4x_operand_subword (operands[2], 0, 1, HImode); | |
6631 | operands[6] = c4x_operand_subword (operands[0], 1, 1, HImode); | |
6632 | operands[7] = c4x_operand_subword (operands[1], 1, 1, HImode); | |
6633 | operands[8] = c4x_operand_subword (operands[2], 1, 1, HImode);") | |
6634 | ||
6635 | (define_expand "subhi3" | |
6636 | [(parallel [(set (match_operand:HI 0 "ext_reg_operand" "") | |
6637 | (minus:HI (match_operand:HI 1 "src_operand" "") | |
6638 | (match_operand:HI 2 "src_operand" ""))) | |
6639 | (clobber (reg:CC_NOOV 21))])] | |
6640 | "" | |
6641 | "legitimize_operands (MINUS, operands, HImode);") | |
6642 | ||
6643 | ||
6644 | (define_insn "*subhi3_clobber" | |
65c78c7d MH |
6645 | [(set (match_operand:HI 0 "ext_reg_operand" "=d,d,?d") |
6646 | (minus:HI (match_operand:HI 1 "src_operand" "0,rR,rS<>") | |
6647 | (match_operand:HI 2 "src_operand" "rm,R,rS<>"))) | |
cb0ca284 MH |
6648 | (clobber (reg:CC_NOOV 21))] |
6649 | "valid_operands (MINUS, operands, HImode)" | |
6650 | "#" | |
6651 | [(set_attr "type" "multi,multi,multi")]) | |
6652 | ||
6653 | (define_split | |
6654 | [(set (match_operand:HI 0 "ext_reg_operand" "") | |
6655 | (minus:HI (match_operand:HI 1 "src_operand" "") | |
6656 | (match_operand:HI 2 "src_operand" ""))) | |
6657 | (clobber (reg:CC_NOOV 21))] | |
6658 | "reload_completed" | |
6659 | [(parallel [(set (reg:CC_NOOV 21) | |
6660 | (compare:CC_NOOV (minus:QI (match_dup 4) (match_dup 5)) | |
6661 | (const_int 0))) | |
6662 | (set (match_dup 3) (minus:QI (match_dup 4) (match_dup 5)))]) | |
6663 | (parallel [(set (match_dup 6) (minus:QI (match_dup 7) (match_dup 8))) | |
6664 | (use (reg:CC_NOOV 21)) | |
6665 | (clobber (reg:CC_NOOV 21))])] | |
6666 | "operands[3] = c4x_operand_subword (operands[0], 0, 1, HImode); | |
6667 | operands[4] = c4x_operand_subword (operands[1], 0, 1, HImode); | |
6668 | operands[5] = c4x_operand_subword (operands[2], 0, 1, HImode); | |
6669 | operands[6] = c4x_operand_subword (operands[0], 1, 1, HImode); | |
6670 | operands[7] = c4x_operand_subword (operands[1], 1, 1, HImode); | |
6671 | operands[8] = c4x_operand_subword (operands[2], 1, 1, HImode);") | |
6672 | ||
6673 | (define_expand "iorhi3" | |
6674 | [(parallel [(set (match_operand:HI 0 "reg_operand" "") | |
6675 | (ior:HI (match_operand:HI 1 "src_operand" "") | |
6676 | (match_operand:HI 2 "src_operand" ""))) | |
6677 | (clobber (reg:CC 21))])] | |
6678 | "" | |
6679 | "legitimize_operands (IOR, operands, HImode);") | |
6680 | ||
6681 | (define_insn "*iorhi3_clobber" | |
65c78c7d MH |
6682 | [(set (match_operand:HI 0 "reg_operand" "=d,d,?d") |
6683 | (ior:HI (match_operand:HI 1 "src_operand" "%0,rR,rS<>") | |
6684 | (match_operand:HI 2 "src_operand" "rm,R,rS<>"))) | |
cb0ca284 MH |
6685 | (clobber (reg:CC 21))] |
6686 | "valid_operands (IOR, operands, HImode)" | |
6687 | "#" | |
6688 | [(set_attr "type" "multi,multi,multi")]) | |
6689 | ||
6690 | (define_split | |
6691 | [(set (match_operand:HI 0 "reg_operand" "") | |
6692 | (ior:HI (match_operand:HI 1 "src_operand" "") | |
6693 | (match_operand:HI 2 "src_operand" ""))) | |
6694 | (clobber (reg:CC 21))] | |
6695 | "reload_completed" | |
6696 | [(parallel [(set (match_dup 3) (ior:QI (match_dup 4) (match_dup 5))) | |
6697 | (clobber (reg:CC 21))]) | |
6698 | (parallel [(set (match_dup 6) (ior:QI (match_dup 7) (match_dup 8))) | |
6699 | (clobber (reg:CC 21))])] | |
6700 | "operands[3] = c4x_operand_subword (operands[0], 0, 1, HImode); | |
6701 | operands[4] = c4x_operand_subword (operands[1], 0, 1, HImode); | |
6702 | operands[5] = c4x_operand_subword (operands[2], 0, 1, HImode); | |
6703 | operands[6] = c4x_operand_subword (operands[0], 1, 1, HImode); | |
6704 | operands[7] = c4x_operand_subword (operands[1], 1, 1, HImode); | |
6705 | operands[8] = c4x_operand_subword (operands[2], 1, 1, HImode);") | |
6706 | ||
6707 | (define_expand "andhi3" | |
6708 | [(parallel [(set (match_operand:HI 0 "reg_operand" "") | |
6709 | (and:HI (match_operand:HI 1 "src_operand" "") | |
6710 | (match_operand:HI 2 "src_operand" ""))) | |
6711 | (clobber (reg:CC 21))])] | |
6712 | "" | |
6713 | "legitimize_operands (AND, operands, HImode);") | |
6714 | ||
6715 | (define_insn "*andhi3_clobber" | |
65c78c7d MH |
6716 | [(set (match_operand:HI 0 "reg_operand" "=d,d,?d") |
6717 | (and:HI (match_operand:HI 1 "src_operand" "%0,rR,rS<>") | |
6718 | (match_operand:HI 2 "src_operand" "rm,R,rS<>"))) | |
cb0ca284 MH |
6719 | (clobber (reg:CC 21))] |
6720 | "valid_operands (AND, operands, HImode)" | |
6721 | "#" | |
6722 | [(set_attr "type" "multi,multi,multi")]) | |
6723 | ||
6724 | (define_split | |
6725 | [(set (match_operand:HI 0 "reg_operand" "") | |
6726 | (and:HI (match_operand:HI 1 "src_operand" "") | |
6727 | (match_operand:HI 2 "src_operand" ""))) | |
6728 | (clobber (reg:CC 21))] | |
6729 | "reload_completed" | |
6730 | [(parallel [(set (match_dup 3) (and:QI (match_dup 4) (match_dup 5))) | |
6731 | (clobber (reg:CC 21))]) | |
6732 | (parallel [(set (match_dup 6) (and:QI (match_dup 7) (match_dup 8))) | |
6733 | (clobber (reg:CC 21))])] | |
6734 | "operands[3] = c4x_operand_subword (operands[0], 0, 1, HImode); | |
6735 | operands[4] = c4x_operand_subword (operands[1], 0, 1, HImode); | |
6736 | operands[5] = c4x_operand_subword (operands[2], 0, 1, HImode); | |
6737 | operands[6] = c4x_operand_subword (operands[0], 1, 1, HImode); | |
6738 | operands[7] = c4x_operand_subword (operands[1], 1, 1, HImode); | |
6739 | operands[8] = c4x_operand_subword (operands[2], 1, 1, HImode);") | |
6740 | ||
6741 | (define_expand "xorhi3" | |
6742 | [(parallel [(set (match_operand:HI 0 "reg_operand" "") | |
6743 | (xor:HI (match_operand:HI 1 "src_operand" "") | |
6744 | (match_operand:HI 2 "src_operand" ""))) | |
6745 | (clobber (reg:CC 21))])] | |
6746 | "" | |
8de858c0 | 6747 | "legitimize_operands (XOR, operands, HImode);") |
cb0ca284 MH |
6748 | |
6749 | ||
6750 | (define_insn "*xorhi3_clobber" | |
65c78c7d MH |
6751 | [(set (match_operand:HI 0 "reg_operand" "=d,d,?d") |
6752 | (xor:HI (match_operand:HI 1 "src_operand" "%0,rR,rS<>") | |
6753 | (match_operand:HI 2 "src_operand" "rm,R,rS<>"))) | |
cb0ca284 MH |
6754 | (clobber (reg:CC 21))] |
6755 | "valid_operands (XOR, operands, HImode)" | |
6756 | "#" | |
6757 | [(set_attr "type" "multi,multi,multi")]) | |
6758 | ||
6759 | (define_split | |
6760 | [(set (match_operand:HI 0 "reg_operand" "") | |
6761 | (xor:HI (match_operand:HI 1 "src_operand" "") | |
6762 | (match_operand:HI 2 "src_operand" ""))) | |
6763 | (clobber (reg:CC 21))] | |
6764 | "reload_completed" | |
6765 | [(parallel [(set (match_dup 3) (xor:QI (match_dup 4) (match_dup 5))) | |
6766 | (clobber (reg:CC 21))]) | |
6767 | (parallel [(set (match_dup 6) (xor:QI (match_dup 7) (match_dup 8))) | |
6768 | (clobber (reg:CC 21))])] | |
6769 | "operands[3] = c4x_operand_subword (operands[0], 0, 1, HImode); | |
6770 | operands[4] = c4x_operand_subword (operands[1], 0, 1, HImode); | |
6771 | operands[5] = c4x_operand_subword (operands[2], 0, 1, HImode); | |
6772 | operands[6] = c4x_operand_subword (operands[0], 1, 1, HImode); | |
6773 | operands[7] = c4x_operand_subword (operands[1], 1, 1, HImode); | |
6774 | operands[8] = c4x_operand_subword (operands[2], 1, 1, HImode);") | |
6775 | ||
cb0ca284 MH |
6776 | (define_expand "ashlhi3" |
6777 | [(parallel [(set (match_operand:HI 0 "reg_operand" "") | |
6778 | (ashift:HI (match_operand:HI 1 "src_operand" "") | |
6779 | (match_operand:QI 2 "src_operand" ""))) | |
6780 | (clobber (reg:CC 21))])] | |
6781 | "" | |
6782 | "if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32) | |
6783 | { | |
6784 | rtx op0hi = operand_subword (operands[0], 1, 0, HImode); | |
6785 | rtx op0lo = operand_subword (operands[0], 0, 0, HImode); | |
6786 | rtx op1lo = operand_subword (operands[1], 0, 0, HImode); | |
e27f8c8a | 6787 | rtx count = GEN_INT ((INTVAL (operands[2]) - 32)); |
cb0ca284 MH |
6788 | |
6789 | if (INTVAL (count)) | |
6790 | emit_insn (gen_ashlqi3 (op0hi, op1lo, count)); | |
6791 | else | |
6792 | emit_insn (gen_movqi (op0hi, op1lo)); | |
6793 | emit_insn (gen_movqi (op0lo, const0_rtx)); | |
6794 | DONE; | |
6795 | } | |
4b97aaeb MH |
6796 | if (! REG_P (operands[1])) |
6797 | operands[1] = force_reg (HImode, operands[1]); | |
6798 | emit_insn (gen_ashlhi3_reg (operands[0], operands[1], operands[2])); | |
6799 | DONE; | |
6800 | ") | |
cb0ca284 MH |
6801 | |
6802 | ; %0.lo = %1.lo << %2 | |
6803 | ; %0.hi = (%1.hi << %2 ) | (%1.lo >> (32 - %2)) | |
6804 | ; This algorithm should work for shift counts greater than 32 | |
6805 | (define_expand "ashlhi3_reg" | |
4b97aaeb | 6806 | [(use (match_operand:HI 1 "reg_operand" "")) |
cb0ca284 MH |
6807 | (use (match_operand:HI 0 "reg_operand" "")) |
6808 | /* If the shift count is greater than 32 this will give zero. */ | |
6809 | (parallel [(set (match_dup 7) | |
6810 | (ashift:QI (match_dup 3) | |
6811 | (match_operand:QI 2 "reg_operand" ""))) | |
6812 | (clobber (reg:CC 21))]) | |
6813 | /* If the shift count is greater than 32 this will give zero. */ | |
6814 | (parallel [(set (match_dup 8) | |
6815 | (ashift:QI (match_dup 4) (match_dup 2))) | |
6816 | (clobber (reg:CC 21))]) | |
6817 | (parallel [(set (match_dup 10) | |
6818 | (plus:QI (match_dup 2) (const_int -32))) | |
6819 | (clobber (reg:CC_NOOV 21))]) | |
6820 | /* If the shift count is greater than 32 this will do a left shift. */ | |
6821 | (parallel [(set (match_dup 9) | |
6822 | (lshiftrt:QI (match_dup 3) (neg:QI (match_dup 10)))) | |
6823 | (clobber (reg:CC 21))]) | |
6824 | (set (match_dup 5) (match_dup 7)) | |
6825 | (parallel [(set (match_dup 6) | |
6826 | (ior:QI (match_dup 8) (match_dup 9))) | |
6827 | (clobber (reg:CC 21))])] | |
6828 | "" | |
6829 | " | |
6830 | operands[3] = operand_subword (operands[1], 0, 1, HImode); /* lo */ | |
6831 | operands[4] = operand_subword (operands[1], 1, 1, HImode); /* hi */ | |
6832 | operands[5] = operand_subword (operands[0], 0, 1, HImode); /* lo */ | |
6833 | operands[6] = operand_subword (operands[0], 1, 1, HImode); /* hi */ | |
6834 | operands[7] = gen_reg_rtx (QImode); /* lo << count */ | |
6835 | operands[8] = gen_reg_rtx (QImode); /* hi << count */ | |
6836 | operands[9] = gen_reg_rtx (QImode); /* lo >> (32 - count) */ | |
6837 | operands[10] = gen_reg_rtx (QImode); /* 32 - count */ | |
6838 | ") | |
6839 | ||
6840 | ; This should do all the dirty work with define_split | |
6841 | (define_expand "lshrhi3" | |
6842 | [(parallel [(set (match_operand:HI 0 "reg_operand" "") | |
6843 | (lshiftrt:HI (match_operand:HI 1 "src_operand" "") | |
6844 | (match_operand:QI 2 "src_operand" ""))) | |
6845 | (clobber (reg:CC 21))])] | |
6846 | "" | |
6847 | "if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32) | |
6848 | { | |
6849 | rtx op0hi = operand_subword (operands[0], 1, 0, HImode); | |
6850 | rtx op0lo = operand_subword (operands[0], 0, 0, HImode); | |
6851 | rtx op1hi = operand_subword (operands[1], 1, 0, HImode); | |
e27f8c8a | 6852 | rtx count = GEN_INT ((INTVAL (operands[2]) - 32)); |
cb0ca284 MH |
6853 | |
6854 | if (INTVAL (count)) | |
6855 | emit_insn (gen_lshrqi3 (op0lo, op1hi, count)); | |
6856 | else | |
6857 | emit_insn (gen_movqi (op0lo, op1hi)); | |
6858 | emit_insn (gen_movqi (op0hi, const0_rtx)); | |
6859 | DONE; | |
6860 | } | |
4b97aaeb MH |
6861 | if (! REG_P (operands[1])) |
6862 | operands[1] = force_reg (HImode, operands[1]); | |
6863 | emit_insn (gen_lshrhi3_reg (operands[0], operands[1], operands[2])); | |
6864 | DONE;") | |
cb0ca284 MH |
6865 | |
6866 | ; %0.hi = %1.hi >> %2 | |
6867 | ; %0.lo = (%1.lo >> %2 ) | (%1.hi << (32 - %2)) | |
6868 | ; This algorithm should work for shift counts greater than 32 | |
6869 | (define_expand "lshrhi3_reg" | |
4b97aaeb | 6870 | [(use (match_operand:HI 1 "reg_operand" "")) |
cb0ca284 MH |
6871 | (use (match_operand:HI 0 "reg_operand" "")) |
6872 | (parallel [(set (match_dup 11) | |
6873 | (neg:QI (match_operand:QI 2 "reg_operand" ""))) | |
6874 | (clobber (reg:CC_NOOV 21))]) | |
6875 | /* If the shift count is greater than 32 this will give zero. */ | |
6876 | (parallel [(set (match_dup 7) | |
6877 | (lshiftrt:QI (match_dup 3) | |
6878 | (neg:QI (match_dup 11)))) | |
6879 | (clobber (reg:CC 21))]) | |
6880 | /* If the shift count is greater than 32 this will give zero. */ | |
6881 | (parallel [(set (match_dup 8) | |
6882 | (lshiftrt:QI (match_dup 4) | |
6883 | (neg:QI (match_dup 11)))) | |
6884 | (clobber (reg:CC 21))]) | |
6885 | (parallel [(set (match_dup 10) | |
6886 | (plus:QI (match_dup 11) (const_int 32))) | |
6887 | (clobber (reg:CC_NOOV 21))]) | |
6888 | /* If the shift count is greater than 32 this will do an arithmetic | |
6889 | right shift. However, we need a logical right shift. */ | |
6890 | (parallel [(set (match_dup 9) | |
f959ff1a | 6891 | (ashift:QI (match_dup 4) (unspec:QI [(match_dup 10)] 3))) |
cb0ca284 MH |
6892 | (clobber (reg:CC 21))]) |
6893 | (set (match_dup 6) (match_dup 8)) | |
6894 | (parallel [(set (match_dup 5) | |
6895 | (ior:QI (match_dup 7) (match_dup 9))) | |
6896 | (clobber (reg:CC 21))])] | |
6897 | "" | |
6898 | " | |
6899 | operands[3] = operand_subword (operands[1], 0, 1, HImode); /* lo */ | |
6900 | operands[4] = operand_subword (operands[1], 1, 1, HImode); /* hi */ | |
6901 | operands[5] = operand_subword (operands[0], 0, 1, HImode); /* lo */ | |
6902 | operands[6] = operand_subword (operands[0], 1, 1, HImode); /* hi */ | |
6903 | operands[7] = gen_reg_rtx (QImode); /* lo >> count */ | |
6904 | operands[8] = gen_reg_rtx (QImode); /* hi >> count */ | |
6905 | operands[9] = gen_reg_rtx (QImode); /* hi << (32 - count) */ | |
6906 | operands[10] = gen_reg_rtx (QImode); /* 32 - count */ | |
6907 | operands[11] = gen_reg_rtx (QImode); /* -count */ | |
6908 | ") | |
6909 | ||
6910 | ; This should do all the dirty work with define_split | |
6911 | (define_expand "ashrhi3" | |
6912 | [(parallel [(set (match_operand:HI 0 "reg_operand" "") | |
6913 | (ashiftrt:HI (match_operand:HI 1 "src_operand" "") | |
6914 | (match_operand:QI 2 "src_operand" ""))) | |
6915 | (clobber (reg:CC 21))])] | |
6916 | "" | |
6917 | "if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32) | |
6918 | { | |
6919 | rtx op0hi = operand_subword (operands[0], 1, 0, HImode); | |
6920 | rtx op0lo = operand_subword (operands[0], 0, 0, HImode); | |
6921 | rtx op1hi = operand_subword (operands[1], 1, 0, HImode); | |
e27f8c8a | 6922 | rtx count = GEN_INT ((INTVAL (operands[2]) - 32)); |
cb0ca284 MH |
6923 | |
6924 | if (INTVAL (count)) | |
6925 | emit_insn (gen_ashrqi3 (op0lo, op1hi, count)); | |
6926 | else | |
6927 | emit_insn (gen_movqi (op0lo, op1hi)); | |
e27f8c8a | 6928 | emit_insn (gen_ashrqi3 (op0hi, op1hi, GEN_INT (31))); |
cb0ca284 MH |
6929 | DONE; |
6930 | } | |
4b97aaeb MH |
6931 | if (! REG_P (operands[1])) |
6932 | operands[1] = force_reg (HImode, operands[1]); | |
6933 | emit_insn (gen_ashrhi3_reg (operands[0], operands[1], operands[2])); | |
6934 | DONE;") | |
cb0ca284 MH |
6935 | |
6936 | ; %0.hi = %1.hi >> %2 | |
6937 | ; %0.lo = (%1.lo >> %2 ) | (%1.hi << (32 - %2)) | |
6938 | ; This algorithm should work for shift counts greater than 32 | |
6939 | (define_expand "ashrhi3_reg" | |
4b97aaeb | 6940 | [(use (match_operand:HI 1 "reg_operand" "")) |
cb0ca284 MH |
6941 | (use (match_operand:HI 0 "reg_operand" "")) |
6942 | (parallel [(set (match_dup 11) | |
6943 | (neg:QI (match_operand:QI 2 "reg_operand" ""))) | |
6944 | (clobber (reg:CC_NOOV 21))]) | |
6945 | /* If the shift count is greater than 32 this will give zero. */ | |
6946 | (parallel [(set (match_dup 7) | |
6947 | (lshiftrt:QI (match_dup 3) | |
6948 | (neg:QI (match_dup 11)))) | |
6949 | (clobber (reg:CC 21))]) | |
6950 | /* If the shift count is greater than 32 this will give zero. */ | |
6951 | (parallel [(set (match_dup 8) | |
6952 | (ashiftrt:QI (match_dup 4) | |
6953 | (neg:QI (match_dup 11)))) | |
6954 | (clobber (reg:CC 21))]) | |
6955 | (parallel [(set (match_dup 10) | |
6956 | (plus:QI (match_dup 11) (const_int 32))) | |
6957 | (clobber (reg:CC_NOOV 21))]) | |
6958 | /* If the shift count is greater than 32 this will do an arithmetic | |
6959 | right shift. */ | |
6960 | (parallel [(set (match_dup 9) | |
6961 | (ashift:QI (match_dup 4) (match_dup 10))) | |
6962 | (clobber (reg:CC 21))]) | |
6963 | (set (match_dup 6) (match_dup 8)) | |
6964 | (parallel [(set (match_dup 5) | |
6965 | (ior:QI (match_dup 7) (match_dup 9))) | |
6966 | (clobber (reg:CC 21))])] | |
6967 | "" | |
6968 | " | |
6969 | operands[3] = operand_subword (operands[1], 0, 1, HImode); /* lo */ | |
6970 | operands[4] = operand_subword (operands[1], 1, 1, HImode); /* hi */ | |
6971 | operands[5] = operand_subword (operands[0], 0, 1, HImode); /* lo */ | |
6972 | operands[6] = operand_subword (operands[0], 1, 1, HImode); /* hi */ | |
6973 | operands[7] = gen_reg_rtx (QImode); /* lo >> count */ | |
6974 | operands[8] = gen_reg_rtx (QImode); /* hi >> count */ | |
6975 | operands[9] = gen_reg_rtx (QImode); /* hi << (32 - count) */ | |
6976 | operands[10] = gen_reg_rtx (QImode); /* 32 - count */ | |
6977 | operands[11] = gen_reg_rtx (QImode); /* -count */ | |
6978 | ") | |
6979 | ||
6980 | (define_expand "cmphi" | |
6981 | [(set (reg:CC 21) | |
6982 | (compare:CC (match_operand:HI 0 "src_operand" "") | |
6983 | (match_operand:HI 1 "src_operand" "")))] | |
6984 | "" | |
6985 | "legitimize_operands (COMPARE, operands, HImode); | |
6986 | c4x_compare_op0 = operands[0]; | |
6987 | c4x_compare_op1 = operands[1]; | |
6988 | DONE;") | |
6989 | ||
52695ce0 HB |
6990 | (define_insn "*cmphi_cc" |
6991 | [(set (reg:CC 21) | |
6992 | (compare:CC (match_operand:HI 0 "src_operand" "rR,rS<>") | |
6993 | (match_operand:HI 1 "src_operand" "R,rS<>")))] | |
6994 | "valid_operands (COMPARE, operands, HImode)" | |
6995 | "#" | |
6996 | [(set_attr "type" "multi")]) | |
6997 | ||
6998 | (define_insn "*cmphi_cc_noov" | |
6999 | [(set (reg:CC_NOOV 21) | |
7000 | (compare:CC_NOOV (match_operand:HI 0 "src_operand" "rR,rS<>") | |
7001 | (match_operand:HI 1 "src_operand" "R,rS<>")))] | |
7002 | "valid_operands (COMPARE, operands, HImode)" | |
7003 | "#" | |
7004 | [(set_attr "type" "multi")]) | |
7005 | ||
cb0ca284 MH |
7006 | ; This works only before reload because we need 2 extra registers. |
7007 | ; Use unspec to avoid recursive split. | |
7008 | (define_split | |
7009 | [(set (reg:CC 21) | |
7010 | (compare:CC (match_operand:HI 0 "src_operand" "") | |
7011 | (match_operand:HI 1 "src_operand" "")))] | |
4ddb3ea6 | 7012 | "! reload_completed" |
cb0ca284 | 7013 | [(parallel [(set (reg:CC 21) |
f959ff1a MH |
7014 | (unspec:CC [(compare:CC (match_dup 0) |
7015 | (match_dup 1))] 4)) | |
cb0ca284 MH |
7016 | (clobber (match_scratch:QI 2 "")) |
7017 | (clobber (match_scratch:QI 3 ""))])] | |
7018 | "") | |
7019 | ||
7020 | (define_split | |
7021 | [(set (reg:CC_NOOV 21) | |
7022 | (compare:CC_NOOV (match_operand:HI 0 "src_operand" "") | |
7023 | (match_operand:HI 1 "src_operand" "")))] | |
4ddb3ea6 | 7024 | "! reload_completed" |
cb0ca284 | 7025 | [(parallel [(set (reg:CC_NOOV 21) |
f959ff1a MH |
7026 | (unspec:CC_NOOV [(compare:CC_NOOV (match_dup 0) |
7027 | (match_dup 1))] 4)) | |
cb0ca284 MH |
7028 | (clobber (match_scratch:QI 2 "")) |
7029 | (clobber (match_scratch:QI 3 ""))])] | |
7030 | "") | |
7031 | ||
7032 | ; This is normally not used. The define splits above are used first. | |
52695ce0 HB |
7033 | (define_split |
7034 | [(set (reg:CC 21) | |
7035 | (compare:CC (match_operand:HI 0 "src_operand" "") | |
7036 | (match_operand:HI 1 "src_operand" "")))] | |
7037 | "reload_completed" | |
7038 | [(parallel [(set (reg:CC 21) | |
7039 | (compare:CC (match_dup 0) (match_dup 1))) | |
7040 | (use (reg:QI 20))])] | |
7041 | "") | |
7042 | ||
7043 | (define_split | |
7044 | [(set (reg:CC_NOOV 21) | |
7045 | (compare:CC_NOOV (match_operand:HI 0 "src_operand" "") | |
7046 | (match_operand:HI 1 "src_operand" "")))] | |
7047 | "reload_completed" | |
7048 | [(parallel [(set (reg:CC_NOOV 21) | |
7049 | (compare:CC_NOOV (match_dup 0) (match_dup 1))) | |
7050 | (use (reg:QI 20))])] | |
7051 | "") | |
7052 | ||
cb0ca284 MH |
7053 | (define_insn "*cmphi" |
7054 | [(set (reg:CC 21) | |
7055 | (compare:CC (match_operand:HI 0 "src_operand" "rR,rS<>") | |
52695ce0 HB |
7056 | (match_operand:HI 1 "src_operand" "R,rS<>"))) |
7057 | (use (reg:QI 20))] | |
cb0ca284 MH |
7058 | "valid_operands (COMPARE, operands, HImode)" |
7059 | "* | |
7060 | { | |
7061 | int use_ir1 = (reg_operand (operands[0], HImode) | |
7062 | && REG_P (operands[0]) | |
7063 | && REGNO (operands[0]) == IR1_REGNO) | |
7064 | || (reg_operand (operands[1], HImode) | |
7065 | && REG_P (operands[1]) | |
7066 | && REGNO (operands[1]) == IR1_REGNO); | |
7067 | ||
7068 | if (use_ir1) | |
7069 | output_asm_insn (\"push\\tir1\", operands); | |
7070 | else | |
7071 | output_asm_insn (\"push\\tbk\", operands); | |
7072 | output_asm_insn (\"push\\tr0\", operands); | |
7073 | output_asm_insn (\"subi3\\t%1,%0,r0\", operands); | |
7074 | if (use_ir1) | |
7075 | { | |
7076 | output_asm_insn (\"ldiu\\tst,ir1\", operands); | |
7077 | output_asm_insn (\"or\\t07bh,ir1\", operands); | |
7078 | } | |
7079 | else | |
7080 | { | |
7081 | output_asm_insn (\"ldiu\\tst,bk\", operands); | |
7082 | output_asm_insn (\"or\\t07bh,bk\", operands); | |
7083 | } | |
7084 | output_asm_insn (\"subb3\\t%O1,%O0,r0\", operands); | |
7085 | if (use_ir1) | |
7086 | output_asm_insn (\"and3\\tir1,st,ir1\", operands); | |
7087 | else | |
7088 | output_asm_insn (\"and3\\tbk,st,bk\", operands); | |
7089 | output_asm_insn (\"pop\\tr0\", operands); | |
7090 | if (use_ir1) | |
7091 | { | |
7092 | output_asm_insn (\"ldiu\\tir1,st\", operands); | |
7093 | output_asm_insn (\"pop\\tir1\", operands); | |
7094 | } | |
7095 | else | |
7096 | { | |
7097 | output_asm_insn (\"ldiu\\tbk,st\", operands); | |
7098 | output_asm_insn (\"pop\\tbk\", operands); | |
7099 | } | |
7100 | return \"\"; | |
7101 | }" | |
7102 | [(set_attr "type" "multi")]) | |
7103 | ||
7104 | (define_insn "*cmphi_noov" | |
7105 | [(set (reg:CC_NOOV 21) | |
7106 | (compare:CC_NOOV (match_operand:HI 0 "src_operand" "rR,rS<>") | |
52695ce0 HB |
7107 | (match_operand:HI 1 "src_operand" "R,rS<>"))) |
7108 | (use (reg:QI 20))] | |
cb0ca284 MH |
7109 | "valid_operands (COMPARE, operands, HImode)" |
7110 | "* | |
7111 | { | |
7112 | int use_ir1 = (reg_operand (operands[0], HImode) | |
7113 | && REG_P (operands[0]) | |
7114 | && REGNO (operands[0]) == IR1_REGNO) | |
7115 | || (reg_operand (operands[1], HImode) | |
7116 | && REG_P (operands[1]) | |
7117 | && REGNO (operands[1]) == IR1_REGNO); | |
7118 | ||
7119 | if (use_ir1) | |
7120 | output_asm_insn (\"push\\tir1\", operands); | |
7121 | else | |
7122 | output_asm_insn (\"push\\tbk\", operands); | |
7123 | output_asm_insn (\"push\\tr0\", operands); | |
7124 | output_asm_insn (\"subi3\\t%1,%0,r0\", operands); | |
7125 | if (use_ir1) | |
7126 | { | |
7127 | output_asm_insn (\"ldiu\\tst,ir1\", operands); | |
7128 | output_asm_insn (\"or\\t07bh,ir1\", operands); | |
7129 | } | |
7130 | else | |
7131 | { | |
7132 | output_asm_insn (\"ldiu\\tst,bk\", operands); | |
7133 | output_asm_insn (\"or\\t07bh,bk\", operands); | |
7134 | } | |
7135 | output_asm_insn (\"subb3\\t%O1,%O0,r0\", operands); | |
7136 | if (use_ir1) | |
7137 | output_asm_insn (\"and3\\tir1,st,ir1\", operands); | |
7138 | else | |
7139 | output_asm_insn (\"and3\\tbk,st,bk\", operands); | |
7140 | output_asm_insn (\"pop\\tr0\", operands); | |
7141 | if (use_ir1) | |
7142 | { | |
7143 | output_asm_insn (\"ldiu\\tir1,st\", operands); | |
7144 | output_asm_insn (\"pop\\tir1\", operands); | |
7145 | } | |
7146 | else | |
7147 | { | |
7148 | output_asm_insn (\"ldiu\\tbk,st\", operands); | |
7149 | output_asm_insn (\"pop\\tbk\", operands); | |
7150 | } | |
7151 | return \"\"; | |
7152 | }" | |
7153 | [(set_attr "type" "multi")]) | |
7154 | ||
7155 | ||
7156 | (define_insn "cmphi_cc" | |
7157 | [(set (reg:CC 21) | |
f416f18c | 7158 | (unspec:CC [(compare:CC (match_operand:HI 0 "src_operand" "rR,rS<>") |
a9d3cc3f | 7159 | (match_operand:HI 1 "src_operand" "R,rS<>"))] 4)) |
cb0ca284 MH |
7160 | (clobber (match_scratch:QI 2 "=&d,&d")) |
7161 | (clobber (match_scratch:QI 3 "=&c,&c"))] | |
7162 | "valid_operands (COMPARE, operands, HImode)" | |
7163 | "* | |
7164 | output_asm_insn (\"subi3\\t%1,%0,%2\", operands); | |
7165 | output_asm_insn (\"ldiu\\tst,%3\", operands); | |
7166 | output_asm_insn (\"or\\t07bh,%3\", operands); | |
7167 | output_asm_insn (\"subb3\\t%O1,%O0,%2\", operands); | |
7168 | output_asm_insn (\"and\\t%3,st\", operands); | |
7169 | return \"\";" | |
7170 | [(set_attr "type" "multi")]) | |
7171 | ||
7172 | (define_insn "cmphi_cc_noov" | |
7173 | [(set (reg:CC_NOOV 21) | |
a9d3cc3f MH |
7174 | (unspec:CC_NOOV [(compare:CC_NOOV (match_operand:HI 0 "src_operand" "rR,rS<>") |
7175 | (match_operand:HI 1 "src_operand" "R,rS<>"))] 4)) | |
cb0ca284 MH |
7176 | (clobber (match_scratch:QI 2 "=&d,&d")) |
7177 | (clobber (match_scratch:QI 3 "=&c,&c"))] | |
7178 | "valid_operands (COMPARE, operands, HImode)" | |
7179 | "* | |
7180 | output_asm_insn (\"subi3\\t%1,%0,%2\", operands); | |
7181 | output_asm_insn (\"ldiu\\tst,%3\", operands); | |
7182 | output_asm_insn (\"or\\t07bh,%3\", operands); | |
7183 | output_asm_insn (\"subb3\\t%O1,%O0,%2\", operands); | |
7184 | output_asm_insn (\"and\\t%3,st\", operands); | |
7185 | return \"\";" | |
7186 | [(set_attr "type" "multi")]) | |
7187 | ||
7188 | (define_expand "mulhi3" | |
7189 | [(parallel [(set (match_operand:HI 0 "reg_operand" "") | |
7190 | (mult:HI (match_operand:HI 1 "src_operand" "") | |
7191 | (match_operand:HI 2 "src_operand" ""))) | |
7192 | (clobber (reg:CC 21))])] | |
7193 | "" | |
4fda2521 HB |
7194 | "c4x_emit_libcall3 (smul_optab->handlers[(int) HImode].libfunc, |
7195 | MULT, HImode, operands); | |
cb0ca284 MH |
7196 | DONE;") |
7197 | ||
cb0ca284 MH |
7198 | |
7199 | ; | |
7200 | ; PEEPHOLES | |
7201 | ; | |
7202 | ||
7203 | ; dbCC peepholes | |
7204 | ; | |
7205 | ; Turns | |
7206 | ; loop: | |
7207 | ; [ ... ] | |
7208 | ; bCC label ; abnormal loop termination | |
7209 | ; dbu aN, loop ; normal loop termination | |
7210 | ; | |
7211 | ; Into | |
7212 | ; loop: | |
7213 | ; [ ... ] | |
7214 | ; dbCC aN, loop | |
7215 | ; bCC label | |
7216 | ; | |
7217 | ; Which moves the bCC condition outside the inner loop for free. | |
7218 | ; | |
7219 | (define_peephole | |
7220 | [(set (pc) (if_then_else (match_operator 3 "comparison_operator" | |
7221 | [(reg:CC 21) (const_int 0)]) | |
7222 | (label_ref (match_operand 2 "" "")) | |
7223 | (pc))) | |
7224 | (parallel | |
7225 | [(set (pc) | |
7226 | (if_then_else | |
50c33087 | 7227 | (ge (plus:QI (match_operand:QI 0 "addr_reg_operand" "+a") |
cb0ca284 MH |
7228 | (const_int -1)) |
7229 | (const_int 0)) | |
7230 | (label_ref (match_operand 1 "" "")) | |
7231 | (pc))) | |
50c33087 | 7232 | (set (match_dup 0) |
cb0ca284 | 7233 | (plus:QI (match_dup 0) |
f475349b | 7234 | (const_int -1))) |
52695ce0 | 7235 | (use (reg:QI 20)) |
f475349b | 7236 | (clobber (reg:CC_NOOV 21))])] |
4ddb3ea6 | 7237 | "! c4x_label_conflict (insn, operands[2], operands[1])" |
dfb31eec MH |
7238 | "db%I3\\t%0,%l1\\n\\tb%3\\t%l2" |
7239 | [(set_attr "type" "multi")]) | |
cb0ca284 MH |
7240 | |
7241 | (define_peephole | |
7242 | [(set (pc) (if_then_else (match_operator 3 "comparison_operator" | |
7243 | [(reg:CC 21) (const_int 0)]) | |
7244 | (label_ref (match_operand 2 "" "")) | |
7245 | (pc))) | |
7246 | (parallel | |
7247 | [(set (pc) | |
7248 | (if_then_else | |
50c33087 | 7249 | (ne (match_operand:QI 0 "addr_reg_operand" "+a") |
cb0ca284 MH |
7250 | (const_int 0)) |
7251 | (label_ref (match_operand 1 "" "")) | |
7252 | (pc))) | |
50c33087 | 7253 | (set (match_dup 0) |
cb0ca284 | 7254 | (plus:QI (match_dup 0) |
a9d3cc3f | 7255 | (const_int -1)))])] |
4ddb3ea6 | 7256 | "! c4x_label_conflict (insn, operands[2], operands[1])" |
dfb31eec MH |
7257 | "db%I3\\t%0,%l1\\n\\tb%3\\t%l2" |
7258 | [(set_attr "type" "multi")]) | |
cb0ca284 MH |
7259 | |
7260 | ; | |
7261 | ; Peepholes to convert 'call label; rets' into jump label | |
7262 | ; | |
f475349b | 7263 | |
cb0ca284 | 7264 | (define_peephole |
55310df7 | 7265 | [(parallel [(call (mem:QI (match_operand:QI 0 "call_address_operand" "")) |
cb0ca284 MH |
7266 | (match_operand:QI 1 "general_operand" "")) |
7267 | (clobber (reg:QI 31))]) | |
7268 | (return)] | |
7269 | "c4x_null_epilogue_p ()" | |
50c33087 | 7270 | "* |
b2e9a2fd | 7271 | if (REG_P (operands[0])) |
50c33087 MH |
7272 | return \"bu%#\\t%C0\"; |
7273 | else | |
7274 | return \"br%#\\t%C0\";" | |
7275 | [(set_attr "type" "jump")]) | |
cb0ca284 MH |
7276 | |
7277 | (define_peephole | |
7278 | [(parallel [(set (match_operand 0 "" "") | |
55310df7 | 7279 | (call (mem:QI (match_operand:QI 1 "call_address_operand" "")) |
cb0ca284 MH |
7280 | (match_operand:QI 2 "general_operand" ""))) |
7281 | (clobber (reg:QI 31))]) | |
7282 | (return)] | |
7283 | "c4x_null_epilogue_p ()" | |
50c33087 | 7284 | "* |
b2e9a2fd | 7285 | if (REG_P (operands[1])) |
50c33087 MH |
7286 | return \"bu%#\\t%C1\"; |
7287 | else | |
7288 | return \"br%#\\t%C1\";" | |
7289 | [(set_attr "type" "jump")]) | |
cb0ca284 | 7290 | |
cb0ca284 MH |
7291 | |
7292 | ; This peephole should be unnecessary with my patches to flow.c | |
7293 | ; for better autoincrement detection | |
7294 | (define_peephole | |
7295 | [(set (match_operand:QF 0 "ext_low_reg_operand" "") | |
7296 | (mem:QF (match_operand:QI 1 "addr_reg_operand" ""))) | |
7297 | (set (match_operand:QF 2 "ext_low_reg_operand" "") | |
7298 | (mem:QF (plus:QI (match_dup 1) (const_int 1)))) | |
7299 | (parallel [(set (match_dup 1) (plus:QI (match_dup 1) (const_int 2))) | |
7300 | (clobber (reg:CC_NOOV 21))])] | |
7301 | "" | |
7302 | "ldf\\t*%1++,%0\\n\\tldf\\t*%1++,%2") | |
7303 | ||
a9d3cc3f | 7304 | |
cb0ca284 MH |
7305 | ; This peephole should be unnecessary with my patches to flow.c |
7306 | ; for better autoincrement detection | |
7307 | (define_peephole | |
7308 | [(set (mem:QF (match_operand:QI 0 "addr_reg_operand" "")) | |
7309 | (match_operand:QF 1 "ext_low_reg_operand" "")) | |
7310 | (set (mem:QF (plus:QI (match_dup 0) (const_int 1))) | |
7311 | (match_operand:QF 2 "ext_low_reg_operand" "")) | |
7312 | (parallel [(set (match_dup 0) (plus:QI (match_dup 0) (const_int 2))) | |
7313 | (clobber (reg:CC_NOOV 21))])] | |
7314 | "" | |
7315 | "stf\\t%1,*%0++\\n\\tstf\\t%2,*%0++") | |
7316 | ||
cb0ca284 | 7317 | |
82bfb8e3 MH |
7318 | ; The following two peepholes remove an unecessary load |
7319 | ; often found at the end of a function. These peepholes | |
7320 | ; could be generalised to other binary operators. They shouldn't | |
7321 | ; be required if we run a post reload mop-up pass. | |
7322 | (define_peephole | |
7323 | [(parallel [(set (match_operand:QF 0 "ext_reg_operand" "") | |
7324 | (plus:QF (match_operand:QF 1 "ext_reg_operand" "") | |
7325 | (match_operand:QF 2 "ext_reg_operand" ""))) | |
7326 | (clobber (reg:CC_NOOV 21))]) | |
7327 | (set (match_operand:QF 3 "ext_reg_operand" "") | |
7328 | (match_dup 0))] | |
7329 | "dead_or_set_p (insn, operands[0])" | |
7330 | "addf3\\t%2,%1,%3") | |
7331 | ||
7332 | (define_peephole | |
7333 | [(parallel [(set (match_operand:QI 0 "reg_operand" "") | |
7334 | (plus:QI (match_operand:QI 1 "reg_operand" "") | |
7335 | (match_operand:QI 2 "reg_operand" ""))) | |
7336 | (clobber (reg:CC_NOOV 21))]) | |
7337 | (set (match_operand:QI 3 "reg_operand" "") | |
7338 | (match_dup 0))] | |
7339 | "dead_or_set_p (insn, operands[0])" | |
7340 | "addi3\\t%2,%1,%3") |