OSDN Git Service

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