OSDN Git Service

Update FSF address.
[pf3gnuchains/gcc-fork.git] / gcc / config / c4x / c4x.md
1 ;; Machine description for the TMS320C[34]x for GCC
2 ;; Copyright (C) 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
4
5 ;; Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)
6 ;;            and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl)
7
8 ;; This file is part of GCC.
9
10 ;; GCC 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 ;; GCC 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 GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
24
25 ;
26 ; TODO :
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 synthesize a proper 32 bit multiply.
33
34 ; Additional C30/C40 instructions not coded:
35 ; CALLcond, IACK, IDLE, LDE, LDFI, LDII, LDM, NORM, RETIcond
36 ; ROLC, RORC, SIGI, STFI, STII, SUBC, SWI
37
38 ; Additional C40 instructions not coded:
39 ; LDEP, LDPE, LWRct, LAJcond, RETIcondD
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]
69 ; src_operand           general operand                            [rfHmI]
70 ; par_ind_operand       indirect S mode (ARx + 0, 1, IRx)          [S<>]
71 ; parallel_operand      par_ind_operand or ext_low_reg_operand
72 ; symbolic_address_operand
73 ; call_address_operand
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) 
95 ; e
96 ; f   fp reg               R0-R11 (sets CC when dst)
97 ; g   general reg, memory, constant
98 ; h   fp reg (HFmode)      R0-R11 (sets CC when dst) 
99 ; i   immediate int constant
100 ; j
101 ; k   block count          BK
102 ; l
103 ; m   memory
104 ; n   immediate int constant with known numeric value
105 ; o   offsettable memory
106 ; p   memory address
107 ; q   low fp reg           R0-R7  (sets CC when dst)
108 ; r   general reg          R0-R11, AR0-AR7, IR0-IR1, RC, RS, RE
109 ; s   immediate int constant (value not explicit)
110 ; t                        R0-R1
111 ; u                        R2-R3
112 ; v   repeat count reg     RC
113 ; w
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
130 ; T   direct memory operand
131 ; V   non offsettable memory
132 ; X   any operand
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
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.
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 satisfying 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' constraint 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 explicitly 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 chooses 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 a 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 cannot be executed in the first delay slot 
324 ; and ldpk cannot 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"
351        (cond [(eq_attr "type" "unary,unarycc,compare,lda,ldp,store")
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
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.  */
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
379 /* Disable ldp because the c4x contains a bug. The ldp insn modifies
380    the dp register when the insn is anulled or not.
381    Also disable autoincrement insns because of a silicon bug.  */
382 (define_attr "in_annul_slot_3" "false,true"
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"))
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 (define_constants
450   [
451    (UNSPEC_BU                   1)
452    (UNSPEC_RPTS                 2)
453    (UNSPEC_LSH                  3)
454    (UNSPEC_CMPHI                4)
455    (UNSPEC_RCPF                 5)
456    (UNSPEC_RND                  6)
457    (UNSPEC_RPTB_FILL            7)
458    (UNSPEC_LOADHF_INT           8)
459    (UNSPEC_STOREHF_INT          9)
460    (UNSPEC_RSQRF                10)
461    (UNSPEC_LOADQF_INT           11)
462    (UNSPEC_STOREQF_INT          12)
463    (UNSPEC_LDIV                 13)
464    (UNSPEC_PUSH_ST              14)
465    (UNSPEC_POP_ST               15)
466    (UNSPEC_PUSH_DP              16)
467    (UNSPEC_POP_DP               17)
468    (UNSPEC_POPQI                18)
469    (UNSPEC_POPQF                19)
470    (UNSPEC_ANDN_ST              20)
471    (UNSPEC_RPTB_INIT            22)
472    (UNSPEC_TOIEEE               23)
473    (UNSPEC_FRIEEE               24)
474   ])
475
476 ;
477 ; C4x PIPELINE MODEL
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 ; When a C4x address register is loaded it will not be available for
485 ; an extra machine cycle.  Calculating with a C4x address register
486 ; makes it unavailable for 2 machine cycles.
487 ;
488 ; Just some dummy definitions. The real work is done in c4x_adjust_cost.
489 ; These are needed so the min/max READY_DELAY is known.
490
491 (define_insn_reservation "any_insn" 1 (const_int 1) "nothing")
492 (define_insn_reservation "slowest_insn" 3 (const_int 0) "nothing")
493
494 ; The attribute setar0 is set to 1 for insns where ar0 is a dst operand.
495 ; Note that the attributes unarycc and binarycc do not apply
496 ; if ar0 is a dst operand (only loading an ext. prec. reg. sets CC)
497 (define_attr "setar0" ""
498        (cond [(eq_attr "type" "unary,binary")
499                        (if_then_else (match_operand 0 "ar0_reg_operand" "")
500                                      (const_int 1) (const_int 0))]
501              (const_int 0)))
502
503 (define_attr "setlda_ar0" ""
504        (cond [(eq_attr "type" "lda")
505                        (if_then_else (match_operand 0 "ar0_reg_operand" "")
506                                      (const_int 1) (const_int 0))]
507              (const_int 0)))
508
509 ; The attribute usear0 is set to 1 for insns where ar0 is used
510 ; for addressing, as a src operand, or as a dst operand.
511 (define_attr "usear0" ""
512        (cond [(eq_attr "type" "compare,store")
513                        (if_then_else (match_operand 0 "ar0_mem_operand" "")
514                                      (const_int 1) (const_int 0))
515               (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
516                        (if_then_else (match_operand 1 "ar0_mem_operand" "")
517                                      (const_int 1) (const_int 0))
518               (eq_attr "type" "binary,binarycc")
519                        (if_then_else (match_operand 2 "ar0_mem_operand" "")
520                                      (const_int 1) (const_int 0))
521               (eq_attr "type" "db,dbc")
522                        (if_then_else (match_operand 0 "ar0_reg_operand" "")
523                                      (const_int 1) (const_int 0))]
524              (const_int 0)))
525
526 ; The attribute readar0 is set to 1 for insns where ar0 is a src operand.
527 (define_attr "readar0" ""
528        (cond [(eq_attr "type" "compare")
529                        (if_then_else (match_operand 0 "ar0_reg_operand" "")
530                                      (const_int 1) (const_int 0))
531               (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
532                        (if_then_else (match_operand 1 "ar0_reg_operand" "")
533                                      (const_int 1) (const_int 0))
534               (eq_attr "type" "binary,binarycc")
535                        (if_then_else (match_operand 2 "ar0_reg_operand" "")
536                                      (const_int 1) (const_int 0))]
537              (const_int 0)))
538
539 (define_attr "setar1" ""
540        (cond [(eq_attr "type" "unary,binary")
541                        (if_then_else (match_operand 0 "ar1_reg_operand" "")
542                                      (const_int 1) (const_int 0))]
543              (const_int 0)))
544
545 (define_attr "setlda_ar1" ""
546        (cond [(eq_attr "type" "lda")
547                        (if_then_else (match_operand 0 "ar1_reg_operand" "")
548                                      (const_int 1) (const_int 0))]
549              (const_int 0)))
550
551 (define_attr "usear1" ""
552        (cond [(eq_attr "type" "compare,store")
553                        (if_then_else (match_operand 0 "ar1_mem_operand" "")
554                                      (const_int 1) (const_int 0))
555               (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
556                        (if_then_else (match_operand 1 "ar1_mem_operand" "")
557                                      (const_int 1) (const_int 0))
558               (eq_attr "type" "binary,binarycc")
559                        (if_then_else (match_operand 2 "ar1_mem_operand" "")
560                                      (const_int 1) (const_int 0))
561               (eq_attr "type" "db,dbc")
562                        (if_then_else (match_operand 0 "ar1_reg_operand" "")
563                                      (const_int 1) (const_int 0))]
564              (const_int 0)))
565
566 (define_attr "readar1" ""
567        (cond [(eq_attr "type" "compare")
568                        (if_then_else (match_operand 0 "ar1_reg_operand" "")
569                                      (const_int 1) (const_int 0))
570               (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
571                        (if_then_else (match_operand 1 "ar1_reg_operand" "")
572                                      (const_int 1) (const_int 0))
573               (eq_attr "type" "binary,binarycc")
574                        (if_then_else (match_operand 2 "ar1_reg_operand" "")
575                                      (const_int 1) (const_int 0))]
576              (const_int 0)))
577
578 (define_attr "setar2" ""
579        (cond [(eq_attr "type" "unary,binary")
580                        (if_then_else (match_operand 0 "ar2_reg_operand" "")
581                                      (const_int 1) (const_int 0))]
582              (const_int 0)))
583
584 (define_attr "setlda_ar2" ""
585        (cond [(eq_attr "type" "lda")
586                        (if_then_else (match_operand 0 "ar2_reg_operand" "")
587                                      (const_int 1) (const_int 0))]
588              (const_int 0)))
589
590 (define_attr "usear2" ""
591        (cond [(eq_attr "type" "compare,store")
592                        (if_then_else (match_operand 0 "ar2_mem_operand" "")
593                                      (const_int 1) (const_int 0))
594               (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
595                        (if_then_else (match_operand 1 "ar2_mem_operand" "")
596                                      (const_int 1) (const_int 0))
597               (eq_attr "type" "binary,binarycc")
598                        (if_then_else (match_operand 2 "ar2_mem_operand" "")
599                                      (const_int 1) (const_int 0))
600               (eq_attr "type" "db,dbc")
601                        (if_then_else (match_operand 0 "ar2_reg_operand" "")
602                                      (const_int 1) (const_int 0))]
603              (const_int 0)))
604
605 (define_attr "readar2" ""
606        (cond [(eq_attr "type" "compare")
607                        (if_then_else (match_operand 0 "ar2_reg_operand" "")
608                                      (const_int 1) (const_int 0))
609               (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
610                        (if_then_else (match_operand 1 "ar2_reg_operand" "")
611                                      (const_int 1) (const_int 0))
612               (eq_attr "type" "binary,binarycc")
613                        (if_then_else (match_operand 2 "ar2_reg_operand" "")
614                                      (const_int 1) (const_int 0))]
615              (const_int 0)))
616
617 (define_attr "setar3" ""
618        (cond [(eq_attr "type" "unary,binary")
619                        (if_then_else (match_operand 0 "ar3_reg_operand" "")
620                                      (const_int 1) (const_int 0))]
621              (const_int 0)))
622
623 (define_attr "setlda_ar3" ""
624        (cond [(eq_attr "type" "lda")
625                        (if_then_else (match_operand 0 "ar3_reg_operand" "")
626                                      (const_int 1) (const_int 0))]
627              (const_int 0)))
628
629 (define_attr "usear3" ""
630        (cond [(eq_attr "type" "compare,store")
631                        (if_then_else (match_operand 0 "ar3_mem_operand" "")
632                                      (const_int 1) (const_int 0))
633               (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
634                        (if_then_else (match_operand 1 "ar3_mem_operand" "")
635                                      (const_int 1) (const_int 0))
636               (eq_attr "type" "binary,binarycc")
637                        (if_then_else (match_operand 2 "ar3_mem_operand" "")
638                                      (const_int 1) (const_int 0))
639               (eq_attr "type" "db,dbc")
640                        (if_then_else (match_operand 0 "ar3_reg_operand" "")
641                                      (const_int 1) (const_int 0))]
642              (const_int 0)))
643
644 (define_attr "readar3" ""
645        (cond [(eq_attr "type" "compare")
646                        (if_then_else (match_operand 0 "ar3_reg_operand" "")
647                                      (const_int 1) (const_int 0))
648               (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
649                        (if_then_else (match_operand 1 "ar3_reg_operand" "")
650                                      (const_int 1) (const_int 0))
651               (eq_attr "type" "binary,binarycc")
652                        (if_then_else (match_operand 2 "ar3_reg_operand" "")
653                                      (const_int 1) (const_int 0))]
654              (const_int 0)))
655
656 (define_attr "setar4" ""
657        (cond [(eq_attr "type" "unary,binary")
658                        (if_then_else (match_operand 0 "ar4_reg_operand" "")
659                                      (const_int 1) (const_int 0))]
660              (const_int 0)))
661
662 (define_attr "setlda_ar4" ""
663        (cond [(eq_attr "type" "lda")
664                        (if_then_else (match_operand 0 "ar4_reg_operand" "")
665                                      (const_int 1) (const_int 0))]
666              (const_int 0)))
667
668 (define_attr "usear4" ""
669        (cond [(eq_attr "type" "compare,store")
670                        (if_then_else (match_operand 0 "ar4_mem_operand" "")
671                                      (const_int 1) (const_int 0))
672               (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
673                        (if_then_else (match_operand 1 "ar4_mem_operand" "")
674                                      (const_int 1) (const_int 0))
675               (eq_attr "type" "binary,binarycc")
676                        (if_then_else (match_operand 2 "ar4_mem_operand" "")
677                                      (const_int 1) (const_int 0))
678               (eq_attr "type" "db,dbc")
679                        (if_then_else (match_operand 0 "ar4_reg_operand" "")
680                                      (const_int 1) (const_int 0))]
681              (const_int 0)))
682
683 (define_attr "readar4" ""
684        (cond [(eq_attr "type" "compare")
685                        (if_then_else (match_operand 0 "ar4_reg_operand" "")
686                                      (const_int 1) (const_int 0))
687               (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
688                        (if_then_else (match_operand 1 "ar4_reg_operand" "")
689                                      (const_int 1) (const_int 0))
690               (eq_attr "type" "binary,binarycc")
691                        (if_then_else (match_operand 2 "ar4_reg_operand" "")
692                                      (const_int 1) (const_int 0))]
693              (const_int 0)))
694
695 (define_attr "setar5" ""
696        (cond [(eq_attr "type" "unary,binary")
697                        (if_then_else (match_operand 0 "ar5_reg_operand" "")
698                                      (const_int 1) (const_int 0))]
699              (const_int 0)))
700
701 (define_attr "setlda_ar5" ""
702        (cond [(eq_attr "type" "lda")
703                        (if_then_else (match_operand 0 "ar5_reg_operand" "")
704                                      (const_int 1) (const_int 0))]
705              (const_int 0)))
706
707 (define_attr "usear5" ""
708        (cond [(eq_attr "type" "compare,store")
709                        (if_then_else (match_operand 0 "ar5_mem_operand" "")
710                                      (const_int 1) (const_int 0))
711               (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
712                        (if_then_else (match_operand 1 "ar5_mem_operand" "")
713                                      (const_int 1) (const_int 0))
714               (eq_attr "type" "binary,binarycc")
715                        (if_then_else (match_operand 2 "ar5_mem_operand" "")
716                                      (const_int 1) (const_int 0))
717               (eq_attr "type" "db,dbc")
718                        (if_then_else (match_operand 0 "ar5_reg_operand" "")
719                                      (const_int 1) (const_int 0))]
720              (const_int 0)))
721
722 (define_attr "readar5" ""
723        (cond [(eq_attr "type" "compare")
724                        (if_then_else (match_operand 0 "ar5_reg_operand" "")
725                                      (const_int 1) (const_int 0))
726               (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
727                        (if_then_else (match_operand 1 "ar5_reg_operand" "")
728                                      (const_int 1) (const_int 0))
729               (eq_attr "type" "binary,binarycc")
730                        (if_then_else (match_operand 2 "ar5_reg_operand" "")
731                                      (const_int 1) (const_int 0))]
732              (const_int 0)))
733
734 (define_attr "setar6" ""
735        (cond [(eq_attr "type" "unary,binary")
736                        (if_then_else (match_operand 0 "ar6_reg_operand" "")
737                                      (const_int 1) (const_int 0))]
738              (const_int 0)))
739
740 (define_attr "setlda_ar6" ""
741        (cond [(eq_attr "type" "lda")
742                        (if_then_else (match_operand 0 "ar6_reg_operand" "")
743                                      (const_int 1) (const_int 0))]
744              (const_int 0)))
745
746 (define_attr "usear6" ""
747        (cond [(eq_attr "type" "compare,store")
748                        (if_then_else (match_operand 0 "ar6_mem_operand" "")
749                                      (const_int 1) (const_int 0))
750               (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
751                        (if_then_else (match_operand 1 "ar6_mem_operand" "")
752                                      (const_int 1) (const_int 0))
753               (eq_attr "type" "binary,binarycc")
754                        (if_then_else (match_operand 2 "ar6_mem_operand" "")
755                                      (const_int 1) (const_int 0))
756               (eq_attr "type" "db,dbc")
757                        (if_then_else (match_operand 0 "ar6_reg_operand" "")
758                                      (const_int 1) (const_int 0))]
759              (const_int 0)))
760
761 (define_attr "readar6" ""
762        (cond [(eq_attr "type" "compare")
763                        (if_then_else (match_operand 0 "ar6_reg_operand" "")
764                                      (const_int 1) (const_int 0))
765               (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
766                        (if_then_else (match_operand 1 "ar6_reg_operand" "")
767                                      (const_int 1) (const_int 0))
768               (eq_attr "type" "binary,binarycc")
769                        (if_then_else (match_operand 2 "ar6_reg_operand" "")
770                                      (const_int 1) (const_int 0))]
771              (const_int 0)))
772
773 (define_attr "setar7" ""
774        (cond [(eq_attr "type" "unary,binary")
775                        (if_then_else (match_operand 0 "ar7_reg_operand" "")
776                                      (const_int 1) (const_int 0))]
777              (const_int 0)))
778
779 (define_attr "setlda_ar7" ""
780        (cond [(eq_attr "type" "lda")
781                        (if_then_else (match_operand 0 "ar7_reg_operand" "")
782                                      (const_int 1) (const_int 0))]
783              (const_int 0)))
784
785 (define_attr "usear7" ""
786        (cond [(eq_attr "type" "compare,store")
787                        (if_then_else (match_operand 0 "ar7_mem_operand" "")
788                                      (const_int 1) (const_int 0))
789               (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
790                        (if_then_else (match_operand 1 "ar7_mem_operand" "")
791                                      (const_int 1) (const_int 0))
792               (eq_attr "type" "binary,binarycc")
793                        (if_then_else (match_operand 2 "ar7_mem_operand" "")
794                                      (const_int 1) (const_int 0))
795               (eq_attr "type" "db,dbc")
796                        (if_then_else (match_operand 0 "ar7_reg_operand" "")
797                                      (const_int 1) (const_int 0))]
798              (const_int 0)))
799
800 (define_attr "readar7" ""
801        (cond [(eq_attr "type" "compare")
802                        (if_then_else (match_operand 0 "ar7_reg_operand" "")
803                                      (const_int 1) (const_int 0))
804               (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
805                        (if_then_else (match_operand 1 "ar7_reg_operand" "")
806                                      (const_int 1) (const_int 0))
807               (eq_attr "type" "binary,binarycc")
808                        (if_then_else (match_operand 2 "ar7_reg_operand" "")
809                                      (const_int 1) (const_int 0))]
810              (const_int 0)))
811
812 (define_attr "setir0" ""
813        (cond [(eq_attr "type" "unary,binary")
814                        (if_then_else (match_operand 0 "ir0_reg_operand" "")
815                                      (const_int 1) (const_int 0))]
816              (const_int 0)))
817
818 (define_attr "setlda_ir0" ""
819        (cond [(eq_attr "type" "lda")
820                        (if_then_else (match_operand 0 "ir0_reg_operand" "")
821                                      (const_int 1) (const_int 0))]
822              (const_int 0)))
823
824 (define_attr "useir0" ""
825        (cond [(eq_attr "type" "compare,store")
826                        (if_then_else (match_operand 0 "ir0_mem_operand" "")
827                                      (const_int 1) (const_int 0))
828               (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
829                        (if_then_else (match_operand 1 "ir0_mem_operand" "")
830                                      (const_int 1) (const_int 0))
831               (eq_attr "type" "binary,binarycc")
832                        (if_then_else (match_operand 2 "ir0_mem_operand" "")
833                                      (const_int 1) (const_int 0))]
834              (const_int 0)))
835
836 (define_attr "setir1" ""
837        (cond [(eq_attr "type" "unary,binary")
838                        (if_then_else (match_operand 0 "ir1_reg_operand" "")
839                                      (const_int 1) (const_int 0))]
840              (const_int 0)))
841
842 (define_attr "setlda_ir1" ""
843        (cond [(eq_attr "type" "lda")
844                        (if_then_else (match_operand 0 "ir1_reg_operand" "")
845                                      (const_int 1) (const_int 0))]
846              (const_int 0)))
847
848 (define_attr "useir1" ""
849        (cond [(eq_attr "type" "compare,store")
850                        (if_then_else (match_operand 0 "ir1_mem_operand" "")
851                                      (const_int 1) (const_int 0))
852               (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
853                        (if_then_else (match_operand 1 "ir1_mem_operand" "")
854                                      (const_int 1) (const_int 0))
855               (eq_attr "type" "binary,binarycc")
856                        (if_then_else (match_operand 2 "ir1_mem_operand" "")
857                                      (const_int 1) (const_int 0))]
858              (const_int 0)))
859
860 ; With the C3x, things are simpler but slower, i.e. more pipeline conflicts :(
861 ; There are three functional groups:
862 ; (1) AR0-AR7, IR0-IR1, BK
863 ; (2) DP
864 ; (3) SP
865 ;
866 ; When a register in one of these functional groups is loaded,
867 ; the contents of that or any other register in its group
868 ; will not be available to the next instruction for 2 machine cycles.
869 ; Similarly, when a register in one of the functional groups is read
870 ; excepting (IR0-IR1, BK, DP) the contents of that or any other register
871 ; in its group will not be available to the next instruction for
872 ; 1 machine cycle.
873 ;
874 ; Let's ignore functional groups 2 and 3 for now, since they are not
875 ; so important.
876
877 (define_attr "setgroup1" ""
878        (cond [(eq_attr "type" "lda,unary,binary")
879                   (if_then_else (match_operand 0 "group1_reg_operand" "")
880                                 (const_int 1) (const_int 0))]
881              (const_int 0)))
882
883 (define_attr "usegroup1" ""
884        (cond [(eq_attr "type" "compare,store,store_store,store_load")
885               (if_then_else (match_operand 0 "group1_mem_operand" "")
886                             (const_int 1) (const_int 0))
887               (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc,load_load,load_store")
888               (if_then_else (match_operand 1 "group1_mem_operand" "")
889                             (const_int 1) (const_int 0))
890               (eq_attr "type" "store_store,load_store")
891               (if_then_else (match_operand 2 "group1_mem_operand" "")
892                             (const_int 1) (const_int 0))
893               (eq_attr "type" "load_load,store_load")
894               (if_then_else (match_operand 3 "group1_mem_operand" "")
895                             (const_int 1) (const_int 0))]
896              (const_int 0)))
897
898 (define_attr "readarx" ""
899        (cond [(eq_attr "type" "compare")
900               (if_then_else (match_operand 0 "arx_reg_operand" "")
901                             (const_int 1) (const_int 0))
902               (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
903               (if_then_else (match_operand 1 "arx_reg_operand" "")
904                             (const_int 1) (const_int 0))
905               (eq_attr "type" "binary,binarycc")
906               (if_then_else (match_operand 2 "arx_reg_operand" "")
907                             (const_int 1) (const_int 0))]
908              (const_int 0)))
909
910
911 ;
912 ; C4x INSN PATTERNS:
913 ;
914 ; Note that the movMM and addP patterns can be called during reload
915 ; so we need to take special care with theses patterns since
916 ; we cannot blindly clobber CC or generate new pseudo registers.
917
918 ;
919 ; TWO OPERAND INTEGER INSTRUCTIONS
920 ;
921
922 ;
923 ; LDP/LDPK
924 ;
925 (define_insn "set_ldp"
926   [(set (match_operand:QI 0 "dp_reg_operand" "=z")
927         (high:QI (match_operand:QI 1 "" "")))]
928   "! TARGET_SMALL"
929   "* return (TARGET_C3X) ? \"ldp\\t%A1\" : \"ldpk\\t%A1\";"
930   [(set_attr "type" "ldp")])
931
932 (define_insn "set_ldp_prologue"
933   [(set (match_operand:QI 0 "dp_reg_operand" "=z")
934         (high:QI (match_operand:QI 1 "" "")))]
935   "TARGET_SMALL && TARGET_PARANOID"
936   "* return (TARGET_C3X) ? \"ldp\\t@data_sec\" : \"ldpk\\t@data_sec\";"
937   [(set_attr "type" "ldp")])
938
939 (define_insn "set_high"
940   [(set (match_operand:QI 0 "std_reg_operand" "=c")
941         (high:QI (match_operand:QI 1 "symbolic_address_operand" "")))]
942   "! TARGET_C3X && ! TARGET_TI"
943   "ldhi\\t^%H1,%0"
944   [(set_attr "type" "unary")])
945
946 (define_insn "set_lo_sum"
947   [(set (match_operand:QI 0 "std_reg_operand" "+c")
948         (lo_sum:QI (match_dup 0)
949                    (match_operand:QI 1 "symbolic_address_operand" "")))]
950   "! TARGET_TI"
951   "or\\t#%H1,%0"
952   [(set_attr "type" "unary")])
953
954 (define_split
955   [(set (match_operand:QI 0 "std_reg_operand" "")
956         (match_operand:QI 1 "symbolic_address_operand" ""))]
957   "reload_completed && ! TARGET_C3X && ! TARGET_TI"
958   [(set (match_dup 0) (high:QI (match_dup 1)))
959    (set (match_dup 0) (lo_sum:QI (match_dup 0) (match_dup 1)))]
960   "")
961
962 (define_split
963   [(set (match_operand:QI 0 "reg_operand" "")
964         (match_operand:QI 1 "const_int_operand" ""))
965    (clobber (reg:QI 16))]
966   "! TARGET_C3X
967    && ! IS_INT16_CONST (INTVAL (operands[1]))
968    && ! IS_HIGH_CONST (INTVAL (operands[1]))
969    && reload_completed
970    && std_reg_operand (operands[0], QImode)"
971   [(set (match_dup 0) (match_dup 2))
972    (set (match_dup 0) (ior:QI (match_dup 0) (match_dup 3)))]
973   "
974 {
975    operands[2] = GEN_INT (INTVAL (operands[1]) & ~0xffff);
976    operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
977 }")
978
979 (define_split
980   [(set (match_operand:QI 0 "reg_operand" "")
981         (match_operand:QI 1 "const_int_operand" ""))]
982   "! TARGET_C3X
983    && ! IS_INT16_CONST (INTVAL (operands[1]))
984    && ! IS_HIGH_CONST (INTVAL (operands[1]))
985    && reload_completed
986    && std_reg_operand (operands[0], QImode)"
987   [(set (match_dup 0) (match_dup 2))
988    (set (match_dup 0) (ior:QI (match_dup 0) (match_dup 3)))]
989   "
990 {
991    operands[2] = GEN_INT (INTVAL (operands[1]) & ~0xffff);
992    operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
993 }")
994
995 (define_split
996   [(set (match_operand:QI 0 "reg_operand" "")
997         (match_operand:QI 1 "const_int_operand" ""))
998    (clobber (reg:QI 16))]
999   "TARGET_C3X && ! TARGET_SMALL
1000    && ! IS_INT16_CONST (INTVAL (operands[1]))
1001    && reload_completed
1002    && std_reg_operand (operands[0], QImode)
1003    && c4x_shiftable_constant (operands[1]) < 0"
1004   [(set (match_dup 0) (match_dup 2))
1005    (set (match_dup 0) (ashift:QI (match_dup 0) (match_dup 4)))
1006    (set (match_dup 0) (ior:QI (match_dup 0) (match_dup 3)))]
1007   "
1008 {
1009    /* Generate two's complement value of 16 MSBs.  */
1010    operands[2] = GEN_INT ((((INTVAL (operands[1]) >> 16) & 0xffff)
1011                            - 0x8000) ^ ~0x7fff);
1012    operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
1013    operands[4] = GEN_INT (16);
1014 }")
1015
1016 (define_split
1017   [(set (match_operand:QI 0 "reg_operand" "")
1018         (match_operand:QI 1 "const_int_operand" ""))]
1019   "TARGET_C3X && ! TARGET_SMALL
1020    && ! IS_INT16_CONST (INTVAL (operands[1]))
1021    && reload_completed
1022    && std_reg_operand (operands[0], QImode)
1023    && c4x_shiftable_constant (operands[1]) < 0"
1024   [(set (match_dup 0) (match_dup 2))
1025    (set (match_dup 0) (ashift:QI (match_dup 0) (match_dup 4)))
1026    (set (match_dup 0) (ior:QI (match_dup 0) (match_dup 3)))]
1027   "
1028 {
1029    /* Generate two's complement value of 16 MSBs.  */
1030    operands[2] = GEN_INT ((((INTVAL (operands[1]) >> 16) & 0xffff)
1031                            - 0x8000) ^ ~0x7fff);
1032    operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
1033    operands[4] = GEN_INT (16);
1034 }")
1035
1036 (define_split
1037   [(set (match_operand:QI 0 "reg_operand" "")
1038         (match_operand:QI 1 "const_int_operand" ""))
1039    (clobber (reg:QI 16))]
1040   "TARGET_C3X
1041    && ! IS_INT16_CONST (INTVAL (operands[1]))
1042    && reload_completed
1043    && std_reg_operand (operands[0], QImode)
1044    && c4x_shiftable_constant (operands[1]) >= 0"
1045   [(set (match_dup 0) (match_dup 2))
1046    (set (match_dup 0) (ashift:QI (match_dup 0) (match_dup 3)))]
1047   "
1048 {
1049    /* Generate two's complement value of MSBs.  */
1050    int shift = c4x_shiftable_constant (operands[1]);
1051
1052    operands[2] = GEN_INT ((((INTVAL (operands[1]) >> shift) & 0xffff)
1053                            - 0x8000) ^ ~0x7fff);
1054    operands[3] = GEN_INT (shift);
1055 }")
1056
1057 (define_split
1058   [(set (match_operand:QI 0 "reg_operand" "")
1059         (match_operand:QI 1 "const_int_operand" ""))]
1060   "TARGET_C3X
1061    && ! IS_INT16_CONST (INTVAL (operands[1]))
1062    && reload_completed
1063    && std_reg_operand (operands[0], QImode)
1064    && c4x_shiftable_constant (operands[1]) >= 0"
1065   [(set (match_dup 0) (match_dup 2))
1066    (set (match_dup 0) (ashift:QI (match_dup 0) (match_dup 3)))]
1067   "
1068 {
1069    /* Generate two's complement value of MSBs.  */
1070    int shift = c4x_shiftable_constant (operands[1]);
1071
1072    operands[2] = GEN_INT ((((INTVAL (operands[1]) >> shift) & 0xffff)
1073                             - 0x8000) ^ ~0x7fff);
1074    operands[3] = GEN_INT (shift);
1075 }")
1076
1077 (define_split
1078   [(set (match_operand:QI 0 "reg_operand" "")
1079         (match_operand:QI 1 "const_int_operand" ""))
1080    (clobber (reg:QI 16))]
1081   "! TARGET_SMALL
1082    && ! IS_INT16_CONST (INTVAL (operands[1]))
1083    && ! IS_HIGH_CONST (INTVAL (operands[1]))
1084    && reload_completed
1085    && ! std_reg_operand (operands[0], QImode)"
1086   [(set (match_dup 2) (high:QI (match_dup 3)))
1087    (set (match_dup 0) (match_dup 4))
1088    (use (match_dup 1))]
1089   "
1090 {
1091    rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
1092    operands[2] = dp_reg;
1093    operands[3] = force_const_mem (Pmode, operands[1]);
1094    operands[4] = change_address (operands[3], QImode,
1095                                  gen_rtx_LO_SUM (Pmode, dp_reg,
1096                                                  XEXP (operands[3], 0)));
1097    operands[3] = XEXP (operands[3], 0);
1098 }")
1099
1100 (define_split
1101   [(set (match_operand:QI 0 "reg_operand" "")
1102         (match_operand:QI 1 "const_int_operand" ""))]
1103   "! TARGET_SMALL
1104    && ! IS_INT16_CONST (INTVAL (operands[1]))
1105    && ! IS_HIGH_CONST (INTVAL (operands[1]))
1106    && reload_completed
1107    && ! std_reg_operand (operands[0], QImode)"
1108   [(set (match_dup 2) (high:QI (match_dup 3)))
1109    (set (match_dup 0) (match_dup 4))
1110    (use (match_dup 1))]
1111   "
1112 {
1113    rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
1114    operands[2] = dp_reg;
1115    operands[3] = force_const_mem (Pmode, operands[1]);
1116    operands[4] = change_address (operands[3], QImode,
1117                                  gen_rtx_LO_SUM (Pmode, dp_reg,
1118                                                  XEXP (operands[3], 0)));
1119    operands[3] = XEXP (operands[3], 0);
1120 }")
1121
1122 (define_split
1123   [(set (match_operand:QI 0 "reg_operand" "")
1124         (match_operand:QI 1 "const_int_operand" ""))
1125    (clobber (reg:QI 16))]
1126   "TARGET_SMALL
1127    && ! IS_INT16_CONST (INTVAL (operands[1]))
1128    && ! IS_HIGH_CONST (INTVAL (operands[1]))
1129    && reload_completed
1130    && ((TARGET_C3X && c4x_shiftable_constant (operands[1]) < 0)
1131        || ! std_reg_operand (operands[0], QImode))"
1132   [(set (match_dup 0) (match_dup 2))
1133    (use (match_dup 1))]
1134   "
1135 {
1136    rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
1137    operands[2] = force_const_mem (Pmode, operands[1]);
1138    operands[2] = change_address (operands[2], QImode,
1139                                  gen_rtx_LO_SUM (Pmode, dp_reg,
1140                                                  XEXP (operands[2], 0)));
1141 }")
1142
1143 (define_split
1144   [(set (match_operand:QI 0 "reg_operand" "")
1145         (match_operand:QI 1 "const_int_operand" ""))]
1146   "TARGET_SMALL
1147    && ! IS_INT16_CONST (INTVAL (operands[1]))
1148    && ! IS_HIGH_CONST (INTVAL (operands[1]))
1149    && reload_completed
1150    && ((TARGET_C3X && c4x_shiftable_constant (operands[1]) < 0)
1151        || ! std_reg_operand (operands[0], QImode))"
1152   [(set (match_dup 0) (match_dup 2))
1153    (use (match_dup 1))]
1154   "
1155 {
1156    rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
1157    operands[2] = force_const_mem (Pmode, operands[1]);
1158    operands[2] = change_address (operands[2], QImode,
1159                                  gen_rtx_LO_SUM (Pmode, dp_reg,
1160                                                  XEXP (operands[2], 0)));
1161 }")
1162
1163 (define_split
1164   [(set (match_operand:HI 0 "reg_operand" "")
1165         (match_operand:HI 1 "const_int_operand" ""))
1166    (clobber (reg:QI 16))]
1167   "reload_completed"
1168   [(set (match_dup 2) (match_dup 4))
1169    (set (match_dup 3) (match_dup 5))]
1170   "
1171 {
1172    operands[2] = c4x_operand_subword (operands[0], 0, 1, HImode);
1173    operands[3] = c4x_operand_subword (operands[0], 1, 1, HImode);
1174    operands[4] = c4x_operand_subword (operands[1], 0, 1, HImode);
1175    operands[5] = c4x_operand_subword (operands[1], 1, 1, HImode);
1176 }")
1177
1178
1179 ; We need to clobber the DP reg to be safe in case we
1180 ; need to load this address from memory
1181 (define_insn "load_immed_address"
1182   [(set (match_operand:QI 0 "reg_operand" "=a?x?c*r")
1183         (match_operand:QI 1 "symbolic_address_operand" ""))
1184    (clobber (reg:QI 16))]
1185   "TARGET_LOAD_ADDRESS"
1186   "#"
1187   [(set_attr "type" "multi")])
1188
1189
1190 (define_split
1191   [(set (match_operand:QI 0 "std_reg_operand" "")
1192         (match_operand:QI 1 "symbolic_address_operand" ""))
1193    (clobber (reg:QI 16))]
1194   "reload_completed && ! TARGET_C3X && ! TARGET_TI"
1195   [(set (match_dup 0) (high:QI (match_dup 1)))
1196    (set (match_dup 0) (lo_sum:QI (match_dup 0) (match_dup 1)))]
1197   "")
1198
1199 ; CC has been selected to load a symbolic address.  We force the address
1200 ; into memory and then generate LDP and LDIU insns.
1201 ; This is also required for the C30 if we pretend that we can 
1202 ; easily load symbolic addresses into a register.
1203 (define_split
1204   [(set (match_operand:QI 0 "reg_operand" "")
1205         (match_operand:QI 1 "symbolic_address_operand" ""))
1206    (clobber (reg:QI 16))]
1207   "reload_completed
1208    && ! TARGET_SMALL 
1209    && (TARGET_C3X || TARGET_TI || ! std_reg_operand (operands[0], QImode))"
1210   [(set (match_dup 2) (high:QI (match_dup 3)))
1211    (set (match_dup 0) (match_dup 4))
1212    (use (match_dup 1))]
1213   "
1214 {
1215    rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
1216    operands[2] = dp_reg;
1217    operands[3] = force_const_mem (Pmode, operands[1]);
1218    operands[4] = change_address (operands[3], QImode,
1219                                  gen_rtx_LO_SUM (Pmode, dp_reg,
1220                                                  XEXP (operands[3], 0)));
1221    operands[3] = XEXP (operands[3], 0);
1222 }")
1223
1224 ; This pattern is similar to the above but does not emit a LDP
1225 ; for the small memory model.
1226 (define_split
1227   [(set (match_operand:QI 0 "reg_operand" "")
1228         (match_operand:QI 1 "symbolic_address_operand" ""))
1229    (clobber (reg:QI 16))]
1230   "reload_completed
1231    && TARGET_SMALL
1232    && (TARGET_C3X || TARGET_TI || ! std_reg_operand (operands[0], QImode))"
1233   [(set (match_dup 0) (match_dup 2))
1234    (use (match_dup 1))]
1235   "
1236 {  
1237    rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
1238    operands[2] = force_const_mem (Pmode, operands[1]);
1239    operands[2] = change_address (operands[2], QImode,
1240                                  gen_rtx_LO_SUM (Pmode, dp_reg,
1241                                                  XEXP (operands[2], 0)));
1242 }")
1243
1244 (define_insn "loadhi_big_constant"
1245   [(set (match_operand:HI 0 "reg_operand" "=c*d")
1246         (match_operand:HI 1 "const_int_operand" ""))
1247    (clobber (reg:QI 16))]
1248   ""
1249   "#"
1250   [(set_attr "type" "multi")])
1251
1252 ;
1253 ; LDIU/LDA/STI/STIK
1254 ;
1255 ; The following moves will not set the condition codes register.
1256 ;
1257
1258 ; This must come before the general case
1259 (define_insn "*movqi_stik"
1260   [(set (match_operand:QI 0 "memory_operand" "=m")
1261         (match_operand:QI 1 "stik_const_operand" "K"))]
1262   "! TARGET_C3X"
1263   "stik\\t%1,%0"
1264   [(set_attr "type" "store")])
1265
1266 (define_insn "loadqi_big_constant"
1267   [(set (match_operand:QI 0 "reg_operand" "=c*d")
1268         (match_operand:QI 1 "const_int_operand" ""))
1269    (clobber (reg:QI 16))]
1270   "! IS_INT16_CONST (INTVAL (operands[1]))
1271    && ! IS_HIGH_CONST (INTVAL (operands[1]))"
1272   "#"
1273   [(set_attr "type" "multi")])
1274
1275 ; We must provide an alternative to store to memory in case we have to
1276 ; spill a register.
1277 (define_insn "movqi_noclobber"
1278   [(set (match_operand:QI 0 "dst_operand" "=d,*c,m,r")
1279         (match_operand:QI 1 "src_hi_operand" "rIm,rIm,r,O"))]
1280   "(REG_P (operands[0]) || REG_P (operands[1])
1281     || GET_CODE (operands[0]) == SUBREG
1282     || GET_CODE (operands[1]) == SUBREG)
1283     && ! symbolic_address_operand (operands[1], QImode)"
1284   "*
1285    if (which_alternative == 2)
1286      return \"sti\\t%1,%0\";
1287
1288    if (! TARGET_C3X && which_alternative == 3)
1289      {
1290        operands[1] = GEN_INT ((INTVAL (operands[1]) >> 16) & 0xffff);
1291        return \"ldhi\\t%1,%0\";
1292      }
1293
1294    /* The lda instruction cannot use the same register as source
1295       and destination.  */
1296    if (! TARGET_C3X && which_alternative == 1
1297        && (   IS_ADDR_REG (operands[0])
1298            || IS_INDEX_REG (operands[0])
1299            || IS_SP_REG (operands[0]))
1300        && (REGNO (operands[0]) != REGNO (operands[1])))
1301       return \"lda\\t%1,%0\";
1302    return \"ldiu\\t%1,%0\";
1303   "
1304   [(set_attr "type" "unary,lda,store,unary")
1305    (set_attr "data" "int16,int16,int16,high_16")])
1306
1307 ;
1308 ; LDI
1309 ;
1310
1311 ; We shouldn't need these peepholes, but the combiner seems to miss them...
1312 (define_peephole
1313   [(set (match_operand:QI 0 "ext_reg_operand" "=d")
1314         (match_operand:QI 1 "src_operand" "rIm"))
1315    (set (reg:CC 21)
1316         (compare:CC (match_dup 0) (const_int 0)))]
1317   ""
1318   "ldi\\t%1,%0"
1319   [(set_attr "type" "unarycc")
1320    (set_attr "data" "int16")])
1321
1322 (define_insn "*movqi_set"
1323   [(set (reg:CC 21)
1324         (compare:CC (match_operand:QI 1 "src_operand" "rIm") 
1325                     (const_int 0)))
1326    (set (match_operand:QI 0 "ext_reg_operand" "=d")
1327         (match_dup 1))]
1328   ""
1329   "ldi\\t%1,%0"
1330   [(set_attr "type" "unarycc")
1331    (set_attr "data" "int16")])
1332
1333 ; This pattern probably gets in the way and requires a scratch register
1334 ; when a simple compare with zero will suffice.
1335 ;(define_insn "*movqi_test"
1336 ; [(set (reg:CC 21)
1337 ;       (compare:CC (match_operand:QI 1 "src_operand" "rIm") 
1338 ;                   (const_int 0)))
1339 ;  (clobber (match_scratch:QI 0 "=d"))]
1340 ; ""
1341 ; "@
1342 ;  ldi\\t%1,%0"
1343 ;  [(set_attr "type" "unarycc")
1344 ;   (set_attr "data" "int16")])
1345
1346 ;  If one of the operands is not a register, then we should
1347 ;  emit two insns, using a scratch register.  This will produce
1348 ;  better code in loops if the source operand is invariant, since
1349 ;  the source reload can be optimized out.  During reload we cannot
1350 ;  use change_address or force_reg which will allocate new pseudo regs.
1351
1352 ;  Unlike most other insns, the move insns can't be split with
1353 ;  different predicates, because register spilling and other parts of
1354 ;  the compiler, have memoized the insn number already.
1355
1356 (define_expand "movqi"
1357   [(set (match_operand:QI 0 "general_operand" "")
1358         (match_operand:QI 1 "general_operand" ""))]
1359   ""
1360   "
1361 {
1362   if (c4x_emit_move_sequence (operands, QImode))
1363     DONE;
1364 }")
1365
1366
1367 ; As far as GCC is concerned, the moves are performed in parallel
1368 ; thus it must be convinced that there is no aliasing.
1369 ; It also assumes that the input operands are simultaneously loaded
1370 ; and then the output operands are simultaneously stored.
1371 ; With the C4x, if there are parallel stores to the same address
1372 ; both stores are executed.
1373 ; If there is a parallel load and store to the same address,
1374 ; the load is performed first.
1375 ; The problem with this pattern is that reload can spoil
1376 ; the show when it eliminates a reference to the frame pointer.
1377 ; This can invalidate the memory addressing mode, i.e., when
1378 ; the displacement is greater than 1.
1379 (define_insn "movqi_parallel"
1380   [(set (match_operand:QI 0 "parallel_operand" "=q,S<>!V,q,S<>!V")
1381         (match_operand:QI 1 "parallel_operand" "S<>!V,q,S<>!V,q"))
1382    (set (match_operand:QI 2 "parallel_operand" "=q,S<>!V,S<>!V,q")
1383         (match_operand:QI 3 "parallel_operand" "S<>!V,q,q,S<>!V"))]
1384   "TARGET_PARALLEL && valid_parallel_load_store (operands, QImode)"
1385   "@
1386    ldi1\\t%1,%0\\n||\\tldi2\\t%3,%2
1387    sti1\\t%1,%0\\n||\\tsti2\\t%3,%2
1388    ldi\\t%1,%0\\n||\\tsti\\t%3,%2
1389    ldi\\t%3,%2\\n||\\tsti\\t%1,%0"
1390   [(set_attr "type" "load_load,store_store,load_store,store_load")])
1391
1392 ;
1393 ; PUSH/POP
1394 ;
1395 (define_insn "pushqi"
1396   [(set (mem:QI (pre_inc:QI (reg:QI 20)))
1397         (match_operand:QI 0 "reg_operand" "r"))]
1398   ""
1399   "push\\t%0"
1400   [(set_attr "type" "push")])
1401
1402 (define_insn "push_st"
1403   [(set (mem:QI (pre_inc:QI (reg:QI 20)))
1404         (unspec:QI [(reg:QI 21)] UNSPEC_PUSH_ST))
1405    (use (reg:QI 21))]
1406   ""
1407   "push\\tst"
1408   [(set_attr "type" "push")])
1409
1410 (define_insn "push_dp"
1411   [(set (mem:QI (pre_inc:QI (reg:QI 20))) 
1412         (unspec:QI [(reg:QI 16)] UNSPEC_PUSH_DP))
1413    (use (reg:QI 16))]
1414   ""
1415   "push\\tdp"
1416   [(set_attr "type" "push")])
1417
1418 (define_insn "popqi"
1419   [(set (match_operand:QI 0 "reg_operand" "=r")
1420         (mem:QI (post_dec:QI (reg:QI 20))))
1421    (clobber (reg:CC 21))]
1422   ""
1423   "pop\\t%0"
1424   [(set_attr "type" "pop")])
1425
1426 (define_insn "pop_st"
1427   [(set (unspec:QI [(reg:QI 21)] UNSPEC_POP_ST) 
1428         (mem:QI (post_dec:QI (reg:QI 20))))
1429    (clobber (reg:CC 21))]
1430   ""
1431   "pop\\tst"
1432   [(set_attr "type" "pop")])
1433
1434 (define_insn "pop_dp"
1435   [(set (unspec:QI [(reg:QI 16)] UNSPEC_POP_DP)
1436         (mem:QI (post_dec:QI (reg:QI 20))))
1437    (clobber (reg:CC 16))]
1438   ""
1439   "pop\\tdp"
1440   [(set_attr "type" "pop")])
1441
1442 (define_insn "popqi_unspec"
1443   [(set (unspec:QI [(match_operand:QI 0 "reg_operand" "=r")] UNSPEC_POPQI)
1444         (mem:QI (post_dec:QI (reg:QI 20))))
1445    (clobber (match_dup 0))
1446    (clobber (reg:CC 21))]
1447   ""
1448   "pop\\t%0"
1449   [(set_attr "type" "pop")])
1450
1451 ;
1452 ; ABSI
1453 ;
1454 (define_expand "absqi2"
1455   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
1456                    (abs:QI (match_operand:QI 1 "src_operand" "")))
1457               (clobber (reg:CC_NOOV 21))])]
1458   ""
1459   "")
1460
1461 (define_insn "*absqi2_clobber"
1462   [(set (match_operand:QI 0 "reg_operand" "=d,c")
1463         (abs:QI (match_operand:QI 1 "src_operand" "rIm,rIm")))
1464    (clobber (reg:CC_NOOV 21))]
1465   ""
1466   "absi\\t%1,%0"
1467   [(set_attr "type" "unarycc,unary")
1468    (set_attr "data" "int16,int16")])
1469
1470 (define_insn "*absqi2_noclobber"
1471   [(set (match_operand:QI 0 "std_reg_operand" "=c")
1472         (abs:QI (match_operand:QI 1 "src_operand" "rIm")))]
1473   ""
1474   "absi\\t%1,%0"
1475   [(set_attr "type" "unary")
1476    (set_attr "data" "int16")])
1477
1478 (define_split
1479   [(set (match_operand:QI 0 "std_reg_operand" "")
1480         (abs:QI (match_operand:QI 1 "src_operand" "")))
1481    (clobber (reg:CC_NOOV 21))]
1482   "reload_completed"
1483   [(set (match_dup 0)
1484         (abs:QI (match_dup 1)))]
1485   "")
1486
1487 (define_insn "*absqi2_test"
1488   [(set (reg:CC_NOOV 21)
1489         (compare:CC_NOOV (abs:QI (match_operand:QI 1 "src_operand" "rIm"))
1490                          (const_int 0)))
1491    (clobber (match_scratch:QI 0 "=d"))]
1492   ""
1493   "absi\\t%1,%0"
1494   [(set_attr "type" "unarycc")
1495    (set_attr "data" "int16")])
1496
1497 (define_insn "*absqi2_set"
1498   [(set (reg:CC_NOOV 21)
1499         (compare:CC_NOOV (abs:QI (match_operand:QI 1 "src_operand" "rIm"))
1500                          (const_int 0)))
1501    (set (match_operand:QI 0 "ext_reg_operand" "=d")
1502         (abs:QI (match_dup 1)))]
1503   ""
1504   "absi\\t%1,%0"
1505   [(set_attr "type" "unarycc")
1506    (set_attr "data" "int16")])        
1507
1508 ;
1509 ; NEGI
1510 ;
1511 (define_expand "negqi2"
1512   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
1513                    (neg:QI (match_operand:QI 1 "src_operand" "")))
1514               (clobber (reg:CC_NOOV 21))])]
1515 ""
1516 "")
1517
1518 (define_insn "*negqi2_clobber"
1519   [(set (match_operand:QI 0 "reg_operand" "=d,c")
1520         (neg:QI (match_operand:QI 1 "src_operand" "rIm,rIm")))
1521    (clobber (reg:CC_NOOV 21))]
1522   ""
1523   "negi\\t%1,%0"
1524   [(set_attr "type" "unarycc,unary")
1525    (set_attr "data" "int16,int16")])
1526
1527 (define_insn "*negqi2_noclobber"
1528   [(set (match_operand:QI 0 "std_reg_operand" "=c")
1529         (neg:QI (match_operand:QI 1 "src_operand" "rIm")))]
1530   ""
1531   "negi\\t%1,%0"
1532   [(set_attr "type" "unary")
1533    (set_attr "data" "int16")])
1534
1535 (define_split
1536   [(set (match_operand:QI 0 "std_reg_operand" "")
1537         (neg:QI (match_operand:QI 1 "src_operand" "")))
1538    (clobber (reg:CC_NOOV 21))]
1539   "reload_completed"
1540   [(set (match_dup 0)
1541         (neg:QI (match_dup 1)))]
1542   "")
1543
1544 (define_insn "*negqi2_test"
1545   [(set (reg:CC_NOOV 21)
1546         (compare:CC_NOOV (neg:QI (match_operand:QI 1 "src_operand" "rIm"))
1547                          (const_int 0)))
1548    (clobber (match_scratch:QI 0 "=d"))]
1549   ""
1550   "negi\\t%1,%0"
1551   [(set_attr "type" "unarycc")
1552    (set_attr "data" "int16")])
1553
1554 (define_insn "*negqi2_set"
1555   [(set (reg:CC_NOOV 21)
1556         (compare:CC_NOOV (neg:QI (match_operand:QI 1 "src_operand" "rIm"))
1557                          (const_int 0)))
1558    (set (match_operand:QI 0 "ext_reg_operand" "=d")
1559         (neg:QI (match_dup 1)))]
1560   ""
1561   "negi\\t%1,%0"
1562   [(set_attr "type" "unarycc")
1563    (set_attr "data" "int16")])        
1564
1565 (define_insn "*negbqi2_clobber"
1566   [(set (match_operand:QI 0 "ext_reg_operand" "=d")
1567         (neg:QI (match_operand:QI 1 "src_operand" "rIm")))
1568    (use (reg:CC_NOOV 21))
1569    (clobber (reg:CC_NOOV 21))]
1570   ""
1571   "negb\\t%1,%0"
1572   [(set_attr "type" "unarycc")
1573    (set_attr "data" "int16")])        
1574
1575 ;
1576 ; NOT
1577 ;
1578 (define_expand "one_cmplqi2"
1579   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
1580                    (not:QI (match_operand:QI 1 "lsrc_operand" "")))
1581               (clobber (reg:CC 21))])]
1582   ""
1583   "")
1584
1585 (define_insn "*one_cmplqi2_clobber"
1586   [(set (match_operand:QI 0 "reg_operand" "=d,c")
1587         (not:QI (match_operand:QI 1 "lsrc_operand" "rLm,rLm")))
1588    (clobber (reg:CC 21))]
1589   ""
1590   "not\\t%1,%0"
1591   [(set_attr "type" "unarycc,unary")
1592    (set_attr "data" "uint16,uint16")])
1593
1594 (define_insn "*one_cmplqi2_noclobber"
1595   [(set (match_operand:QI 0 "std_reg_operand" "=c")
1596         (not:QI (match_operand:QI 1 "lsrc_operand" "rLm")))]
1597   ""
1598   "not\\t%1,%0"
1599   [(set_attr "type" "unary")
1600    (set_attr "data" "uint16")])
1601
1602 (define_split
1603   [(set (match_operand:QI 0 "std_reg_operand" "")
1604         (not:QI (match_operand:QI 1 "lsrc_operand" "")))
1605    (clobber (reg:CC 21))]
1606   "reload_completed"
1607   [(set (match_dup 0)
1608         (not:QI (match_dup 1)))]
1609   "")
1610
1611 (define_insn "*one_cmplqi2_test"
1612   [(set (reg:CC 21)
1613         (compare:CC (not:QI (match_operand:QI 1 "lsrc_operand" "rLm"))
1614                     (const_int 0)))
1615    (clobber (match_scratch:QI 0 "=d"))]
1616   ""
1617   "not\\t%1,%0"
1618   [(set_attr "type" "unarycc")
1619    (set_attr "data" "uint16")])
1620
1621 (define_insn "*one_cmplqi2_set"
1622   [(set (reg:CC 21)
1623         (compare:CC (not:QI (match_operand:QI 1 "lsrc_operand" "rLm"))
1624                     (const_int 0)))
1625    (set (match_operand:QI 0 "ext_reg_operand" "=d")        
1626         (not:QI (match_dup 1)))]
1627   ""
1628   "not\\t%1,%0"
1629   [(set_attr "type" "unarycc")
1630    (set_attr "data" "uint16")])        
1631
1632 (define_insn "*one_cmplqi2_const_clobber"
1633   [(set (match_operand:QI 0 "reg_operand" "=d,c")
1634         (match_operand:QI 1 "not_const_operand" "N,N"))
1635    (clobber (reg:CC 21))]
1636   ""
1637   "@
1638    not\\t%N1,%0
1639    not\\t%N1,%0"
1640    [(set_attr "type" "unarycc,unary")
1641     (set_attr "data" "not_uint16,not_uint16")])
1642
1643 ; movqi can use this for loading an integer that can't normally
1644 ; fit into a 16-bit signed integer.  The drawback is that it cannot
1645 ; go into R0-R11 since that will clobber the CC and movqi shouldn't
1646 ; do that.  This can cause additional reloading but in most cases
1647 ; this will cause only an additional register move.  With the large
1648 ; memory model we require an extra instruction to load DP anyway,
1649 ; if we're loading the constant from memory.  The big advantage of
1650 ; allowing constants that satisfy not_const_operand in movqi, is that
1651 ; it allows andn to be generated more often.
1652 ; However, there is a problem if GCC has decided that it wants
1653 ; to use R0-R11, since we won't have a matching pattern...
1654 ; In interim, we prevent immed_const allowing `N' constants.
1655 (define_insn "*one_cmplqi2_const_noclobber"
1656   [(set (match_operand:QI 0 "std_reg_operand" "=c")
1657         (match_operand:QI 1 "not_const_operand" "N"))]
1658   ""
1659   "not\\t%N1,%0"
1660   [(set_attr "type" "unary")
1661    (set_attr "data" "not_uint16")])
1662
1663 ;
1664 ; ROL
1665 ;
1666 (define_expand "rotlqi3"
1667   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
1668                    (rotate:QI (match_operand:QI 1 "reg_operand" "")
1669                               (match_operand:QI 2 "const_int_operand" "")))
1670               (clobber (reg:CC 21))])]
1671   ""
1672   "if (INTVAL (operands[2]) > 4)
1673      FAIL; /* Open code as two shifts and an or */
1674    if (INTVAL (operands[2]) > 1)
1675      {
1676         int i;
1677         rtx tmp;
1678
1679         /* If we have 4 or fewer shifts, then it is probably faster
1680            to emit separate ROL instructions.  A C3x requires
1681            at least 4 instructions (a C4x requires at least 3), to
1682            perform a rotation by shifts.  */
1683
1684         tmp = operands[1];
1685         for (i = 0; i < INTVAL (operands[2]) - 1; i++)
1686           {
1687             tmp = gen_reg_rtx (QImode);
1688             emit_insn (gen_rotl_1_clobber (tmp, operands[1]));
1689             operands[1] = tmp;
1690           }
1691         emit_insn (gen_rotl_1_clobber (operands[0], tmp));
1692         DONE;
1693      }")
1694
1695 (define_insn "rotl_1_clobber"
1696   [(set (match_operand:QI 0 "reg_operand" "=d,c")
1697         (rotate:QI (match_operand:QI 1 "reg_operand" "0,0")
1698                    (const_int 1)))
1699    (clobber (reg:CC 21))]
1700   ""
1701   "rol\\t%0"
1702   [(set_attr "type" "unarycc,unary")])
1703 ; Default to int16 data attr.
1704
1705 ;
1706 ; ROR
1707 ;
1708 (define_expand "rotrqi3"
1709   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
1710                    (rotatert:QI (match_operand:QI 1 "reg_operand" "")
1711                                 (match_operand:QI 2 "const_int_operand" "")))
1712               (clobber (reg:CC 21))])]
1713   ""
1714   "if (INTVAL (operands[2]) > 4)
1715      FAIL; /* Open code as two shifts and an or */
1716    if (INTVAL (operands[2]) > 1)
1717      {
1718         int i;
1719         rtx tmp;
1720  
1721         /* If we have 4 or fewer shifts, then it is probably faster
1722            to emit separate ROL instructions.  A C3x requires
1723            at least 4 instructions (a C4x requires at least 3), to
1724            perform a rotation by shifts.  */
1725  
1726         tmp = operands[1];
1727         for (i = 0; i < INTVAL (operands[2]) - 1; i++)
1728           {
1729             tmp = gen_reg_rtx (QImode);
1730             emit_insn (gen_rotr_1_clobber (tmp, operands[1]));
1731             operands[1] = tmp;
1732           }
1733         emit_insn (gen_rotr_1_clobber (operands[0], tmp));
1734         DONE;
1735      }")
1736
1737 (define_insn "rotr_1_clobber"
1738   [(set (match_operand:QI 0 "reg_operand" "=d,c")
1739         (rotatert:QI (match_operand:QI 1 "reg_operand" "0,0")
1740                      (const_int 1)))
1741    (clobber (reg:CC 21))]
1742   ""
1743   "ror\\t%0"
1744   [(set_attr "type" "unarycc,unary")])
1745 ; Default to int16 data attr.
1746
1747
1748 ;
1749 ; THREE OPERAND INTEGER INSTRUCTIONS
1750 ;
1751
1752 ;
1753 ; ADDI
1754 ;
1755 ; This is used by reload when it calls gen_add2_insn for address arithmetic
1756 ; so we must emit the pattern that doesn't clobber CC.
1757 ;
1758 (define_expand "addqi3"
1759   [(parallel [(set (match_operand:QI 0 "std_or_reg_operand" "")
1760                    (plus:QI (match_operand:QI 1 "src_operand" "")
1761                             (match_operand:QI 2 "src_operand" "")))
1762               (clobber (reg:CC_NOOV 21))])]
1763   ""
1764   "legitimize_operands (PLUS, operands, QImode);
1765    if (reload_in_progress
1766        || (! IS_PSEUDO_REG (operands[0]) 
1767            && ! IS_EXT_REG (operands[0])))
1768    {
1769       emit_insn (gen_addqi3_noclobber (operands[0], operands[1], operands[2]));
1770       DONE;
1771    }")
1772
1773 ; This pattern is required primarily for manipulating the stack pointer
1774 ; where GCC doesn't expect CC to be clobbered or for calculating
1775 ; addresses during reload.  Since this is a more specific pattern
1776 ; it needs to go first (otherwise we get into problems trying to decide
1777 ; to add clobbers).
1778 (define_insn "addqi3_noclobber"
1779   [(set (match_operand:QI 0 "std_reg_operand" "=c,c,c")
1780         (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
1781                  (match_operand:QI 2 "src_operand" "rIm,JR,rS<>")))]
1782   "valid_operands (PLUS, operands, QImode)"
1783   "@
1784    addi\\t%2,%0
1785    addi3\\t%2,%1,%0
1786    addi3\\t%2,%1,%0"
1787   [(set_attr "type" "binary,binary,binary")])
1788 ; Default to int16 data attr.
1789
1790 (define_insn "*addqi3_clobber"
1791   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
1792         (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>")
1793                  (match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>")))
1794    (clobber (reg:CC_NOOV 21))]
1795   "valid_operands (PLUS, operands, QImode)"
1796   "@
1797    addi\\t%2,%0
1798    addi3\\t%2,%1,%0
1799    addi3\\t%2,%1,%0
1800    addi\\t%2,%0
1801    addi3\\t%2,%1,%0
1802    addi3\\t%2,%1,%0"
1803   [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")])
1804 ; Default to int16 data attr.
1805
1806 (define_split
1807   [(set (match_operand:QI 0 "std_reg_operand" "")
1808         (plus:QI (match_operand:QI 1 "src_operand" "")
1809                  (match_operand:QI 2 "src_operand" "")))
1810    (clobber (reg:CC_NOOV 21))]
1811   "reload_completed"
1812   [(set (match_dup 0)
1813         (plus:QI (match_dup 1)
1814                  (match_dup 2)))]
1815   "")
1816
1817 (define_insn "*addqi3_test"
1818   [(set (reg:CC_NOOV 21)
1819         (compare:CC_NOOV (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
1820                                   (match_operand:QI 2 "src_operand" "rIm,JR,rS<>"))
1821                          (const_int 0)))
1822    (clobber (match_scratch:QI 0 "=d,d,d"))]
1823   "valid_operands (PLUS, operands, QImode)"
1824   "@
1825    addi\\t%2,%0
1826    addi3\\t%2,%1,%0
1827    addi3\\t%2,%1,%0"
1828   [(set_attr "type" "binarycc,binarycc,binarycc")])
1829 ; Default to int16 data attr.
1830
1831 ; gcc does this in combine.c we just reverse it here
1832 (define_insn "*cmp_neg"
1833   [(set (reg:CC_NOOV 21)
1834         (compare:CC_NOOV (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
1835                          (neg: QI (match_operand:QI 2 "src_operand" "g,JR,rS<>"))))
1836    (clobber (match_scratch:QI 0 "=d,d,d"))]
1837   "valid_operands (PLUS, operands, QImode)"
1838   "@
1839    addi\\t%2,%0
1840    addi3\\t%2,%1,%0
1841    addi3\\t%2,%1,%0"
1842   [(set_attr "type" "binarycc,binarycc,binarycc")])
1843   
1844 (define_peephole
1845   [(parallel [(set (match_operand:QI 0 "ext_reg_operand" "=d,d,d")
1846                    (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
1847                             (match_operand:QI 2 "src_operand" "g,JR,rS<>")))
1848               (clobber (reg:CC_NOOV 21))])
1849    (set (reg:CC_NOOV 21)
1850         (compare:CC_NOOV (match_dup 0) (const_int 0)))]
1851   "valid_operands (PLUS, operands, QImode)"
1852   "@
1853    addi\\t%2,%0
1854    addi3\\t%2,%1,%0
1855    addi3\\t%2,%1,%0"
1856   [(set_attr "type" "binarycc,binarycc,binarycc")])
1857
1858 (define_insn "*addqi3_set"
1859   [(set (reg:CC_NOOV 21)
1860         (compare:CC_NOOV (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
1861                                   (match_operand:QI 2 "src_operand" "rIm,JR,rS<>"))
1862                          (const_int 0)))
1863    (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d")
1864         (plus:QI (match_dup 1) (match_dup 2)))]
1865   "valid_operands (PLUS, operands, QImode)"
1866   "@
1867    addi\\t%2,%0
1868    addi3\\t%2,%1,%0
1869    addi3\\t%2,%1,%0"
1870   [(set_attr "type" "binarycc,binarycc,binarycc")])
1871 ; Default to int16 data attr.
1872
1873
1874 ; This pattern is required during reload when eliminate_regs_in_insn
1875 ; effectively converts a move insn into an add insn when the src
1876 ; operand is the frame pointer plus a constant.  Without this
1877 ; pattern, gen_addqi3 can be called with a register for operand0
1878 ; that can clobber CC.
1879 ; For example, we may have (set (mem (reg ar0)) (reg 99))
1880 ; with (set (reg 99) (plus (reg ar3) (const_int 8)))
1881 ; Now since ar3, the frame pointer, is unchanging within the function,
1882 ; (plus (reg ar3) (const_int 8)) is considered a constant.
1883 ; eliminate_regs_in_insn substitutes this constant to give
1884 ; (set (mem (reg ar0)) (plus (reg ar3) (const_int 8))).
1885 ; This is an invalid C4x insn but if we don't provide a pattern
1886 ; for it, it will be considered to be a move insn for reloading.
1887 (define_insn "*addqi3_noclobber_reload"
1888   [(set (match_operand:QI 0 "std_reg_operand" "=c,c,c")
1889         (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
1890                  (match_operand:QI 2 "src_operand" "rIm,JR,rS<>")))]
1891   "reload_in_progress"
1892   "@
1893    addi\\t%2,%0
1894    addi3\\t%2,%1,%0
1895    addi3\\t%2,%1,%0"
1896   [(set_attr "type" "binary,binary,binary")])
1897 ; Default to int16 data attr.
1898
1899
1900 (define_insn "*addqi3_carry_clobber"
1901   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
1902         (plus:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>")
1903                  (match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>")))
1904    (use (reg:CC_NOOV 21))
1905    (clobber (reg:CC_NOOV 21))]
1906   "valid_operands (PLUS, operands, QImode)"
1907   "@
1908    addc\\t%2,%0
1909    addc3\\t%2,%1,%0
1910    addc3\\t%2,%1,%0
1911    addc\\t%2,%0
1912    addc3\\t%2,%1,%0
1913    addc3\\t%2,%1,%0"
1914   [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")])
1915 ; Default to int16 data attr.
1916
1917
1918 ;
1919 ; SUBI/SUBRI
1920 ;
1921 (define_expand "subqi3"
1922   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
1923                    (minus:QI (match_operand:QI 1 "src_operand" "")
1924                              (match_operand:QI 2 "src_operand" "")))
1925               (clobber (reg:CC_NOOV 21))])]
1926   ""
1927   "legitimize_operands (MINUS, operands, QImode);")
1928
1929 (define_insn "*subqi3_clobber"
1930   [(set (match_operand:QI 0 "reg_operand" "=d,d,d,?d,c,c,c,?c")
1931         (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>,0,rIm,rR,rS<>")
1932                   (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>,rIm,0,JR,rS<>")))
1933    (clobber (reg:CC_NOOV 21))]
1934   "valid_operands (MINUS, operands, QImode)"
1935   "@
1936    subi\\t%2,%0
1937    subri\\t%1,%0
1938    subi3\\t%2,%1,%0
1939    subi3\\t%2,%1,%0
1940    subi\\t%2,%0
1941    subri\\t%1,%0
1942    subi3\\t%2,%1,%0
1943    subi3\\t%2,%1,%0"
1944   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc,binary,binary,binary,binary")])
1945 ; Default to int16 data attr.
1946
1947 (define_split
1948   [(set (match_operand:QI 0 "std_reg_operand" "")
1949         (minus:QI (match_operand:QI 1 "src_operand" "")
1950                   (match_operand:QI 2 "src_operand" "")))
1951    (clobber (reg:CC_NOOV 21))]
1952   "reload_completed"
1953   [(set (match_dup 0)
1954         (minus:QI (match_dup 1)
1955                  (match_dup 2)))]
1956   "")
1957
1958 (define_insn "*subqi3_test"
1959   [(set (reg:CC_NOOV 21)
1960         (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>")
1961                                    (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>"))
1962                          (const_int 0)))
1963    (clobber (match_scratch:QI 0 "=d,d,d,?d"))]
1964   "valid_operands (MINUS, operands, QImode)"
1965   "@
1966    subi\\t%2,%0
1967    subri\\t%1,%0
1968    subi3\\t%2,%1,%0
1969    subi3\\t%2,%1,%0"
1970   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")])
1971 ; Default to int16 data attr.
1972
1973 (define_peephole
1974   [(parallel [(set (match_operand:QI 0 "ext_reg_operand" "=d,d,d,?d")
1975                    (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>")
1976                              (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>")))
1977               (clobber (reg:CC_NOOV 21))])
1978    (set (reg:CC_NOOV 21)
1979         (compare:CC_NOOV (match_dup 0) (const_int 0)))]
1980   "valid_operands (MINUS, operands, QImode)"
1981   "@
1982    subi\\t%2,%0
1983    subri\\t%1,%0
1984    subi3\\t%2,%1,%0
1985    subi3\\t%2,%1,%0"
1986   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")])
1987   
1988 (define_insn "*subqi3_set"
1989   [(set (reg:CC_NOOV 21)
1990         (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>")
1991                                    (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>"))
1992                          (const_int 0)))
1993    (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d,?d")
1994         (minus:QI (match_dup 1)
1995                   (match_dup 2)))]
1996   "valid_operands (MINUS, operands, QImode)"
1997   "@
1998    subi\\t%2,%0
1999    subri\\t%1,%0
2000    subi3\\t%2,%1,%0
2001    subi3\\t%2,%1,%0"
2002   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")])
2003 ; Default to int16 data attr.
2004
2005 (define_insn "*subqi3_noclobber"
2006   [(set (match_operand:QI 0 "std_reg_operand" "=c,c,c,?c")
2007         (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>")
2008                   (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>")))]
2009   "valid_operands (MINUS, operands, QImode)"
2010   "@
2011    subi\\t%2,%0
2012    subri\\t%1,%0
2013    subi3\\t%2,%1,%0
2014    subi3\\t%2,%1,%0"
2015   [(set_attr "type" "binary,binary,binary,binary")])
2016 ; Default to int16 data attr.
2017
2018 (define_insn "*subqi3_carry_clobber"
2019   [(set (match_operand:QI 0 "reg_operand" "=d,d,d,?d,c,c,c,?c")
2020         (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>,0,rIm,rR,rS<>")
2021                   (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>,rIm,0,JR,rS<>")))
2022    (use (reg:CC_NOOV 21))
2023    (clobber (reg:CC_NOOV 21))]
2024   "valid_operands (MINUS, operands, QImode)"
2025   "@
2026    subb\\t%2,%0
2027    subrb\\t%1,%0
2028    subb3\\t%2,%1,%0
2029    subb3\\t%2,%1,%0
2030    subb\\t%2,%0
2031    subrb\\t%1,%0
2032    subb3\\t%2,%1,%0
2033    subb3\\t%2,%1,%0"
2034   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc,binary,binary,binary,binary")])
2035 ; Default to int16 data attr.
2036
2037 (define_insn "*subqi3_carry_set"
2038   [(set (reg:CC_NOOV 21)
2039         (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "0,rIm,rR,rS<>")
2040                                    (match_operand:QI 2 "src_operand" "rIm,0,JR,rS<>"))
2041                          (const_int 0)))
2042    (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d,?d")
2043         (minus:QI (match_dup 1)
2044                   (match_dup 2)))
2045    (use (reg:CC_NOOV 21))]
2046   "valid_operands (MINUS, operands, QImode)"
2047   "@
2048    subb\\t%2,%0
2049    subrb\\t%1,%0
2050    subb3\\t%2,%1,%0
2051    subb3\\t%2,%1,%0"
2052   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")])
2053 ; Default to int16 data attr.
2054
2055 ;
2056 ; MPYI
2057 ;
2058 (define_expand "mulqi3"
2059   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
2060                    (mult:QI (match_operand:QI 1 "src_operand" "")
2061                             (match_operand:QI 2 "src_operand" "")))
2062               (clobber (reg:CC_NOOV 21))])]
2063   ""
2064   "if (TARGET_MPYI || (GET_CODE (operands[2]) == CONST_INT
2065        && exact_log2 (INTVAL (operands[2])) >= 0))
2066      legitimize_operands (MULT, operands, QImode);
2067    else
2068      {        
2069        if (GET_CODE (operands[2]) == CONST_INT)
2070          {
2071           /* Let GCC try to synthesize the multiplication using shifts
2072              and adds.  In most cases this will be more profitable than
2073              using the C3x MPYI.  */
2074             FAIL;
2075          }
2076        if (operands[1] == operands[2])
2077          {
2078             /* Do the squaring operation in-line.  */
2079             emit_insn (gen_sqrqi2_inline (operands[0], operands[1]));
2080             DONE;
2081          }
2082        if (TARGET_INLINE)
2083          {
2084             emit_insn (gen_mulqi3_inline (operands[0], operands[1],
2085                                           operands[2]));
2086             DONE;
2087          }
2088        c4x_emit_libcall3 (smul_optab->handlers[(int) QImode].libfunc,
2089                           MULT, QImode, operands);
2090        DONE;
2091      }
2092   ")
2093
2094 (define_insn "*mulqi3_clobber"
2095   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
2096         (mult:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>")
2097                  (match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>")))
2098    (clobber (reg:CC_NOOV 21))]
2099   "valid_operands (MULT, operands, QImode)"
2100   "*
2101   if (which_alternative == 0 || which_alternative == 3)
2102     {
2103       if (TARGET_C3X
2104           && GET_CODE (operands[2]) == CONST_INT
2105           && exact_log2 (INTVAL (operands[2])) >= 0)
2106         return \"ash\\t%L2,%0\";
2107       else
2108         return \"mpyi\\t%2,%0\";
2109     }
2110   else
2111       return \"mpyi3\\t%2,%1,%0\";"
2112   [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")])
2113 ; Default to int16 data attr.
2114
2115 (define_insn "*mulqi3_test"
2116   [(set (reg:CC_NOOV 21)
2117         (compare:CC_NOOV (mult:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
2118                                   (match_operand:QI 2 "src_operand" "rIm,JR,rS<>"))
2119                          (const_int 0)))
2120    (clobber (match_scratch:QI 0 "=d,d,d"))]
2121   "valid_operands (MULT, operands, QImode)"
2122   "*
2123   if (which_alternative == 0)
2124     {
2125       if (TARGET_C3X 
2126           && GET_CODE (operands[2]) == CONST_INT
2127           && exact_log2 (INTVAL (operands[2])) >= 0)
2128         return \"ash\\t%L2,%0\";
2129       else
2130         return \"mpyi\\t%2,%0\";
2131     } 
2132   else
2133       return \"mpyi3\\t%2,%1,%0\";"
2134   [(set_attr "type" "binarycc,binarycc,binarycc")])
2135 ; Default to int16 data attr.
2136
2137 (define_insn "*mulqi3_set"
2138   [(set (reg:CC_NOOV 21)
2139         (compare:CC_NOOV (mult:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
2140                                   (match_operand:QI 2 "src_operand" "rIm,JR,rS<>"))
2141                          (const_int 0)))
2142    (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d")
2143         (mult:QI (match_dup 1)
2144                  (match_dup 2)))]
2145   "valid_operands (MULT, operands, QImode)"
2146   "*
2147   if (which_alternative == 0)
2148     {
2149       if (TARGET_C3X 
2150           && GET_CODE (operands[2]) == CONST_INT
2151           && exact_log2 (INTVAL (operands[2])) >= 0)
2152         return \"ash\\t%L2,%0\";
2153       else
2154         return \"mpyi\\t%2,%0\";
2155     }
2156     else
2157         return \"mpyi3\\t%2,%1,%0\";"
2158   [(set_attr "type" "binarycc,binarycc,binarycc")])
2159 ; Default to int16 data attr.
2160
2161 ; The C3x multiply instruction assumes 24-bit signed integer operands
2162 ; and the 48-bit result is truncated to 32-bits.
2163 (define_insn "mulqi3_24_clobber"
2164   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
2165         (mult:QI
2166          (sign_extend:QI
2167           (and:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>")
2168                   (const_int 16777215)))
2169          (sign_extend:QI
2170           (and:QI (match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>")
2171                   (const_int 16777215)))))
2172    (clobber (reg:CC_NOOV 21))]
2173   "TARGET_C3X && valid_operands (MULT, operands, QImode)"
2174   "@
2175    mpyi\\t%2,%0
2176    mpyi3\\t%2,%1,%0
2177    mpyi3\\t%2,%1,%0
2178    mpyi\\t%2,%0
2179    mpyi3\\t%2,%1,%0
2180    mpyi3\\t%2,%1,%0"
2181   [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")])
2182 ; Default to int16 data attr.
2183
2184
2185 ; Fast square function for C3x where TARGET_MPYI not asserted
2186 (define_expand "sqrqi2_inline"
2187   [(set (match_dup 7) (match_operand:QI 1 "src_operand" ""))
2188    (parallel [(set (match_dup 3)
2189                    (lshiftrt:QI (match_dup 7) (const_int 16)))
2190               (clobber (reg:CC 21))])
2191    (parallel [(set (match_dup 2)
2192                    (and:QI (match_dup 7) (const_int 65535)))
2193               (clobber (reg:CC 21))])
2194    (parallel [(set (match_dup 4)
2195                    (mult:QI (sign_extend:QI (and:QI (match_dup 2) 
2196                                                     (const_int 16777215)))
2197                             (sign_extend:QI (and:QI (match_dup 2) 
2198                                                     (const_int 16777215)))))
2199               (clobber (reg:CC_NOOV 21))])
2200    (parallel [(set (match_dup 5)
2201                    (mult:QI (sign_extend:QI (and:QI (match_dup 2) 
2202                                                     (const_int 16777215)))
2203                             (sign_extend:QI (and:QI (match_dup 3) 
2204                                                     (const_int 16777215)))))
2205               (clobber (reg:CC_NOOV 21))])
2206    (parallel [(set (match_dup 6)
2207                    (ashift:QI (match_dup 5) (const_int 17)))
2208               (clobber (reg:CC 21))])
2209    (parallel [(set (match_operand:QI 0 "reg_operand" "")
2210                    (plus:QI (match_dup 4) (match_dup 6)))
2211               (clobber (reg:CC_NOOV 21))])]
2212   ""
2213   "
2214   operands[2] = gen_reg_rtx (QImode); /* a = val & 0xffff */
2215   operands[3] = gen_reg_rtx (QImode); /* b = val >> 16 */
2216   operands[4] = gen_reg_rtx (QImode); /* a * a */
2217   operands[5] = gen_reg_rtx (QImode); /* a * b */
2218   operands[6] = gen_reg_rtx (QImode); /* (a * b) << 17 */
2219   operands[7] = gen_reg_rtx (QImode); /* val */
2220   ")
2221
2222 ; Inlined integer multiply for C3x
2223 (define_expand "mulqi3_inline"
2224   [(set (match_dup 12) (const_int -16))
2225    (set (match_dup 13) (match_operand:QI 1 "src_operand" ""))
2226    (set (match_dup 14) (match_operand:QI 2 "src_operand" ""))
2227    (parallel [(set (match_dup 4)
2228                    (lshiftrt:QI (match_dup 13) (neg:QI (match_dup 12))))
2229               (clobber (reg:CC 21))])
2230    (parallel [(set (match_dup 6)
2231                    (lshiftrt:QI (match_dup 14) (neg:QI (match_dup 12))))
2232               (clobber (reg:CC 21))])
2233    (parallel [(set (match_dup 3)
2234                    (and:QI (match_dup 13)
2235                            (const_int 65535)))
2236               (clobber (reg:CC 21))])
2237    (parallel [(set (match_dup 5)
2238                    (and:QI (match_dup 14) 
2239                            (const_int 65535)))
2240               (clobber (reg:CC 21))])
2241    (parallel [(set (match_dup 7)
2242                    (mult:QI (sign_extend:QI (and:QI (match_dup 4) 
2243                                                     (const_int 16777215)))
2244                             (sign_extend:QI (and:QI (match_dup 5) 
2245                                                     (const_int 16777215)))))
2246               (clobber (reg:CC_NOOV 21))])
2247    (parallel [(set (match_dup 8)
2248                    (mult:QI (sign_extend:QI (and:QI (match_dup 3) 
2249                                                     (const_int 16777215)))
2250                             (sign_extend:QI (and:QI (match_dup 5) 
2251                                                     (const_int 16777215)))))
2252               (clobber (reg:CC_NOOV 21))])
2253    (parallel [(set (match_dup 9)
2254                    (mult:QI (sign_extend:QI (and:QI (match_dup 3) 
2255                                                     (const_int 16777215)))
2256                             (sign_extend:QI (and:QI (match_dup 6) 
2257                                                     (const_int 16777215)))))
2258               (clobber (reg:CC_NOOV 21))])
2259    (parallel [(set (match_dup 10)
2260                    (plus:QI (match_dup 7) (match_dup 9)))
2261               (clobber (reg:CC_NOOV 21))])
2262    (parallel [(set (match_dup 11)
2263                    (ashift:QI (match_dup 10) (const_int 16)))
2264               (clobber (reg:CC 21))])
2265    (parallel [(set (match_operand:QI 0 "reg_operand" "")
2266                    (plus:QI (match_dup 8) (match_dup 11)))
2267               (clobber (reg:CC_NOOV 21))])]
2268   "TARGET_C3X"
2269   "
2270   operands[3] = gen_reg_rtx (QImode); /* a = arg1 & 0xffff */
2271   operands[4] = gen_reg_rtx (QImode); /* b = arg1 >> 16 */
2272   operands[5] = gen_reg_rtx (QImode); /* a = arg2 & 0xffff */
2273   operands[6] = gen_reg_rtx (QImode); /* b = arg2 >> 16 */
2274   operands[7] = gen_reg_rtx (QImode); /* b * c */
2275   operands[8] = gen_reg_rtx (QImode); /* a * c */
2276   operands[9] = gen_reg_rtx (QImode); /* a * d */
2277   operands[10] = gen_reg_rtx (QImode); /* b * c + a * d */
2278   operands[11] = gen_reg_rtx (QImode); /* (b *c + a * d) << 16 */
2279   operands[12] = gen_reg_rtx (QImode); /* -16 */
2280   operands[13] = gen_reg_rtx (QImode); /* arg1 */
2281   operands[14] = gen_reg_rtx (QImode); /* arg2 */
2282   ")
2283
2284 ;
2285 ; MPYSHI (C4x only)
2286 ;
2287 (define_expand "smulqi3_highpart"
2288   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
2289                    (truncate:QI
2290                     (lshiftrt:HI
2291                      (mult:HI
2292                       (sign_extend:HI (match_operand:QI 1 "src_operand" ""))
2293                       (sign_extend:HI (match_operand:QI 2 "src_operand" "")))
2294                  (const_int 32))))
2295               (clobber (reg:CC_NOOV 21))])]
2296  ""
2297  "legitimize_operands (MULT, operands, QImode);
2298   if (TARGET_C3X)
2299     {
2300        c4x_emit_libcall_mulhi (smulhi3_libfunc, SIGN_EXTEND, QImode, operands);
2301        DONE;
2302     }
2303  ")
2304
2305 (define_insn "*smulqi3_highpart_clobber"
2306   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
2307         (truncate:QI 
2308          (lshiftrt:HI
2309           (mult:HI
2310            (sign_extend:HI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>"))
2311            (sign_extend:HI (match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>")))
2312       (const_int 32))))
2313    (clobber (reg:CC_NOOV 21))]
2314   "! TARGET_C3X && valid_operands (MULT, operands, QImode)"
2315   "@
2316    mpyshi\\t%2,%0
2317    mpyshi3\\t%2,%1,%0
2318    mpyshi3\\t%2,%1,%0
2319    mpyshi\\t%2,%0
2320    mpyshi3\\t%2,%1,%0
2321    mpyshi3\\t%2,%1,%0"
2322   [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")
2323    (set_attr "data" "int16,int16,int16,int16,int16,int16")])
2324
2325 (define_insn "*smulqi3_highpart_noclobber"
2326   [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c")
2327         (truncate:QI 
2328          (lshiftrt:HI
2329           (mult:HI
2330            (sign_extend:HI (match_operand:QI 1 "src_operand" "0,rR,rS<>"))
2331            (sign_extend:HI (match_operand:QI 2 "src_operand" "rIm,JR,rS<>")))
2332       (const_int 32))))]
2333   "! TARGET_C3X && valid_operands (MULT, operands, QImode)"
2334   "@
2335    mpyshi\\t%2,%0
2336    mpyshi3\\t%2,%1,%0
2337    mpyshi3\\t%2,%1,%0"
2338   [(set_attr "type" "binary,binary,binary")
2339    (set_attr "data" "int16,int16,int16")])
2340
2341 ;
2342 ; MPYUHI (C4x only)
2343 ;
2344 (define_expand "umulqi3_highpart"
2345   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
2346                (truncate:QI
2347                 (lshiftrt:HI
2348                  (mult:HI
2349                   (zero_extend:HI (match_operand:QI 1
2350                                    "nonimmediate_src_operand" ""))
2351                   (zero_extend:HI (match_operand:QI 2
2352                                    "nonimmediate_lsrc_operand" "")))
2353                  (const_int 32))))
2354               (clobber (reg:CC_NOOV 21))])]
2355  ""
2356  "legitimize_operands (MULT, operands, QImode);
2357   if (TARGET_C3X) 
2358     {
2359       c4x_emit_libcall_mulhi (umulhi3_libfunc, ZERO_EXTEND, QImode, operands);
2360       DONE;
2361     }
2362  ")
2363
2364 (define_insn "*umulqi3_highpart_clobber"
2365   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
2366         (truncate:QI
2367          (lshiftrt:HI
2368           (mult:HI 
2369            (zero_extend:HI (match_operand:QI 1
2370                             "nonimmediate_src_operand" "%0,rR,rS<>,0,rR,rS<>"))
2371            (zero_extend:HI (match_operand:QI 2
2372                             "nonimmediate_lsrc_operand" "rm,R,rS<>,rm,R,rS<>")))
2373           (const_int 32))))
2374    (clobber (reg:CC_NOOV 21))]
2375   "! TARGET_C3X && valid_operands (MULT, operands, QImode)"
2376   "@
2377    mpyuhi\\t%2,%0
2378    mpyuhi3\\t%2,%1,%0
2379    mpyuhi3\\t%2,%1,%0
2380    mpyuhi\\t%2,%0
2381    mpyuhi3\\t%2,%1,%0
2382    mpyuhi3\\t%2,%1,%0"
2383   [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")
2384    (set_attr "data" "uint16,uint16,uint16,uint16,uint16,uint16")])
2385
2386 (define_insn "*umulqi3_highpart_noclobber"
2387   [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c")
2388         (truncate:QI
2389          (lshiftrt:HI
2390           (mult:HI 
2391            (zero_extend:HI (match_operand:QI 1
2392                             "nonimmediate_src_operand" "0,rR,rS<>"))
2393            (zero_extend:HI (match_operand:QI 2
2394                             "nonimmediate_lsrc_operand" "rm,R,rS<>")))
2395           (const_int 32))))]
2396   "! TARGET_C3X && valid_operands (MULT, operands, QImode)"
2397   "@
2398    mpyuhi\\t%2,%0
2399    mpyuhi3\\t%2,%1,%0
2400    mpyuhi3\\t%2,%1,%0"
2401   [(set_attr "type" "binary,binary,binary")
2402    (set_attr "data" "uint16,uint16,uint16")])
2403
2404 ;
2405 ; AND
2406 ;
2407 (define_expand "andqi3"
2408   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
2409                    (and:QI (match_operand:QI 1 "src_operand" "")
2410                            (match_operand:QI 2 "tsrc_operand" "")))
2411               (clobber (reg:CC 21))])]
2412  ""
2413  "legitimize_operands (AND, operands, QImode);")
2414
2415
2416 (define_insn "*andqi3_255_clobber"
2417   [(set (match_operand:QI 0 "reg_operand" "=d,c")
2418         (and:QI (match_operand:QI 1 "src_operand" "mr,mr")
2419                 (const_int 255)))
2420    (clobber (reg:CC 21))]
2421  "! TARGET_C3X"
2422  "lbu0\\t%1,%0"
2423   [(set_attr "type" "unarycc,unary")])
2424
2425 (define_insn "*andqi3_255_noclobber"
2426   [(set (match_operand:QI 0 "reg_operand" "=c")
2427         (and:QI (match_operand:QI 1 "src_operand" "mr")
2428                 (const_int 255)))]
2429  "! TARGET_C3X"
2430  "lbu0\\t%1,%0"
2431   [(set_attr "type" "unary")])
2432
2433
2434 (define_insn "*andqi3_65535_clobber"
2435   [(set (match_operand:QI 0 "reg_operand" "=d,c")
2436         (and:QI (match_operand:QI 1 "src_operand" "mr,mr")
2437                 (const_int 65535)))
2438    (clobber (reg:CC 21))]
2439  "! TARGET_C3X"
2440  "lhu0\\t%1,%0"
2441   [(set_attr "type" "unarycc,unary")])
2442
2443 (define_insn "*andqi3_65535_noclobber"
2444   [(set (match_operand:QI 0 "reg_operand" "=c")
2445         (and:QI (match_operand:QI 1 "src_operand" "mr")
2446                 (const_int 65535)))]
2447  "! TARGET_C3X"
2448  "lhu0\\t%1,%0"
2449   [(set_attr "type" "unary")])
2450
2451 (define_insn "*andqi3_clobber"
2452   [(set (match_operand:QI 0 "reg_operand" "=d,d,d,?d,c,c,c,?c")
2453         (and:QI (match_operand:QI 1 "src_operand" "%0,0,rR,rS<>,0,0,rR,rS<>")
2454                 (match_operand:QI 2 "tsrc_operand" "N,rLm,JR,rS<>,N,rLm,JR,rS<>")))
2455    (clobber (reg:CC 21))]
2456   "valid_operands (AND, operands, QImode)"
2457   "@
2458    andn\\t%N2,%0
2459    and\\t%2,%0
2460    and3\\t%2,%1,%0
2461    and3\\t%2,%1,%0
2462    andn\\t%N2,%0
2463    and\\t%2,%0
2464    and3\\t%2,%1,%0
2465    and3\\t%2,%1,%0"
2466   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc,binary,binary,binary,binary")
2467    (set_attr "data" "not_uint16,uint16,int16,uint16,not_uint16,uint16,int16,uint16")])
2468
2469 (define_insn "*andqi3_noclobber"
2470   [(set (match_operand:QI 0 "std_reg_operand" "=c,c,c,?c")
2471         (and:QI (match_operand:QI 1 "src_operand" "%0,0,rR,rS<>")
2472                 (match_operand:QI 2 "tsrc_operand" "N,rLm,JR,rS<>")))]
2473   "valid_operands (AND, operands, QImode)"
2474   "@
2475    andn\\t%N2,%0
2476    and\\t%2,%0
2477    and3\\t%2,%1,%0
2478    and3\\t%2,%1,%0"
2479   [(set_attr "type" "binary,binary,binary,binary")
2480    (set_attr "data" "not_uint16,uint16,int16,uint16")])
2481
2482 (define_insn "andn_st"
2483   [(set (unspec:QI [(reg:QI 21)] 20)
2484         (and:QI (unspec:QI [(reg:QI 21)] UNSPEC_ANDN_ST)
2485                 (match_operand:QI 0 "" "N")))
2486    (use (match_dup 0))
2487    (use (reg:CC 21))
2488    (clobber (reg:CC 21))]
2489   ""
2490   "andn\\t%N0,st"
2491   [(set_attr "type" "misc")
2492    (set_attr "data" "not_uint16")])
2493
2494 (define_split
2495   [(set (match_operand:QI 0 "std_reg_operand" "")
2496         (and:QI (match_operand:QI 1 "src_operand" "")
2497                 (match_operand:QI 2 "tsrc_operand" "")))
2498    (clobber (reg:CC 21))]
2499   "reload_completed"
2500   [(set (match_dup 0)
2501         (and:QI (match_dup 1)
2502                 (match_dup 2)))]
2503   "")
2504
2505 (define_insn "*andqi3_test"
2506   [(set (reg:CC 21)
2507         (compare:CC (and:QI (match_operand:QI 1 "src_operand" "%0,r,rR,rS<>")
2508                             (match_operand:QI 2 "tsrc_operand" "N,rLm,JR,rS<>"))
2509                     (const_int 0)))
2510    (clobber (match_scratch:QI 0 "=d,X,X,?X"))]
2511   "valid_operands (AND, operands, QImode)"
2512   "@
2513    andn\\t%N2,%0
2514    tstb\\t%2,%1
2515    tstb3\\t%2,%1
2516    tstb3\\t%2,%1"
2517   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")
2518    (set_attr "data" "not_uint16,uint16,int16,uint16")])
2519
2520 (define_peephole
2521   [(parallel [(set (match_operand:QI 0 "ext_reg_operand" "=d,d,d,?d")
2522                    (and:QI (match_operand:QI 1 "src_operand" "%0,0,rR,rS<>")
2523                            (match_operand:QI 2 "tsrc_operand" "N,rLm,JR,rS<>")))
2524               (clobber (reg:CC 21))])
2525    (set (reg:CC 21)
2526         (compare:CC (match_dup 0) (const_int 0)))]
2527   "valid_operands (AND, operands, QImode)"
2528   "@
2529    andn\\t%N2,%0
2530    and\\t%2,%0
2531    and3\\t%2,%1,%0
2532    and3\\t%2,%1,%0"
2533   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")
2534    (set_attr "data" "not_uint16,uint16,int16,uint16")])
2535   
2536 (define_insn "*andqi3_set"
2537   [(set (reg:CC 21)
2538         (compare:CC (and:QI (match_operand:QI 1 "src_operand" "%0,0,rR,rS<>")
2539                             (match_operand:QI 2 "tsrc_operand" "N,rLm,JR,rS<>"))
2540                     (const_int 0)))
2541    (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d,?d")
2542         (and:QI (match_dup 1)
2543                 (match_dup 2)))]
2544   "valid_operands (AND, operands, QImode)"
2545   "@
2546    andn\\t%N2,%0
2547    and\\t%2,%0
2548    and3\\t%2,%1,%0
2549    and3\\t%2,%1,%0"
2550   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")
2551    (set_attr "data" "not_uint16,uint16,int16,uint16")])
2552
2553 ;
2554 ; ANDN
2555 ;
2556 ; NB, this insn doesn't have commutative operands, but valid_operands
2557 ; assumes that the code AND does.  We might have to kludge this if
2558 ; we make valid_operands stricter.
2559 (define_insn "*andnqi3_clobber"
2560   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
2561         (and:QI (not:QI (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>,rLm,JR,rS<>"))
2562                 (match_operand:QI 1 "src_operand" "0,rR,rS<>,0,rR,rS<>")))
2563    (clobber (reg:CC 21))]
2564   "valid_operands (AND, operands, QImode)"
2565   "@
2566    andn\\t%2,%0
2567    andn3\\t%2,%1,%0
2568    andn3\\t%2,%1,%0
2569    andn\\t%2,%0
2570    andn3\\t%2,%1,%0
2571    andn3\\t%2,%1,%0"
2572   [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")
2573    (set_attr "data" "uint16,int16,uint16,uint16,int16,uint16")])
2574
2575 (define_insn "*andnqi3_noclobber"
2576   [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c")
2577         (and:QI (not:QI (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>"))
2578                 (match_operand:QI 1 "src_operand" "0,rR,rS<>")))]
2579   "valid_operands (AND, operands, QImode)"
2580   "@
2581    andn\\t%2,%0
2582    andn3\\t%2,%1,%0
2583    andn3\\t%2,%1,%0"
2584   [(set_attr "type" "binary,binary,binary")
2585    (set_attr "data" "uint16,int16,uint16")])
2586
2587 (define_split
2588   [(set (match_operand:QI 0 "std_reg_operand" "")
2589         (and:QI (not:QI (match_operand:QI 2 "lsrc_operand" ""))
2590                 (match_operand:QI 1 "src_operand" "")))
2591    (clobber (reg:CC 21))]
2592   "reload_completed"
2593   [(set (match_dup 0)
2594         (and:QI (not:QI (match_dup 2))
2595                 (match_dup 1)))]
2596   "")
2597
2598 (define_insn "*andnqi3_test"
2599   [(set (reg:CC 21)
2600         (compare:CC (and:QI (not:QI (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>"))
2601                             (match_operand:QI 1 "src_operand" "0,rR,rS<>"))
2602                     (const_int 0)))
2603    (clobber (match_scratch:QI 0 "=d,d,d"))]
2604   "valid_operands (AND, operands, QImode)"
2605   "@
2606    andn\\t%2,%0
2607    andn3\\t%2,%1,%0
2608    andn3\\t%2,%1,%0"
2609   [(set_attr "type" "binarycc,binarycc,binarycc")
2610    (set_attr "data" "uint16,int16,uint16")])
2611
2612 (define_insn "*andnqi3_set"
2613   [(set (reg:CC 21)
2614         (compare:CC (and:QI (not:QI (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>"))
2615                             (match_operand:QI 1 "src_operand" "0,rR,rS<>"))
2616                     (const_int 0)))
2617    (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d")
2618         (and:QI (not:QI (match_dup 2))
2619                 (match_dup 1)))]
2620   "valid_operands (AND, operands, QImode)"
2621   "@
2622    andn\\t%2,%0
2623    andn3\\t%2,%1,%0
2624    andn3\\t%2,%1,%0"
2625   [(set_attr "type" "binarycc,binarycc,binarycc")
2626    (set_attr "data" "uint16,int16,uint16")])
2627
2628 ;
2629 ; OR
2630 ;
2631 (define_expand "iorqi3"
2632   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
2633                    (ior:QI (match_operand:QI 1 "src_operand" "")
2634                            (match_operand:QI 2 "lsrc_operand" "")))
2635               (clobber (reg:CC 21))])]
2636  ""
2637  "legitimize_operands (IOR, operands, QImode);")
2638
2639 (define_insn "*iorqi3_clobber"
2640   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
2641         (ior:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>")
2642                 (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>,rLm,JR,rS<>")))
2643    (clobber (reg:CC 21))]
2644   "valid_operands (IOR, operands, QImode)"
2645   "@
2646    or\\t%2,%0
2647    or3\\t%2,%1,%0
2648    or3\\t%2,%1,%0
2649    or\\t%2,%0
2650    or3\\t%2,%1,%0
2651    or3\\t%2,%1,%0"
2652   [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")
2653    (set_attr "data" "uint16,int16,uint16,uint16,int16,uint16")])
2654
2655 (define_split
2656   [(set (match_operand:QI 0 "std_reg_operand" "")
2657         (ior:QI (match_operand:QI 1 "src_operand" "")
2658                 (match_operand:QI 2 "lsrc_operand" "")))
2659    (clobber (reg:CC 21))]
2660   "reload_completed"
2661   [(set (match_dup 0)
2662         (ior:QI (match_dup 1)
2663                 (match_dup 2)))]
2664   "")
2665
2666 (define_insn "*iorqi3_test"
2667   [(set (reg:CC 21)
2668         (compare:CC (ior:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
2669                             (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>"))
2670                     (const_int 0)))
2671    (clobber (match_scratch:QI 0 "=d,d,d"))]
2672   "valid_operands (IOR, operands, QImode)"
2673   "@
2674    or\\t%2,%0
2675    or3\\t%2,%1,%0
2676    or3\\t%2,%1,%0"
2677   [(set_attr "type" "binarycc,binarycc,binarycc")
2678    (set_attr "data" "uint16,int16,uint16")])
2679
2680 (define_peephole
2681   [(parallel [(set (match_operand:QI 0 "ext_reg_operand" "=d,d,d")
2682                    (ior:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
2683                            (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>")))
2684               (clobber (reg:CC 21))])
2685    (set (reg:CC 21)
2686         (compare:CC (match_dup 0) (const_int 0)))]
2687   "valid_operands (IOR, operands, QImode)"
2688   "@
2689    or\\t%2,%0
2690    or3\\t%2,%1,%0
2691    or3\\t%2,%1,%0"
2692   [(set_attr "type" "binarycc,binarycc,binarycc")
2693    (set_attr "data" "uint16,int16,uint16")])
2694   
2695 (define_insn "*iorqi3_set"
2696   [(set (reg:CC 21)
2697         (compare:CC (ior:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
2698                             (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>"))
2699                     (const_int 0)))
2700    (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d")
2701         (ior:QI (match_dup 1)
2702                 (match_dup 2)))]
2703   "valid_operands (IOR, operands, QImode)"
2704   "@
2705    or\\t%2,%0
2706    or3\\t%2,%1,%0
2707    or3\\t%2,%1,%0"
2708   [(set_attr "type" "binarycc,binarycc,binarycc")
2709    (set_attr "data" "uint16,int16,uint16")])
2710
2711 ; This pattern is used for loading symbol references in several parts. 
2712 (define_insn "iorqi3_noclobber"
2713   [(set (match_operand:QI 0 "std_reg_operand" "=c,c,c")
2714         (ior:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
2715                 (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>")))]
2716   "valid_operands (IOR, operands, QImode)"
2717   "@
2718    or\\t%2,%0
2719    or3\\t%2,%1,%0
2720    or3\\t%2,%1,%0"
2721   [(set_attr "type" "binary,binary,binary")
2722    (set_attr "data" "uint16,int16,uint16")])
2723
2724 ;
2725 ; XOR
2726 ;
2727 (define_expand "xorqi3"
2728   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
2729                    (xor:QI (match_operand:QI 1 "src_operand" "")
2730                            (match_operand:QI 2 "lsrc_operand" "")))
2731               (clobber (reg:CC 21))])]
2732  ""
2733  "legitimize_operands (XOR, operands, QImode);")
2734
2735 (define_insn "*xorqi3_clobber"
2736   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
2737         (xor:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>,0,rR,rS<>")
2738                 (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>,rLm,JR,rS<>")))
2739    (clobber (reg:CC 21))]
2740   "valid_operands (XOR, operands, QImode)"
2741   "@
2742    xor\\t%2,%0
2743    xor3\\t%2,%1,%0
2744    xor3\\t%2,%1,%0
2745    xor\\t%2,%0
2746    xor3\\t%2,%1,%0
2747    xor3\\t%2,%1,%0"
2748   [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")
2749    (set_attr "data" "uint16,int16,uint16,uint16,int16,uint16")])
2750
2751 (define_insn "*xorqi3_noclobber"
2752   [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c")
2753         (xor:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
2754                 (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>")))]
2755   "valid_operands (XOR, operands, QImode)"
2756   "@
2757    xor\\t%2,%0
2758    xor3\\t%2,%1,%0
2759    xor3\\t%2,%1,%0"
2760   [(set_attr "type" "binary,binary,binary")
2761    (set_attr "data" "uint16,int16,uint16")])
2762
2763 (define_split
2764   [(set (match_operand:QI 0 "std_reg_operand" "")
2765         (xor:QI (match_operand:QI 1 "src_operand" "")
2766                 (match_operand:QI 2 "lsrc_operand" "")))
2767    (clobber (reg:CC 21))]
2768   "reload_completed"
2769   [(set (match_dup 0)
2770         (xor:QI (match_dup 1)
2771                 (match_dup 2)))]
2772   "")
2773
2774 (define_insn "*xorqi3_test"
2775   [(set (reg:CC 21)
2776         (compare:CC (xor:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
2777                             (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>"))
2778                     (const_int 0)))
2779    (clobber (match_scratch:QI 0 "=d,d,d"))]
2780   "valid_operands (XOR, operands, QImode)"
2781   "@
2782    xor\\t%2,%0
2783    xor3\\t%2,%1,%0
2784    xor3\\t%2,%1,%0"
2785   [(set_attr "type" "binarycc,binarycc,binarycc")
2786    (set_attr "data" "uint16,int16,uint16")])
2787
2788 (define_insn "*xorqi3_set"
2789   [(set (reg:CC 21)
2790         (compare:CC (xor:QI (match_operand:QI 1 "src_operand" "%0,rR,rS<>")
2791                             (match_operand:QI 2 "lsrc_operand" "rLm,JR,rS<>"))
2792                     (const_int 0)))
2793    (set (match_operand:QI 0 "ext_reg_operand" "=d,d,d")
2794         (xor:QI (match_dup 1)
2795                 (match_dup 2)))]
2796   "valid_operands (XOR, operands, QImode)"
2797   "@
2798    xor\\t%2,%0
2799    xor3\\t%2,%1,%0
2800    xor3\\t%2,%1,%0"
2801   [(set_attr "type" "binarycc,binarycc,binarycc")
2802    (set_attr "data" "uint16,int16,uint16")])
2803
2804 ;
2805 ; LSH/ASH (left)
2806 ;
2807 ; The C3x and C4x have two shift instructions ASH and LSH
2808 ; If the shift count is positive, a left shift is performed
2809 ; otherwise a right shift is performed.  The number of bits
2810 ; shifted is determined by the seven LSBs of the shift count.
2811 ; If the absolute value of the count is 32 or greater, the result
2812 ; using the LSH instruction is zero; with the ASH insn the result
2813 ; is zero or negative 1.   Note that the ISO C standard allows 
2814 ; the result to be machine dependent whenever the shift count
2815 ; exceeds the size of the object.
2816 (define_expand "ashlqi3"
2817   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
2818                    (ashift:QI (match_operand:QI 1 "src_operand" "")
2819                               (match_operand:QI 2 "src_operand" "")))
2820               (clobber (reg:CC 21))])]
2821  ""
2822  "legitimize_operands (ASHIFT, operands, QImode);")
2823
2824 (define_insn "*ashlqi3_clobber"
2825   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
2826         (ashift:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>,0,rR,rS<>")
2827                    (match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>")))
2828    (clobber (reg:CC 21))]
2829   "valid_operands (ASHIFT, operands, QImode)"
2830   "@
2831    ash\\t%2,%0
2832    ash3\\t%2,%1,%0
2833    ash3\\t%2,%1,%0
2834    ash\\t%2,%0
2835    ash3\\t%2,%1,%0
2836    ash3\\t%2,%1,%0"
2837   [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")])
2838 ; Default to int16 data attr.
2839
2840 (define_insn "*ashlqi3_set"
2841   [(set (reg:CC 21)
2842         (compare:CC
2843           (ashift:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>")
2844                      (match_operand:QI 2 "src_operand" "rIm,JR,rS<>"))
2845           (const_int 0)))
2846    (set (match_operand:QI 0 "reg_operand" "=d,d,d")
2847         (ashift:QI (match_dup 1)
2848                    (match_dup 2)))]
2849   "valid_operands (ASHIFT, operands, QImode)"
2850   "@
2851    ash\\t%2,%0
2852    ash3\\t%2,%1,%0
2853    ash3\\t%2,%1,%0"
2854   [(set_attr "type" "binarycc,binarycc,binarycc")])
2855 ; Default to int16 data attr.
2856
2857 (define_insn "ashlqi3_noclobber"
2858   [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c")
2859         (ashift:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>")
2860                    (match_operand:QI 2 "src_operand" "rIm,JR,rS<>")))]
2861   "valid_operands (ASHIFT, operands, QImode)"
2862   "@
2863    ash\\t%2,%0
2864    ash3\\t%2,%1,%0
2865    ash3\\t%2,%1,%0"
2866   [(set_attr "type" "binary,binary,binary")])
2867 ; Default to int16 data attr.
2868
2869 (define_split
2870   [(set (match_operand:QI 0 "std_reg_operand" "")
2871         (ashift:QI (match_operand:QI 1 "src_operand" "")
2872                    (match_operand:QI 2 "src_operand" "")))
2873    (clobber (reg:CC 21))]
2874   "reload_completed"
2875   [(set (match_dup 0)
2876         (ashift:QI (match_dup 1)
2877                    (match_dup 2)))]
2878   "")
2879
2880 ; This is only used by lshrhi3_reg where we need a LSH insn that will
2881 ; shift both ways.
2882 (define_insn "*lshlqi3_clobber"
2883   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
2884         (ashift:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>,0,rR,rS<>")
2885                    (unspec:QI [(match_operand:QI 2 "src_operand" "rIm,JR,rS<>,rIm,JR,rS<>")] UNSPEC_LSH)))
2886    (clobber (reg:CC 21))]
2887   "valid_operands (ASHIFT, operands, QImode)"
2888   "@
2889    lsh\\t%2,%0
2890    lsh3\\t%2,%1,%0
2891    lsh3\\t%2,%1,%0
2892    lsh\\t%2,%0
2893    lsh3\\t%2,%1,%0
2894    lsh3\\t%2,%1,%0"
2895   [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")])
2896 ; Default to int16 data attr.
2897
2898 ;
2899 ; LSH (right)
2900 ;
2901 ; Logical right shift on the C[34]x works by negating the shift count,
2902 ; then emitting a right shift with the shift count negated.  This means
2903 ; that all actual shift counts in the RTL will be positive.
2904 ;
2905 (define_expand "lshrqi3"
2906   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
2907                    (lshiftrt:QI (match_operand:QI 1 "src_operand" "")
2908                                 (match_operand:QI 2 "src_operand" "")))
2909               (clobber (reg:CC 21))])]
2910   ""
2911   "legitimize_operands (LSHIFTRT, operands, QImode);")
2912
2913
2914 (define_insn "*lshrqi3_24_clobber"
2915   [(set (match_operand:QI 0 "reg_operand" "=d,c")
2916         (lshiftrt:QI (match_operand:QI 1 "src_operand" "mr,mr")
2917                      (const_int 24)))
2918    (clobber (reg:CC 21))]
2919   "! TARGET_C3X"
2920   "lbu3\\t%1,%0"
2921   [(set_attr "type" "unarycc")])
2922
2923
2924 (define_insn "*ashrqi3_24_clobber"
2925   [(set (match_operand:QI 0 "reg_operand" "=d,c")
2926         (ashiftrt:QI (match_operand:QI 1 "src_operand" "mr,mr")
2927                      (const_int 24)))
2928    (clobber (reg:CC 21))]
2929   "! TARGET_C3X"
2930   "lb3\\t%1,%0"
2931   [(set_attr "type" "unarycc")])
2932
2933
2934 (define_insn "lshrqi3_16_clobber"
2935   [(set (match_operand:QI 0 "reg_operand" "=d,c")
2936         (lshiftrt:QI (match_operand:QI 1 "src_operand" "mr,mr")
2937                      (const_int 16)))
2938    (clobber (reg:CC 21))]
2939   "! TARGET_C3X"
2940   "lhu1\\t%1,%0"
2941   [(set_attr "type" "unarycc")])
2942
2943
2944 (define_insn "*ashrqi3_16_clobber"
2945   [(set (match_operand:QI 0 "reg_operand" "=d,c")
2946         (ashiftrt:QI (match_operand:QI 1 "src_operand" "mr,mr")
2947                      (const_int 16)))
2948    (clobber (reg:CC 21))]
2949   "! TARGET_C3X"
2950   "lh1\\t%1,%0"
2951   [(set_attr "type" "unarycc")])
2952
2953
2954 ; When the shift count is greater than the size of the word
2955 ; the result can be implementation specific
2956 (define_insn "*lshrqi3_const_clobber"
2957   [(set (match_operand:QI 0 "reg_operand" "=d,c,?d,?c")
2958         (lshiftrt:QI (match_operand:QI 1 "src_operand" "0,0,r,r")
2959                      (match_operand:QI 2 "const_int_operand" "n,n,J,J")))
2960    (clobber (reg:CC 21))]
2961   "valid_operands (LSHIFTRT, operands, QImode)"
2962   "@
2963    lsh\\t%n2,%0
2964    lsh\\t%n2,%0
2965    lsh3\\t%n2,%1,%0
2966    lsh3\\t%n2,%1,%0"
2967   [(set_attr "type" "binarycc,binary,binarycc,binary")])
2968
2969 (define_insn "*lshrqi3_const_noclobber"
2970   [(set (match_operand:QI 0 "std_reg_operand" "=c,?c")
2971         (lshiftrt:QI (match_operand:QI 1 "src_operand" "0,r")
2972                      (match_operand:QI 2 "const_int_operand" "n,J")))]
2973   "valid_operands (LSHIFTRT, operands, QImode)"
2974   "@
2975    lsh\\t%n2,%0
2976    lsh3\\t%n2,%1,%0"
2977   [(set_attr "type" "binary,binary")])
2978
2979 ; When the shift count is greater than the size of the word
2980 ; the result can be implementation specific
2981 (define_insn "*lshrqi3_const_set"
2982   [(set (reg:CC 21)
2983         (compare:CC
2984           (lshiftrt:QI (match_operand:QI 1 "src_operand" "0,r")
2985                        (match_operand:QI 2 "const_int_operand" "n,J"))
2986           (const_int 0)))
2987    (set (match_operand:QI 0 "reg_operand" "=?d,d")
2988         (lshiftrt:QI (match_dup 1)
2989                      (match_dup 2)))]
2990   "valid_operands (LSHIFTRT, operands, QImode)"
2991   "@
2992    lsh\\t%n2,%0
2993    lsh3\\t%n2,%1,%0"
2994   [(set_attr "type" "binarycc,binarycc")])
2995
2996 (define_insn "*lshrqi3_nonconst_clobber"
2997   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
2998         (lshiftrt:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>,0,rR,rS<>")
2999                      (neg:QI (match_operand:QI 2 "src_operand" "rm,R,rS<>,rm,R,rS<>"))))
3000    (clobber (reg:CC 21))]
3001   "valid_operands (LSHIFTRT, operands, QImode)"
3002   "@
3003    lsh\\t%2,%0
3004    lsh3\\t%2,%1,%0
3005    lsh3\\t%2,%1,%0
3006    lsh\\t%2,%0
3007    lsh3\\t%2,%1,%0
3008    lsh3\\t%2,%1,%0"
3009   [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")])
3010 ; Default to int16 data attr.
3011
3012 (define_insn "*lshrqi3_nonconst_noclobber"
3013   [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c")
3014         (lshiftrt:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>")
3015                      (neg:QI (match_operand:QI 2 "src_operand" "rm,R,rS<>"))))]
3016   "valid_operands (LSHIFTRT, operands, QImode)"
3017   "@
3018    lsh\\t%2,%0
3019    lsh3\\t%2,%1,%0
3020    lsh3\\t%2,%1,%0"
3021   [(set_attr "type" "binary,binary,binary")])
3022 ; Default to int16 data attr.
3023
3024 ;
3025 ; ASH (right)
3026 ;
3027 ; Arithmetic right shift on the C[34]x works by negating the shift count,
3028 ; then emitting a right shift with the shift count negated.  This means
3029 ; that all actual shift counts in the RTL will be positive.
3030
3031 (define_expand "ashrqi3"
3032   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
3033                    (ashiftrt:QI (match_operand:QI 1 "src_operand" "")
3034                                 (match_operand:QI 2 "src_operand" "")))
3035               (clobber (reg:CC 21))])]
3036   ""
3037   "legitimize_operands (ASHIFTRT, operands, QImode);")
3038
3039 ; When the shift count is greater than the size of the word
3040 ; the result can be implementation specific
3041 (define_insn "*ashrqi3_const_clobber"
3042   [(set (match_operand:QI 0 "reg_operand" "=d,c,?d,?c")
3043         (ashiftrt:QI (match_operand:QI 1 "src_operand" "0,0,r,r")
3044                      (match_operand:QI 2 "const_int_operand" "n,n,J,J")))
3045    (clobber (reg:CC 21))]
3046   "valid_operands (ASHIFTRT, operands, QImode)"
3047   "@
3048    ash\\t%n2,%0
3049    ash\\t%n2,%0
3050    ash3\\t%n2,%1,%0
3051    ash3\\t%n2,%1,%0"
3052   [(set_attr "type" "binarycc,binary,binarycc,binary")])
3053
3054 (define_insn "*ashrqi3_const_noclobber"
3055   [(set (match_operand:QI 0 "std_reg_operand" "=c,?c")
3056         (ashiftrt:QI (match_operand:QI 1 "src_operand" "0,r")
3057                      (match_operand:QI 2 "const_int_operand" "n,J")))]
3058   "valid_operands (ASHIFTRT, operands, QImode)"
3059   "@
3060    ash\\t%n2,%0
3061    ash3\\t%n2,%1,%0"
3062   [(set_attr "type" "binarycc,binarycc")])
3063
3064 ; When the shift count is greater than the size of the word
3065 ; the result can be implementation specific
3066 (define_insn "*ashrqi3_const_set"
3067   [(set (reg:CC 21)
3068         (compare:CC
3069           (ashiftrt:QI (match_operand:QI 1 "src_operand" "0,r")
3070                        (match_operand:QI 2 "const_int_operand" "n,J"))
3071           (const_int 0)))
3072    (set (match_operand:QI 0 "reg_operand" "=?d,d")
3073         (ashiftrt:QI (match_dup 1)
3074                      (match_dup 2)))]
3075   "valid_operands (ASHIFTRT, operands, QImode)"
3076   "@
3077    ash\\t%n2,%0
3078    ash3\\t%n2,%1,%0"
3079   [(set_attr "type" "binarycc,binarycc")])
3080
3081 (define_insn "*ashrqi3_nonconst_clobber"
3082   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
3083         (ashiftrt:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>,0,rR,rS<>")
3084                      (neg:QI (match_operand:QI 2 "src_operand" "rm,R,rS<>,rm,R,rS<>"))))
3085    (clobber (reg:CC 21))]
3086   "valid_operands (ASHIFTRT, operands, QImode)"
3087   "@
3088    ash\\t%2,%0
3089    ash3\\t%2,%1,%0
3090    ash3\\t%2,%1,%0
3091    ash\\t%2,%0
3092    ash3\\t%2,%1,%0
3093    ash3\\t%2,%1,%0"
3094   [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")])
3095 ; Default to int16 data attr.
3096
3097 (define_insn "*ashrqi3_nonconst_noclobber"
3098   [(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c")
3099         (ashiftrt:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>")
3100                      (neg:QI (match_operand:QI 2 "src_operand" "rm,R,rS<>"))))]
3101   "valid_operands (ASHIFTRT, operands, QImode)"
3102   "@
3103    ash\\t%2,%0
3104    ash3\\t%2,%1,%0
3105    ash3\\t%2,%1,%0"
3106   [(set_attr "type" "binary,binary,binary")])
3107 ; Default to int16 data attr.
3108
3109 ;
3110 ; CMPI
3111 ;
3112 ; Unfortunately the C40 doesn't allow cmpi3 7, *ar0++ so the next best
3113 ; thing would be to get the small constant loaded into a register (say r0)
3114 ; so that it could be hoisted out of the loop so that we only
3115 ; would need to do cmpi3 *ar0++, r0.  Now the loop optimization pass
3116 ; comes before the flow pass (which finds autoincrements) so we're stuck.
3117 ; Ideally, GCC requires another loop optimization pass (preferably after
3118 ; reload) so that it can hoist invariants out of loops.
3119 ; The current solution modifies legitimize_operands () so that small
3120 ; constants are forced into a pseudo register.
3121
3122 (define_expand "cmpqi"
3123   [(set (reg:CC 21)
3124         (compare:CC (match_operand:QI 0 "src_operand" "")
3125                     (match_operand:QI 1 "src_operand" "")))]
3126   ""
3127   "legitimize_operands (COMPARE, operands, QImode);
3128    c4x_compare_op0 = operands[0];
3129    c4x_compare_op1 = operands[1];
3130    DONE;")
3131
3132 (define_insn "*cmpqi_test"
3133   [(set (reg:CC 21)
3134         (compare:CC (match_operand:QI 0 "src_operand" "r,rR,rS<>")
3135                     (match_operand:QI 1 "src_operand" "rIm,JR,rS<>")))]
3136   "valid_operands (COMPARE, operands, QImode)"
3137   "@
3138    cmpi\\t%1,%0
3139    cmpi3\\t%1,%0
3140    cmpi3\\t%1,%0"
3141   [(set_attr "type" "compare,compare,compare")])
3142
3143 (define_insn "*cmpqi_test_noov"
3144   [(set (reg:CC_NOOV 21)
3145         (compare:CC_NOOV (match_operand:QI 0 "src_operand" "r,rR,rS<>")
3146                          (match_operand:QI 1 "src_operand" "rIm,JR,rS<>")))]
3147   "valid_operands (COMPARE, operands, QImode)"
3148   "@
3149    cmpi\\t%1,%0
3150    cmpi3\\t%1,%0
3151    cmpi3\\t%1,%0"
3152   [(set_attr "type" "compare,compare,compare")])
3153
3154
3155 ;
3156 ; BIT-FIELD INSTRUCTIONS
3157 ;
3158
3159 ;
3160 ; LBx/LHw (C4x only)
3161 ;
3162 (define_expand "extv"
3163   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
3164                    (sign_extract:QI (match_operand:QI 1 "src_operand" "")
3165                                     (match_operand:QI 2 "const_int_operand" "")
3166                                     (match_operand:QI 3 "const_int_operand" "")))
3167               (clobber (reg:CC 21))])]
3168  "! TARGET_C3X"
3169  "if ((INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)
3170       || (INTVAL (operands[3]) % INTVAL (operands[2]) != 0))
3171         FAIL;
3172  ")
3173
3174 (define_insn "*extv_clobber"
3175   [(set (match_operand:QI 0 "reg_operand" "=d,c")
3176         (sign_extract:QI (match_operand:QI 1 "src_operand" "rLm,rLm")
3177                          (match_operand:QI 2 "const_int_operand" "n,n")
3178                          (match_operand:QI 3 "const_int_operand" "n,n")))
3179    (clobber (reg:CC 21))]
3180   "! TARGET_C3X
3181    && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
3182    && (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)"
3183   "*
3184    if (INTVAL (operands[2]) == 8)
3185      {
3186        operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
3187        return \"lb%3\\t%1,%0\";
3188      }
3189    operands[3] = GEN_INT (INTVAL (operands[3]) / 16);
3190    return \"lh%3\\t%1,%0\";
3191   "
3192   [(set_attr "type" "binarycc,binary")
3193    (set_attr "data" "int16,int16")])
3194
3195 (define_insn "*extv_clobber_test"
3196   [(set (reg:CC 21)
3197         (compare:CC (sign_extract:QI (match_operand:QI 1 "src_operand" "rLm")
3198                                      (match_operand:QI 2 "const_int_operand" "n")
3199                                      (match_operand:QI 3 "const_int_operand" "n"))
3200                     (const_int 0)))
3201    (clobber (match_scratch:QI 0 "=d"))]
3202   "! TARGET_C3X
3203    && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
3204    && (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)"
3205   "*
3206    if (INTVAL (operands[2]) == 8)
3207      {
3208        operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
3209        return \"lb%3\\t%1,%0\";
3210      }
3211    operands[3] = GEN_INT (INTVAL (operands[3]) / 16);
3212    return \"lh%3\\t%1,%0\";
3213   "
3214   [(set_attr "type" "binarycc")
3215    (set_attr "data" "int16")])
3216
3217 (define_insn "*extv_clobber_set"
3218   [(set (reg:CC 21)
3219         (compare:CC (sign_extract:QI (match_operand:QI 1 "src_operand" "rLm")
3220                                      (match_operand:QI 2 "const_int_operand" "n")
3221                                      (match_operand:QI 3 "const_int_operand" "n"))
3222                     (const_int 0)))
3223    (set (match_operand:QI 0 "reg_operand" "=d")
3224         (sign_extract:QI (match_dup 1)
3225                          (match_dup 2)
3226                          (match_dup 3)))]
3227   "! TARGET_C3X
3228    && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
3229    && (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)"
3230   "*
3231    if (INTVAL (operands[2]) == 8)
3232      {
3233        operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
3234        return \"lb%3\\t%1,%0\";
3235      }
3236    operands[3] = GEN_INT (INTVAL (operands[3]) / 16);
3237    return \"lh%3\\t%1,%0\";
3238   "
3239   [(set_attr "type" "binarycc")
3240    (set_attr "data" "int16")])
3241
3242 ;
3243 ; LBUx/LHUw (C4x only)
3244 ;
3245 (define_expand "extzv"
3246   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
3247                    (zero_extract:QI (match_operand:QI 1 "src_operand" "")
3248                                     (match_operand:QI 2 "const_int_operand" "")
3249                                     (match_operand:QI 3 "const_int_operand" "")))
3250               (clobber (reg:CC 21))])]
3251  "! TARGET_C3X"
3252  "if ((INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)
3253       || (INTVAL (operands[3]) % INTVAL (operands[2]) != 0))
3254         FAIL;
3255  ")
3256
3257 (define_insn "*extzv_clobber"
3258   [(set (match_operand:QI 0 "reg_operand" "=d,c")
3259         (zero_extract:QI (match_operand:QI 1 "src_operand" "rLm,rLm")
3260                          (match_operand:QI 2 "const_int_operand" "n,n")
3261                          (match_operand:QI 3 "const_int_operand" "n,n")))
3262    (clobber (reg:CC 21))]
3263   "! TARGET_C3X
3264    && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
3265    && (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)"
3266   "*
3267    if (INTVAL (operands[2]) == 8)
3268      {
3269        operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
3270        return \"lbu%3\\t%1,%0\";
3271      }
3272    operands[3] = GEN_INT (INTVAL (operands[3]) / 16);
3273    return \"lhu%3\\t%1,%0\";
3274   "
3275   [(set_attr "type" "binarycc,binary")
3276    (set_attr "data" "uint16,uint16")])
3277
3278 (define_insn "*extzv_test"
3279   [(set (reg:CC 21)
3280         (compare:CC (zero_extract:QI (match_operand:QI 1 "src_operand" "rLm")
3281                                      (match_operand:QI 2 "const_int_operand" "n")
3282                                      (match_operand:QI 3 "const_int_operand" "n"))
3283                     (const_int 0)))
3284    (clobber (match_scratch:QI 0 "=d"))]
3285   "! TARGET_C3X
3286    && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
3287    && (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)"
3288   "*
3289    if (INTVAL (operands[2]) == 8)
3290      {
3291        operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
3292        return \"lbu%3\\t%1,%0\";
3293      }
3294    operands[3] = GEN_INT (INTVAL (operands[3]) / 16);
3295    return \"lhu%3\\t%1,%0\";
3296   "
3297   [(set_attr "type" "binarycc")
3298    (set_attr "data" "uint16")])
3299
3300 (define_insn "*extzv_set"
3301   [(set (reg:CC 21)
3302         (compare:CC (zero_extract:QI (match_operand:QI 1 "src_operand" "rLm")
3303                                      (match_operand:QI 2 "const_int_operand" "n")
3304                                      (match_operand:QI 3 "const_int_operand" "n"))
3305                     (const_int 0)))
3306    (set (match_operand:QI 0 "ext_reg_operand" "=d")
3307         (zero_extract:QI (match_dup 1)
3308                          (match_dup 2)
3309                          (match_dup 3)))]
3310   "! TARGET_C3X
3311    && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
3312    && (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)"
3313   "*
3314    if (INTVAL (operands[2]) == 8)
3315      {
3316         /* 8 bit extract.  */
3317        operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
3318        return \"lbu%3\\t%1,%0\";
3319      }
3320    /* 16 bit extract.  */
3321    operands[3] = GEN_INT (INTVAL (operands[3]) / 16);
3322    return \"lhu%3\\t%1,%0\";
3323   "
3324   [(set_attr "type" "binarycc")
3325    (set_attr "data" "uint16")])
3326
3327 ;
3328 ; MBx/MHw (C4x only)
3329 ;
3330 (define_expand "insv"
3331   [(parallel [(set (zero_extract:QI (match_operand:QI 0 "reg_operand" "")
3332                                     (match_operand:QI 1 "const_int_operand" "")
3333                                     (match_operand:QI 2 "const_int_operand" ""))
3334                    (match_operand:QI 3 "src_operand" ""))
3335               (clobber (reg:CC 21))])]
3336  "! TARGET_C3X"
3337  "if (! (((INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
3338          && (INTVAL (operands[2]) % INTVAL (operands[1]) == 0))
3339         || (INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8)))
3340     FAIL;
3341  ")
3342
3343 (define_insn "*insv_clobber"
3344   [(set (zero_extract:QI (match_operand:QI 0 "reg_operand" "+d,c")
3345                          (match_operand:QI 1 "const_int_operand" "n,n")
3346                          (match_operand:QI 2 "const_int_operand" "n,n"))
3347         (match_operand:QI 3 "src_operand" "rLm,rLm"))
3348    (clobber (reg:CC 21))]
3349   "! TARGET_C3X
3350    && (((INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
3351         && (INTVAL (operands[2]) % INTVAL (operands[1]) == 0))
3352        || (INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8))"
3353   "*
3354    if (INTVAL (operands[1]) == 8)
3355      {
3356        /* 8 bit insert.  */
3357        operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
3358        return \"mb%2\\t%3,%0\";
3359      }
3360    else if (INTVAL (operands[1]) == 16)
3361      {
3362        /* 16 bit insert.  */
3363        operands[2] = GEN_INT (INTVAL (operands[2]) / 16);
3364        return \"mh%2\\t%3,%0\";
3365      }
3366    /* 24 bit insert.  */
3367    return \"lwl1\\t%3,%0\";
3368   "
3369   [(set_attr "type" "binarycc,binary")
3370    (set_attr "data" "uint16,uint16")])
3371
3372 (define_peephole
3373   [(parallel [(set (zero_extract:QI (match_operand:QI 0 "ext_reg_operand" "+d")
3374                                     (match_operand:QI 1 "const_int_operand" "n")
3375                                     (match_operand:QI 2 "const_int_operand" "n"))
3376                    (match_operand:QI 3 "src_operand" "rLm"))
3377               (clobber (reg:CC 21))])
3378    (set (reg:CC 21)
3379         (compare:CC (match_dup 0) (const_int 0)))]
3380   "! TARGET_C3X
3381    && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
3382    && (INTVAL (operands[2]) % INTVAL (operands[1]) == 0)"
3383   "*
3384    if (INTVAL (operands[1]) == 8)
3385      {
3386        operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
3387        return \"mb%2\\t%3,%0\";
3388      }
3389    operands[2] = GEN_INT (INTVAL (operands[2]) / 16);
3390    return \"mh%2\\t%3,%0\";
3391   "
3392   [(set_attr "type" "binarycc")
3393    (set_attr "data" "uint16")])
3394
3395
3396 ; TWO OPERAND FLOAT INSTRUCTIONS
3397 ;
3398
3399 ;
3400 ; LDF/STF
3401 ;
3402 ;  If one of the operands is not a register, then we should
3403 ;  emit two insns, using a scratch register.  This will produce
3404 ;  better code in loops if the source operand is invariant, since
3405 ;  the source reload can be optimized out.  During reload we cannot
3406 ;  use change_address or force_reg.
3407 (define_expand "movqf"
3408   [(set (match_operand:QF 0 "src_operand" "")
3409         (match_operand:QF 1 "src_operand" ""))]
3410  ""
3411  "
3412 {
3413   if (c4x_emit_move_sequence (operands, QFmode))
3414     DONE;
3415 }")
3416
3417 ; This can generate invalid stack slot displacements
3418 (define_split
3419  [(set (match_operand:QI 0 "reg_operand" "")
3420        (unspec:QI [(match_operand:QF 1 "reg_operand" "")] UNSPEC_STOREQF_INT))]
3421   "reload_completed"
3422   [(set (match_dup 3) (match_dup 1))
3423    (set (match_dup 0) (match_dup 2))]
3424   "operands[2] = assign_stack_temp (QImode, GET_MODE_SIZE (QImode), 0);
3425    operands[3] = copy_rtx (operands[2]);
3426    PUT_MODE (operands[3], QFmode);")
3427
3428
3429 (define_insn "storeqf_int"
3430  [(set (match_operand:QI 0 "reg_operand" "=r")
3431        (unspec:QI [(match_operand:QF 1 "reg_operand" "f")] UNSPEC_STOREQF_INT))]
3432  ""
3433  "#"
3434   [(set_attr "type" "multi")])
3435
3436 (define_split
3437  [(parallel [(set (match_operand:QI 0 "reg_operand" "")
3438                   (unspec:QI [(match_operand:QF 1 "reg_operand" "")] UNSPEC_STOREQF_INT))
3439              (clobber (reg:CC 21))])]
3440   "reload_completed"
3441   [(set (mem:QF (pre_inc:QI (reg:QI 20)))
3442         (match_dup 1))
3443    (parallel [(set (match_dup 0)
3444                    (mem:QI (post_dec:QI (reg:QI 20))))
3445               (clobber (reg:CC 21))])]
3446   "")
3447
3448
3449 ; We need accurate death notes for this...
3450 ;(define_peephole
3451 ;  [(set (match_operand:QF 0 "reg_operand" "=f")
3452 ;        (match_operand:QF 1 "memory_operand" "m"))
3453 ;   (set (mem:QF (pre_inc:QI (reg:QI 20)))
3454 ;        (match_dup 0))
3455 ;   (parallel [(set (match_operand:QI 2 "reg_operand" "r")
3456 ;                   (mem:QI (post_dec:QI (reg:QI 20))))
3457 ;              (clobber (reg:CC 21))])]
3458 ;  ""
3459 ;  "ldiu\\t%1,%0")
3460
3461 (define_insn "storeqf_int_clobber"
3462  [(parallel [(set (match_operand:QI 0 "reg_operand" "=r")
3463                   (unspec:QI [(match_operand:QF 1 "reg_operand" "f")] UNSPEC_STOREQF_INT))
3464              (clobber (reg:CC 21))])]
3465  ""
3466  "#"
3467   [(set_attr "type" "multi")])
3468
3469
3470 ; This can generate invalid stack slot displacements
3471 (define_split
3472  [(set (match_operand:QF 0 "reg_operand" "")
3473        (unspec:QF [(match_operand:QI 1 "reg_operand" "")] UNSPEC_LOADQF_INT))]
3474   "reload_completed"
3475   [(set (match_dup 2) (match_dup 1))
3476    (set (match_dup 0) (match_dup 3))]
3477   "operands[2] = assign_stack_temp (QImode, GET_MODE_SIZE (QImode), 0);
3478    operands[3] = copy_rtx (operands[2]);
3479    PUT_MODE (operands[3], QFmode);")
3480
3481
3482 (define_insn "loadqf_int"
3483  [(set (match_operand:QF 0 "reg_operand" "=f")
3484        (unspec:QF [(match_operand:QI 1 "reg_operand" "r")] UNSPEC_LOADQF_INT))]
3485  ""
3486  "#"
3487   [(set_attr "type" "multi")])
3488
3489 (define_split
3490  [(parallel [(set (match_operand:QF 0 "reg_operand" "")
3491                   (unspec:QF [(match_operand:QI 1 "reg_operand" "")] UNSPEC_LOADQF_INT))
3492              (clobber (reg:CC 21))])]
3493   "reload_completed"
3494   [(set (mem:QI (pre_inc:QI (reg:QI 20)))
3495         (match_dup 1))
3496    (parallel [(set (match_dup 0)
3497                    (mem:QF (post_dec:QI (reg:QI 20))))
3498               (clobber (reg:CC 21))])]
3499   "")
3500
3501 (define_insn "loadqf_int_clobber"
3502  [(parallel [(set (match_operand:QF 0 "reg_operand" "=f")
3503                   (unspec:QF [(match_operand:QI 1 "reg_operand" "r")] UNSPEC_LOADQF_INT))
3504              (clobber (reg:CC 21))])]
3505  ""
3506  "#"
3507   [(set_attr "type" "multi")])
3508
3509 ; We must provide an alternative to store to memory in case we have to
3510 ; spill a register.
3511 (define_insn "movqf_noclobber"
3512  [(set (match_operand:QF 0 "dst_operand" "=f,m")
3513        (match_operand:QF 1 "src_operand" "fHm,f"))]
3514  "REG_P (operands[0]) || REG_P (operands[1])"
3515  "@
3516   ldfu\\t%1,%0
3517   stf\\t%1,%0"
3518   [(set_attr "type" "unary,store")])
3519
3520 ;(define_insn "*movqf_clobber"
3521 ;  [(set (match_operand:QF 0 "reg_operand" "=f")
3522 ;        (match_operand:QF 1 "src_operand" "fHm"))
3523 ;   (clobber (reg:CC 21))]
3524 ; "0"
3525 ; "ldf\\t%1,%0"
3526 ;  [(set_attr "type" "unarycc")])
3527
3528 (define_insn "*movqf_test"
3529   [(set (reg:CC 21)
3530         (compare:CC (match_operand:QF 1 "src_operand" "fHm")
3531                     (const_int 0)))
3532    (clobber (match_scratch:QF 0 "=f"))]
3533  ""
3534  "ldf\\t%1,%0"
3535   [(set_attr "type" "unarycc")])
3536
3537 (define_insn "*movqf_set"
3538   [(set (reg:CC 21)
3539         (compare:CC (match_operand:QF 1 "src_operand" "fHm")
3540                     (match_operand:QF 2 "fp_zero_operand" "G")))
3541     (set (match_operand:QF 0 "reg_operand" "=f")
3542          (match_dup 1))]
3543  ""
3544  "ldf\\t%1,%0"
3545   [(set_attr "type" "unarycc")])
3546
3547
3548 (define_insn "*movqf_parallel"
3549  [(set (match_operand:QF 0 "parallel_operand" "=q,S<>!V,q,S<>!V")
3550        (match_operand:QF 1 "parallel_operand" "S<>!V,q,S<>!V,q"))
3551   (set (match_operand:QF 2 "parallel_operand" "=q,S<>!V,S<>!V,q")
3552        (match_operand:QF 3 "parallel_operand" "S<>!V,q,q,S<>!V"))]
3553  "TARGET_PARALLEL && valid_parallel_load_store (operands, QFmode)"
3554  "@
3555   ldf1\\t%1,%0\\n||\\tldf2\\t%3,%2
3556   stf1\\t%1,%0\\n||\\tstf2\\t%3,%2
3557   ldf\\t%1,%0\\n||\\tstf\\t%3,%2
3558   ldf\\t%3,%2\\n||\\tstf\\t%1,%0"
3559   [(set_attr "type" "load_load,store_store,load_store,store_load")])
3560
3561
3562 ;
3563 ; PUSH/POP
3564 ;
3565 (define_insn "pushqf"
3566   [(set (mem:QF (pre_inc:QI (reg:QI 20)))
3567         (match_operand:QF 0 "reg_operand" "f"))]
3568  ""
3569  "pushf\\t%0"
3570  [(set_attr "type" "push")])
3571
3572 (define_insn "popqf"
3573   [(set (match_operand:QF 0 "reg_operand" "=f")
3574         (mem:QF (post_dec:QI (reg:QI 20))))
3575    (clobber (reg:CC 21))]
3576  ""
3577  "popf\\t%0"
3578  [(set_attr "type" "pop")])
3579
3580 (define_insn "popqf_unspec"
3581   [(set (unspec:QF [(match_operand:QF 0 "reg_operand" "=f")] UNSPEC_POPQF)
3582         (mem:QF (post_dec:QI (reg:QI 20))))
3583    (clobber (match_dup 0))
3584    (clobber (reg:CC 21))]
3585  ""
3586  "popf\\t%0"
3587  [(set_attr "type" "pop")])
3588
3589 ;
3590 ; ABSF
3591 ;
3592 (define_expand "absqf2"
3593   [(parallel [(set (match_operand:QF 0 "reg_operand" "")
3594                    (abs:QF (match_operand:QF 1 "src_operand" "")))
3595               (clobber (reg:CC_NOOV 21))])]
3596 ""
3597 "")
3598
3599 (define_insn "*absqf2_clobber"
3600   [(set (match_operand:QF 0 "reg_operand" "=f")
3601         (abs:QF (match_operand:QF 1 "src_operand" "fHm")))
3602    (clobber (reg:CC_NOOV 21))]
3603   ""
3604   "absf\\t%1,%0"
3605   [(set_attr "type" "unarycc")])
3606
3607 (define_insn "*absqf2_test"
3608   [(set (reg:CC_NOOV 21)
3609         (compare:CC_NOOV (abs:QF (match_operand:QF 1 "src_operand" "fHm"))
3610                          (match_operand:QF 2 "fp_zero_operand" "G")))
3611    (clobber (match_scratch:QF 0 "=f"))]
3612   ""
3613   "absf\\t%1,%0"
3614   [(set_attr "type" "unarycc")])
3615
3616 (define_insn "*absqf2_set"
3617   [(set (reg:CC_NOOV 21)
3618         (compare:CC_NOOV (abs:QF (match_operand:QF 1 "src_operand" "fHm"))
3619                          (match_operand:QF 2 "fp_zero_operand" "G")))
3620    (set (match_operand:QF 0 "reg_operand" "=f")
3621         (abs:QF (match_dup 1)))]
3622
3623   ""
3624   "absf\\t%1,%0"
3625   [(set_attr "type" "unarycc")])
3626
3627 ;
3628 ; NEGF
3629 ;
3630 (define_expand "negqf2"
3631   [(parallel [(set (match_operand:QF 0 "reg_operand" "")
3632                    (neg:QF (match_operand:QF 1 "src_operand" "")))
3633               (clobber (reg:CC_NOOV 21))])]
3634 ""
3635 "")
3636
3637 (define_insn "*negqf2_clobber"
3638   [(set (match_operand:QF 0 "reg_operand" "=f")
3639         (neg:QF (match_operand:QF 1 "src_operand" "fHm")))
3640    (clobber (reg:CC_NOOV 21))]
3641   ""
3642   "negf\\t%1,%0"
3643   [(set_attr "type" "unarycc")])
3644
3645 (define_insn "*negqf2_test"
3646   [(set (reg:CC_NOOV 21)
3647         (compare:CC_NOOV (neg:QF (match_operand:QF 1 "src_operand" "fHm"))
3648                          (match_operand:QF 2 "fp_zero_operand" "G")))
3649    (clobber (match_scratch:QF 0 "=f"))]
3650   ""
3651   "negf\\t%1,%0"
3652   [(set_attr "type" "unarycc")])
3653
3654 (define_insn "*negqf2_set"
3655   [(set (reg:CC_NOOV 21)
3656         (compare:CC_NOOV (neg:QF (match_operand:QF 1 "src_operand" "fHm"))
3657                          (match_operand:QF 2 "fp_zero_operand" "G")))
3658    (set (match_operand:QF 0 "reg_operand" "=f")
3659         (neg:QF (match_dup 1)))]
3660   ""
3661   "negf\\t%1,%0"
3662   [(set_attr "type" "unarycc")])
3663
3664 ;
3665 ; FLOAT
3666 ;
3667 (define_insn "floatqiqf2"
3668   [(set (match_operand:QF 0 "reg_operand" "=f")
3669         (float:QF (match_operand:QI 1 "src_operand" "rIm")))
3670    (clobber (reg:CC 21))]
3671  ""
3672  "float\\t%1,%0"
3673   [(set_attr "type" "unarycc")])
3674
3675 (define_insn "*floatqiqf2_set"
3676   [(set (reg:CC 21)
3677         (compare:CC (float:QF (match_operand:QI 1 "src_operand" "rIm"))
3678                     (match_operand:QF 2 "fp_zero_operand" "G")))
3679    (set (match_operand:QF 0 "reg_operand" "=f")
3680         (float:QF (match_dup 1)))]
3681  ""
3682  "float\\t%1,%0"
3683   [(set_attr "type" "unarycc")])
3684
3685 ; Unsigned conversions are a little tricky because we need to
3686 ; add the value for the high bit if necessary.
3687
3688 ;
3689 (define_expand "floatunsqiqf2"
3690  [(set (match_dup 2) (match_dup 3))
3691   (parallel [(set (reg:CC 21)
3692                   (compare:CC (float:QF (match_operand:QI 1 "src_operand" ""))
3693                               (match_dup 3)))
3694              (set (match_dup 4)
3695                   (float:QF (match_dup 1)))])
3696   (set (match_dup 2)
3697        (if_then_else:QF (lt (reg:CC 21) (const_int 0))
3698                         (match_dup 5)
3699                         (match_dup 2)))
3700   (parallel [(set (match_operand:QF 0 "reg_operand" "")
3701                   (plus:QF (match_dup 2) (match_dup 4)))
3702              (clobber (reg:CC_NOOV 21))])]
3703  ""
3704  "operands[2] = gen_reg_rtx (QFmode);
3705   operands[3] = CONST0_RTX (QFmode); 
3706   operands[4] = gen_reg_rtx (QFmode);
3707   operands[5] = gen_reg_rtx (QFmode);
3708   emit_move_insn (operands[5], CONST_DOUBLE_ATOF (\"4294967296.0\", QFmode));")
3709
3710 (define_expand "floatunsqihf2"
3711  [(set (match_dup 2) (match_dup 3))
3712   (parallel [(set (reg:CC 21)
3713                   (compare:CC (float:HF (match_operand:QI 1 "src_operand" ""))
3714                               (match_dup 3)))
3715              (set (match_dup 4)
3716                   (float:HF (match_dup 1)))])
3717   (set (match_dup 2)
3718        (if_then_else:HF (lt (reg:CC 21) (const_int 0))
3719                         (match_dup 5)
3720                         (match_dup 2)))
3721   (parallel [(set (match_operand:HF 0 "reg_operand" "")
3722                   (plus:HF (match_dup 2) (match_dup 4)))
3723              (clobber (reg:CC_NOOV 21))])]
3724  ""
3725  "operands[2] = gen_reg_rtx (HFmode);
3726   operands[3] = CONST0_RTX (HFmode); 
3727   operands[4] = gen_reg_rtx (HFmode);
3728   operands[5] = gen_reg_rtx (HFmode);
3729   emit_move_insn (operands[5], CONST_DOUBLE_ATOF (\"4294967296.0\", HFmode));")
3730
3731 (define_insn "floatqihf2"
3732   [(set (match_operand:HF 0 "reg_operand" "=h")
3733         (float:HF (match_operand:QI 1 "src_operand" "rIm")))
3734    (clobber (reg:CC 21))]
3735  ""
3736  "float\\t%1,%0"
3737   [(set_attr "type" "unarycc")])
3738
3739 (define_insn "*floatqihf2_set"
3740   [(set (reg:CC 21)
3741         (compare:CC (float:HF (match_operand:QI 1 "src_operand" "rIm"))
3742                     (match_operand:QF 2 "fp_zero_operand" "G")))
3743    (set (match_operand:HF 0 "reg_operand" "=h")
3744         (float:HF (match_dup 1)))]
3745  ""
3746  "float\\t%1,%0"
3747   [(set_attr "type" "unarycc")])
3748
3749 ;
3750 ; FIX
3751 ;
3752 (define_insn "fixqfqi_clobber"
3753   [(set (match_operand:QI 0 "reg_operand" "=d,c")
3754         (fix:QI (match_operand:QF 1 "src_operand" "fHm,fHm")))
3755    (clobber (reg:CC 21))]
3756  ""
3757  "fix\\t%1,%0"
3758   [(set_attr "type" "unarycc")])
3759
3760 (define_insn "*fixqfqi_set"
3761   [(set (reg:CC 21)
3762         (compare:CC (fix:QI (match_operand:QF 1 "src_operand" "fHm"))
3763                     (const_int 0)))
3764    (set (match_operand:QI 0 "ext_reg_operand" "=d")
3765         (fix:QI (match_dup 1)))]
3766  ""
3767  "fix\\t%1,%0"
3768   [(set_attr "type" "unarycc")])
3769
3770 ;
3771 ; The C[34]x fix instruction implements a floor, not a straight trunc,
3772 ; so we have to invert the number, fix it, and reinvert it if negative
3773 ;
3774 (define_expand "fix_truncqfqi2"
3775   [(parallel [(set (match_dup 2)
3776                    (fix:QI (match_operand:QF 1 "src_operand" "")))
3777               (clobber (reg:CC 21))])
3778    (parallel [(set (match_dup 3) (neg:QF (match_dup 1)))
3779               (clobber (reg:CC_NOOV 21))])
3780    (parallel [(set (match_dup 4) (fix:QI (match_dup 3)))
3781               (clobber (reg:CC 21))])
3782    (parallel [(set (reg:CC_NOOV 21)
3783                    (compare:CC_NOOV (neg:QI (match_dup 4)) (const_int 0)))
3784               (set (match_dup 5) (neg:QI (match_dup 4)))])
3785    (set (match_dup 2)
3786         (if_then_else:QI (le (reg:CC 21) (const_int 0))
3787                          (match_dup 5)
3788                          (match_dup 2)))
3789    (set (match_operand:QI 0 "reg_operand" "=r") (match_dup 2))]
3790  ""
3791  "if (TARGET_FAST_FIX)
3792     {
3793        emit_insn (gen_fixqfqi_clobber (operands[0], operands[1]));
3794        DONE;
3795     }
3796   operands[2] = gen_reg_rtx (QImode);
3797   operands[3] = gen_reg_rtx (QFmode);
3798   operands[4] = gen_reg_rtx (QImode);
3799   operands[5] = gen_reg_rtx (QImode);
3800  ")
3801
3802 (define_expand "fix_truncqfhi2"
3803   [(parallel [(set (match_operand:HI 0 "reg_operand" "")
3804                    (fix:HI (match_operand:QF 1 "src_operand" "")))
3805               (clobber (reg:CC 21))])]
3806   ""
3807   "c4x_emit_libcall (fix_truncqfhi2_libfunc, FIX, HImode, QFmode, 2, operands);
3808    DONE;")
3809
3810 (define_expand "fixuns_truncqfqi2"
3811  [(parallel [(set (match_dup 2)
3812                   (fix:QI (match_operand:QF 1 "src_operand" "fHm")))
3813              (clobber (reg:CC 21))])
3814   (parallel [(set (match_dup 3)
3815                   (minus:QF (match_dup 1) (match_dup 5)))
3816              (clobber (reg:CC_NOOV 21))])
3817   (parallel [(set (reg:CC 21)
3818                   (compare:CC (fix:QI (match_dup 3))
3819                               (const_int 0)))
3820              (set (match_dup 4)
3821                   (fix:QI (match_dup 3)))])
3822   (parallel [(set (match_dup 4) (unspec:QI [(match_dup 2)] UNSPEC_LDIV))
3823              (use (reg:CC 21))])
3824   (set (match_operand:QI 0 "reg_operand" "=r") (match_dup 4))]
3825  ""
3826  "operands[2] = gen_reg_rtx (QImode);
3827   operands[3] = gen_reg_rtx (QFmode);
3828   operands[4] = gen_reg_rtx (QImode);
3829   operands[5] = gen_reg_rtx (QFmode);
3830   emit_move_insn (operands[5], CONST_DOUBLE_ATOF (\"4294967296.0\", QFmode));")
3831
3832 (define_expand "fixuns_truncqfhi2"
3833   [(parallel [(set (match_operand:HI 0 "reg_operand" "")
3834                    (unsigned_fix:HI (match_operand:QF 1 "src_operand" "")))
3835               (clobber (reg:CC 21))])]
3836   ""
3837   "c4x_emit_libcall (fixuns_truncqfhi2_libfunc, UNSIGNED_FIX, 
3838                      HImode, QFmode, 2, operands);
3839    DONE;")
3840
3841 ;
3842 ; RCPF
3843 ;
3844 (define_insn "rcpfqf_clobber"
3845   [(set (match_operand:QF 0 "reg_operand" "=f")
3846         (unspec:QF [(match_operand:QF 1 "src_operand" "fHm")] UNSPEC_RCPF))
3847    (clobber (reg:CC_NOOV 21))]
3848   "! TARGET_C3X"
3849   "rcpf\\t%1,%0"
3850   [(set_attr "type" "unarycc")])
3851
3852 ;
3853 ; RSQRF
3854 ;
3855 (define_insn "*rsqrfqf_clobber"
3856   [(set (match_operand:QF 0 "reg_operand" "=f")
3857         (unspec:QF [(match_operand:QF 1 "src_operand" "fHm")] UNSPEC_RSQRF))
3858    (clobber (reg:CC_NOOV 21))]
3859   "! TARGET_C3X"
3860   "rsqrf\\t%1,%0"
3861   [(set_attr "type" "unarycc")])
3862
3863 ;
3864 ; RNDF
3865 ;
3866 (define_insn "*rndqf_clobber"
3867   [(set (match_operand:QF 0 "reg_operand" "=f")
3868         (unspec:QF [(match_operand:QF 1 "src_operand" "fHm")] UNSPEC_RND))
3869    (clobber (reg:CC_NOOV 21))]
3870   "! TARGET_C3X"
3871   "rnd\\t%1,%0"
3872   [(set_attr "type" "unarycc")])
3873
3874
3875 ; Inlined float square root for C4x
3876 (define_expand "sqrtqf2_inline"
3877   [(parallel [(set (match_dup 2)
3878                    (unspec:QF [(match_operand:QF 1 "src_operand" "")] UNSPEC_RSQRF))
3879               (clobber (reg:CC_NOOV 21))])
3880    (parallel [(set (match_dup 3) (mult:QF (match_dup 5) (match_dup 1)))
3881               (clobber (reg:CC_NOOV 21))])
3882    (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 3)))
3883               (clobber (reg:CC_NOOV 21))])
3884    (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 4)))
3885               (clobber (reg:CC_NOOV 21))])
3886    (parallel [(set (match_dup 4) (minus:QF (match_dup 6) (match_dup 4)))
3887               (clobber (reg:CC_NOOV 21))])
3888    (parallel [(set (match_dup 2) (mult:QF (match_dup 2) (match_dup 4)))
3889               (clobber (reg:CC_NOOV 21))])
3890    (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 3)))
3891               (clobber (reg:CC_NOOV 21))])
3892    (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 4)))
3893               (clobber (reg:CC_NOOV 21))])
3894    (parallel [(set (match_dup 4) (minus:QF (match_dup 6) (match_dup 4)))
3895               (clobber (reg:CC_NOOV 21))])
3896    (parallel [(set (match_dup 2) (mult:QF (match_dup 2) (match_dup 4)))
3897               (clobber (reg:CC_NOOV 21))])
3898    (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 1)))
3899               (clobber (reg:CC_NOOV 21))])
3900    (parallel [(set (match_operand:QF 0 "reg_operand" "")
3901                    (unspec:QF [(match_dup 4)] UNSPEC_RND))
3902               (clobber (reg:CC_NOOV 21))])]
3903   "! TARGET_C3X"
3904   "if (! reload_in_progress
3905        && ! reg_operand (operands[1], QFmode))
3906      operands[1] = force_reg (QFmode, operands[1]);
3907    operands[2] = gen_reg_rtx (QFmode);
3908    operands[3] = gen_reg_rtx (QFmode);
3909    operands[4] = gen_reg_rtx (QFmode);
3910    operands[5] = CONST_DOUBLE_ATOF (\"0.5\", QFmode);
3911    operands[6] = CONST_DOUBLE_ATOF (\"1.5\", QFmode);")
3912
3913 (define_expand "sqrtqf2"
3914   [(parallel [(set (match_operand:QF 0 "reg_operand" "")
3915                    (sqrt:QF (match_operand:QF 1 "src_operand" "")))
3916               (clobber (reg:CC 21))])]
3917   "! TARGET_C3X && TARGET_INLINE"
3918   "emit_insn (gen_sqrtqf2_inline (operands[0], operands[1]));
3919    DONE;")
3920
3921 ;
3922 ; TOIEEE / FRIEEE
3923 ;
3924 (define_insn "toieee"
3925   [(set (match_operand:QF 0 "reg_operand" "=f")
3926         (unspec:QF [(match_operand:QF 1 "src_operand" "fHm")] UNSPEC_TOIEEE))
3927    (clobber (reg:CC 21))]
3928  ""
3929  "toieee\\t%1,%0")
3930
3931 (define_insn "frieee"
3932   [(set (match_operand:QF 0 "reg_operand" "=f")
3933         (unspec:QF [(match_operand:QF 1 "memory_operand" "m")] UNSPEC_FRIEEE))
3934    (clobber (reg:CC 21))]
3935  ""
3936  "frieee\\t%1,%0")
3937
3938 ;
3939 ; THREE OPERAND FLOAT INSTRUCTIONS
3940 ;
3941
3942 ;
3943 ; ADDF
3944 ;
3945 (define_expand "addqf3"
3946   [(parallel [(set (match_operand:QF 0 "reg_operand" "")
3947                    (plus:QF (match_operand:QF 1 "src_operand" "")
3948                             (match_operand:QF 2 "src_operand" "")))
3949               (clobber (reg:CC_NOOV 21))])]
3950   ""
3951   "legitimize_operands (PLUS, operands, QFmode);")
3952
3953 (define_insn "*addqf3_clobber"
3954   [(set (match_operand:QF 0 "reg_operand" "=f,f,?f")
3955         (plus:QF (match_operand:QF 1 "src_operand" "%0,fR,fS<>")
3956                  (match_operand:QF 2 "src_operand" "fHm,R,fS<>")))
3957    (clobber (reg:CC_NOOV 21))]
3958   "valid_operands (PLUS, operands, QFmode)"
3959   "@
3960    addf\\t%2,%0
3961    addf3\\t%2,%1,%0
3962    addf3\\t%2,%1,%0"
3963   [(set_attr "type" "binarycc,binarycc,binarycc")])
3964
3965 (define_insn "*addqf3_test"
3966   [(set (reg:CC_NOOV 21)
3967         (compare:CC_NOOV (plus:QF (match_operand:QF 1 "src_operand" "%0,fR,fS<>")
3968                                   (match_operand:QF 2 "src_operand" "fHm,R,fS<>"))
3969                          (match_operand:QF 3 "fp_zero_operand" "G,G,G")))
3970    (clobber (match_scratch:QF 0 "=f,f,?f"))]
3971   "valid_operands (PLUS, operands, QFmode)"
3972   "@
3973    addf\\t%2,%0
3974    addf3\\t%2,%1,%0
3975    addf3\\t%2,%1,%0"
3976   [(set_attr "type" "binarycc,binarycc,binarycc")])
3977
3978 (define_insn "*addqf3_set"
3979   [(set (reg:CC_NOOV 21)
3980         (compare:CC_NOOV (plus:QF (match_operand:QF 1 "src_operand" "%0,fR,fS<>")
3981                                   (match_operand:QF 2 "src_operand" "fHm,R,fS<>"))
3982                          (match_operand:QF 3 "fp_zero_operand" "G,G,G")))
3983    (set (match_operand:QF 0 "reg_operand" "=f,f,?f")
3984         (plus:QF (match_dup 1)
3985                  (match_dup 2)))]
3986   "valid_operands (PLUS, operands, QFmode)"
3987   "@
3988    addf\\t%2,%0
3989    addf3\\t%2,%1,%0
3990    addf3\\t%2,%1,%0"
3991   [(set_attr "type" "binarycc,binarycc,binarycc")])
3992
3993 ;
3994 ; SUBF/SUBRF
3995 ;
3996 (define_expand "subqf3"
3997   [(parallel [(set (match_operand:QF 0 "reg_operand" "")
3998                    (minus:QF (match_operand:QF 1 "src_operand" "")
3999                              (match_operand:QF 2 "src_operand" "")))
4000               (clobber (reg:CC_NOOV 21))])]
4001   ""
4002   "legitimize_operands (MINUS, operands, QFmode);")
4003
4004 (define_insn "*subqf3_clobber"
4005    [(set (match_operand:QF 0 "reg_operand" "=f,f,f,?f")
4006          (minus:QF (match_operand:QF 1 "src_operand" "0,fHm,fR,fS<>")
4007                    (match_operand:QF 2 "src_operand" "fHm,0,R,fS<>")))
4008    (clobber (reg:CC_NOOV 21))]
4009   "valid_operands (MINUS, operands, QFmode)"
4010   "@
4011    subf\\t%2,%0
4012    subrf\\t%1,%0
4013    subf3\\t%2,%1,%0
4014    subf3\\t%2,%1,%0"
4015   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")])
4016
4017 (define_insn "*subqf3_test"
4018   [(set (reg:CC_NOOV 21)
4019         (compare:CC_NOOV (minus:QF (match_operand:QF 1 "src_operand" "0,fHm,fR,fS<>")
4020                                    (match_operand:QF 2 "src_operand" "fHm,0,R,fS<>"))
4021                          (match_operand:QF 3 "fp_zero_operand" "G,G,G,G")))
4022    (clobber (match_scratch:QF 0 "=f,f,f,?f"))]
4023   "valid_operands (MINUS, operands, QFmode)"
4024   "@
4025    subf\\t%2,%0
4026    subrf\\t%1,%0
4027    subf3\\t%2,%1,%0
4028    subf3\\t%2,%1,%0"
4029   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")])
4030
4031 (define_insn "*subqf3_set"
4032   [(set (reg:CC_NOOV 21)
4033         (compare:CC_NOOV (minus:QF (match_operand:QF 1 "src_operand" "0,fHm,fR,fS<>")
4034                                    (match_operand:QF 2 "src_operand" "fHm,0,R,fS<>"))
4035                          (match_operand:QF 3 "fp_zero_operand" "G,G,G,G")))
4036    (set (match_operand:QF 0 "reg_operand" "=f,f,f,?f")
4037         (minus:QF (match_dup 1)
4038                   (match_dup 2)))]
4039   "valid_operands (MINUS, operands, QFmode)"
4040   "@
4041    subf\\t%2,%0
4042    subrf\\t%1,%0
4043    subf3\\t%2,%1,%0
4044    subf3\\t%2,%1,%0"
4045   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")])
4046
4047 ;
4048 ; MPYF
4049 ;
4050 (define_expand "mulqf3"
4051   [(parallel [(set (match_operand:QF 0 "reg_operand" "")
4052                    (mult:QF (match_operand:QF 1 "src_operand" "")
4053                             (match_operand:QF 2 "src_operand" "")))
4054               (clobber (reg:CC_NOOV 21))])]
4055   ""
4056   "legitimize_operands (MULT, operands, QFmode);")
4057
4058 (define_insn "*mulqf3_clobber"
4059   [(set (match_operand:QF 0 "reg_operand" "=f,f,?f")
4060         (mult:QF (match_operand:QF 1 "src_operand" "%0,fR,fS<>")
4061                  (match_operand:QF 2 "src_operand" "fHm,R,fS<>")))
4062    (clobber (reg:CC_NOOV 21))]
4063   "valid_operands (MULT, operands, QFmode)"
4064   "@
4065    mpyf\\t%2,%0
4066    mpyf3\\t%2,%1,%0
4067    mpyf3\\t%2,%1,%0"
4068   [(set_attr "type" "binarycc,binarycc,binarycc")])
4069
4070 (define_insn "*mulqf3_test"
4071   [(set (reg:CC_NOOV 21)
4072         (compare:CC_NOOV (mult:QF (match_operand:QF 1 "src_operand" "%0,fR,fS<>")
4073                                   (match_operand:QF 2 "src_operand" "fHm,R,fS<>"))
4074                          (match_operand:QF 3 "fp_zero_operand" "G,G,G")))
4075    (clobber (match_scratch:QF 0 "=f,f,?f"))]
4076   "valid_operands (MULT, operands, QFmode)"
4077   "@
4078    mpyf\\t%2,%0
4079    mpyf3\\t%2,%1,%0
4080    mpyf3\\t%2,%1,%0"
4081   [(set_attr "type" "binarycc,binarycc,binarycc")])
4082
4083 (define_insn "*mulqf3_set"
4084   [(set (reg:CC_NOOV 21)
4085         (compare:CC_NOOV (mult:QF (match_operand:QF 1 "src_operand" "%0,fR,fS<>")
4086                                   (match_operand:QF 2 "src_operand" "fHm,R,fS<>"))
4087                          (match_operand:QF 3 "fp_zero_operand" "G,G,G")))
4088    (set (match_operand:QF 0 "reg_operand" "=f,f,?f")
4089         (mult:QF (match_dup 1)
4090                  (match_dup 2)))]
4091   "valid_operands (MULT, operands, QFmode)"
4092   "@
4093    mpyf\\t%2,%0
4094    mpyf3\\t%2,%1,%0
4095    mpyf3\\t%2,%1,%0"
4096   [(set_attr "type" "binarycc,binarycc,binarycc")])
4097
4098 ;
4099 ; CMPF
4100 ;
4101 (define_expand "cmpqf"
4102   [(set (reg:CC 21)
4103         (compare:CC (match_operand:QF 0 "src_operand" "")
4104                     (match_operand:QF 1 "src_operand" "")))]
4105   ""
4106   "legitimize_operands (COMPARE, operands, QFmode);
4107    c4x_compare_op0 = operands[0];
4108    c4x_compare_op1 = operands[1];
4109    DONE;")
4110
4111 (define_insn "*cmpqf"
4112   [(set (reg:CC 21)
4113         (compare:CC (match_operand:QF 0 "src_operand" "f,fR,fS<>")
4114                     (match_operand:QF 1 "src_operand" "fHm,R,fS<>")))]
4115   "valid_operands (COMPARE, operands, QFmode)"
4116   "@
4117    cmpf\\t%1,%0
4118    cmpf3\\t%1,%0
4119    cmpf3\\t%1,%0"
4120   [(set_attr "type" "compare,compare,compare")])
4121
4122 (define_insn "*cmpqf_noov"
4123   [(set (reg:CC_NOOV 21)
4124         (compare:CC_NOOV (match_operand:QF 0 "src_operand" "f,fR,fS<>")
4125                          (match_operand:QF 1 "src_operand" "fHm,R,fS<>")))]
4126   "valid_operands (COMPARE, operands, QFmode)"
4127   "@
4128    cmpf\\t%1,%0
4129    cmpf3\\t%1,%0
4130    cmpf3\\t%1,%0"
4131   [(set_attr "type" "compare,compare,compare")])
4132
4133 ; Inlined float divide for C4x
4134 (define_expand "divqf3_inline"
4135   [(parallel [(set (match_dup 3)
4136                    (unspec:QF [(match_operand:QF 2 "src_operand" "")] UNSPEC_RCPF))
4137               (clobber (reg:CC_NOOV 21))])
4138    (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 3)))
4139               (clobber (reg:CC_NOOV 21))])
4140    (parallel [(set (match_dup 4) (minus:QF (match_dup 5) (match_dup 4)))
4141               (clobber (reg:CC_NOOV 21))])
4142    (parallel [(set (match_dup 3) (mult:QF (match_dup 3) (match_dup 4)))
4143               (clobber (reg:CC_NOOV 21))])
4144    (parallel [(set (match_dup 4) (mult:QF (match_dup 2) (match_dup 3)))
4145               (clobber (reg:CC_NOOV 21))])
4146    (parallel [(set (match_dup 4) (minus:QF (match_dup 5) (match_dup 4)))
4147               (clobber (reg:CC_NOOV 21))])
4148    (parallel [(set (match_dup 3) (mult:QF (match_dup 3) (match_dup 4)))
4149               (clobber (reg:CC_NOOV 21))])
4150    (parallel [(set (match_dup 3)
4151                    (mult:QF (match_operand:QF 1 "src_operand" "")
4152                             (match_dup 3)))
4153               (clobber (reg:CC_NOOV 21))])
4154    (parallel [(set (match_operand:QF 0 "reg_operand" "")
4155                    (unspec:QF [(match_dup 3)] UNSPEC_RND))
4156               (clobber (reg:CC_NOOV 21))])]
4157   "! TARGET_C3X"
4158   "if (! reload_in_progress
4159       && ! reg_operand (operands[2], QFmode))
4160      operands[2] = force_reg (QFmode, operands[2]);
4161    operands[3] = gen_reg_rtx (QFmode);
4162    operands[4] = gen_reg_rtx (QFmode);
4163    operands[5] = CONST2_RTX (QFmode);")
4164
4165 (define_expand "divqf3"
4166   [(parallel [(set (match_operand:QF 0 "reg_operand" "")
4167                    (div:QF (match_operand:QF 1 "src_operand" "")
4168                             (match_operand:QF 2 "src_operand" "")))
4169               (clobber (reg:CC 21))])]
4170   "! TARGET_C3X && TARGET_INLINE"
4171   "emit_insn (gen_divqf3_inline (operands[0], operands[1], operands[2]));
4172    DONE;")
4173
4174 ;
4175 ; CONDITIONAL MOVES
4176 ;
4177
4178 ; ???  We should make these pattern fail if the src operand combination
4179 ; is not valid.  Although reload will fix things up, it will introduce
4180 ; extra load instructions that won't be hoisted out of a loop.
4181
4182 (define_insn "*ldi_conditional"
4183   [(set (match_operand:QI 0 "reg_operand" "=r,r")
4184         (if_then_else:QI (match_operator 1 "comparison_operator"
4185                           [(reg:CC 21) (const_int 0)])
4186                          (match_operand:QI 2 "src_operand" "rIm,0")
4187                          (match_operand:QI 3 "src_operand" "0,rIm")))]
4188  "valid_operands (IF_THEN_ELSE, operands, QImode)"
4189  "@
4190   ldi%1\\t%2,%0
4191   ldi%I1\\t%3,%0"
4192  [(set_attr "type" "binary")])
4193
4194 (define_insn "*ldi_conditional_noov"
4195   [(set (match_operand:QI 0 "reg_operand" "=r,r")
4196         (if_then_else:QI (match_operator 1 "comparison_operator"
4197                           [(reg:CC_NOOV 21) (const_int 0)])
4198                          (match_operand:QI 2 "src_operand" "rIm,0")
4199                          (match_operand:QI 3 "src_operand" "0,rIm")))]
4200  "GET_CODE (operands[1]) != LE
4201   && GET_CODE (operands[1]) != GE
4202   && GET_CODE (operands[1]) != LT
4203   && GET_CODE (operands[1]) != GT
4204   && valid_operands (IF_THEN_ELSE, operands, QImode)"
4205  "@
4206   ldi%1\\t%2,%0
4207   ldi%I1\\t%3,%0"
4208  [(set_attr "type" "binary")])
4209
4210 (define_insn "*ldi_on_overflow"
4211   [(set (match_operand:QI 0 "reg_operand" "=r")
4212         (unspec:QI [(match_operand:QI 1 "src_operand" "rIm")] UNSPEC_LDIV))
4213    (use (reg:CC 21))]
4214   ""
4215   "ldiv\\t%1,%0"
4216   [(set_attr "type" "unary")])
4217
4218 ; Move operand 2 to operand 0 if condition (operand 1) is true
4219 ; else move operand 3 to operand 0.
4220 ; The temporary register is required below because some of the operands
4221 ; might be identical (namely 0 and 2). 
4222 ;
4223 (define_expand "movqicc"
4224   [(set (match_operand:QI 0 "reg_operand" "")
4225         (if_then_else:QI (match_operand 1 "comparison_operator" "")
4226                          (match_operand:QI 2 "src_operand" "")
4227                          (match_operand:QI 3 "src_operand" "")))]
4228  ""
4229  "{ 
4230     enum rtx_code code = GET_CODE (operands[1]);
4231     rtx ccreg = c4x_gen_compare_reg (code, c4x_compare_op0, c4x_compare_op1);
4232     if (ccreg == NULL_RTX) FAIL;
4233     emit_insn (gen_rtx_SET (QImode, operands[0],
4234                             gen_rtx_IF_THEN_ELSE (QImode,
4235                                  gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx),
4236                                                  operands[2], operands[3])));
4237     DONE;}")
4238                       
4239 (define_insn "*ldf_conditional"
4240   [(set (match_operand:QF 0 "reg_operand" "=f,f")
4241         (if_then_else:QF (match_operator 1 "comparison_operator"
4242                           [(reg:CC 21) (const_int 0)])
4243                          (match_operand:QF 2 "src_operand" "fHm,0")
4244                          (match_operand:QF 3 "src_operand" "0,fHm")))]
4245  "valid_operands (IF_THEN_ELSE, operands, QFmode)"
4246  "@
4247   ldf%1\\t%2,%0
4248   ldf%I1\\t%3,%0"
4249  [(set_attr "type" "binary")])
4250
4251 (define_insn "*ldf_conditional_noov"
4252   [(set (match_operand:QF 0 "reg_operand" "=f,f")
4253         (if_then_else:QF (match_operator 1 "comparison_operator"
4254                           [(reg:CC_NOOV 21) (const_int 0)])
4255                          (match_operand:QF 2 "src_operand" "fHm,0")
4256                          (match_operand:QF 3 "src_operand" "0,fHm")))]
4257  "GET_CODE (operands[1]) != LE
4258   && GET_CODE (operands[1]) != GE
4259   && GET_CODE (operands[1]) != LT
4260   && GET_CODE (operands[1]) != GT
4261   && valid_operands (IF_THEN_ELSE, operands, QFmode)"
4262  "@
4263   ldf%1\\t%2,%0
4264   ldf%I1\\t%3,%0"
4265  [(set_attr "type" "binary")])
4266
4267 (define_expand "movqfcc"
4268   [(set (match_operand:QF 0 "reg_operand" "")
4269         (if_then_else:QF (match_operand 1 "comparison_operator" "")
4270                          (match_operand:QF 2 "src_operand" "")
4271                          (match_operand:QF 3 "src_operand" "")))]
4272  ""
4273  "{ 
4274     enum rtx_code code = GET_CODE (operands[1]);
4275     rtx ccreg = c4x_gen_compare_reg (code, c4x_compare_op0, c4x_compare_op1);
4276     if (ccreg == NULL_RTX) FAIL;
4277     emit_insn (gen_rtx_SET (QFmode, operands[0],
4278                             gen_rtx_IF_THEN_ELSE (QFmode,
4279                                  gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx),
4280                                                  operands[2], operands[3])));
4281     DONE;}")
4282
4283 (define_insn "*ldhf_conditional"
4284   [(set (match_operand:HF 0 "reg_operand" "=h,h")
4285         (if_then_else:HF (match_operator 1 "comparison_operator"
4286                           [(reg:CC 21) (const_int 0)])
4287                          (match_operand:HF 2 "src_operand" "hH,0")
4288                          (match_operand:HF 3 "src_operand" "0,hH")))]
4289  ""
4290  "@
4291   ldf%1\\t%2,%0
4292   ldf%I1\\t%3,%0"
4293  [(set_attr "type" "binary")])
4294
4295 (define_insn "*ldhf_conditional_noov"
4296   [(set (match_operand:HF 0 "reg_operand" "=h,h")
4297         (if_then_else:HF (match_operator 1 "comparison_operator"
4298                           [(reg:CC_NOOV 21) (const_int 0)])
4299                          (match_operand:HF 2 "src_operand" "hH,0")
4300                          (match_operand:HF 3 "src_operand" "0,hH")))]
4301  "GET_CODE (operands[1]) != LE
4302   && GET_CODE (operands[1]) != GE
4303   && GET_CODE (operands[1]) != LT
4304   && GET_CODE (operands[1]) != GT"
4305  "@
4306   ldf%1\\t%2,%0
4307   ldf%I1\\t%3,%0"
4308  [(set_attr "type" "binary")])
4309
4310 (define_expand "movhfcc"
4311   [(set (match_operand:HF 0 "reg_operand" "")
4312         (if_then_else:HF (match_operand 1 "comparison_operator" "")
4313                          (match_operand:HF 2 "src_operand" "")
4314                          (match_operand:HF 3 "src_operand" "")))]
4315  ""
4316  "{ 
4317     enum rtx_code code = GET_CODE (operands[1]);
4318     rtx ccreg = c4x_gen_compare_reg (code, c4x_compare_op0, c4x_compare_op1);
4319     if (ccreg == NULL_RTX) FAIL;
4320     emit_insn (gen_rtx_SET (HFmode, operands[0],
4321                             gen_rtx_IF_THEN_ELSE (HFmode,
4322                                  gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx),
4323                                                  operands[2], operands[3])));
4324     DONE;}")
4325
4326 (define_expand "seq"
4327  [(set (match_operand:QI 0 "reg_operand" "")
4328        (const_int 0))
4329   (set (match_dup 0)
4330        (if_then_else:QI (eq (match_dup 1) (const_int 0))
4331                         (const_int 1)
4332                         (match_dup 0)))]
4333  ""
4334  "operands[1] = c4x_gen_compare_reg (EQ, c4x_compare_op0, c4x_compare_op1);")
4335
4336 (define_expand "sne"
4337  [(set (match_operand:QI 0 "reg_operand" "")
4338        (const_int 0))
4339   (set (match_dup 0)
4340        (if_then_else:QI (ne (match_dup 1) (const_int 0))
4341                         (const_int 1)
4342                         (match_dup 0)))]
4343  ""
4344  "operands[1] = c4x_gen_compare_reg (NE, c4x_compare_op0, c4x_compare_op1);")
4345
4346 (define_expand "slt"
4347   [(set (match_operand:QI 0 "reg_operand" "")
4348         (const_int 0))
4349    (set (match_dup 0)
4350         (if_then_else:QI (lt (match_dup 1) (const_int 0))
4351                         (const_int 1)
4352                          (match_dup 0)))]
4353   ""
4354   "operands[1] = c4x_gen_compare_reg (LT, c4x_compare_op0, c4x_compare_op1);
4355    if (operands[1] == NULL_RTX) FAIL;")
4356
4357 (define_expand "sltu"
4358   [(set (match_operand:QI 0 "reg_operand" "")
4359         (const_int 0))
4360    (set (match_dup 0)
4361         (if_then_else:QI (ltu (match_dup 1) (const_int 0))
4362                         (const_int 1)
4363                          (match_dup 0)))]
4364   ""
4365   "operands[1] = c4x_gen_compare_reg (LTU, c4x_compare_op0, c4x_compare_op1);")
4366
4367 (define_expand "sgt"
4368   [(set (match_operand:QI 0 "reg_operand" "")
4369         (const_int 0))
4370    (set (match_dup 0)
4371         (if_then_else:QI (gt (match_dup 1) (const_int 0))
4372                         (const_int 1)
4373                          (match_dup 0)))]
4374   "" 
4375   "operands[1] = c4x_gen_compare_reg (GT, c4x_compare_op0, c4x_compare_op1);
4376    if (operands[1] == NULL_RTX) FAIL;")
4377
4378 (define_expand "sgtu"
4379   [(set (match_operand:QI 0 "reg_operand" "")
4380         (const_int 0))
4381    (set (match_dup 0)
4382         (if_then_else:QI (gtu (match_dup 1) (const_int 0))
4383                         (const_int 1)
4384                          (match_dup 0)))]
4385   ""
4386   "operands[1] = c4x_gen_compare_reg (GTU, c4x_compare_op0, c4x_compare_op1);")
4387
4388 (define_expand "sle"
4389   [(set (match_operand:QI 0 "reg_operand" "")
4390         (const_int 0))
4391    (set (match_dup 0)
4392         (if_then_else:QI (le (match_dup 1) (const_int 0))
4393                          (const_int 1)
4394                          (match_dup 0)))]
4395   ""
4396   "operands[1] = c4x_gen_compare_reg (LE, c4x_compare_op0, c4x_compare_op1);
4397    if (operands[1] == NULL_RTX) FAIL;")
4398
4399 (define_expand "sleu"
4400   [(set (match_operand:QI 0 "reg_operand" "")
4401         (const_int 0))
4402    (set (match_dup 0)
4403         (if_then_else:QI (leu (match_dup 1) (const_int 0))
4404                          (const_int 1)
4405                          (match_dup 0)))]
4406   ""
4407   "operands[1] = c4x_gen_compare_reg (LEU, c4x_compare_op0, c4x_compare_op1);")
4408
4409 (define_expand "sge"
4410   [(set (match_operand:QI 0 "reg_operand" "")
4411         (const_int 0))
4412    (set (match_dup 0)
4413         (if_then_else:QI (ge (match_dup 1) (const_int 0))
4414                          (const_int 1)
4415                          (match_dup 0)))]
4416   ""
4417   "operands[1] = c4x_gen_compare_reg (GE, c4x_compare_op0, c4x_compare_op1);
4418    if (operands[1] == NULL_RTX) FAIL;")
4419
4420 (define_expand "sgeu"
4421   [(set (match_operand:QI 0 "reg_operand" "")
4422         (const_int 0))
4423    (set (match_dup 0)
4424         (if_then_else:QI (geu (match_dup 1) (const_int 0))
4425                          (const_int 1)
4426                          (match_dup 0)))]
4427   ""
4428   "operands[1] = c4x_gen_compare_reg (GEU, c4x_compare_op0, c4x_compare_op1);")
4429
4430 (define_split
4431   [(set (match_operand:QI 0 "reg_operand" "")
4432         (match_operator:QI 1 "comparison_operator" [(reg:CC 21) (const_int 0)]))]
4433   "reload_completed"
4434   [(set (match_dup 0) (const_int 0))
4435    (set (match_dup 0)
4436         (if_then_else:QI (match_op_dup 1 [(reg:CC 21) (const_int 0)])
4437                         (const_int 1)
4438                          (match_dup 0)))]
4439   "")
4440
4441 (define_split
4442   [(set (match_operand:QI 0 "reg_operand" "")
4443         (match_operator:QI 1 "comparison_operator" [(reg:CC_NOOV 21) (const_int 0)]))]
4444   "reload_completed"
4445   [(set (match_dup 0) (const_int 0))
4446    (set (match_dup 0)
4447         (if_then_else:QI (match_op_dup 1 [(reg:CC_NOOV 21) (const_int 0)])
4448                          (const_int 1)
4449                          (match_dup 0)))]
4450   "")
4451
4452 (define_insn "*bu"
4453   [(set (pc)
4454         (unspec [(match_operand:QI 0 "reg_operand" "r")] UNSPEC_BU))]
4455   ""
4456   "bu%#\\t%0"
4457   [(set_attr "type" "jump")])
4458
4459 (define_expand "caseqi"
4460   [(parallel [(set (match_dup 5)
4461                    (minus:QI (match_operand:QI 0 "reg_operand" "")
4462                              (match_operand:QI 1 "src_operand" "")))
4463               (clobber (reg:CC_NOOV 21))])
4464    (set (reg:CC 21)
4465         (compare:CC (match_dup 5)
4466                     (match_operand:QI 2 "src_operand" "")))
4467    (set (pc)
4468         (if_then_else (gtu (reg:CC 21)
4469                            (const_int 0))
4470                       (label_ref (match_operand 4 "" ""))
4471                       (pc)))
4472    (parallel [(set (match_dup 6)
4473                    (plus:QI (match_dup 5)
4474                             (label_ref:QI (match_operand 3 "" ""))))
4475               (clobber (reg:CC_NOOV 21))])
4476    (set (match_dup 7)
4477         (mem:QI (match_dup 6)))
4478    (set (pc) (match_dup 7))]
4479   ""
4480   "operands[5] = gen_reg_rtx (QImode);
4481    operands[6] = gen_reg_rtx (QImode);
4482    operands[7] = gen_reg_rtx (QImode);")
4483                 
4484 ;
4485 ; PARALLEL FLOAT INSTRUCTIONS
4486 ;
4487 ; This patterns are under development
4488
4489 ;
4490 ; ABSF/STF
4491 ;
4492
4493 (define_insn "*absqf2_movqf_clobber"
4494   [(set (match_operand:QF 0 "ext_low_reg_operand" "=q")
4495         (abs:QF (match_operand:QF 1 "par_ind_operand" "S<>")))
4496    (set (match_operand:QF 2 "par_ind_operand" "=S<>")
4497         (match_operand:QF 3 "ext_low_reg_operand" "q"))
4498    (clobber (reg:CC_NOOV 21))]
4499   "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)"
4500   "absf\\t%1,%0\\n||\\tstf\\t%3,%2"
4501   [(set_attr "type" "binarycc")])
4502
4503 ;
4504 ; ADDF/STF
4505 ;
4506
4507 (define_insn "*addqf3_movqf_clobber"
4508   [(set (match_operand:QF 0 "ext_low_reg_operand" "=q,q")
4509         (plus:QF (match_operand:QF 1 "parallel_operand" "%q,S<>")
4510                  (match_operand:QF 2 "parallel_operand" "S<>,q")))
4511    (set (match_operand:QF 3 "par_ind_operand" "=S<>,S<>")
4512         (match_operand:QF 4 "ext_low_reg_operand" "q,q"))
4513    (clobber (reg:CC 21))]
4514   "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QFmode)"
4515   "addf3\\t%2,%1,%0\\n||\\tstf\\t%4,%3"
4516   [(set_attr "type" "binarycc,binarycc")])
4517
4518 ;
4519 ; FLOAT/STF
4520 ;
4521
4522 (define_insn "*floatqiqf2_movqf_clobber"
4523   [(set (match_operand:QF 0 "ext_low_reg_operand" "=q")
4524         (float:QF (match_operand:QI 1 "par_ind_operand" "S<>")))
4525    (set (match_operand:QF 2 "par_ind_operand" "=S<>")
4526         (match_operand:QF 3 "ext_low_reg_operand" "q"))
4527    (clobber (reg:CC 21))]
4528   "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)"
4529   "float\\t%1,%0\\n||\\tstf\\t%3,%2"
4530   [(set_attr "type" "binarycc")])
4531
4532 ;
4533 ; MPYF/ADDF
4534 ;
4535
4536 (define_insn "*mulqf3_addqf3_clobber"
4537   [(set (match_operand:QF 0 "r0r1_reg_operand" "=t,t,t,t")
4538         (mult:QF (match_operand:QF 1 "parallel_operand" "%S<>!V,q,S<>!V,q")
4539                  (match_operand:QF 2 "parallel_operand" "q,S<>!V,S<>!V,q")))
4540    (set (match_operand:QF 3 "r2r3_reg_operand" "=u,u,u,u")
4541         (plus:QF (match_operand:QF 4 "parallel_operand" "%S<>!V,q,q,S<>!V")
4542                  (match_operand:QF 5 "parallel_operand" "q,S<>!V,q,S<>!V")))
4543    (clobber (reg:CC_NOOV 21))]
4544   "TARGET_PARALLEL_MPY && valid_parallel_operands_6 (operands, QFmode)"
4545   "mpyf3\\t%2,%1,%0\\n||\\taddf3\\t%5,%4,%3"
4546   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")])
4547
4548
4549 ;
4550 ; MPYF/STF
4551 ;
4552
4553 (define_insn "*mulqf3_movqf_clobber"
4554   [(set (match_operand:QF 0 "ext_low_reg_operand" "=q,q")
4555         (mult:QF (match_operand:QF 1 "parallel_operand" "%q,S<>")
4556                  (match_operand:QF 2 "parallel_operand" "S<>,q")))
4557    (set (match_operand:QF 3 "par_ind_operand" "=S<>,S<>")
4558         (match_operand:QF 4 "ext_low_reg_operand" "q,q"))
4559    (clobber (reg:CC 21))]
4560   "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QFmode)"
4561   "mpyf3\\t%2,%1,%0\\n||\\tstf\\t%4,%3"
4562   [(set_attr "type" "binarycc,binarycc")])
4563
4564 ;
4565 ; MPYF/SUBF
4566 ;
4567
4568 (define_insn "*mulqf3_subqf3_clobber"
4569   [(set (match_operand:QF 0 "r0r1_reg_operand" "=t,t")
4570         (mult:QF (match_operand:QF 1 "parallel_operand" "S<>,q")
4571                  (match_operand:QF 2 "parallel_operand" "q,S<>")))
4572    (set (match_operand:QF 3 "r2r3_reg_operand" "=u,u")
4573         (minus:QF (match_operand:QF 4 "parallel_operand" "S<>,q")
4574                   (match_operand:QF 5 "parallel_operand" "q,S<>")))
4575    (clobber (reg:CC 21))]
4576   "TARGET_PARALLEL_MPY && valid_parallel_operands_6 (operands, QFmode)"
4577   "mpyf3\\t%2,%1,%0\\n||\\tsubf3\\t%5,%4,%3"
4578   [(set_attr "type" "binarycc,binarycc")])
4579
4580 ;
4581 ; MPYF/LDF 0
4582 ;
4583
4584 (define_insn "*mulqf3_clrqf_clobber"
4585   [(set (match_operand:QF 0 "r0r1_reg_operand" "=t")
4586         (mult:QF (match_operand:QF 1 "par_ind_operand" "%S<>")
4587                  (match_operand:QF 2 "par_ind_operand" "S<>")))
4588    (set (match_operand:QF 3 "r2r3_reg_operand" "=u")
4589         (match_operand:QF 4 "fp_zero_operand" "G"))
4590    (clobber (reg:CC 21))]
4591   "TARGET_PARALLEL_MPY"
4592   "mpyf3\\t%2,%1,%0\\n||\\tsubf3\\t%3,%3,%3"
4593   [(set_attr "type" "binarycc")])
4594
4595 ;
4596 ; NEGF/STF
4597 ;
4598
4599 (define_insn "*negqf2_movqf_clobber"
4600   [(set (match_operand:QF 0 "ext_low_reg_operand" "=q")
4601         (neg:QF (match_operand:QF 1 "par_ind_operand" "S<>")))
4602    (set (match_operand:QF 2 "par_ind_operand" "=S<>")
4603         (match_operand:QF 3 "ext_low_reg_operand" "q"))
4604    (clobber (reg:CC 21))]
4605   "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)"
4606   "negf\\t%1,%0\\n||\\tstf\\t%3,%2"
4607   [(set_attr "type" "binarycc")])
4608
4609 ;
4610 ; SUBF/STF
4611 ;
4612
4613 (define_insn "*subqf3_movqf_clobber"
4614   [(set (match_operand:QF 0 "ext_low_reg_operand" "=q")
4615         (minus:QF (match_operand:QF 1 "ext_low_reg_operand" "q")
4616                   (match_operand:QF 2 "par_ind_operand" "S<>")))
4617    (set (match_operand:QF 3 "par_ind_operand" "=S<>")
4618         (match_operand:QF 4 "ext_low_reg_operand" "q"))
4619    (clobber (reg:CC 21))]
4620   "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QFmode)"
4621   "subf3\\t%2,%1,%0\\n||\\tstf\\t%4,%3"
4622   [(set_attr "type" "binarycc")])
4623
4624 ;
4625 ; TOIEEE/STF
4626 ;
4627
4628 (define_insn "*toieee_movqf_clobber"
4629   [(set (match_operand:QF 0 "ext_low_reg_operand" "=q")
4630         (unspec:QF [(match_operand:QF 1 "par_ind_operand" "S<>")] UNSPEC_TOIEEE))
4631    (set (match_operand:QF 2 "par_ind_operand" "=S<>")
4632         (match_operand:QF 3 "ext_low_reg_operand" "q"))
4633    (clobber (reg:CC 21))]
4634   "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)"
4635   "toieee\\t%1,%0\\n||\\tstf\\t%3,%2"
4636   [(set_attr "type" "binarycc")])
4637
4638 ;
4639 ; FRIEEE/STF
4640 ;
4641
4642 (define_insn "*frieee_movqf_clobber"
4643   [(set (match_operand:QF 0 "ext_low_reg_operand" "=q")
4644         (unspec:QF [(match_operand:QF 1 "par_ind_operand" "S<>")] UNSPEC_FRIEEE))
4645    (set (match_operand:QF 2 "par_ind_operand" "=S<>")
4646         (match_operand:QF 3 "ext_low_reg_operand" "q"))
4647    (clobber (reg:CC 21))]
4648   "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)"
4649   "frieee\\t%1,%0\\n||\\tstf\\t%3,%2"
4650   [(set_attr "type" "binarycc")])
4651
4652 ;
4653 ; PARALLEL INTEGER INSTRUCTIONS
4654 ;
4655
4656 ;
4657 ; ABSI/STI
4658 ;
4659
4660 (define_insn "*absqi2_movqi_clobber"
4661   [(set (match_operand:QI 0 "ext_low_reg_operand" "=q")
4662         (abs:QI (match_operand:QI 1 "par_ind_operand" "S<>")))
4663    (set (match_operand:QI 2 "par_ind_operand" "=S<>")
4664         (match_operand:QI 3 "ext_low_reg_operand" "q"))
4665    (clobber (reg:CC_NOOV 21))]
4666   "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QImode)"
4667   "absi\\t%1,%0\\n||\\tsti\\t%3,%2"
4668   [(set_attr "type" "binarycc")])
4669
4670 ;
4671 ; ADDI/STI
4672 ;
4673
4674 (define_insn "*addqi3_movqi_clobber"
4675   [(set (match_operand:QI 0 "ext_low_reg_operand" "=q,q")
4676         (plus:QI (match_operand:QI 1 "parallel_operand" "%q,S<>")
4677                  (match_operand:QI 2 "parallel_operand" "S<>,q")))
4678    (set (match_operand:QI 3 "par_ind_operand" "=S<>,S<>")
4679         (match_operand:QI 4 "ext_low_reg_operand" "q,q"))
4680    (clobber (reg:CC 21))]
4681   "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)"
4682   "addi3\\t%2,%1,%0\\n||\\tsti\\t%4,%3"
4683   [(set_attr "type" "binarycc,binarycc")])
4684
4685 ;
4686 ; AND/STI
4687 ;
4688
4689 (define_insn "*andqi3_movqi_clobber"
4690   [(set (match_operand:QI 0 "ext_low_reg_operand" "=q,q")
4691         (and:QI (match_operand:QI 1 "parallel_operand" "%q,S<>")
4692                 (match_operand:QI 2 "parallel_operand" "S<>,q")))
4693    (set (match_operand:QI 3 "par_ind_operand" "=S<>,S<>")
4694         (match_operand:QI 4 "ext_low_reg_operand" "q,q"))
4695    (clobber (reg:CC 21))]
4696   "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)"
4697   "and3\\t%2,%1,%0\\n||\\tsti\\t%4,%3"
4698   [(set_attr "type" "binarycc,binarycc")])
4699
4700 ;
4701 ; ASH(left)/STI 
4702 ;
4703
4704 (define_insn "*ashlqi3_movqi_clobber"
4705   [(set (match_operand:QI 0 "ext_low_reg_operand" "=q")
4706         (ashift:QI (match_operand:QI 1 "par_ind_operand" "S<>")
4707                    (match_operand:QI 2 "ext_low_reg_operand" "q")))
4708    (set (match_operand:QI 3 "par_ind_operand" "=S<>")
4709         (match_operand:QI 4 "ext_low_reg_operand" "q"))
4710    (clobber (reg:CC 21))]
4711   "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)"
4712   "ash3\\t%2,%1,%0\\n||\\tsti\\t%4,%3"
4713   [(set_attr "type" "binarycc")])
4714
4715 ;
4716 ; ASH(right)/STI 
4717 ;
4718
4719 (define_insn "*ashrqi3_movqi_clobber"
4720   [(set (match_operand:QI 0 "ext_low_reg_operand" "=q")
4721         (ashiftrt:QI (match_operand:QI 1 "par_ind_operand" "S<>")
4722                      (neg:QI (match_operand:QI 2 "ext_low_reg_operand" "q"))))
4723    (set (match_operand:QI 3 "par_ind_operand" "=S<>")
4724         (match_operand:QI 4 "ext_low_reg_operand" "q"))
4725    (clobber (reg:CC 21))]
4726   "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)"
4727   "ash3\\t%2,%1,%0\\n||\\tsti\\t%4,%3"
4728   [(set_attr "type" "binarycc")])
4729
4730 ;
4731 ; FIX/STI
4732 ;
4733
4734 (define_insn "*fixqfqi2_movqi_clobber"
4735   [(set (match_operand:QI 0 "ext_low_reg_operand" "=q")
4736         (fix:QI (match_operand:QF 1 "par_ind_operand" "S<>")))
4737    (set (match_operand:QI 2 "par_ind_operand" "=S<>")
4738         (match_operand:QI 3 "ext_low_reg_operand" "q"))
4739    (clobber (reg:CC 21))]
4740   "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QImode)"
4741   "fix\\t%1,%0\\n||\\tsti\\t%3,%2"
4742   [(set_attr "type" "binarycc")])
4743
4744 ;
4745 ; LSH(right)/STI 
4746 ;
4747
4748 (define_insn "*lshrqi3_movqi_clobber"
4749   [(set (match_operand:QI 0 "ext_low_reg_operand" "=q")
4750         (lshiftrt:QI (match_operand:QI 1 "par_ind_operand" "S<>")
4751                      (neg:QI (match_operand:QI 2 "ext_low_reg_operand" "q"))))
4752    (set (match_operand:QI 3 "par_ind_operand" "=S<>")
4753         (match_operand:QI 4 "ext_low_reg_operand" "q"))
4754    (clobber (reg:CC 21))]
4755   "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)"
4756   "lsh3\\t%2,%1,%0\\n||\\tsti\\t%4,%3"
4757   [(set_attr "type" "binarycc")])
4758
4759 ;
4760 ; MPYI/ADDI
4761 ;
4762
4763 (define_insn "*mulqi3_addqi3_clobber"
4764   [(set (match_operand:QI 0 "r0r1_reg_operand" "=t,t,t,t")
4765         (mult:QI (match_operand:QI 1 "parallel_operand" "%S<>!V,q,S<>!V,q")
4766                  (match_operand:QI 2 "parallel_operand" "q,S<>!V,S<>!V,q")))
4767    (set (match_operand:QI 3 "r2r3_reg_operand" "=u,u,u,u")
4768         (plus:QI (match_operand:QI 4 "parallel_operand" "%S<>!V,q,q,S<>!V")
4769                  (match_operand:QI 5 "parallel_operand" "q,S<>!V,q,S<>!V")))
4770    (clobber (reg:CC 21))]
4771   "TARGET_PARALLEL_MPY && TARGET_MPYI 
4772    && valid_parallel_operands_6 (operands, QImode)"
4773   "mpyi3\\t%2,%1,%0\\n||\\taddi3\\t%5,%4,%3"
4774   [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")])
4775
4776
4777 ;
4778 ; MPYI/STI
4779 ;
4780
4781 (define_insn "*mulqi3_movqi_clobber"
4782   [(set (match_operand:QI 0 "ext_low_reg_operand" "=q,q")
4783         (mult:QI (match_operand:QI 1 "parallel_operand" "%q,S<>")
4784                  (match_operand:QI 2 "parallel_operand" "S<>,q")))
4785    (set (match_operand:QI 3 "par_ind_operand" "=S<>,S<>")
4786         (match_operand:QI 4 "ext_low_reg_operand" "q,q"))
4787    (clobber (reg:CC 21))]
4788   "TARGET_PARALLEL && TARGET_MPYI
4789    && valid_parallel_operands_5 (operands, QImode)"
4790   "mpyi3\\t%2,%1,%0\\n||\\tsti\\t%4,%3"
4791   [(set_attr "type" "binarycc,binarycc")])
4792
4793 ;
4794 ; MPYI/SUBI
4795 ;
4796
4797 (define_insn "*mulqi3_subqi3_clobber"
4798   [(set (match_operand:QI 0 "r0r1_reg_operand" "=t,t")
4799         (mult:QI (match_operand:QI 1 "parallel_operand" "S<>,q")
4800                  (match_operand:QI 2 "parallel_operand" "q,S<>")))
4801    (set (match_operand:QI 3 "r2r3_reg_operand" "=u,u")
4802         (minus:QI (match_operand:QI 4 "parallel_operand" "S<>,q")
4803                   (match_operand:QI 5 "parallel_operand" "q,S<>")))
4804    (clobber (reg:CC 21))]
4805   "TARGET_PARALLEL_MPY && TARGET_MPYI
4806    && valid_parallel_operands_6 (operands, QImode)"
4807   "mpyi3\\t%2,%1,%0\\n||\\tsubi3\\t%5,%4,%3"
4808   [(set_attr "type" "binarycc,binarycc")])
4809
4810 ;
4811 ; MPYI/LDI 0
4812 ;
4813
4814 (define_insn "*mulqi3_clrqi_clobber"
4815   [(set (match_operand:QI 0 "r0r1_reg_operand" "=t")
4816         (mult:QI (match_operand:QI 1 "par_ind_operand" "%S<>")
4817                  (match_operand:QI 2 "par_ind_operand" "S<>")))
4818    (set (match_operand:QI 3 "r2r3_reg_operand" "=u")
4819         (const_int 0))
4820    (clobber (reg:CC 21))]
4821   "TARGET_PARALLEL_MPY && TARGET_MPYI"
4822   "mpyi3\\t%2,%1,%0\\n||\\tsubi3\\t%3,%3,%3"
4823   [(set_attr "type" "binarycc")])
4824
4825 ;
4826 ; NEGI/STI
4827 ;
4828
4829 (define_insn "*negqi2_movqi_clobber"
4830   [(set (match_operand:QI 0 "ext_low_reg_operand" "=q")
4831         (neg:QI (match_operand:QI 1 "par_ind_operand" "S<>")))
4832    (set (match_operand:QI 2 "par_ind_operand" "=S<>")
4833         (match_operand:QI 3 "ext_low_reg_operand" "q"))
4834    (clobber (reg:CC 21))]
4835   "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QImode)"
4836   "negi\\t%1,%0\\n||\\tsti\\t%3,%2"
4837   [(set_attr "type" "binarycc")])
4838
4839 ;
4840 ; NOT/STI
4841 ;
4842
4843 (define_insn "*notqi2_movqi_clobber"
4844   [(set (match_operand:QI 0 "ext_low_reg_operand" "=q")
4845         (not:QI (match_operand:QI 1 "par_ind_operand" "S<>")))
4846    (set (match_operand:QI 2 "par_ind_operand" "=S<>")
4847         (match_operand:QI 3 "ext_low_reg_operand" "q"))
4848    (clobber (reg:CC 21))]
4849   "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QImode)"
4850   "not\\t%1,%0\\n||\\tsti\\t%3,%2"
4851   [(set_attr "type" "binarycc")])
4852
4853 ;
4854 ; OR/STI
4855 ;
4856
4857 (define_insn "*iorqi3_movqi_clobber"
4858   [(set (match_operand:QI 0 "ext_low_reg_operand" "=q,q")
4859         (ior:QI (match_operand:QI 1 "parallel_operand" "%q,S<>")
4860                 (match_operand:QI 2 "parallel_operand" "S<>,q")))
4861    (set (match_operand:QI 3 "par_ind_operand" "=S<>,S<>")
4862         (match_operand:QI 4 "ext_low_reg_operand" "q,q"))
4863    (clobber (reg:CC 21))]
4864   "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)"
4865   "or3\\t%2,%1,%0\\n||\\tsti\\t%4,%3"
4866   [(set_attr "type" "binarycc,binarycc")])
4867
4868 ;
4869 ; SUBI/STI
4870 ;
4871
4872 (define_insn "*subqi3_movqi_clobber"
4873   [(set (match_operand:QI 0 "ext_low_reg_operand" "=q")
4874         (minus:QI (match_operand:QI 1 "par_ind_operand" "S<>")
4875                   (match_operand:QI 2 "ext_low_reg_operand" "q")))
4876    (set (match_operand:QI 3 "par_ind_operand" "=S<>")
4877         (match_operand:QI 4 "ext_low_reg_operand" "q"))
4878    (clobber (reg:CC 21))]
4879   "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)"
4880   "subi3\\t%2,%1,%0\\n||\\tsti\\t%4,%3"
4881   [(set_attr "type" "binarycc")])
4882
4883 ;
4884 ; XOR/STI
4885 ;
4886
4887 (define_insn "*xorqi3_movqi_clobber"
4888   [(set (match_operand:QI 0 "ext_low_reg_operand" "=q,q")
4889         (xor:QI (match_operand:QI 1 "parallel_operand" "%q,S<>")
4890                 (match_operand:QI 2 "parallel_operand" "S<>,q")))
4891    (set (match_operand:QI 3 "par_ind_operand" "=S<>,S<>")
4892         (match_operand:QI 4 "ext_low_reg_operand" "q,q"))
4893    (clobber (reg:CC 21))]
4894   "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)"
4895   "xor3\\t%2,%1,%0\\n||\\tsti\\t%4,%3"
4896   [(set_attr "type" "binarycc,binarycc")])
4897
4898 ;
4899 ; BRANCH/CALL INSTRUCTIONS
4900 ;
4901
4902 ;
4903 ; Branch instructions
4904 ;
4905 (define_insn "*b"
4906   [(set (pc) (if_then_else (match_operator 0 "comparison_operator"
4907                            [(reg:CC 21) (const_int 0)])
4908                            (label_ref (match_operand 1 "" ""))
4909                            (pc)))]
4910   ""
4911   "*
4912    return c4x_output_cbranch (\"b%0\", insn);"
4913   [(set_attr "type" "jmpc")])
4914
4915 (define_insn "*b_rev"
4916   [(set (pc) (if_then_else (match_operator 0 "comparison_operator"
4917                            [(reg:CC 21) (const_int 0)])
4918                            (pc)
4919                            (label_ref (match_operand 1 "" ""))))]
4920   ""
4921   "*
4922    return c4x_output_cbranch (\"b%I0\", insn);"
4923   [(set_attr "type" "jmpc")])
4924
4925 (define_insn "*b_noov"
4926   [(set (pc) (if_then_else (match_operator 0 "comparison_operator"
4927                            [(reg:CC_NOOV 21) (const_int 0)])
4928                            (label_ref (match_operand 1 "" ""))
4929                            (pc)))]
4930  "GET_CODE (operands[0]) != LE
4931   && GET_CODE (operands[0]) != GE
4932   && GET_CODE (operands[0]) != LT
4933   && GET_CODE (operands[0]) != GT"
4934   "*
4935    return c4x_output_cbranch (\"b%0\", insn);"
4936   [(set_attr "type" "jmpc")])
4937
4938 (define_insn "*b_noov_rev"
4939   [(set (pc) (if_then_else (match_operator 0 "comparison_operator"
4940                            [(reg:CC_NOOV 21) (const_int 0)])
4941                            (pc)
4942                            (label_ref (match_operand 1 "" ""))))]
4943  "GET_CODE (operands[0]) != LE
4944   && GET_CODE (operands[0]) != GE
4945   && GET_CODE (operands[0]) != LT
4946   && GET_CODE (operands[0]) != GT"
4947   "*
4948    return c4x_output_cbranch (\"b%I0\", insn);"
4949   [(set_attr "type" "jmpc")])
4950
4951 (define_expand "beq"
4952   [(set (pc) (if_then_else (eq (match_dup 1) (const_int 0))
4953                            (label_ref (match_operand 0 "" ""))
4954                            (pc)))]
4955   ""
4956   "operands[1] = c4x_gen_compare_reg (EQ, c4x_compare_op0, c4x_compare_op1);")
4957
4958 (define_expand "bne"
4959   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
4960                            (label_ref (match_operand 0 "" ""))
4961                            (pc)))]
4962   ""
4963   "operands[1] = c4x_gen_compare_reg (NE, c4x_compare_op0, c4x_compare_op1);")
4964
4965 (define_expand "blt"
4966   [(set (pc) (if_then_else (lt (match_dup 1) (const_int 0))
4967                            (label_ref (match_operand 0 "" ""))
4968                            (pc)))]
4969   ""
4970   "operands[1] = c4x_gen_compare_reg (LT, c4x_compare_op0, c4x_compare_op1);
4971    if (operands[1] == NULL_RTX) FAIL;")
4972
4973 (define_expand "bltu"
4974   [(set (pc) (if_then_else (ltu (match_dup 1) (const_int 0))
4975                            (label_ref (match_operand 0 "" ""))
4976                            (pc)))]
4977   ""
4978   "operands[1] = c4x_gen_compare_reg (LTU, c4x_compare_op0, c4x_compare_op1);")
4979
4980 (define_expand "bgt"
4981   [(set (pc) (if_then_else (gt (match_dup 1) (const_int 0))
4982                            (label_ref (match_operand 0 "" ""))
4983                            (pc)))]
4984   ""
4985   "operands[1] = c4x_gen_compare_reg (GT, c4x_compare_op0, c4x_compare_op1);
4986    if (operands[1] == NULL_RTX) FAIL;")
4987
4988 (define_expand "bgtu"
4989   [(set (pc) (if_then_else (gtu (match_dup 1) (const_int 0))
4990                            (label_ref (match_operand 0 "" ""))
4991                            (pc)))]
4992   ""
4993   "operands[1] = c4x_gen_compare_reg (GTU, c4x_compare_op0, c4x_compare_op1);")
4994
4995 (define_expand "ble"
4996   [(set (pc) (if_then_else (le (match_dup 1) (const_int 0))
4997                            (label_ref (match_operand 0 "" ""))
4998                            (pc)))]
4999   ""
5000   "operands[1] = c4x_gen_compare_reg (LE, c4x_compare_op0, c4x_compare_op1);
5001    if (operands[1] == NULL_RTX) FAIL;")
5002
5003 (define_expand "bleu"
5004   [(set (pc) (if_then_else (leu (match_dup 1) (const_int 0))
5005                            (label_ref (match_operand 0 "" ""))
5006                            (pc)))]
5007   ""
5008   "operands[1] = c4x_gen_compare_reg (LEU, c4x_compare_op0, c4x_compare_op1);")
5009
5010 (define_expand "bge"
5011   [(set (pc) (if_then_else (ge (match_dup 1) (const_int 0))
5012                            (label_ref (match_operand 0 "" ""))
5013                            (pc)))]
5014   ""
5015   "operands[1] = c4x_gen_compare_reg (GE, c4x_compare_op0, c4x_compare_op1);
5016    if (operands[1] == NULL_RTX) FAIL;")
5017
5018 (define_expand "bgeu"
5019   [(set (pc) (if_then_else (geu (match_dup 1) (const_int 0))
5020                            (label_ref (match_operand 0 "" ""))
5021                            (pc)))]
5022   ""
5023   "operands[1] = c4x_gen_compare_reg (GEU, c4x_compare_op0, c4x_compare_op1);")
5024
5025 (define_insn "*b_reg"
5026  [(set (pc) (match_operand:QI 0 "reg_operand" "r"))]
5027  ""
5028  "bu%#\\t%0"
5029   [(set_attr "type" "jump")])
5030
5031 (define_expand "indirect_jump"
5032  [(set (pc) (match_operand:QI 0 "reg_operand" ""))]
5033  ""
5034  "")
5035
5036 (define_insn "tablejump"
5037   [(set (pc) (match_operand:QI 0 "src_operand" "r"))
5038    (use (label_ref (match_operand 1 "" "")))]
5039   ""
5040   "bu%#\\t%0"
5041   [(set_attr "type" "jump")])
5042
5043 ;
5044 ; CALL
5045 ;
5046 (define_insn "*call_c3x"
5047  [(call (mem:QI (match_operand:QI 0 "call_address_operand" "Ur"))
5048         (match_operand:QI 1 "general_operand" ""))
5049   (clobber (reg:QI 31))]
5050   ;; Operand 1 not really used on the C4x.  The C30 doesn't have reg 31.
5051
5052   "TARGET_C3X"
5053   "call%U0\\t%C0"
5054   [(set_attr "type" "call")])
5055
5056 ; LAJ requires R11 (31) for the return address
5057 (define_insn "*laj"
5058  [(call (mem:QI (match_operand:QI 0 "call_address_operand" "Ur"))
5059         (match_operand:QI 1 "general_operand" ""))
5060   (clobber (reg:QI 31))]
5061   ;; Operand 1 not really used on the C4x.
5062
5063   "! TARGET_C3X"
5064   "*
5065    if (final_sequence)
5066      return c4x_check_laj_p (insn)
5067          ? \"nop\\n\\tlaj%U0\\t%C0\" : \"laj%U0\\t%C0\";
5068    else
5069      return \"call%U0\\t%C0\";"
5070   [(set_attr "type" "laj")])
5071
5072 (define_expand "call"
5073  [(parallel [(call (match_operand:QI 0 "" "")
5074                    (match_operand:QI 1 "general_operand" ""))
5075              (clobber (reg:QI 31))])]
5076  ""
5077  "
5078 {
5079   if (GET_CODE (operands[0]) == MEM
5080       && ! call_address_operand (XEXP (operands[0], 0), Pmode))
5081     operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
5082                                force_reg (Pmode, XEXP (operands[0], 0)));
5083 }")
5084
5085 (define_insn "nodb_call"
5086  [(call (mem:QI (match_operand:QI 0 "call_address_operand" "Ur"))
5087         (const_int 0))]
5088   ""
5089   "call%U0\\t%C0"
5090   [(set_attr "type" "call")])
5091
5092 (define_insn "*callv_c3x"
5093  [(set (match_operand 0 "" "=r")
5094        (call (mem:QI (match_operand:QI 1 "call_address_operand" "Ur"))
5095              (match_operand:QI 2 "general_operand" "")))
5096   (clobber (reg:QI 31))]
5097   ;; Operand 0 and 2 not really used for the C4x. 
5098   ;; The C30 doesn't have reg 31.
5099
5100   "TARGET_C3X"
5101   "call%U1\\t%C1"
5102   [(set_attr "type" "call")])
5103
5104 ; LAJ requires R11 (31) for the return address
5105 (define_insn "*lajv"
5106  [(set (match_operand 0 "" "=r")
5107        (call (mem:QI (match_operand:QI 1 "call_address_operand" "Ur"))
5108              (match_operand:QI 2 "general_operand" "")))
5109   (clobber (reg:QI 31))]
5110   ;; Operand 0 and 2 not really used in the C30 instruction.
5111
5112   "! TARGET_C3X"
5113   "*
5114    if (final_sequence)
5115      return c4x_check_laj_p (insn)
5116          ? \"nop\\n\\tlaj%U1\\t%C1\" : \"laj%U1\\t%C1\";
5117    else
5118      return \"call%U1\\t%C1\";"
5119   [(set_attr "type" "laj")])
5120
5121 (define_expand "call_value"
5122  [(parallel [(set (match_operand 0 "" "")
5123                   (call (match_operand:QI 1 "" "")
5124                         (match_operand:QI 2 "general_operand" "")))
5125              (clobber (reg:QI 31))])]
5126  ""
5127  "
5128 {
5129   if (GET_CODE (operands[0]) == MEM
5130       && ! call_address_operand (XEXP (operands[1], 0), Pmode))
5131     operands[0] = gen_rtx_MEM (GET_MODE (operands[1]),
5132                                force_reg (Pmode, XEXP (operands[1], 0)));
5133 }")
5134
5135 (define_insn "return"
5136   [(return)]
5137   "! c4x_null_epilogue_p ()"
5138   "rets"
5139   [(set_attr "type" "rets")])
5140
5141 (define_insn "return_from_epilogue"
5142   [(return)]
5143   "reload_completed && ! c4x_interrupt_function_p ()"
5144   "rets"
5145   [(set_attr "type" "rets")])
5146
5147 (define_insn "return_from_interrupt_epilogue"
5148   [(return)]
5149   "reload_completed && c4x_interrupt_function_p ()"
5150   "reti"
5151   [(set_attr "type" "rets")])
5152
5153 (define_insn "*return_cc"
5154   [(set (pc)
5155         (if_then_else (match_operator 0 "comparison_operator"
5156                       [(reg:CC 21) (const_int 0)])
5157                       (return)
5158                        (pc)))]
5159   "! c4x_null_epilogue_p ()"
5160   "rets%0"
5161   [(set_attr "type" "rets")])
5162
5163 (define_insn "*return_cc_noov"
5164   [(set (pc)
5165         (if_then_else (match_operator 0 "comparison_operator"
5166                       [(reg:CC_NOOV 21) (const_int 0)])
5167                       (return)
5168                        (pc)))]
5169   "GET_CODE (operands[0]) != LE
5170    && GET_CODE (operands[0]) != GE
5171    && GET_CODE (operands[0]) != LT
5172    && GET_CODE (operands[0]) != GT
5173    && ! c4x_null_epilogue_p ()"
5174   "rets%0"
5175   [(set_attr "type" "rets")])
5176
5177 (define_insn "*return_cc_inverse"
5178   [(set (pc)
5179         (if_then_else (match_operator 0 "comparison_operator"
5180                       [(reg:CC 21) (const_int 0)])
5181                        (pc)
5182                       (return)))]
5183   "! c4x_null_epilogue_p ()"
5184   "rets%I0"
5185   [(set_attr "type" "rets")])
5186
5187 (define_insn "*return_cc_noov_inverse"
5188   [(set (pc)
5189         (if_then_else (match_operator 0 "comparison_operator"
5190                       [(reg:CC_NOOV 21) (const_int 0)])
5191                        (pc)
5192                       (return)))]
5193   "GET_CODE (operands[0]) != LE
5194    && GET_CODE (operands[0]) != GE
5195    && GET_CODE (operands[0]) != LT
5196    && GET_CODE (operands[0]) != GT
5197    && ! c4x_null_epilogue_p ()"
5198   "rets%I0"
5199   [(set_attr "type" "rets")])
5200
5201 (define_insn "jump"
5202   [(set (pc) (label_ref (match_operand 0 "" "")))]
5203   ""
5204   "br%#\\t%l0"
5205   [(set_attr "type" "jump")])
5206
5207 (define_insn "trap"
5208   [(trap_if (const_int 1) (const_int 31))]
5209   ""
5210   "trapu\\t31"
5211   [(set_attr "type" "call")])
5212
5213 (define_expand "conditional_trap"
5214  [(trap_if (match_operand 0 "comparison_operator" "")
5215            (match_operand 1 "const_int_operand" ""))]
5216  ""
5217  "{
5218     enum rtx_code code = GET_CODE (operands[1]);
5219     rtx ccreg = c4x_gen_compare_reg (code, c4x_compare_op0, c4x_compare_op1);
5220     if (ccreg == NULL_RTX) FAIL;
5221     if (GET_MODE (ccreg) == CCmode)
5222       emit_insn (gen_cond_trap_cc (operands[0], operands[1]));
5223     else 
5224       emit_insn (gen_cond_trap_cc_noov (operands[0], operands[1]));
5225     DONE;}")
5226
5227 (define_insn "cond_trap_cc"
5228   [(trap_if (match_operator 0 "comparison_operator"
5229             [(reg:CC 21) (const_int 0)])
5230             (match_operand 1 "const_int_operand" ""))]
5231   ""
5232   "trap%0\\t31"
5233   [(set_attr "type" "call")])
5234
5235 (define_insn "cond_trap_cc_noov"
5236   [(trap_if (match_operator 0 "comparison_operator"
5237             [(reg:CC_NOOV 21) (const_int 0)])
5238             (match_operand 1 "const_int_operand" ""))]
5239   "GET_CODE (operands[0]) != LE
5240    && GET_CODE (operands[0]) != GE
5241    && GET_CODE (operands[0]) != LT
5242    && GET_CODE (operands[0]) != GT"
5243   "trap%0\\t31"
5244   [(set_attr "type" "call")])
5245
5246 ;
5247 ; DBcond
5248 ;
5249 ; Note we have to emit a dbu instruction if there are no delay slots
5250 ; to fill.
5251 ; Also note that GCC will try to reverse a loop to see if it can
5252 ; utilize this instruction.  However, if there are more than one
5253 ; memory reference in the loop, it cannot guarantee that reversing
5254 ; the loop will work :(  (see check_dbra_loop() in loop.c)
5255 ; Note that the C3x only decrements the 24 LSBs of the address register
5256 ; and the 8 MSBs are untouched.  The C4x uses all 32-bits.  We thus
5257 ; have an option to disable this instruction.
5258 (define_insn "*db"
5259   [(set (pc)
5260         (if_then_else (ne (match_operand:QI 0 "addr_reg_operand" "+a,?*d,??*r,!m")
5261                           (const_int 0))
5262                       (label_ref (match_operand 1 "" ""))
5263                       (pc)))
5264    (set (match_dup 0)
5265         (plus:QI (match_dup 0)
5266                  (const_int -1)))
5267    (use (reg:QI 20))
5268    (clobber (reg:CC_NOOV 21))]
5269   "TARGET_DB && TARGET_LOOP_UNSIGNED"
5270   "*
5271   if (which_alternative == 0)
5272     return \"dbu%#\\t%0,%l1\";
5273   else if (which_alternative == 1)
5274     return c4x_output_cbranch (\"subi\\t1,%0\\n\\tbge\", insn);
5275   else if (which_alternative == 2)
5276     return c4x_output_cbranch (\"subi\\t1,%0\\n\\tcmpi\\t0,%0\\n\\tbge\", insn);
5277   else
5278     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);
5279   "
5280   [(set_attr "type" "db,jmpc,jmpc,jmpc")])
5281
5282 (define_insn "*db_noclobber"
5283   [(set (pc)
5284         (if_then_else (ne (match_operand:QI 0 "addr_reg_operand" "+a")
5285                           (const_int 0))
5286                       (label_ref (match_operand 1 "" ""))
5287                       (pc)))
5288    (set (match_dup 0)
5289         (plus:QI (match_dup 0)
5290                  (const_int -1)))]
5291   "reload_completed && TARGET_DB && TARGET_LOOP_UNSIGNED"
5292   "dbu%#\\t%0,%l1"
5293   [(set_attr "type" "db")])
5294
5295 (define_split
5296   [(set (pc)
5297         (if_then_else (ne (match_operand:QI 0 "addr_reg_operand" "")
5298                           (const_int 0))
5299                       (label_ref (match_operand 1 "" ""))
5300                       (pc)))
5301    (set (match_dup 0)
5302         (plus:QI (match_dup 0)
5303                  (const_int -1)))
5304    (use (reg:QI 20))
5305    (clobber (reg:CC_NOOV 21))]
5306   "reload_completed && TARGET_DB && TARGET_LOOP_UNSIGNED"
5307   [(parallel [(set (pc)
5308                    (if_then_else (ne (match_dup 0)
5309                                      (const_int 0))
5310                                  (label_ref (match_dup 1))
5311                                  (pc)))
5312               (set (match_dup 0)
5313                    (plus:QI (match_dup 0)
5314                             (const_int -1)))])]
5315   "")
5316   
5317
5318 ; This insn is used for some loop tests, typically loops reversed when
5319 ; strength reduction is used.  It is actually created when the instruction
5320 ; combination phase combines the special loop test.  Since this insn
5321 ; is both a jump insn and has an output, it must deal with its own
5322 ; reloads, hence the `m' constraints. 
5323
5324 ; The C4x does the decrement and then compares the result against zero.
5325 ; It branches if the result was greater than or equal to zero.
5326 ; In the RTL the comparison and decrement are assumed to happen
5327 ; at the same time so we bias the iteration counter with by -1
5328 ; when we make the test.
5329 (define_insn "decrement_and_branch_until_zero"
5330   [(set (pc)
5331         (if_then_else (ge (plus:QI (match_operand:QI 0 "addr_reg_operand" "+a,?*d,??*r,!m")
5332                                    (const_int -1))
5333                           (const_int 0))
5334                       (label_ref (match_operand 1 "" ""))
5335                       (pc)))
5336    (set (match_dup 0)
5337         (plus:QI (match_dup 0)
5338                  (const_int -1)))
5339    (use (reg:QI 20))
5340    (clobber (reg:CC_NOOV 21))]
5341   "TARGET_DB && (find_reg_note (insn, REG_NONNEG, 0) || TARGET_LOOP_UNSIGNED)"
5342   "*
5343   if (which_alternative == 0)
5344     return \"dbu%#\\t%0,%l1\";
5345   else if (which_alternative == 1)
5346     return c4x_output_cbranch (\"subi\\t1,%0\\n\\tbge\", insn);
5347   else if (which_alternative == 2)
5348     return c4x_output_cbranch (\"subi\\t1,%0\\n\\tcmpi\\t0,%0\\n\\tbge\", insn);
5349   else
5350     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);
5351   "
5352   [(set_attr "type" "db,jmpc,jmpc,jmpc")])
5353
5354 (define_insn "*decrement_and_branch_until_zero_noclobber"
5355   [(set (pc)
5356         (if_then_else (ge (plus:QI (match_operand:QI 0 "addr_reg_operand" "+a")
5357                                    (const_int -1))
5358                           (const_int 0))
5359                       (label_ref (match_operand 1 "" ""))
5360                       (pc)))
5361    (set (match_dup 0)
5362         (plus:QI (match_dup 0)
5363                  (const_int -1)))]
5364   "reload_completed && TARGET_DB && TARGET_LOOP_UNSIGNED"
5365   "dbu%#\\t%0,%l1"
5366   [(set_attr "type" "db")])
5367
5368 (define_split
5369   [(set (pc)
5370         (if_then_else (ge (plus:QI (match_operand:QI 0 "addr_reg_operand" "")
5371                                    (const_int -1))
5372                           (const_int 0))
5373                       (label_ref (match_operand 1 "" ""))
5374                       (pc)))
5375    (set (match_dup 0)
5376         (plus:QI (match_dup 0)
5377                  (const_int -1)))
5378    (use (reg:QI 20))
5379    (clobber (reg:CC_NOOV 21))]
5380   "reload_completed && TARGET_DB && TARGET_LOOP_UNSIGNED"
5381   [(parallel [(set (pc)
5382                    (if_then_else (ge (plus:QI (match_dup 0)
5383                                               (const_int -1))
5384                                      (const_int 0))
5385                                  (label_ref (match_dup 1))
5386                                  (pc)))
5387               (set (match_dup 0)
5388                    (plus:QI (match_dup 0)
5389                             (const_int -1)))])]
5390   "")
5391
5392 ;
5393 ; MISC INSTRUCTIONS
5394 ;
5395
5396 ;
5397 ; NOP
5398 ;
5399 (define_insn "nop"
5400   [(const_int 0)]
5401   ""
5402   "nop")
5403 ; Default to misc type attr.
5404
5405 (define_insn "return_indirect_internal"
5406   [(return)
5407    (use (match_operand:QI 0 "reg_operand" ""))]
5408   "reload_completed"                           
5409   "bu%#\\t%0"
5410   [(set_attr "type" "jump")])
5411
5412 (define_expand "prologue"
5413   [(const_int 1)]
5414   ""                           
5415   "c4x_expand_prologue (); DONE;")
5416
5417 (define_expand "epilogue"
5418   [(const_int 1)]
5419   ""
5420   "c4x_expand_epilogue (); DONE;")
5421
5422 ;
5423 ; RPTB
5424 ;
5425 (define_insn "rptb_top"
5426   [(use (label_ref (match_operand 0 "" "")))
5427    (use (label_ref (match_operand 1 "" "")))
5428    (clobber (reg:QI 25))
5429    (clobber (reg:QI 26))]
5430   ""
5431   "*
5432    return ! final_sequence && c4x_rptb_rpts_p (insn, operands[0])
5433          ? \"rpts\\trc\" : \"rptb%#\\t%l1-1\";
5434   "
5435   [(set_attr "type" "repeat_top")])
5436
5437 (define_insn "rpts_top"
5438   [(unspec [(use (label_ref (match_operand 0 "" "")))
5439             (use (label_ref (match_operand 1 "" "")))] UNSPEC_RPTS)
5440    (clobber (reg:QI 25))
5441    (clobber (reg:QI 26))]
5442   ""
5443   "*
5444    return ! final_sequence && c4x_rptb_rpts_p (insn, operands[0])
5445          ? \"rpts\\trc\" : \"rptb%#\\t%l1-1\";
5446   "
5447   [(set_attr "type" "repeat")])
5448
5449 ; This pattern needs to be emitted at the start of the loop to
5450 ; say that RS and RE are loaded.
5451 (define_insn "rptb_init"
5452   [(unspec [(match_operand:QI 0 "register_operand" "va")] UNSPEC_RPTB_INIT)
5453    (clobber (reg:QI 25))
5454    (clobber (reg:QI 26))]
5455   ""
5456   ""
5457   [(set_attr "type" "repeat")])
5458
5459
5460 ; operand 0 is the loop count pseudo register
5461 ; operand 1 is the number of loop iterations or 0 if it is unknown
5462 ; operand 2 is the maximum number of loop iterations
5463 ; operand 3 is the number of levels of enclosed loops
5464 (define_expand "doloop_begin"
5465   [(use (match_operand 0 "register_operand" ""))
5466    (use (match_operand:QI 1 "const_int_operand" ""))
5467    (use (match_operand:QI 2 "const_int_operand" ""))
5468    (use (match_operand:QI 3 "const_int_operand" ""))]
5469   ""
5470   "if (INTVAL (operands[3]) > 1 || ! TARGET_RPTB)
5471      FAIL;
5472    emit_insn (gen_rptb_init (operands[0]));
5473    DONE;
5474   ")
5475
5476
5477 ; The RS (25) and RE (26) registers must be unviolate from the top of the loop
5478 ; to here.
5479 (define_insn "rptb_end"
5480   [(set (pc)
5481         (if_then_else (ge (match_operand:QI 0 "register_operand" "+v,?a,!*d,!*x*k,!m")
5482                           (const_int 0))
5483                       (label_ref (match_operand 1 "" ""))
5484                       (pc)))
5485    (set (match_dup 0)
5486         (plus:QI (match_dup 0)
5487                  (const_int -1)))
5488    (use (reg:QI 25))
5489    (use (reg:QI 26))
5490    (use (reg:QI 20))
5491    (clobber (reg:CC_NOOV 21))]
5492   ""
5493   "*
5494    if (which_alternative == 0)
5495      return c4x_rptb_nop_p (insn) ? \"nop\" : \"\";
5496    else if (which_alternative == 1 && TARGET_DB)
5497      return \"dbu%#\\t%0,%l1\";
5498    else if (which_alternative == 2)
5499      return c4x_output_cbranch (\"subi\\t1,%0\\n\\tbge\", insn);
5500    else if (which_alternative == 3 || (which_alternative == 1 && ! TARGET_DB))
5501      return c4x_output_cbranch (\"subi\\t1,%0\\n\\tcmpi\\t0,%0\\n\\tbge\", insn);
5502    else
5503      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);
5504   "
5505   [(set_attr "type" "repeat,db,jmpc,jmpc,jmpc")])
5506
5507 (define_split
5508    [(set (pc)
5509         (if_then_else (ge (match_operand:QI 0 "addr_reg_operand" "")
5510                           (const_int 0))
5511                       (label_ref (match_operand 1 "" ""))
5512                       (pc)))
5513    (set (match_dup 0)
5514         (plus:QI (match_dup 0)
5515                  (const_int -1)))
5516    (use (match_operand:QI 2 "const_int_operand" ""))
5517    (use (match_operand:QI 3 "const_int_operand" ""))
5518    (use (match_operand:QI 4 "const_int_operand" ""))
5519    (use (reg:QI 25))
5520    (use (reg:QI 26))
5521    (use (reg:QI 20))
5522    (clobber (reg:CC_NOOV 21))]
5523   "reload_completed"
5524   [(parallel [(set (pc)
5525                    (if_then_else (ge (match_dup 0)
5526                                      (const_int 0))
5527                                  (label_ref (match_dup 1))
5528                                  (pc)))
5529               (set (match_dup 0)
5530                    (plus:QI (match_dup 0)
5531                             (const_int -1)))])]
5532   "")
5533
5534 ; operand 0 is the loop count pseudo register
5535 ; operand 1 is the number of loop iterations or 0 if it is unknown
5536 ; operand 2 is the maximum number of loop iterations
5537 ; operand 3 is the number of levels of enclosed loops
5538 ; operand 4 is the label to jump to at the top of the loop
5539 (define_expand "doloop_end"
5540   [(use (match_operand 0 "register_operand" ""))
5541    (use (match_operand:QI 1 "const_int_operand" ""))
5542    (use (match_operand:QI 2 "const_int_operand" ""))
5543    (use (match_operand:QI 3 "const_int_operand" ""))
5544    (use (label_ref (match_operand 4 "" "")))]
5545   ""
5546   "if (! TARGET_LOOP_UNSIGNED 
5547        && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > ((unsigned) 1 << 31))
5548      FAIL;
5549    if (INTVAL (operands[3]) > 1 || ! TARGET_RPTB)
5550      {
5551         /* The C30 maximum iteration count for DB is 2^24.  */
5552         if (! TARGET_DB)
5553           FAIL;
5554         emit_jump_insn (gen_decrement_and_branch_until_zero (operands[0],
5555                                                              operands[4]));
5556         DONE;
5557      }
5558     emit_jump_insn (gen_rptb_end (operands[0], operands[4]));
5559     DONE;
5560   ")
5561
5562 (define_expand "decrement_and_branch_on_count"
5563   [(parallel [(set (pc)
5564                    (if_then_else (ge (match_operand:QI 0 "register_operand" "")
5565                                      (const_int 0))
5566                                  (label_ref (match_operand 1 "" ""))
5567                                  (pc)))
5568               (set (match_dup 0)
5569                    (plus:QI (match_dup 0)
5570                             (const_int -1)))
5571               (use (reg:QI 25))
5572               (use (reg:QI 26))
5573               (clobber (reg:CC_NOOV 21))])]
5574   "0"
5575   "")
5576
5577 (define_expand "movmemqi_small"
5578   [(parallel [(set (mem:BLK (match_operand:BLK 0 "src_operand" ""))
5579                    (mem:BLK (match_operand:BLK 1 "src_operand" "")))
5580               (use (match_operand:QI 2 "immediate_operand" ""))
5581               (use (match_operand:QI 3 "immediate_operand" ""))
5582               (clobber (match_operand:QI 4 "ext_low_reg_operand" ""))])]
5583   ""
5584   "
5585  {
5586     rtx src, dst, tmp;
5587     rtx src_mem, dst_mem;    
5588     int len;
5589     int i;
5590
5591     dst = operands[0];
5592     src = operands[1];
5593     len = INTVAL (operands[2]);
5594     tmp = operands[4];
5595
5596     src_mem = gen_rtx_MEM (QImode, src);
5597     dst_mem = gen_rtx_MEM (QImode, dst);
5598
5599     if (TARGET_PARALLEL)
5600       {
5601         emit_insn (gen_movqi (tmp, src_mem));   
5602         emit_insn (gen_addqi3_noclobber (src, src, const1_rtx));        
5603         for (i = 1; i < len; i++)
5604           {
5605             emit_insn (gen_movqi_parallel (tmp, src_mem, dst_mem, tmp));
5606             emit_insn (gen_addqi3_noclobber (src, src, const1_rtx));    
5607             emit_insn (gen_addqi3_noclobber (dst, dst, const1_rtx));    
5608           }
5609         emit_insn (gen_movqi (dst_mem, tmp));   
5610         emit_insn (gen_addqi3_noclobber (dst, dst, const1_rtx));        
5611       }
5612     else
5613       {
5614         for (i = 0; i < len; i++)
5615           {
5616             emit_insn (gen_movqi (tmp, src_mem));       
5617             emit_insn (gen_movqi (dst_mem, tmp));       
5618             emit_insn (gen_addqi3_noclobber (src, src, const1_rtx));    
5619             emit_insn (gen_addqi3_noclobber (dst, dst, const1_rtx));    
5620           }
5621       }
5622     DONE;
5623   }
5624   ")
5625
5626
5627 ;
5628 ; BLOCK MOVE
5629 ; We should probably get RC loaded when using RPTB automagically...
5630 ; There's probably no need to call _memcpy() if we don't get
5631 ; an immediate operand for the size.  We could do a better job here
5632 ; than most memcpy() implementations.
5633 ; operand 2 is the number of bytes
5634 ; operand 3 is the shared alignment
5635 ; operand 4 is a scratch register
5636
5637 (define_insn "movmemqi_large"
5638   [(set (mem:BLK (match_operand:QI 0 "addr_reg_operand" "a"))
5639         (mem:BLK (match_operand:QI 1 "addr_reg_operand" "a")))
5640    (use (match_operand:QI 2 "immediate_operand" "i"))
5641    (use (match_operand:QI 3 "immediate_operand" ""))
5642    (clobber (match_operand:QI 4 "ext_low_reg_operand" "=&q"))
5643    (clobber (match_scratch:QI 5 "=0"))
5644    (clobber (match_scratch:QI 6 "=1"))
5645    (clobber (reg:QI 25))
5646    (clobber (reg:QI 26))
5647    (clobber (reg:QI 27))]
5648   ""
5649   "*
5650  {
5651    int i;
5652    int len = INTVAL (operands[2]);
5653
5654    output_asm_insn (\"ldiu\\t*%1++,%4\", operands);
5655    if (len < 8)
5656      {
5657        for (i = 1; i < len; i++)
5658          {
5659            output_asm_insn (\"sti\\t%4,*%0++\", operands);
5660            output_asm_insn (\"|| ldi\\t*%1++,%4\", operands);
5661          } 
5662      }
5663    else
5664      {
5665        if (TARGET_RPTS_CYCLES (len))
5666          {
5667            output_asm_insn (\"rpts\\t%2-2\", operands);  
5668            output_asm_insn (\"sti\\t%4,*%0++\", operands);
5669            output_asm_insn (\"|| ldi\\t*%1++,%4\", operands);
5670          }
5671        else
5672          {
5673            output_asm_insn (\"ldiu\\t%2-2,rc\", operands);
5674            output_asm_insn (\"rptb\\t$+1\", operands);  
5675            output_asm_insn (\"sti\\t%4,*%0++\", operands);
5676            output_asm_insn (\"|| ldi\\t*%1++,%4\", operands);
5677          }
5678      }
5679    return \"sti\\t%4,*%0++\";
5680  }"
5681  [(set_attr "type" "multi")])
5682
5683 ; Operand 2 is the count, operand 3 is the alignment.
5684 (define_expand "movmemqi"
5685   [(parallel [(set (mem:BLK (match_operand:BLK 0 "src_operand" ""))
5686                    (mem:BLK (match_operand:BLK 1 "src_operand" "")))
5687               (use (match_operand:QI 2 "immediate_operand" ""))
5688               (use (match_operand:QI 3 "immediate_operand" ""))])]
5689   ""
5690   "
5691  {
5692    rtx tmp;
5693    if (GET_CODE (operands[2]) != CONST_INT 
5694        || INTVAL (operands[2]) > 32767 
5695        || INTVAL (operands[2]) <= 0)
5696      {
5697         FAIL;  /* Try to call _memcpy */
5698      }
5699
5700    operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
5701    operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
5702    tmp = gen_reg_rtx (QImode);
5703    /* Disabled because of reload problems.  */
5704    if (0 && INTVAL (operands[2]) < 8)
5705      emit_insn (gen_movmemqi_small (operands[0], operands[1], operands[2],
5706                                     operands[3], tmp));
5707    else
5708      {
5709       emit_insn (gen_movmemqi_large (operands[0], operands[1], operands[2],
5710                                      operands[3], tmp));
5711      }
5712    DONE;
5713  }")
5714
5715
5716 (define_insn "*cmpstrqi"
5717   [(set (match_operand:QI 0 "ext_reg_operand" "=d")
5718         (compare:QI (mem:BLK (match_operand:QI 1 "addr_reg_operand" "+a"))
5719                     (mem:BLK (match_operand:QI 2 "addr_reg_operand" "+a"))))
5720    (use (match_operand:QI 3 "immediate_operand" "i"))
5721    (use (match_operand:QI 4 "immediate_operand" ""))
5722    (clobber (match_operand:QI 5 "std_reg_operand" "=&c"))
5723    (clobber (reg:QI 21))]
5724   ""
5725   "*
5726  {
5727     output_asm_insn (\"ldi\\t%3-1,%5\", operands);
5728     output_asm_insn (\"$1:\tsubi3\\t*%1++,*%2++,%0\", operands);
5729     output_asm_insn (\"dbeq\\t%5,$1\", operands);
5730     return \"\";
5731  }")
5732
5733 (define_expand "cmpstrqi"
5734   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
5735                    (compare:QI (match_operand:BLK 1 "general_operand" "")
5736                                (match_operand:BLK 2 "general_operand" "")))
5737               (use (match_operand:QI 3 "immediate_operand" ""))
5738               (use (match_operand:QI 4 "immediate_operand" ""))
5739               (clobber (match_dup 5))
5740               (clobber (reg:QI 21))])]
5741   ""
5742   "
5743 {
5744    if (GET_CODE (operands[3]) != CONST_INT
5745        || INTVAL (operands[3]) > 32767 
5746        || INTVAL (operands[3]) <= 0)
5747      {
5748         FAIL;
5749      }
5750    operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
5751    operands[2] = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
5752    operands[5] = gen_reg_rtx (QImode);
5753 }")
5754
5755 ;
5756 ; TWO OPERAND LONG DOUBLE INSTRUCTIONS
5757 ;
5758
5759 (define_expand "movhf"
5760   [(set (match_operand:HF 0 "src_operand" "")
5761         (match_operand:HF 1 "src_operand" ""))]
5762  ""
5763  "if (c4x_emit_move_sequence (operands, HFmode))
5764     DONE;")
5765
5766 (define_insn "*movhf_noclobber_reg"
5767   [(set (match_operand:HF 0 "reg_operand" "=h")
5768         (match_operand:HF 1 "src_operand" "Hh"))]
5769  "GET_CODE (operands[1]) != MEM"
5770  "ldfu\\t%1,%0"
5771   [(set_attr "type" "unary")])
5772
5773 (define_insn "*movhf_noclobber"
5774  [(set (match_operand:HF 0 "dst_operand" "=h,m")
5775        (match_operand:HF 1 "src_operand" "Hm,h"))]
5776  "reg_operand (operands[0], HFmode) ^ reg_operand (operands[1], HFmode)"
5777  "#"
5778  [(set_attr "type" "multi,multi")])
5779
5780 (define_insn "*movhf_test"
5781   [(set (reg:CC 21)
5782         (compare:CC (match_operand:HF 1 "reg_operand" "h")
5783                     (const_int 0)))
5784    (clobber (match_scratch:HF 0 "=h"))]
5785  ""
5786  "ldf\\t%1,%0"
5787   [(set_attr "type" "unarycc")])
5788
5789 (define_insn "*movhf_set"
5790   [(set (reg:CC 21)
5791         (compare:CC (match_operand:HF 1 "reg_operand" "h")
5792                     (match_operand:HF 2 "fp_zero_operand" "G")))
5793     (set (match_operand:HF 0 "reg_operand" "=h")
5794          (match_dup 1))]
5795  ""
5796  "ldf\\t%1,%0"
5797   [(set_attr "type" "unarycc")])
5798
5799 (define_split
5800  [(set (match_operand:HF 0 "reg_operand" "")
5801        (match_operand:HF 1 "memory_operand" ""))]
5802  "reload_completed"
5803  [(set (match_dup 0) (float_extend:HF (match_dup 2)))
5804   (set (match_dup 0) (unspec:HF [(subreg:QI (match_dup 0) 0)
5805                                             (match_dup 3)] UNSPEC_LOADHF_INT))]
5806  "operands[2] = c4x_operand_subword (operands[1], 0, 1, HFmode);
5807   operands[3] = c4x_operand_subword (operands[1], 1, 1, HFmode);
5808   PUT_MODE (operands[2], QFmode);
5809   PUT_MODE (operands[3], QImode);")
5810
5811 (define_split
5812  [(set (match_operand:HF 0 "reg_operand" "")
5813        (match_operand:HF 1 "const_operand" ""))]
5814  "reload_completed && 0"
5815  [(set (match_dup 0) (float_extend:HF (match_dup 2)))
5816   (set (match_dup 0) (unspec:HF [(subreg:QI (match_dup 0) 0)
5817                                             (match_dup 3)] UNSPEC_LOADHF_INT))]
5818  "operands[2] = c4x_operand_subword (operands[1], 0, 1, HFmode);
5819   operands[3] = c4x_operand_subword (operands[1], 1, 1, HFmode);
5820   PUT_MODE (operands[2], QFmode);
5821   PUT_MODE (operands[3], QImode);")
5822
5823 (define_split
5824  [(set (match_operand:HF 0 "memory_operand" "")
5825        (match_operand:HF 1 "reg_operand" ""))]
5826   "reload_completed"
5827   [(set (match_dup 2) (float_truncate:QF (match_dup 1)))
5828    (set (match_dup 3) (unspec:QI [(match_dup 1)] UNSPEC_STOREHF_INT))]
5829  "operands[2] = c4x_operand_subword (operands[0], 0, 1, HFmode);
5830   operands[3] = c4x_operand_subword (operands[0], 1, 1, HFmode);
5831   PUT_MODE (operands[2], QFmode);
5832   PUT_MODE (operands[3], QImode);")
5833
5834 (define_insn "*loadhf_float"
5835  [(set (match_operand:HF 0 "reg_operand" "=h")
5836        (float_extend:HF (match_operand:QF 1 "src_operand" "fHm")))]
5837  ""
5838  "ldfu\\t%1,%0"
5839   [(set_attr "type" "unary")])
5840
5841 (define_insn "*loadhf_int"
5842  [(set (match_operand:HF 0 "reg_operand" "+h")
5843        (unspec:HF [(subreg:QI (match_dup 0) 0)
5844                    (match_operand:QI 1 "src_operand" "rIm")] UNSPEC_LOADHF_INT))]
5845  ""
5846  "ldiu\\t%1,%0"
5847   [(set_attr "type" "unary")])
5848
5849 (define_insn "*storehf_float"
5850   [(set (match_operand:QF 0 "memory_operand" "=m")
5851         (float_truncate:QF (match_operand:HF 1 "reg_operand" "h")))]
5852   ""
5853   "stf\\t%1,%0"
5854   [(set_attr "type" "store")])
5855
5856 (define_insn "*storehf_int"
5857  [(set (match_operand:QI 0 "memory_operand" "=m")
5858        (unspec:QI [(match_operand:HF 1 "reg_operand" "h")] UNSPEC_STOREHF_INT))]
5859  ""
5860  "sti\\t%1,%0"
5861   [(set_attr "type" "store")])
5862
5863 (define_insn "extendqfhf2"
5864   [(set (match_operand:HF 0 "reg_operand" "=h")
5865         (float_extend:HF (match_operand:QF 1 "reg_operand" "h")))]
5866   ""
5867   "ldfu\\t%1,%0"
5868   [(set_attr "type" "unarycc")])
5869
5870 (define_insn "trunchfqf2"
5871   [(set (match_operand:QF 0 "reg_operand" "=h")
5872         (float_truncate:QF (match_operand:HF 1 "reg_operand" "0")))
5873    (clobber (reg:CC 21))]
5874   ""
5875   "andn\\t0ffh,%0"
5876   [(set_attr "type" "unarycc")])
5877
5878 ;
5879 ; PUSH/POP
5880 ;
5881 (define_insn "pushhf"
5882   [(set (mem:HF (pre_inc:QI (reg:QI 20)))
5883         (match_operand:HF 0 "reg_operand" "h"))]
5884  ""
5885  "#"
5886  [(set_attr "type" "multi")])
5887
5888 (define_split
5889  [(set (mem:HF (pre_inc:QI (reg:QI 20)))
5890         (match_operand:HF 0 "reg_operand" ""))]
5891   "reload_completed"
5892   [(set (mem:QF (pre_inc:QI (reg:QI 20)))
5893         (float_truncate:QF (match_dup 0)))
5894    (set (mem:QI (pre_inc:QI (reg:QI 20)))
5895         (unspec:QI [(match_dup 0)] UNSPEC_STOREHF_INT))]
5896  "")
5897
5898 (define_insn "pushhf_trunc"
5899   [(set (mem:QF (pre_inc:QI (reg:QI 20)))
5900         (float_truncate:QF (match_operand:HF 0 "reg_operand" "h")))]
5901  ""
5902  "pushf\\t%0"
5903  [(set_attr "type" "push")])
5904
5905 (define_insn "pushhf_int"
5906   [(set (mem:QI (pre_inc:QI (reg:QI 20)))
5907         (unspec:QI [(match_operand:HF 0 "reg_operand" "h")] UNSPEC_STOREHF_INT))]
5908  ""
5909  "push\\t%0"
5910  [(set_attr "type" "push")])
5911
5912 ; we cannot use this because the popf will destroy the low 8 bits
5913 ;(define_insn "pophf"
5914 ;  [(set (match_operand:HF 0 "reg_operand" "=h")
5915 ;        (mem:HF (post_dec:QI (reg:QI 20))))
5916 ;   (clobber (reg:CC 21))]
5917 ; ""
5918 ; "#"
5919 ; [(set_attr "type" "multi")])
5920
5921 (define_split
5922  [(set (match_operand:HF 0 "reg_operand" "")
5923        (mem:HF (post_dec:QI (reg:QI 20))))
5924    (clobber (reg:CC 21))]
5925   "reload_completed"
5926   [(parallel [(set (match_operand:HF 0 "reg_operand" "=h")
5927                    (float_extend:HF (mem:QF (post_dec:QI (reg:QI 20)))))
5928               (clobber (reg:CC 21))])
5929    (parallel [(set (match_dup 0)
5930                    (unspec:HF [(subreg:QI (match_dup 0) 0)
5931                    (mem:QI (post_dec:QI (reg:QI 20)))] UNSPEC_LOADHF_INT))
5932               (clobber (reg:CC 21))])]
5933  "")
5934
5935 (define_insn "*pophf_int"
5936  [(set (match_operand:HF 0 "reg_operand" "+h")
5937        (unspec:HF [(subreg:QI (match_dup 0) 0)
5938                    (mem:QI (post_dec:QI (reg:QI 20)))] UNSPEC_LOADHF_INT))
5939   (clobber (reg:CC 21))]
5940  ""
5941  "pop\\t%0"
5942   [(set_attr "type" "pop")])
5943
5944 (define_insn "*pophf_float"
5945  [(set (match_operand:HF 0 "reg_operand" "=h")
5946        (float_extend:HF (mem:QF (post_dec:QI (reg:QI 20)))))
5947   (clobber (reg:CC 21))]
5948  ""
5949  "popf\\t%0"
5950   [(set_attr "type" "pop")])
5951
5952 ;
5953 ; FIX
5954 ;
5955 (define_expand "fixuns_trunchfqi2"
5956  [(parallel [(set (match_dup 2)
5957                   (fix:QI (match_operand:HF 1 "reg_or_const_operand" "hH")))
5958              (clobber (reg:CC 21))])
5959   (parallel [(set (match_dup 3)
5960                   (minus:HF (match_dup 1) (match_dup 5)))
5961              (clobber (reg:CC_NOOV 21))])
5962   (parallel [(set (reg:CC 21)
5963                   (compare:CC (fix:QI (match_dup 3))
5964                               (const_int 0)))
5965              (set (match_dup 4)
5966                   (fix:QI (match_dup 3)))])
5967   (parallel [(set (match_dup 4) (unspec:QI [(match_dup 2)] UNSPEC_LDIV))
5968              (use (reg:CC 21))])
5969   (set (match_operand:QI 0 "reg_operand" "=r") (match_dup 4))]
5970  ""
5971  "operands[2] = gen_reg_rtx (QImode);
5972   operands[3] = gen_reg_rtx (HFmode);
5973   operands[4] = gen_reg_rtx (QImode);
5974   operands[5] = gen_reg_rtx (HFmode);
5975   emit_move_insn (operands[5], CONST_DOUBLE_ATOF (\"4294967296.0\", HFmode));")
5976
5977 (define_expand "fix_trunchfqi2"
5978   [(parallel [(set (match_dup 2)
5979                    (fix:QI (match_operand:HF 1 "reg_or_const_operand" "")))
5980               (clobber (reg:CC 21))])
5981    (parallel [(set (match_dup 3) (neg:HF (match_dup 1)))
5982               (clobber (reg:CC_NOOV 21))])
5983    (parallel [(set (match_dup 4) (fix:QI (match_dup 3)))
5984               (clobber (reg:CC 21))])
5985    (parallel [(set (reg:CC_NOOV 21)
5986                    (compare:CC_NOOV (neg:QI (match_dup 4)) (const_int 0)))
5987               (set (match_dup 5) (neg:QI (match_dup 4)))])
5988    (set (match_dup 2)
5989         (if_then_else:QI (le (reg:CC 21) (const_int 0))
5990                          (match_dup 5)
5991                          (match_dup 2)))
5992    (set (match_operand:QI 0 "reg_operand" "=r") (match_dup 2))]
5993  ""
5994  "if (TARGET_FAST_FIX)
5995     {
5996        emit_insn (gen_fixhfqi_clobber (operands[0], operands[1]));
5997        DONE;
5998     }
5999   operands[2] = gen_reg_rtx (QImode);
6000   operands[3] = gen_reg_rtx (HFmode);
6001   operands[4] = gen_reg_rtx (QImode);
6002   operands[5] = gen_reg_rtx (QImode);
6003  ")
6004
6005 (define_insn "*fixhfqi_set"
6006   [(set (reg:CC 21)
6007         (compare:CC (fix:QI (match_operand:HF 1 "reg_or_const_operand" "hH"))
6008                     (const_int 0)))
6009    (set (match_operand:QI 0 "ext_reg_operand" "=d")
6010         (fix:QI (match_dup 1)))]
6011  ""
6012  "fix\\t%1,%0"
6013   [(set_attr "type" "unarycc")])
6014
6015 (define_insn "fixhfqi_clobber"
6016   [(set (match_operand:QI 0 "reg_operand" "=dc")
6017         (fix:QI (match_operand:HF 1 "reg_or_const_operand" "hH")))
6018    (clobber (reg:CC 21))]
6019  ""
6020  "fix\\t%1,%0"
6021   [(set_attr "type" "unarycc")])
6022
6023 (define_expand "fix_trunchfhi2"
6024   [(parallel [(set (match_operand:HI 0 "reg_operand" "")
6025                    (fix:HI (match_operand:HF 1 "reg_operand" "")))
6026               (clobber (reg:CC 21))])]
6027   ""
6028   "c4x_emit_libcall (fix_trunchfhi2_libfunc, FIX, HImode, HFmode, 2, operands);
6029    DONE;")
6030
6031 (define_expand "fixuns_trunchfhi2"
6032   [(parallel [(set (match_operand:HI 0 "reg_operand" "")
6033                    (unsigned_fix:HI (match_operand:HF 1 "reg_operand" "")))
6034               (clobber (reg:CC 21))])]
6035   ""
6036   "c4x_emit_libcall (fixuns_trunchfhi2_libfunc, UNSIGNED_FIX, 
6037                      HImode, HFmode, 2, operands);
6038    DONE;")
6039
6040 ;
6041 ; ABSF
6042 ;
6043 (define_expand "abshf2"
6044   [(parallel [(set (match_operand:HF 0 "reg_operand" "")
6045                    (abs:HF (match_operand:HF 1 "reg_or_const_operand" "")))
6046               (clobber (reg:CC_NOOV 21))])]
6047 ""
6048 "")
6049
6050 (define_insn "*abshf2_clobber"
6051   [(set (match_operand:HF 0 "reg_operand" "=h")
6052         (abs:HF (match_operand:HF 1 "reg_or_const_operand" "hH")))
6053    (clobber (reg:CC_NOOV 21))]
6054   ""
6055   "absf\\t%1,%0"
6056   [(set_attr "type" "unarycc")])
6057
6058 (define_insn "*abshf2_test"
6059   [(set (reg:CC_NOOV 21)
6060         (compare:CC_NOOV (abs:HF (match_operand:HF 1 "reg_operand" "h"))
6061                          (match_operand:HF 2 "fp_zero_operand" "G")))
6062    (clobber (match_scratch:HF 0 "=h"))]
6063   ""
6064   "absf\\t%1,%0"
6065   [(set_attr "type" "unarycc")])
6066
6067 (define_insn "*abshf2_set"
6068   [(set (reg:CC_NOOV 21)
6069         (compare:CC_NOOV (abs:HF (match_operand:HF 1 "reg_or_const_operand" "hH"))
6070                          (match_operand:HF 2 "fp_zero_operand" "G")))
6071    (set (match_operand:HF 0 "reg_operand" "=h")
6072         (abs:HF (match_dup 1)))]
6073
6074   ""
6075   "absf\\t%1,%0"
6076   [(set_attr "type" "unarycc")])
6077
6078 ;
6079 ; NEGF
6080 ;
6081 (define_expand "neghf2"
6082   [(parallel [(set (match_operand:HF 0 "reg_operand" "")
6083                    (neg:HF (match_operand:HF 1 "reg_or_const_operand" "")))
6084               (clobber (reg:CC_NOOV 21))])]
6085 ""
6086 "")
6087
6088 (define_insn "*neghf2_clobber"
6089   [(set (match_operand:HF 0 "reg_operand" "=h")
6090         (neg:HF (match_operand:HF 1 "reg_or_const_operand" "hH")))
6091    (clobber (reg:CC_NOOV 21))]
6092   ""
6093   "negf\\t%1,%0"
6094   [(set_attr "type" "unarycc")])
6095
6096 (define_insn "*neghf2_test"
6097   [(set (reg:CC_NOOV 21)
6098         (compare:CC_NOOV (neg:HF (match_operand:HF 1 "reg_or_const_operand" "hH"))
6099                          (match_operand:HF 2 "fp_zero_operand" "G")))
6100    (clobber (match_scratch:HF 0 "=h"))]
6101   ""
6102   "negf\\t%1,%0"
6103   [(set_attr "type" "unarycc")])
6104
6105 (define_insn "*neghf2_set"
6106   [(set (reg:CC_NOOV 21)
6107         (compare:CC_NOOV (neg:HF (match_operand:HF 1 "reg_or_const_operand" "hH"))
6108                          (match_operand:HF 2 "fp_zero_operand" "G")))
6109    (set (match_operand:HF 0 "reg_operand" "=h")
6110         (neg:HF (match_dup 1)))]
6111   ""
6112   "negf\\t%1,%0"
6113   [(set_attr "type" "unarycc")])
6114
6115 ;
6116 ; RCPF
6117 ;
6118 (define_insn "*rcpfhf_clobber"
6119   [(set (match_operand:HF 0 "reg_operand" "=h")
6120         (unspec:HF [(match_operand:HF 1 "reg_or_const_operand" "hH")] UNSPEC_RCPF))
6121    (clobber (reg:CC_NOOV 21))]
6122   "! TARGET_C3X"
6123   "rcpf\\t%1,%0"
6124   [(set_attr "type" "unarycc")])
6125
6126 ;
6127 ; RSQRF
6128 ;
6129 (define_insn "*rsqrfhf_clobber"
6130   [(set (match_operand:HF 0 "reg_operand" "=h")
6131         (unspec:HF [(match_operand:HF 1 "reg_or_const_operand" "hH")] UNSPEC_RSQRF))
6132    (clobber (reg:CC_NOOV 21))]
6133   "! TARGET_C3X"
6134   "rsqrf\\t%1,%0"
6135   [(set_attr "type" "unarycc")])
6136
6137 ;
6138 ; RNDF
6139 ;
6140 (define_insn "*rndhf_clobber"
6141   [(set (match_operand:HF 0 "reg_operand" "=h")
6142         (unspec:HF [(match_operand:HF 1 "reg_or_const_operand" "hH")] UNSPEC_RND))
6143    (clobber (reg:CC_NOOV 21))]
6144   "! TARGET_C3X"
6145   "rnd\\t%1,%0"
6146   [(set_attr "type" "unarycc")])
6147
6148
6149 ; Inlined float square root for C4x
6150 (define_expand "sqrthf2_inline"
6151   [(parallel [(set (match_dup 2)
6152                    (unspec:HF [(match_operand:HF 1 "reg_operand" "")] UNSPEC_RSQRF))
6153               (clobber (reg:CC_NOOV 21))])
6154    (parallel [(set (match_dup 3) (mult:HF (match_dup 5) (match_dup 1)))
6155               (clobber (reg:CC_NOOV 21))])
6156    (parallel [(set (match_dup 4) (mult:HF (match_dup 2) (match_dup 3)))
6157               (clobber (reg:CC_NOOV 21))])
6158    (parallel [(set (match_dup 4) (mult:HF (match_dup 2) (match_dup 4)))
6159               (clobber (reg:CC_NOOV 21))])
6160    (parallel [(set (match_dup 4) (minus:HF (match_dup 6) (match_dup 4)))
6161               (clobber (reg:CC_NOOV 21))])
6162    (parallel [(set (match_dup 2) (mult:HF (match_dup 2) (match_dup 4)))
6163               (clobber (reg:CC_NOOV 21))])
6164    (parallel [(set (match_dup 4) (mult:HF (match_dup 2) (match_dup 3)))
6165               (clobber (reg:CC_NOOV 21))])
6166    (parallel [(set (match_dup 4) (mult:HF (match_dup 2) (match_dup 4)))
6167               (clobber (reg:CC_NOOV 21))])
6168    (parallel [(set (match_dup 4) (minus:HF (match_dup 6) (match_dup 4)))
6169               (clobber (reg:CC_NOOV 21))])
6170    (parallel [(set (match_dup 2) (mult:HF (match_dup 2) (match_dup 4)))
6171               (clobber (reg:CC_NOOV 21))])
6172    (parallel [(set (match_operand:HF 0 "reg_operand" "")
6173                    (mult:HF (match_dup 2) (match_dup 1)))
6174               (clobber (reg:CC_NOOV 21))])]
6175   "! TARGET_C3X"
6176   "
6177   operands[2] = gen_reg_rtx (HFmode);
6178   operands[3] = gen_reg_rtx (HFmode);
6179   operands[4] = gen_reg_rtx (HFmode);
6180   operands[5] = CONST_DOUBLE_ATOF (\"0.5\", HFmode);
6181   operands[6] = CONST_DOUBLE_ATOF (\"1.5\", HFmode);
6182   ")
6183
6184
6185 (define_expand "sqrthf2"
6186   [(parallel [(set (match_operand:HF 0 "reg_operand" "")
6187                    (sqrt:HF (match_operand:HF 1 "reg_operand" "")))
6188               (clobber (reg:CC 21))])]
6189   "! TARGET_C3X && TARGET_INLINE"
6190   "emit_insn (gen_sqrthf2_inline (operands[0], operands[1]));
6191    DONE;")
6192
6193 ;
6194 ; THREE OPERAND LONG DOUBLE INSTRUCTIONS
6195 ;
6196
6197 ;
6198 ; ADDF
6199 ;
6200 (define_insn "addhf3"
6201   [(set (match_operand:HF 0 "reg_operand" "=h,?h")
6202         (plus:HF (match_operand:HF 1 "reg_operand" "%0,h")
6203                  (match_operand:HF 2 "reg_or_const_operand" "H,h")))
6204    (clobber (reg:CC_NOOV 21))]
6205   ""
6206   "@
6207    addf\\t%2,%0
6208    addf3\\t%2,%1,%0"
6209   [(set_attr "type" "binarycc,binarycc")])
6210
6211 ;
6212 ; SUBF
6213 ;
6214 (define_insn "subhf3"
6215   [(set (match_operand:HF 0 "reg_operand" "=h,h,?h")
6216         (minus:HF (match_operand:HF 1 "reg_or_const_operand" "0,H,h")
6217                   (match_operand:HF 2 "reg_or_const_operand" "H,0,h")))
6218    (clobber (reg:CC_NOOV 21))]
6219   ""
6220   "@
6221    subf\\t%2,%0
6222    subrf\\t%1,%0
6223    subf3\\t%2,%1,%0"
6224   [(set_attr "type" "binarycc,binarycc,binarycc")])
6225
6226 ;
6227 ; MULF
6228 ;
6229 ; The C3x MPYF only uses 24-bit precision while the C4x uses 32-bit precision.
6230 ;
6231 (define_expand "mulhf3"
6232   [(parallel [(set (match_operand:HF 0 "reg_operand" "=h")
6233                    (mult:HF (match_operand:HF 1 "reg_operand" "h")
6234                             (match_operand:HF 2 "reg_operand" "h")))
6235               (clobber (reg:CC_NOOV 21))])]
6236   "! TARGET_C3X"
6237   "")
6238
6239 (define_insn "*mulhf3_c40"
6240   [(set (match_operand:HF 0 "reg_operand" "=h,?h")
6241         (mult:HF (match_operand:HF 1 "reg_operand" "%0,h")
6242                  (match_operand:HF 2 "reg_or_const_operand" "hH,h")))
6243    (clobber (reg:CC_NOOV 21))]
6244   ""
6245   "@
6246    mpyf\\t%2,%0
6247    mpyf3\\t%2,%1,%0"
6248   [(set_attr "type" "binarycc,binarycc")])
6249
6250 ;
6251 ; CMPF
6252 ;
6253 (define_expand "cmphf"
6254   [(set (reg:CC 21)
6255         (compare:CC (match_operand:HF 0 "reg_operand" "")
6256                     (match_operand:HF 1 "reg_or_const_operand" "")))]
6257   ""
6258   "c4x_compare_op0 = operands[0];
6259    c4x_compare_op1 = operands[1];
6260    DONE;")
6261
6262 (define_insn "*cmphf"
6263   [(set (reg:CC 21)
6264         (compare:CC (match_operand:HF 0 "reg_operand" "h")
6265                     (match_operand:HF 1 "reg_or_const_operand" "hH")))]
6266   ""
6267   "cmpf\\t%1,%0"
6268   [(set_attr "type" "compare")])
6269
6270 (define_insn "*cmphf_noov"
6271   [(set (reg:CC_NOOV 21)
6272         (compare:CC_NOOV (match_operand:HF 0 "reg_operand" "h")
6273                          (match_operand:HF 1 "reg_or_const_operand" "hH")))]
6274   ""
6275   "cmpf\\t%1,%0"
6276   [(set_attr "type" "compare")])
6277
6278 ; Inlined float divide for C4x
6279 (define_expand "divhf3_inline"
6280   [(parallel [(set (match_dup 3)
6281                    (unspec:HF [(match_operand:HF 2 "reg_operand" "")] UNSPEC_RCPF))
6282               (clobber (reg:CC_NOOV 21))])
6283    (parallel [(set (match_dup 4) (mult:HF (match_dup 2) (match_dup 3)))
6284               (clobber (reg:CC_NOOV 21))])
6285    (parallel [(set (match_dup 4) (minus:HF (match_dup 5) (match_dup 4)))
6286               (clobber (reg:CC_NOOV 21))])
6287    (parallel [(set (match_dup 3) (mult:HF (match_dup 3) (match_dup 4)))
6288               (clobber (reg:CC_NOOV 21))])
6289    (parallel [(set (match_dup 4) (mult:HF (match_dup 2) (match_dup 3)))
6290               (clobber (reg:CC_NOOV 21))])
6291    (parallel [(set (match_dup 4) (minus:HF (match_dup 5) (match_dup 4)))
6292               (clobber (reg:CC_NOOV 21))])
6293    (parallel [(set (match_dup 3) (mult:HF (match_dup 3) (match_dup 4)))
6294               (clobber (reg:CC_NOOV 21))])
6295    (parallel [(set (match_operand:HF 0 "reg_operand" "")
6296                    (mult:HF (match_operand:HF 1 "reg_operand" "")
6297                             (match_dup 3)))
6298               (clobber (reg:CC_NOOV 21))])]
6299   "! TARGET_C3X"
6300   "
6301   operands[3] = gen_reg_rtx (HFmode);
6302   operands[4] = gen_reg_rtx (HFmode);
6303   operands[5] = CONST2_RTX (HFmode);
6304   ")
6305
6306 (define_expand "divhf3"
6307   [(parallel [(set (match_operand:HF 0 "reg_operand" "")
6308                    (div:HF (match_operand:HF 1 "reg_operand" "")
6309                            (match_operand:HF 2 "reg_operand" "")))
6310               (clobber (reg:CC 21))])]
6311   "! TARGET_C3X && TARGET_INLINE"
6312   "emit_insn (gen_divhf3_inline (operands[0], operands[1], operands[2]));
6313    DONE;")
6314
6315
6316 ;
6317 ; TWO OPERAND LONG LONG INSTRUCTIONS
6318 ;
6319
6320 (define_insn "*movhi_stik"
6321   [(set (match_operand:HI 0 "memory_operand" "=m")
6322         (match_operand:HI 1 "stik_const_operand" "K"))]
6323   "! TARGET_C3X"
6324   "#"
6325   [(set_attr "type" "multi")])
6326
6327 ; We could load some constants using define_splits for the C30
6328 ; in the large memory model---these would emit shift and or insns.
6329 (define_expand "movhi"
6330   [(set (match_operand:HI 0 "src_operand" "")
6331         (match_operand:HI 1 "src_operand" ""))]
6332  ""
6333  "if (c4x_emit_move_sequence (operands, HImode))
6334     DONE;")
6335
6336 ; The constraints for movhi must include 'r' if we don't
6337 ; restrict HImode regnos to start on an even number, since
6338 ; we can get RC, R8 allocated as a pair.  We want more
6339 ; votes for FP_REGS so we use dr as the constraints.
6340 (define_insn "*movhi_noclobber"
6341   [(set (match_operand:HI 0 "dst_operand" "=dr,m")
6342         (match_operand:HI 1 "src_operand" "drIm,r"))]
6343   "reg_operand (operands[0], HImode)
6344    || reg_operand (operands[1], HImode)"
6345   "#"
6346   [(set_attr "type" "multi,multi")])
6347
6348 ; This will fail miserably if the destination register is used in the 
6349 ; source memory address.
6350 ; The usual strategy in this case is to swap the order of insns we emit,
6351 ; however, this will fail if we have an autoincrement memory address.
6352 ; For example:
6353 ; ldi *ar0++, ar0
6354 ; ldi *ar0++, ar1
6355 ;
6356 ; We could convert this to
6357 ; ldi *ar0(1), ar1
6358 ; ldi *ar0, ar0
6359 ;
6360 ; However, things are likely to be very screwed up if we get this.
6361
6362 (define_split
6363   [(set (match_operand:HI 0 "dst_operand" "")
6364         (match_operand:HI 1 "src_operand" ""))]
6365   "reload_completed
6366    && (reg_operand (operands[0], HImode)
6367        || reg_operand (operands[1], HImode)
6368        || stik_const_operand (operands[1], HImode))"
6369   [(set (match_dup 2) (match_dup 4))
6370    (set (match_dup 3) (match_dup 5))]
6371   "operands[2] = c4x_operand_subword (operands[0], 0, 1, HImode);
6372    operands[3] = c4x_operand_subword (operands[0], 1, 1, HImode);
6373    operands[4] = c4x_operand_subword (operands[1], 0, 1, HImode);
6374    operands[5] = c4x_operand_subword (operands[1], 1, 1, HImode);
6375    if (reg_overlap_mentioned_p (operands[2], operands[5]))
6376      {
6377         /* Swap order of move insns.  */
6378         rtx tmp;
6379         tmp = operands[2];
6380         operands[2] =operands[3];
6381         operands[3] = tmp;
6382         tmp = operands[4];
6383         operands[4] =operands[5];
6384         operands[5] = tmp;        
6385      }")
6386
6387
6388 (define_insn "extendqihi2"
6389   [(set (match_operand:HI 0 "reg_operand" "=dc")
6390         (sign_extend:HI (match_operand:QI 1 "src_operand" "rIm")))
6391    (clobber (reg:CC 21))]
6392   ""
6393   "#"
6394   [(set_attr "type" "multi")])
6395
6396 (define_split
6397   [(set (match_operand:HI 0 "reg_operand" "")
6398         (sign_extend:HI (match_operand:QI 1 "src_operand" "")))
6399    (clobber (reg:CC 21))]
6400   "reload_completed && TARGET_C3X"
6401   [(set (match_dup 2) (match_dup 1))
6402    (set (match_dup 3) (match_dup 2))
6403    (parallel [(set (match_dup 3) (ashiftrt:QI (match_dup 3) (const_int 31)))
6404               (clobber (reg:CC 21))])]
6405   "operands[2] = c4x_operand_subword (operands[0], 0, 0, HImode);
6406    operands[3] = c4x_operand_subword (operands[0], 1, 0, HImode);")
6407
6408 (define_split
6409   [(set (match_operand:HI 0 "reg_operand" "")
6410         (sign_extend:HI (match_operand:QI 1 "src_operand" "")))
6411    (clobber (reg:CC 21))]
6412   "reload_completed && ! TARGET_C3X"
6413   [(set (match_dup 2) (match_dup 1))
6414    (parallel [(set (match_dup 3) (ashiftrt:QI (match_dup 2) (const_int 31)))
6415               (clobber (reg:CC 21))])]
6416   "operands[2] = c4x_operand_subword (operands[0], 0, 0, HImode);
6417    operands[3] = c4x_operand_subword (operands[0], 1, 0, HImode);")
6418
6419 (define_insn "zero_extendqihi2"
6420   [(set (match_operand:HI 0 "reg_operand" "=?dc")
6421         (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "rm")))
6422    (clobber (reg:CC 21))]
6423   ""
6424   "#"
6425   [(set_attr "type" "multi")])
6426
6427 ; If operand0 and operand1 are the same register we don't need
6428 ; the first set.
6429 (define_split
6430   [(set (match_operand:HI 0 "reg_operand" "")
6431         (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "")))
6432    (clobber (reg:CC 21))]
6433   "reload_completed"
6434   [(set (match_dup 2) (match_dup 1))
6435    (set (match_dup 3) (const_int 0))]
6436   "operands[2] = c4x_operand_subword (operands[0], 0, 0, HImode);
6437    operands[3] = c4x_operand_subword (operands[0], 1, 0, HImode);")
6438
6439 ;
6440 ; PUSH/POP
6441 ;
6442 (define_insn "*pushhi"
6443   [(set (mem:HI (pre_inc:QI (reg:QI 20)))
6444         (match_operand:HI 0 "reg_operand" "r"))]
6445   ""
6446   "#"
6447   [(set_attr "type" "multi")])
6448
6449 (define_split
6450   [(set (mem:HI (pre_inc:QI (reg:QI 20)))
6451         (match_operand:HI 0 "reg_operand" ""))]
6452   "reload_completed"
6453   [(set (mem:QI (pre_inc:QI (reg:QI 20))) (match_dup 2))
6454    (set (mem:QI (pre_inc:QI (reg:QI 20))) (match_dup 3))]
6455   "operands[2] = c4x_operand_subword (operands[0], 0, 0, HImode);
6456    operands[3] = c4x_operand_subword (operands[0], 1, 0, HImode);")
6457
6458 (define_insn "*pophi"
6459   [(set (match_operand:HI 0 "reg_operand" "=r")
6460         (mem:HI (post_dec:QI (reg:QI 20))))
6461    (clobber (reg:CC 21))]
6462   ""
6463   "#"
6464   [(set_attr "type" "multi")])
6465
6466 (define_split
6467   [(set (match_operand:HI 0 "reg_operand" "")
6468        (mem:HI (pre_inc:QI (reg:QI 20))))]
6469   "reload_completed"
6470   [(set (match_dup 2) (mem:QI (pre_inc:QI (reg:QI 20))))
6471    (set (match_dup 3) (mem:QI (pre_inc:QI (reg:QI 20))))]
6472   "operands[2] = c4x_operand_subword (operands[0], 0, 0, HImode);
6473    operands[3] = c4x_operand_subword (operands[0], 1, 0, HImode);")
6474
6475 ;
6476 ; NEG
6477 ;
6478 (define_insn "neghi2"
6479   [(set (match_operand:HI 0 "ext_reg_operand" "=d")
6480         (neg:HI (match_operand:HI 1 "src_operand" "rm")))
6481    (clobber (reg:CC_NOOV 21))]
6482   ""
6483   "#"
6484   [(set_attr "type" "multi")])
6485
6486 (define_split
6487   [(set (match_operand:HI 0 "ext_reg_operand" "")
6488         (neg:HI (match_operand:HI 1 "src_operand" "")))
6489    (clobber (reg:CC_NOOV 21))]
6490   "reload_completed"
6491    [(parallel [(set (reg:CC_NOOV 21)
6492                     (compare:CC_NOOV (neg:QI (match_dup 3))
6493                                      (const_int 0)))
6494                (set (match_dup 2) (neg:QI (match_dup 3)))])
6495    (parallel [(set (match_dup 4) (neg:QI (match_dup 5)))
6496               (use (reg:CC_NOOV 21))
6497               (clobber (reg:CC_NOOV 21))])]
6498   "operands[2] = c4x_operand_subword (operands[0], 0, 1, HImode);
6499    operands[3] = c4x_operand_subword (operands[1], 0, 1, HImode);
6500    operands[4] = c4x_operand_subword (operands[0], 1, 1, HImode);
6501    operands[5] = c4x_operand_subword (operands[1], 1, 1, HImode);")
6502
6503 (define_insn "one_cmplhi2"
6504   [(set (match_operand:HI 0 "reg_operand" "=r")
6505         (not:HI (match_operand:HI 1 "src_operand" "rm")))
6506    (clobber (reg:CC 21))]
6507   ""
6508   "#"
6509   [(set_attr "type" "multi")])
6510
6511 (define_split
6512   [(set (match_operand:HI 0 "reg_operand" "")
6513         (not:HI (match_operand:HI 1 "src_operand" "")))
6514    (clobber (reg:CC 21))]
6515   "reload_completed"
6516    [(parallel [(set (match_dup 2) (not:QI (match_dup 3)))
6517                (clobber (reg:CC 21))])
6518     (parallel [(set (match_dup 4) (not:QI (match_dup 5)))
6519                (clobber (reg:CC 21))])]
6520   "operands[2] = c4x_operand_subword (operands[0], 0, 1, HImode);
6521    operands[3] = c4x_operand_subword (operands[1], 0, 1, HImode);
6522    operands[4] = c4x_operand_subword (operands[0], 1, 1, HImode);
6523    operands[5] = c4x_operand_subword (operands[1], 1, 1, HImode);")
6524
6525 (define_expand "floathiqf2"
6526   [(parallel [(set (match_operand:QF 0 "reg_operand" "")
6527                    (float:QF (match_operand:HI 1 "src_operand" "")))
6528               (clobber (reg:CC 21))])]
6529   ""
6530   "c4x_emit_libcall (floathiqf2_libfunc, FLOAT, QFmode, HImode, 2, operands);
6531    DONE;")
6532
6533 (define_expand "floatunshiqf2"
6534   [(parallel [(set (match_operand:QF 0 "reg_operand" "")
6535                    (unsigned_float:QF (match_operand:HI 1 "src_operand" "")))
6536               (clobber (reg:CC 21))])]
6537   ""
6538   "c4x_emit_libcall (floatunshiqf2_libfunc, UNSIGNED_FLOAT,
6539                      QFmode, HImode, 2, operands);
6540    DONE;")
6541
6542 (define_expand "floathihf2"
6543   [(parallel [(set (match_operand:HF 0 "reg_operand" "")
6544                    (float:HF (match_operand:HI 1 "src_operand" "")))
6545               (clobber (reg:CC 21))])]
6546   ""
6547   "c4x_emit_libcall (floathihf2_libfunc, FLOAT, HFmode, HImode, 2, operands);
6548    DONE;")
6549
6550 (define_expand "floatunshihf2"
6551   [(parallel [(set (match_operand:HF 0 "reg_operand" "")
6552                    (unsigned_float:HF (match_operand:HI 1 "src_operand" "")))
6553               (clobber (reg:CC 21))])]
6554   ""
6555   "c4x_emit_libcall (floatunshihf2_libfunc, UNSIGNED_FLOAT,
6556                      HFmode, HImode, 2, operands);
6557    DONE;")
6558
6559
6560 ;
6561 ; THREE OPERAND LONG LONG INSTRUCTIONS
6562 ;
6563
6564 (define_expand "addhi3"
6565   [(parallel [(set (match_operand:HI 0 "ext_reg_operand" "")
6566                    (plus:HI (match_operand:HI 1 "src_operand" "")
6567                             (match_operand:HI 2 "src_operand" "")))
6568               (clobber (reg:CC_NOOV 21))])]
6569   ""
6570   "legitimize_operands (PLUS, operands, HImode);")
6571
6572 (define_insn "*addhi3_clobber"
6573   [(set (match_operand:HI 0 "ext_reg_operand" "=d,d,?d")
6574         (plus:HI (match_operand:HI 1 "src_operand" "%0,rR,rS<>")
6575                  (match_operand:HI 2 "src_operand" "rm,R,rS<>")))
6576    (clobber (reg:CC_NOOV 21))]
6577   "valid_operands (PLUS, operands, HImode)"
6578   "#"
6579   [(set_attr "type" "multi,multi,multi")])
6580
6581 (define_split
6582  [(set (match_operand:HI 0 "ext_reg_operand" "")
6583        (plus:HI (match_operand:HI 1 "src_operand" "")
6584                 (match_operand:HI 2 "src_operand" "")))
6585   (clobber (reg:CC_NOOV 21))]
6586  "reload_completed"
6587   [(parallel [(set (reg:CC_NOOV 21)
6588                    (compare:CC_NOOV (plus:QI (match_dup 4) (match_dup 5))
6589                                     (const_int 0)))
6590               (set (match_dup 3) (plus:QI (match_dup 4) (match_dup 5)))])
6591    (parallel [(set (match_dup 6) (plus:QI (match_dup 7) (match_dup 8)))
6592               (use (reg:CC_NOOV 21))
6593               (clobber (reg:CC_NOOV 21))])]
6594   "operands[3] = c4x_operand_subword (operands[0], 0, 1, HImode);
6595    operands[4] = c4x_operand_subword (operands[1], 0, 1, HImode);
6596    operands[5] = c4x_operand_subword (operands[2], 0, 1, HImode);
6597    operands[6] = c4x_operand_subword (operands[0], 1, 1, HImode);
6598    operands[7] = c4x_operand_subword (operands[1], 1, 1, HImode);
6599    operands[8] = c4x_operand_subword (operands[2], 1, 1, HImode);")
6600
6601 (define_expand "subhi3"
6602   [(parallel [(set (match_operand:HI 0 "ext_reg_operand" "")
6603                    (minus:HI (match_operand:HI 1 "src_operand" "")
6604                              (match_operand:HI 2 "src_operand" "")))
6605               (clobber (reg:CC_NOOV 21))])]
6606   ""
6607   "legitimize_operands (MINUS, operands, HImode);")
6608
6609
6610 (define_insn "*subhi3_clobber"
6611   [(set (match_operand:HI 0 "ext_reg_operand" "=d,d,?d")
6612         (minus:HI (match_operand:HI 1 "src_operand" "0,rR,rS<>")
6613                   (match_operand:HI 2 "src_operand" "rm,R,rS<>")))
6614    (clobber (reg:CC_NOOV 21))]
6615   "valid_operands (MINUS, operands, HImode)"
6616   "#"
6617   [(set_attr "type" "multi,multi,multi")])
6618
6619 (define_split
6620  [(set (match_operand:HI 0 "ext_reg_operand" "")
6621        (minus:HI (match_operand:HI 1 "src_operand" "")
6622                  (match_operand:HI 2 "src_operand" "")))
6623   (clobber (reg:CC_NOOV 21))]
6624  "reload_completed"
6625   [(parallel [(set (reg:CC_NOOV 21)
6626                    (compare:CC_NOOV (minus:QI (match_dup 4) (match_dup 5))
6627                                     (const_int 0)))
6628               (set (match_dup 3) (minus:QI (match_dup 4) (match_dup 5)))])
6629    (parallel [(set (match_dup 6) (minus:QI (match_dup 7) (match_dup 8)))
6630               (use (reg:CC_NOOV 21))
6631               (clobber (reg:CC_NOOV 21))])]
6632   "operands[3] = c4x_operand_subword (operands[0], 0, 1, HImode);
6633    operands[4] = c4x_operand_subword (operands[1], 0, 1, HImode);
6634    operands[5] = c4x_operand_subword (operands[2], 0, 1, HImode);
6635    operands[6] = c4x_operand_subword (operands[0], 1, 1, HImode);
6636    operands[7] = c4x_operand_subword (operands[1], 1, 1, HImode);
6637    operands[8] = c4x_operand_subword (operands[2], 1, 1, HImode);")
6638
6639 (define_expand "iorhi3"
6640   [(parallel [(set (match_operand:HI 0 "reg_operand" "")
6641                    (ior:HI (match_operand:HI 1 "src_operand" "")
6642                            (match_operand:HI 2 "src_operand" "")))
6643               (clobber (reg:CC 21))])]
6644   ""
6645   "legitimize_operands (IOR, operands, HImode);")
6646
6647 (define_insn "*iorhi3_clobber"
6648   [(set (match_operand:HI 0 "reg_operand" "=d,d,?d")
6649         (ior:HI (match_operand:HI 1 "src_operand" "%0,rR,rS<>")
6650                 (match_operand:HI 2 "src_operand" "rm,R,rS<>")))
6651    (clobber (reg:CC 21))]
6652   "valid_operands (IOR, operands, HImode)"
6653   "#"
6654   [(set_attr "type" "multi,multi,multi")])
6655
6656 (define_split
6657  [(set (match_operand:HI 0 "reg_operand" "")
6658        (ior:HI (match_operand:HI 1 "src_operand" "")
6659                (match_operand:HI 2 "src_operand" "")))
6660   (clobber (reg:CC 21))]
6661  "reload_completed"
6662   [(parallel [(set (match_dup 3) (ior:QI (match_dup 4) (match_dup 5)))
6663               (clobber (reg:CC 21))])
6664    (parallel [(set (match_dup 6) (ior:QI (match_dup 7) (match_dup 8)))
6665               (clobber (reg:CC 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 "andhi3"
6674   [(parallel [(set (match_operand:HI 0 "reg_operand" "")
6675                    (and:HI (match_operand:HI 1 "src_operand" "")
6676                            (match_operand:HI 2 "src_operand" "")))
6677               (clobber (reg:CC 21))])]
6678   ""
6679   "legitimize_operands (AND, operands, HImode);")
6680
6681 (define_insn "*andhi3_clobber"
6682   [(set (match_operand:HI 0 "reg_operand" "=d,d,?d")
6683         (and:HI (match_operand:HI 1 "src_operand" "%0,rR,rS<>")
6684                 (match_operand:HI 2 "src_operand" "rm,R,rS<>")))
6685    (clobber (reg:CC 21))]
6686   "valid_operands (AND, operands, HImode)"
6687   "#"
6688   [(set_attr "type" "multi,multi,multi")])
6689
6690 (define_split
6691  [(set (match_operand:HI 0 "reg_operand" "")
6692        (and: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) (and:QI (match_dup 4) (match_dup 5)))
6697               (clobber (reg:CC 21))])
6698    (parallel [(set (match_dup 6) (and: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 "xorhi3"
6708   [(parallel [(set (match_operand:HI 0 "reg_operand" "")
6709                    (xor:HI (match_operand:HI 1 "src_operand" "")
6710                            (match_operand:HI 2 "src_operand" "")))
6711               (clobber (reg:CC 21))])]
6712   ""
6713   "legitimize_operands (XOR, operands, HImode);")
6714
6715
6716 (define_insn "*xorhi3_clobber"
6717   [(set (match_operand:HI 0 "reg_operand" "=d,d,?d")
6718         (xor:HI (match_operand:HI 1 "src_operand" "%0,rR,rS<>")
6719                 (match_operand:HI 2 "src_operand" "rm,R,rS<>")))
6720    (clobber (reg:CC 21))]
6721   "valid_operands (XOR, operands, HImode)"
6722   "#"
6723   [(set_attr "type" "multi,multi,multi")])
6724
6725 (define_split
6726  [(set (match_operand:HI 0 "reg_operand" "")
6727        (xor:HI (match_operand:HI 1 "src_operand" "")
6728                (match_operand:HI 2 "src_operand" "")))
6729   (clobber (reg:CC 21))]
6730  "reload_completed"
6731   [(parallel [(set (match_dup 3) (xor:QI (match_dup 4) (match_dup 5)))
6732               (clobber (reg:CC 21))])
6733    (parallel [(set (match_dup 6) (xor:QI (match_dup 7) (match_dup 8)))
6734               (clobber (reg:CC 21))])]
6735   "operands[3] = c4x_operand_subword (operands[0], 0, 1, HImode);
6736    operands[4] = c4x_operand_subword (operands[1], 0, 1, HImode);
6737    operands[5] = c4x_operand_subword (operands[2], 0, 1, HImode);
6738    operands[6] = c4x_operand_subword (operands[0], 1, 1, HImode);
6739    operands[7] = c4x_operand_subword (operands[1], 1, 1, HImode);
6740    operands[8] = c4x_operand_subword (operands[2], 1, 1, HImode);")
6741
6742 (define_expand "ashlhi3"
6743  [(parallel [(set (match_operand:HI 0 "reg_operand" "")
6744              (ashift:HI (match_operand:HI 1 "src_operand" "")
6745                         (match_operand:QI 2 "src_operand" "")))
6746              (clobber (reg:CC 21))])]
6747  ""
6748  "if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32)
6749     {
6750        rtx op0hi = operand_subword (operands[0], 1, 0, HImode);
6751        rtx op0lo = operand_subword (operands[0], 0, 0, HImode);
6752        rtx op1lo = operand_subword (operands[1], 0, 0, HImode);
6753        rtx count = GEN_INT ((INTVAL (operands[2]) - 32));
6754
6755        if (INTVAL (count))
6756          emit_insn (gen_ashlqi3 (op0hi, op1lo, count));
6757        else
6758          emit_insn (gen_movqi (op0hi, op1lo));
6759        emit_insn (gen_movqi (op0lo, const0_rtx));
6760        DONE;
6761     }
6762   if (! REG_P (operands[1]))
6763     operands[1] = force_reg (HImode, operands[1]);
6764   emit_insn (gen_ashlhi3_reg (operands[0], operands[1], operands[2]));
6765   DONE;
6766  ")
6767
6768 ; %0.lo = %1.lo << %2
6769 ; %0.hi = (%1.hi << %2 ) | (%1.lo >> (32 - %2))
6770 ; This algorithm should work for shift counts greater than 32
6771 (define_expand "ashlhi3_reg" 
6772  [(use (match_operand:HI 1 "reg_operand" ""))
6773   (use (match_operand:HI 0 "reg_operand" ""))
6774   /* If the shift count is greater than 32 this will give zero.  */
6775   (parallel [(set (match_dup 7)
6776                   (ashift:QI (match_dup 3)
6777                              (match_operand:QI 2 "reg_operand" "")))
6778              (clobber (reg:CC 21))])
6779   /* If the shift count is greater than 32 this will give zero.  */
6780   (parallel [(set (match_dup 8)
6781                   (ashift:QI (match_dup 4) (match_dup 2)))
6782              (clobber (reg:CC 21))])
6783   (parallel [(set (match_dup 10)
6784                   (plus:QI (match_dup 2) (const_int -32)))
6785              (clobber (reg:CC_NOOV 21))])
6786   /* If the shift count is greater than 32 this will do a left shift.  */
6787   (parallel [(set (match_dup 9)
6788                   (lshiftrt:QI (match_dup 3) (neg:QI (match_dup 10))))
6789              (clobber (reg:CC 21))])
6790   (set (match_dup 5) (match_dup 7))
6791   (parallel [(set (match_dup 6)
6792                   (ior:QI (match_dup 8) (match_dup 9)))
6793              (clobber (reg:CC 21))])]
6794  ""
6795  " 
6796   operands[3] = operand_subword (operands[1], 0, 1, HImode); /* lo */
6797   operands[4] = operand_subword (operands[1], 1, 1, HImode); /* hi */
6798   operands[5] = operand_subword (operands[0], 0, 1, HImode); /* lo */
6799   operands[6] = operand_subword (operands[0], 1, 1, HImode); /* hi */
6800   operands[7] = gen_reg_rtx (QImode); /* lo << count */
6801   operands[8] = gen_reg_rtx (QImode); /* hi << count */
6802   operands[9] = gen_reg_rtx (QImode); /* lo >> (32 - count) */
6803   operands[10] = gen_reg_rtx (QImode); /* 32 - count */
6804  ")
6805
6806 ; This should do all the dirty work with define_split
6807 (define_expand "lshrhi3"
6808  [(parallel [(set (match_operand:HI 0 "reg_operand" "")
6809              (lshiftrt:HI (match_operand:HI 1 "src_operand" "")
6810                           (match_operand:QI 2 "src_operand" "")))
6811              (clobber (reg:CC 21))])]
6812  ""
6813  "if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32)
6814     {
6815        rtx op0hi = operand_subword (operands[0], 1, 0, HImode);
6816        rtx op0lo = operand_subword (operands[0], 0, 0, HImode);
6817        rtx op1hi = operand_subword (operands[1], 1, 0, HImode);
6818        rtx count = GEN_INT ((INTVAL (operands[2]) - 32));
6819
6820        if (INTVAL (count))
6821          emit_insn (gen_lshrqi3 (op0lo, op1hi, count));
6822        else
6823          emit_insn (gen_movqi (op0lo, op1hi));
6824        emit_insn (gen_movqi (op0hi, const0_rtx));
6825        DONE;
6826     }
6827   if (! REG_P (operands[1]))
6828     operands[1] = force_reg (HImode, operands[1]);
6829   emit_insn (gen_lshrhi3_reg (operands[0], operands[1], operands[2]));
6830   DONE;")
6831
6832 ; %0.hi = %1.hi >> %2
6833 ; %0.lo = (%1.lo >> %2 ) | (%1.hi << (32 - %2))
6834 ; This algorithm should work for shift counts greater than 32
6835 (define_expand "lshrhi3_reg" 
6836  [(use (match_operand:HI 1 "reg_operand" ""))
6837   (use (match_operand:HI 0 "reg_operand" ""))
6838   (parallel [(set (match_dup 11)
6839                   (neg:QI (match_operand:QI 2 "reg_operand" "")))
6840              (clobber (reg:CC_NOOV 21))])
6841   /* If the shift count is greater than 32 this will give zero.  */
6842   (parallel [(set (match_dup 7)
6843                   (lshiftrt:QI (match_dup 3)
6844                                (neg:QI (match_dup 11))))
6845              (clobber (reg:CC 21))])
6846   /* If the shift count is greater than 32 this will give zero.  */
6847   (parallel [(set (match_dup 8)
6848                   (lshiftrt:QI (match_dup 4) 
6849                                (neg:QI (match_dup 11))))
6850              (clobber (reg:CC 21))])
6851   (parallel [(set (match_dup 10)
6852                   (plus:QI (match_dup 11) (const_int 32)))
6853              (clobber (reg:CC_NOOV 21))])
6854   /* If the shift count is greater than 32 this will do an arithmetic
6855      right shift.  However, we need a logical right shift.  */
6856   (parallel [(set (match_dup 9)
6857                   (ashift:QI (match_dup 4) (unspec:QI [(match_dup 10)] UNSPEC_LSH)))
6858              (clobber (reg:CC 21))])
6859   (set (match_dup 6) (match_dup 8))
6860   (parallel [(set (match_dup 5)
6861                   (ior:QI (match_dup 7) (match_dup 9)))
6862              (clobber (reg:CC 21))])]
6863  ""
6864  " 
6865   operands[3] = operand_subword (operands[1], 0, 1, HImode); /* lo */
6866   operands[4] = operand_subword (operands[1], 1, 1, HImode); /* hi */
6867   operands[5] = operand_subword (operands[0], 0, 1, HImode); /* lo */
6868   operands[6] = operand_subword (operands[0], 1, 1, HImode); /* hi */
6869   operands[7] = gen_reg_rtx (QImode); /* lo >> count */
6870   operands[8] = gen_reg_rtx (QImode); /* hi >> count */
6871   operands[9] = gen_reg_rtx (QImode); /* hi << (32 - count) */
6872   operands[10] = gen_reg_rtx (QImode); /* 32 - count */
6873   operands[11] = gen_reg_rtx (QImode); /* -count */
6874  ")
6875
6876 ; This should do all the dirty work with define_split
6877 (define_expand "ashrhi3"
6878   [(parallel [(set (match_operand:HI 0 "reg_operand" "")
6879               (ashiftrt:HI (match_operand:HI 1 "src_operand" "")
6880                            (match_operand:QI 2 "src_operand" "")))
6881               (clobber (reg:CC 21))])]
6882  ""
6883  "if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32)
6884     {
6885        rtx op0hi = operand_subword (operands[0], 1, 0, HImode);
6886        rtx op0lo = operand_subword (operands[0], 0, 0, HImode);
6887        rtx op1hi = operand_subword (operands[1], 1, 0, HImode);
6888        rtx count = GEN_INT ((INTVAL (operands[2]) - 32));
6889
6890        if (INTVAL (count))
6891          emit_insn (gen_ashrqi3 (op0lo, op1hi, count));
6892        else
6893          emit_insn (gen_movqi (op0lo, op1hi));
6894        emit_insn (gen_ashrqi3 (op0hi, op1hi, GEN_INT (31)));
6895        DONE;
6896     }
6897   if (! REG_P (operands[1]))
6898     operands[1] = force_reg (HImode, operands[1]);
6899   emit_insn (gen_ashrhi3_reg (operands[0], operands[1], operands[2]));
6900   DONE;")
6901
6902 ; %0.hi = %1.hi >> %2
6903 ; %0.lo = (%1.lo >> %2 ) | (%1.hi << (32 - %2))
6904 ; This algorithm should work for shift counts greater than 32
6905 (define_expand "ashrhi3_reg" 
6906  [(use (match_operand:HI 1 "reg_operand" ""))
6907   (use (match_operand:HI 0 "reg_operand" ""))
6908   (parallel [(set (match_dup 11)
6909                   (neg:QI (match_operand:QI 2 "reg_operand" "")))
6910              (clobber (reg:CC_NOOV 21))])
6911   /* If the shift count is greater than 32 this will give zero.  */
6912   (parallel [(set (match_dup 7)
6913                   (lshiftrt:QI (match_dup 3)
6914                                (neg:QI (match_dup 11))))
6915              (clobber (reg:CC 21))])
6916   /* If the shift count is greater than 32 this will give zero.  */
6917   (parallel [(set (match_dup 8)
6918                   (ashiftrt:QI (match_dup 4) 
6919                                (neg:QI (match_dup 11))))
6920              (clobber (reg:CC 21))])
6921   (parallel [(set (match_dup 10)
6922                   (plus:QI (match_dup 11) (const_int 32)))
6923              (clobber (reg:CC_NOOV 21))])
6924   /* If the shift count is greater than 32 this will do an arithmetic
6925      right shift.  */
6926   (parallel [(set (match_dup 9)
6927                   (ashift:QI (match_dup 4) (match_dup 10)))
6928              (clobber (reg:CC 21))])
6929   (set (match_dup 6) (match_dup 8))
6930   (parallel [(set (match_dup 5)
6931                   (ior:QI (match_dup 7) (match_dup 9)))
6932              (clobber (reg:CC 21))])]
6933  ""
6934  " 
6935   operands[3] = operand_subword (operands[1], 0, 1, HImode); /* lo */
6936   operands[4] = operand_subword (operands[1], 1, 1, HImode); /* hi */
6937   operands[5] = operand_subword (operands[0], 0, 1, HImode); /* lo */
6938   operands[6] = operand_subword (operands[0], 1, 1, HImode); /* hi */
6939   operands[7] = gen_reg_rtx (QImode); /* lo >> count */
6940   operands[8] = gen_reg_rtx (QImode); /* hi >> count */
6941   operands[9] = gen_reg_rtx (QImode); /* hi << (32 - count) */
6942   operands[10] = gen_reg_rtx (QImode); /* 32 - count */
6943   operands[11] = gen_reg_rtx (QImode); /* -count */
6944  ")
6945
6946 (define_expand "cmphi"
6947   [(set (reg:CC 21)
6948         (compare:CC (match_operand:HI 0 "src_operand" "")
6949                     (match_operand:HI 1 "src_operand" "")))]
6950   ""
6951   "legitimize_operands (COMPARE, operands, HImode);
6952    c4x_compare_op0 = operands[0];
6953    c4x_compare_op1 = operands[1];
6954    DONE;")
6955
6956 (define_insn "*cmphi_cc"
6957   [(set (reg:CC 21)
6958         (compare:CC (match_operand:HI 0 "src_operand" "rR,rS<>")
6959                     (match_operand:HI 1 "src_operand" "R,rS<>")))]
6960   "valid_operands (COMPARE, operands, HImode)"
6961   "#"
6962   [(set_attr "type" "multi")])
6963
6964 (define_insn "*cmphi_cc_noov"
6965   [(set (reg:CC_NOOV 21)
6966         (compare:CC_NOOV (match_operand:HI 0 "src_operand" "rR,rS<>")
6967                          (match_operand:HI 1 "src_operand" "R,rS<>")))]
6968   "valid_operands (COMPARE, operands, HImode)"
6969   "#"
6970   [(set_attr "type" "multi")])
6971
6972 ; This works only before reload because we need 2 extra registers.
6973 ; Use unspec to avoid recursive split.
6974 (define_split
6975   [(set (reg:CC 21)
6976         (compare:CC (match_operand:HI 0 "src_operand" "")
6977                     (match_operand:HI 1 "src_operand" "")))]
6978   "! reload_completed"
6979   [(parallel [(set (reg:CC 21)
6980                    (unspec:CC [(compare:CC (match_dup 0)
6981                                            (match_dup 1))] UNSPEC_CMPHI))
6982               (clobber (match_scratch:QI 2 ""))
6983               (clobber (match_scratch:QI 3 ""))])]
6984   "")
6985
6986 (define_split
6987   [(set (reg:CC_NOOV 21)
6988         (compare:CC_NOOV (match_operand:HI 0 "src_operand" "")
6989                          (match_operand:HI 1 "src_operand" "")))]
6990   "! reload_completed"
6991   [(parallel [(set (reg:CC_NOOV 21)
6992                    (unspec:CC_NOOV [(compare:CC_NOOV (match_dup 0)
6993                                                      (match_dup 1))] UNSPEC_CMPHI))
6994               (clobber (match_scratch:QI 2 ""))
6995               (clobber (match_scratch:QI 3 ""))])]
6996   "")
6997
6998 ; This is normally not used. The define splits above are used first.
6999 (define_split
7000   [(set (reg:CC 21)
7001         (compare:CC (match_operand:HI 0 "src_operand" "")
7002                     (match_operand:HI 1 "src_operand" "")))]
7003   "reload_completed"
7004   [(parallel [(set (reg:CC 21)
7005                    (compare:CC (match_dup 0) (match_dup 1)))
7006               (use (reg:QI 20))])]
7007   "")
7008
7009 (define_split
7010   [(set (reg:CC_NOOV 21)
7011         (compare:CC_NOOV (match_operand:HI 0 "src_operand" "")
7012                          (match_operand:HI 1 "src_operand" "")))]
7013   "reload_completed"
7014   [(parallel [(set (reg:CC_NOOV 21)
7015                    (compare:CC_NOOV (match_dup 0) (match_dup 1)))
7016               (use (reg:QI 20))])]
7017   "")
7018
7019 (define_insn "*cmphi"
7020   [(set (reg:CC 21)
7021         (compare:CC (match_operand:HI 0 "src_operand" "rR,rS<>")
7022                     (match_operand:HI 1 "src_operand" "R,rS<>")))
7023    (use (reg:QI 20))]
7024   "valid_operands (COMPARE, operands, HImode)"
7025   "*
7026    {
7027      int use_ir1 = (reg_operand (operands[0], HImode)
7028                     && REG_P (operands[0])
7029                     && REGNO (operands[0]) == IR1_REGNO)
7030                     || (reg_operand (operands[1], HImode)
7031                         && REG_P (operands[1])
7032                         && REGNO (operands[1]) == IR1_REGNO);
7033
7034      if (use_ir1)
7035        output_asm_insn (\"push\\tir1\", operands);
7036      else
7037        output_asm_insn (\"push\\tbk\", operands);
7038      output_asm_insn (\"push\\tr0\", operands);
7039      output_asm_insn (\"subi3\\t%1,%0,r0\", operands);
7040      if (use_ir1)
7041        {
7042          output_asm_insn (\"ldiu\\tst,ir1\", operands);
7043          output_asm_insn (\"or\\t07bh,ir1\", operands);
7044        }
7045      else
7046        {
7047          output_asm_insn (\"ldiu\\tst,bk\", operands);
7048          output_asm_insn (\"or\\t07bh,bk\", operands);
7049        }
7050      output_asm_insn (\"subb3\\t%O1,%O0,r0\", operands);
7051      if (use_ir1)
7052        output_asm_insn (\"and3\\tir1,st,ir1\", operands);
7053      else
7054        output_asm_insn (\"and3\\tbk,st,bk\", operands);
7055      output_asm_insn (\"pop\\tr0\", operands);
7056      if (use_ir1)
7057        {
7058          output_asm_insn (\"ldiu\\tir1,st\", operands);
7059          output_asm_insn (\"pop\\tir1\", operands);
7060        }
7061      else
7062        {
7063          output_asm_insn (\"ldiu\\tbk,st\", operands);
7064          output_asm_insn (\"pop\\tbk\", operands);
7065        }
7066      return \"\";
7067    }"
7068   [(set_attr "type" "multi")])
7069  
7070 (define_insn "*cmphi_noov"
7071   [(set (reg:CC_NOOV 21)
7072         (compare:CC_NOOV (match_operand:HI 0 "src_operand" "rR,rS<>")
7073                          (match_operand:HI 1 "src_operand" "R,rS<>")))
7074    (use (reg:QI 20))]
7075   "valid_operands (COMPARE, operands, HImode)"
7076   "*
7077    {
7078      int use_ir1 = (reg_operand (operands[0], HImode)
7079                     && REG_P (operands[0])
7080                     && REGNO (operands[0]) == IR1_REGNO)
7081                     || (reg_operand (operands[1], HImode)
7082                         && REG_P (operands[1])
7083                         && REGNO (operands[1]) == IR1_REGNO);
7084
7085      if (use_ir1)
7086        output_asm_insn (\"push\\tir1\", operands);
7087      else
7088        output_asm_insn (\"push\\tbk\", operands);
7089      output_asm_insn (\"push\\tr0\", operands);
7090      output_asm_insn (\"subi3\\t%1,%0,r0\", operands);
7091      if (use_ir1)
7092        {
7093          output_asm_insn (\"ldiu\\tst,ir1\", operands);
7094          output_asm_insn (\"or\\t07bh,ir1\", operands);
7095        }
7096      else
7097        {
7098          output_asm_insn (\"ldiu\\tst,bk\", operands);
7099          output_asm_insn (\"or\\t07bh,bk\", operands);
7100        }
7101      output_asm_insn (\"subb3\\t%O1,%O0,r0\", operands);
7102      if (use_ir1)
7103        output_asm_insn (\"and3\\tir1,st,ir1\", operands);
7104      else
7105        output_asm_insn (\"and3\\tbk,st,bk\", operands);
7106      output_asm_insn (\"pop\\tr0\", operands);
7107      if (use_ir1)
7108        {
7109          output_asm_insn (\"ldiu\\tir1,st\", operands);
7110          output_asm_insn (\"pop\\tir1\", operands);
7111        }
7112      else
7113        {
7114          output_asm_insn (\"ldiu\\tbk,st\", operands);
7115          output_asm_insn (\"pop\\tbk\", operands);
7116        }
7117      return \"\";
7118    }"
7119   [(set_attr "type" "multi")])
7120
7121  
7122 (define_insn "cmphi_cc"
7123   [(set (reg:CC 21)
7124         (unspec:CC [(compare:CC (match_operand:HI 0 "src_operand" "rR,rS<>")
7125                                 (match_operand:HI 1 "src_operand" "R,rS<>"))] UNSPEC_CMPHI))
7126    (clobber (match_scratch:QI 2 "=&d,&d"))
7127    (clobber (match_scratch:QI 3 "=&c,&c"))]
7128   "valid_operands (COMPARE, operands, HImode)"
7129   "*
7130    output_asm_insn (\"subi3\\t%1,%0,%2\", operands);
7131    output_asm_insn (\"ldiu\\tst,%3\", operands);
7132    output_asm_insn (\"or\\t07bh,%3\", operands);
7133    output_asm_insn (\"subb3\\t%O1,%O0,%2\", operands);
7134    output_asm_insn (\"and\\t%3,st\", operands);
7135    return \"\";"
7136   [(set_attr "type" "multi")])
7137
7138 (define_insn "cmphi_cc_noov"
7139   [(set (reg:CC_NOOV 21)
7140         (unspec:CC_NOOV [(compare:CC_NOOV (match_operand:HI 0 "src_operand" "rR,rS<>")
7141                                      (match_operand:HI 1 "src_operand" "R,rS<>"))] UNSPEC_CMPHI))
7142    (clobber (match_scratch:QI 2 "=&d,&d"))
7143    (clobber (match_scratch:QI 3 "=&c,&c"))]
7144   "valid_operands (COMPARE, operands, HImode)"
7145   "*
7146    output_asm_insn (\"subi3\\t%1,%0,%2\", operands);
7147    output_asm_insn (\"ldiu\\tst,%3\", operands);
7148    output_asm_insn (\"or\\t07bh,%3\", operands);
7149    output_asm_insn (\"subb3\\t%O1,%O0,%2\", operands);
7150    output_asm_insn (\"and\\t%3,st\", operands);
7151    return \"\";"
7152   [(set_attr "type" "multi")])
7153
7154 (define_expand "mulhi3"
7155   [(parallel [(set (match_operand:HI 0 "reg_operand" "")
7156                    (mult:HI (match_operand:HI 1 "src_operand" "")
7157                             (match_operand:HI 2 "src_operand" "")))
7158               (clobber (reg:CC 21))])]
7159   ""
7160   "c4x_emit_libcall3 (smul_optab->handlers[(int) HImode].libfunc,
7161                       MULT, HImode, operands);
7162    DONE;")
7163
7164
7165 ;
7166 ; PEEPHOLES
7167 ;
7168
7169 ; dbCC peepholes
7170 ;
7171 ; Turns
7172 ;   loop:
7173 ;           [ ... ]
7174 ;           bCC label           ; abnormal loop termination
7175 ;           dbu aN, loop        ; normal loop termination
7176 ;
7177 ; Into
7178 ;   loop:
7179 ;           [ ... ]
7180 ;           dbCC aN, loop
7181 ;           bCC label
7182 ;
7183 ; Which moves the bCC condition outside the inner loop for free.
7184 ;
7185 (define_peephole
7186   [(set (pc) (if_then_else (match_operator 3 "comparison_operator"
7187                            [(reg:CC 21) (const_int 0)])
7188                            (label_ref (match_operand 2 "" ""))
7189                            (pc)))
7190    (parallel
7191     [(set (pc)
7192           (if_then_else
7193             (ge (plus:QI (match_operand:QI 0 "addr_reg_operand" "+a")
7194                          (const_int -1))
7195                 (const_int 0))
7196             (label_ref (match_operand 1 "" ""))
7197             (pc)))
7198      (set (match_dup 0)
7199           (plus:QI (match_dup 0)
7200                    (const_int -1)))
7201      (use (reg:QI 20))
7202      (clobber (reg:CC_NOOV 21))])]
7203   "! c4x_label_conflict (insn, operands[2], operands[1])"
7204   "db%I3\\t%0,%l1\\n\\tb%3\\t%l2"
7205   [(set_attr "type" "multi")])
7206
7207 (define_peephole
7208   [(set (pc) (if_then_else (match_operator 3 "comparison_operator"
7209                            [(reg:CC 21) (const_int 0)])
7210                            (label_ref (match_operand 2 "" ""))
7211                            (pc)))
7212    (parallel
7213     [(set (pc)
7214           (if_then_else
7215             (ne (match_operand:QI 0 "addr_reg_operand" "+a")
7216                 (const_int 0))
7217             (label_ref (match_operand 1 "" ""))
7218             (pc)))
7219      (set (match_dup 0)
7220           (plus:QI (match_dup 0)
7221                    (const_int -1)))])]
7222   "! c4x_label_conflict (insn, operands[2], operands[1])"
7223   "db%I3\\t%0,%l1\\n\\tb%3\\t%l2"
7224   [(set_attr "type" "multi")])
7225
7226 ;
7227 ; Peepholes to convert 'call label; rets' into jump label
7228 ;
7229
7230 (define_peephole
7231   [(parallel [(call (mem:QI (match_operand:QI 0 "call_address_operand" ""))
7232                     (match_operand:QI 1 "general_operand" ""))
7233               (clobber (reg:QI 31))])
7234    (return)]
7235   "! c4x_null_epilogue_p ()"
7236   "*
7237    if (REG_P (operands[0]))
7238      return \"bu%#\\t%C0\";
7239    else
7240      return \"br%#\\t%C0\";"
7241   [(set_attr "type" "jump")])
7242
7243 (define_peephole
7244   [(parallel [(set (match_operand 0 "" "")
7245                    (call (mem:QI (match_operand:QI 1 "call_address_operand" ""))
7246                          (match_operand:QI 2 "general_operand" "")))
7247               (clobber (reg:QI 31))])
7248    (return)]
7249   "! c4x_null_epilogue_p ()"
7250   "*
7251    if (REG_P (operands[1]))
7252      return \"bu%#\\t%C1\";
7253    else
7254      return \"br%#\\t%C1\";"
7255   [(set_attr "type" "jump")])
7256
7257
7258 ; This peephole should be unnecessary with my patches to flow.c
7259 ; for better autoincrement detection
7260 (define_peephole
7261  [(set (match_operand:QF 0 "ext_low_reg_operand" "")
7262        (mem:QF (match_operand:QI 1 "addr_reg_operand" "")))
7263   (set (match_operand:QF 2 "ext_low_reg_operand" "")
7264        (mem:QF (plus:QI (match_dup 1) (const_int 1))))
7265   (parallel [(set (match_dup 1) (plus:QI (match_dup 1) (const_int 2)))
7266              (clobber (reg:CC_NOOV 21))])]
7267  ""
7268  "ldf\\t*%1++,%0\\n\\tldf\\t*%1++,%2")
7269
7270
7271 ; This peephole should be unnecessary with my patches to flow.c
7272 ; for better autoincrement detection
7273 (define_peephole
7274  [(set (mem:QF (match_operand:QI 0 "addr_reg_operand" ""))
7275        (match_operand:QF 1 "ext_low_reg_operand" ""))
7276   (set (mem:QF (plus:QI (match_dup 0) (const_int 1)))
7277        (match_operand:QF 2 "ext_low_reg_operand" ""))
7278   (parallel [(set (match_dup 0) (plus:QI (match_dup 0) (const_int 2)))
7279              (clobber (reg:CC_NOOV 21))])]
7280  ""
7281  "stf\\t%1,*%0++\\n\\tstf\\t%2,*%0++")
7282
7283
7284 ; The following two peepholes remove an unnecessary load
7285 ; often found at the end of a function.  These peepholes
7286 ; could be generalized to other binary operators.  They shouldn't
7287 ; be required if we run a post reload mop-up pass.
7288 (define_peephole
7289  [(parallel [(set (match_operand:QF 0 "ext_reg_operand" "")
7290                   (plus:QF (match_operand:QF 1 "ext_reg_operand" "")
7291                            (match_operand:QF 2 "ext_reg_operand" "")))
7292              (clobber (reg:CC_NOOV 21))])
7293   (set (match_operand:QF 3 "ext_reg_operand" "")
7294        (match_dup 0))]
7295  "dead_or_set_p (insn, operands[0])"
7296  "addf3\\t%2,%1,%3")
7297
7298 (define_peephole
7299  [(parallel [(set (match_operand:QI 0 "reg_operand" "")
7300                   (plus:QI (match_operand:QI 1 "reg_operand" "")
7301                            (match_operand:QI 2 "reg_operand" "")))
7302              (clobber (reg:CC_NOOV 21))])
7303   (set (match_operand:QI 3 "reg_operand" "")
7304        (match_dup 0))]
7305  "dead_or_set_p (insn, operands[0])"
7306  "addi3\\t%2,%1,%3")