]> gcc.gnu.org Git - gcc.git/blame - gcc/config/c4x/c4x.md
avr.c: Fix comment typos.
[gcc.git] / gcc / config / c4x / c4x.md
CommitLineData
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")
This page took 1.538612 seconds and 5 git commands to generate.