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