OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [config/] [c4x/] [c4x.md] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
;; 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.
4
 
5
;; Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)
6
;;            and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl)
7
 
8
;; This file is part of GCC.
9
 
10
;; GCC is free software; you can redistribute it and/or modify
11
;; it under the terms of the GNU General Public License as published by
12
;; the Free Software Foundation; either version 2, or (at your option)
13
;; any later version.
14
 
15
;; GCC is distributed in the hope that it will be useful,
16
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
;; GNU General Public License for more details.
19
 
20
;; You should have received a copy of the GNU General Public License
21
;; along with GCC; see the file COPYING.  If not, write to
22
;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23
;; Boston, MA 02110-1301, USA.
24
 
25
;
26
; TODO :
27
;        Try using PQImode again for addresses since C30 only uses
28
;        24-bit addresses.   Ideally GCC would emit different insns
29
;        for QImode and Pmode, whether Pmode was QImode or PQImode.
30
;        For addresses we wouldn't have to have a clobber of the CC
31
;        associated with each insn and we could use MPYI in address
32
;        calculations without having to synthesize a proper 32 bit multiply.
33
 
34
; Additional C30/C40 instructions not coded:
35
; CALLcond, IACK, IDLE, LDE, LDFI, LDII, LDM, NORM, RETIcond
36
; ROLC, RORC, SIGI, STFI, STII, SUBC, SWI
37
 
38
; Additional C40 instructions not coded:
39
; LDEP, LDPE, LWRct, LAJcond, RETIcondD
40
 
41
;
42
; C4x MODES
43
;
44
; QImode                char, short, int, long (32-bits)
45
; HImode                long long              (64-bits)
46
; QFmode                float, double          (32-bits)
47
; HFmode                long double            (40-bits)
48
; CCmode
49
; CC_NOOVmode
50
 
51
;
52
; C4x PREDICATES:
53
;
54
; comparison_operator   LT, GT, LE, GE, LTU, GTU, LEU, GEU, EQ, NE
55
; memory_operand        memory                                     [m]
56
; immediate_operand     immediate constant                         [IKN]
57
; register_operand      register                                   [rf]
58
; general_operand       register, memory, constant                 [rfmI]
59
 
60
; addr_reg_operand      AR0-AR7, pseudo reg                        [a]
61
; sp_reg_operand        SP                                         [b]
62
; std_reg_operand       AR0-AR7, IR0-IR1, RC, RS, RE, SP, pseudo   [c]
63
; ext_reg_operand       R0-R11, pseudo reg                         [f]
64
; ext_low_reg_operand   R0-R7, pseudo reg                          [q]
65
; index_reg_operand     IR0-IR1, pseudo reg                        [x]
66
; st_reg_operand        ST                                         [y]
67
; dp_reg_operand        DP                                         [z]
68
; stik_const_operand    5-bit const                                [K]
69
; src_operand           general operand                            [rfHmI]
70
; par_ind_operand       indirect S mode (ARx + 0, 1, IRx)          [S<>]
71
; parallel_operand      par_ind_operand or ext_low_reg_operand
72
; symbolic_address_operand
73
; call_address_operand
74
 
75
; ADDI src2, src1, dst  three operand op
76
; ADDI src, dst         two operand op
77
 
78
;  Note that the predicates are only used when selecting a pattern
79
;  to determine if an operand is valid.
80
 
81
;  The constraints then select which of the possible valid operands
82
;  is present (and guide register selection). The actual assembly
83
;  instruction is then selected on the basis of the constraints.
84
 
85
;  The extra constraint (valid_operands) is used to determine if
86
;  the combination of operands is legitimate for the pattern.
87
 
88
;
89
; C4x CONSTRAINTS:
90
;
91
; a   address reg          AR0-AR7
92
; b   stack pointer        SP
93
; c   other int reg        AR0-AR7, IR0-IR1, RC, RS, RE
94
; d   fp reg               R0-R11 (sets CC when dst)
95
; e
96
; f   fp reg               R0-R11 (sets CC when dst)
97
; g   general reg, memory, constant
98
; h   fp reg (HFmode)      R0-R11 (sets CC when dst)
99
; i   immediate int constant
100
; j
101
; k   block count          BK
102
; l
103
; m   memory
104
; n   immediate int constant with known numeric value
105
; o   offsettable memory
106
; p   memory address
107
; q   low fp reg           R0-R7  (sets CC when dst)
108
; r   general reg          R0-R11, AR0-AR7, IR0-IR1, RC, RS, RE
109
; s   immediate int constant (value not explicit)
110
; t                        R0-R1
111
; u                        R2-R3
112
; v   repeat count reg     RC
113
; w
114
; x   index reg            IR0-IR1
115
; y   status (CC) reg      ST
116
; z   data pointer         DP
117
 
118
; G   fp zero
119
; H   fp 16-bit constant
120
; I   signed 16-bit
121
; J   signed 8-bit    (C4x only)
122
; K   signed 5-bit    (C4x only)
123
; L   unsigned 16-bit
124
; M   unsigned 8-bit  (C4x only)
125
; N   ones complement of unsigned 16-bit
126
; O   16 bit high constant
127
; Q   ARx + 9-bit signed disp
128
; R   ARx + 5-bit unsigned disp  (C4x only)
129
; S   ARx + 0, 1, IRx disp
130
; T   direct memory operand
131
; V   non offsettable memory
132
; X   any operand
133
; <   memory operand with autodecrement addressing
134
; >   memory operand with autoincrement addressing
135
; {   memory operand with pre-modify addressing
136
; }   memory operand with post-modify addressing
137
 
138
;  Note that the 'd', 'f', and 'h' constraints are equivalent.
139
;  The m constraint is equivalent to 'QT<>{}'
140
 
141
;  Note we cannot use the 'g' constraint with Pmode (i.e, QImode)
142
;  operations since LEGITIMATE_CONSTANT_P accepts SYMBOL_REF.
143
;  So instead we use 'rIm' for signed operands or 'rLm' for unsigned operands.
144
 
145
;  Note that the constraints are used to select the operands
146
;  for a chosen pattern.  The constraint that requires the fewest
147
;  instructions to load an operand is chosen.
148
 
149
;  Note that the 'r' constraint is mostly only used for src integer register
150
;  operands,  while 'c' and 'd' constraints are generally only used for dst
151
;  integer register operands (the 'r' constraint is the union of the 'c' and
152
;  'd' constraints).  When a register satisfying the 'd' constraint
153
;  is used as a dst operand, the CC gets clobbered (except for LDIcond)---but
154
;  not for 'c'.
155
 
156
;  The 'f' constraint is only for float register operands---when
157
;  a register satisfying the 'f' constraint is used as a dst operand,
158
;  the CC gets clobbered (except for LDFcond).
159
 
160
;  The ! in front of the 'b' constraint says to GCC to disparage the
161
;  use of this constraint.  The 'b' constraint applies only to the SP.
162
 
163
;  Note that we deal with the condition code CC like some of the RISC
164
;  architectures (arm, sh, sparc) where it is stored in a general register,
165
;  in this case the hard register ST (21).  Unlike these other architectures
166
;  that do not set the CC with many instructions, the C[34]x architectures
167
;  sets the CC for many instructions when the destination register is
168
;  an extended precision register.  While it would have been easier
169
;  to use the generic cc0 register to store the CC, as with most of
170
;  the other ported architectures, this constrains the setting and testing
171
;  of the CC to be consecutive insns.  Thus we would reduce the benefit
172
;  of scheduling instructions to avoid pipeline conflicts and filling of
173
;  delayed branch slots.
174
 
175
;  Since the C[34]x has many instructions that set the CC, we pay the
176
;  price of having to explicitly define which insns clobber the CC
177
;  (rather than using the macro NOTICE_UPDATE_CC).
178
 
179
;  Note that many patterns say that the CC is clobbered when in fact
180
;  that it may not be (depending on the destination register).
181
;  We have to cover ourselves if an extended precision register
182
;  is allocated to the destination register.
183
;  Unfortunately, it is not easy to tell GCC that the clobbering of CC
184
;  is register dependent.  If we could tolerate the ST register being
185
;  copied about, then we could store the CC in a pseudo register and
186
;  use constructs such as (clobber (match_scratch:CC N "&y,X")) to
187
;  indicate that the 'y' class (ST register) is clobbered for the
188
;  first combination of operands but not with the second.
189
;  I tried this approach for a while but reload got unhappy since I
190
;  didn't allow it to move the CC around.
191
 
192
;  Note that fundamental operations, such as moves, must not clobber the
193
;  CC.  Thus movqi chooses a move instruction that doesn't clobber the CC.
194
;  If GCC wants to combine a move with a compare, it is smart enough to
195
;  chose the move instruction that sets the CC.
196
 
197
;  Unfortunately, the C[34]x instruction set does not have arithmetic or
198
;  logical operations that never touch the CC.  We thus have to assume
199
;  that the CC may be clobbered at all times.  If we define patterns
200
;  such as addqi without the clobber of CC, then GCC will be forced
201
;  to use registers such as the auxiliary registers which can cause
202
;  horrible pipeline conflicts.  The tradeoff is that GCC can't now
203
;  sneak in an add instruction between setting and testing of the CC.
204
 
205
;  Most of the C[34]x instructions require operands of the following formats,
206
;  where imm represents an immediate constant, dir a direct memory reference,
207
;  ind an indirect memory reference, and reg a register:
208
 
209
;        src2 (op2)             src1 (op1)      dst (op0)
210
; imm  dir  ind  reg  |  imm  dir  ind  reg  |  reg      Notes
211
;---------------------+----------------------+------
212
; ILH   T   Q<>   r   |   -    -    -    0   |   r       2 operand
213
;  -    -   S<>   r   |   -    -   S<>   r   |   r
214
;  J    -    R    -   |   -    -    R    r   |   r       C4x
215
 
216
;  Arithmetic operations use the I, J constraints for immediate constants,
217
;  while logical operations use the L, J constraints.  Floating point
218
;  operations use the H constraint for immediate constants.
219
 
220
;  With most instructions the src2 and src1 operands are commutative
221
;  (except for SUB, SUBR, ANDN).  The assembler considers
222
;  ADDI 10, R0, R1 and ADDI R0, 10, R1 to be equivalent.
223
;  We thus match src2 and src1 with the src_operand predicate and
224
;  use valid_operands as the extra constraint to reject invalid
225
;  operand combinations.  For example, ADDI @foo, @bar, R0.
226
 
227
;  Note that we use the ? modifier so that reload doesn't preferentially
228
;  try the alternative where three registers are acceptable as
229
;  operands (whenever an operand requires reloading).  Instead it will try
230
;  the 2 operand form which will produce better code since it won't require
231
;  a new spill register.
232
 
233
;  Note that the floating point representation of 0.0 on the C4x
234
;  is 0x80000000 (-2147483648).  This value produces a warning
235
;  message on 32-bit machines about the decimal constant being so large
236
;  that it is unsigned.
237
 
238
;  With two operand instructions patterns having two sets,
239
;  the compare set must come first to keep the combiner happy.
240
;  While the combiner seems to cope most of the time with the
241
;  compare set coming second, it's best to have it first.
242
 
243
;
244
; C4x CONSTANT attributes
245
;
246
(define_attr "cpu" "c4x,c3x"
247
 (const
248
  (cond [(symbol_ref "TARGET_C3X") (const_string "c3x")]
249
         (const_string "c4x"))))
250
 
251
;
252
; C4x INSN ATTRIBUTES:
253
;
254
; lda           load address, non-clobber CC
255
; store         memory store, non-clobber CC
256
; load_load     parallel memory loads, non-clobber CC
257
; load_store    parallel memory load and store, non-clobber CC
258
; store_load    parallel memory store and load, non-clobber CC
259
; store_store   parallel memory stores, non-clobber CC
260
; unary         two operand arithmetic, non-clobber CC
261
; unarycc       two operand arithmetic, clobber CC
262
; binary        three operand arithmetic, non-clobber CC
263
; binarycc      three operand arithmetic, clobber CC
264
; compare       compare, clobber CC
265
; call          function call
266
; rets          return from subroutine
267
; jump          unconditional branch
268
; jmpc          conditional branch
269
; db            decrement and branch (unconditional)
270
; dbc           decrement and branch (conditional)
271
; ldp           load DP
272
; push          stack push
273
; pop           stack pop
274
; repeat        block repeat
275
; repeat_top    block repeat top
276
; laj           link and jump
277
; multi         multiple instruction
278
; misc          nop             (default)
279
 
280
;  The only real instructions that affect things are the ones that modify
281
;  address registers and ones that call or jump.  Note that the number
282
;  of operands refers to the RTL insn pattern, not the number of explicit
283
;  operands in the machine instruction.
284
;
285
(define_attr "type" "lda,store,unary,unarycc,binary,binarycc,compare,call,rets,jump,jmpc,db,dbc,misc,ldp,repeat,repeat_top,laj,load_load,load_store,store_load,store_store,push,pop,multi"
286
             (const_string "misc"))
287
 
288
 
289
; Some instructions operate on unsigned data constants, some on signed data
290
; constants, or the ones complement of unsigned constants.
291
; This differentiates them.  Default to signed.  This attribute
292
; is used by the macro SMALL_CONST () (defined in c4x.h) to determine
293
; whether an immediate integer constant will fit within the instruction,
294
; or will have to be loaded using direct addressing from memory.
295
; Note that logical operations assume unsigned integers whereas
296
; arithmetic operations assume signed integers.  Note that the C4x
297
; small immediate constant (J) used as src2 in three operand instructions
298
; is always signed.  not_uint16 refers to a number that fits into 16-bits
299
; when one's complemented.
300
;
301
(define_attr "data" "int16,uint16,high_16,not_uint16" (const_string "int16"))
302
 
303
(define_asm_attributes
304
  [(set_attr "type" "multi")])
305
 
306
;
307
; C4x DELAY SLOTS
308
;
309
; Define delay slot scheduling for branch and call instructions.
310
; The C[34]x has three delay slots. Note that none of the three instructions
311
; that follow a delayed branch can be a Bcond, BcondD, BR, BRD, DBcond,
312
; DBcondD, CALL, CALLcond, TRAPcond, RETIcond, RETScond, RPTB, RPTS, or IDLE.
313
;
314
; Annulled branches are a bit difficult because the next instructions
315
; are preprocessed.
316
; The table below shows what phase of the c4x is executed.
317
;        BccA[TF] label
318
;        op1             fetch, decode and read executed
319
;        op2             fetch and decode executed
320
;        op3             fetch executed
321
; This means that we can allow any instruction in the last delay slot
322
; and only instructions which modify registers in the first two.
323
; lda cannot be executed in the first delay slot
324
; and ldpk cannot be executed in the first two delay slots.
325
 
326
(define_attr "onlyreg" "false,true"
327
       (cond [(eq_attr "type" "unary,unarycc")
328
                       (if_then_else (and (match_operand 0 "reg_imm_operand" "")
329
                                          (match_operand 1 "reg_imm_operand" ""))
330
                                     (const_string "true") (const_string "false"))
331
              (eq_attr "type" "binary,binarycc")
332
                       (if_then_else (and (match_operand 0 "reg_imm_operand" "")
333
                                          (and (match_operand 1 "reg_imm_operand" "")
334
                                               (match_operand 2 "reg_imm_operand" "")))
335
                                     (const_string "true") (const_string "false"))]
336
             (const_string "false")))
337
 
338
(define_attr "onlyreg_nomod" "false,true"
339
       (cond [(eq_attr "type" "unary,unarycc,compare,lda,store")
340
                       (if_then_else (and (match_operand 0 "not_modify_reg" "")
341
                                          (match_operand 1 "not_modify_reg" ""))
342
                                     (const_string "true") (const_string "false"))
343
              (eq_attr "type" "binary,binarycc")
344
                       (if_then_else (and (match_operand 0 "not_modify_reg" "")
345
                                          (and (match_operand 1 "not_modify_reg" "")
346
                                               (match_operand 2 "not_modify_reg" "")))
347
                                     (const_string "true") (const_string "false"))]
348
             (const_string "false")))
349
 
350
(define_attr "not_repeat_reg" "false,true"
351
       (cond [(eq_attr "type" "unary,unarycc,compare,lda,ldp,store")
352
                       (if_then_else (and (match_operand 0 "not_rc_reg" "")
353
                                          (match_operand 1 "not_rc_reg" ""))
354
                                     (const_string "true") (const_string "false"))
355
              (eq_attr "type" "binary,binarycc")
356
                       (if_then_else (and (match_operand 0 "not_rc_reg" "")
357
                                          (and (match_operand 1 "not_rc_reg" "")
358
                                               (match_operand 2 "not_rc_reg" "")))
359
                                     (const_string "true") (const_string "false"))]
360
             (const_string "false")))
361
 
362
/* Disable compare because the c4x contains a bug. The cmpi insn sets the CC
363
   in the read phase of the pipeline instead of the execution phase when
364
   two registers are compared.  */
365
(define_attr "in_annul_slot_1" "false,true"
366
  (if_then_else (and (and (eq_attr "cpu" "c4x")
367
                          (eq_attr "type" "!jump,call,rets,jmpc,compare,db,dbc,repeat,repeat_top,laj,push,pop,lda,ldp,multi"))
368
                     (eq_attr "onlyreg" "true"))
369
                (const_string "true")
370
                (const_string "false")))
371
 
372
(define_attr "in_annul_slot_2" "false,true"
373
  (if_then_else (and (and (eq_attr "cpu" "c4x")
374
                          (eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,push,pop,ldp,multi"))
375
                     (eq_attr "onlyreg_nomod" "true"))
376
                (const_string "true")
377
                (const_string "false")))
378
 
379
/* Disable ldp because the c4x contains a bug. The ldp insn modifies
380
   the dp register when the insn is anulled or not.
381
   Also disable autoincrement insns because of a silicon bug.  */
382
(define_attr "in_annul_slot_3" "false,true"
383
  (if_then_else (and (and (eq_attr "cpu" "c4x")
384
                          (eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,push,pop,ldp,multi"))
385
                     (eq_attr "onlyreg_nomod" "true"))
386
                (const_string "true")
387
                (const_string "false")))
388
 
389
(define_attr "in_delay_slot" "false,true"
390
  (if_then_else (eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,multi")
391
                (const_string "true")
392
                (const_string "false")))
393
 
394
(define_attr "in_repeat_slot" "false,true"
395
  (if_then_else (and (eq_attr "cpu" "c4x")
396
                     (and (eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,multi")
397
                          (eq_attr "not_repeat_reg" "true")))
398
                (const_string "true")
399
                (const_string "false")))
400
 
401
(define_attr "in_dbc_slot" "false,true"
402
  (if_then_else (eq_attr "type" "!jump,call,rets,jmpc,unarycc,binarycc,compare,db,dbc,repeat,repeat_top,laj,multi")
403
                (const_string "true")
404
                (const_string "false")))
405
 
406
(define_delay (eq_attr "type" "jmpc")
407
              [(eq_attr "in_delay_slot" "true")
408
               (eq_attr "in_annul_slot_1" "true")
409
               (eq_attr "in_annul_slot_1" "true")
410
 
411
               (eq_attr "in_delay_slot" "true")
412
               (eq_attr "in_annul_slot_2" "true")
413
               (eq_attr "in_annul_slot_2" "true")
414
 
415
               (eq_attr "in_delay_slot" "true")
416
               (eq_attr "in_annul_slot_3" "true")
417
               (eq_attr "in_annul_slot_3" "true") ])
418
 
419
 
420
(define_delay (eq_attr "type" "repeat_top")
421
              [(eq_attr "in_repeat_slot" "true") (nil) (nil)
422
               (eq_attr "in_repeat_slot" "true") (nil) (nil)
423
               (eq_attr "in_repeat_slot" "true") (nil) (nil)])
424
 
425
(define_delay (eq_attr "type" "jump,db")
426
              [(eq_attr "in_delay_slot" "true") (nil) (nil)
427
               (eq_attr "in_delay_slot" "true") (nil) (nil)
428
               (eq_attr "in_delay_slot" "true") (nil) (nil)])
429
 
430
 
431
; Decrement and branch conditional instructions cannot modify the
432
; condition codes for the cycles in the delay slots.
433
;
434
(define_delay (eq_attr "type" "dbc")
435
              [(eq_attr "in_dbc_slot" "true") (nil) (nil)
436
               (eq_attr "in_dbc_slot" "true") (nil) (nil)
437
               (eq_attr "in_dbc_slot" "true") (nil) (nil)])
438
 
439
; The LAJ instruction has three delay slots but the last slot is
440
; used for pushing the return address.  Thus we can only use two slots.
441
;
442
(define_delay (eq_attr "type" "laj")
443
              [(eq_attr "in_delay_slot" "true") (nil) (nil)
444
               (eq_attr "in_delay_slot" "true") (nil) (nil)])
445
 
446
;
447
; C4x UNSPEC NUMBERS
448
;
449
(define_constants
450
  [
451
   (UNSPEC_BU                   1)
452
   (UNSPEC_RPTS                 2)
453
   (UNSPEC_LSH                  3)
454
   (UNSPEC_CMPHI                4)
455
   (UNSPEC_RCPF                 5)
456
   (UNSPEC_RND                  6)
457
   (UNSPEC_RPTB_FILL            7)
458
   (UNSPEC_LOADHF_INT           8)
459
   (UNSPEC_STOREHF_INT          9)
460
   (UNSPEC_RSQRF                10)
461
   (UNSPEC_LOADQF_INT           11)
462
   (UNSPEC_STOREQF_INT          12)
463
   (UNSPEC_LDIV                 13)
464
   (UNSPEC_PUSH_ST              14)
465
   (UNSPEC_POP_ST               15)
466
   (UNSPEC_PUSH_DP              16)
467
   (UNSPEC_POP_DP               17)
468
   (UNSPEC_POPQI                18)
469
   (UNSPEC_POPQF                19)
470
   (UNSPEC_ANDN_ST              20)
471
   (UNSPEC_RPTB_INIT            22)
472
   (UNSPEC_TOIEEE               23)
473
   (UNSPEC_FRIEEE               24)
474
  ])
475
 
476
;
477
; C4x PIPELINE MODEL
478
;
479
; With the C3x, an external memory write (with no wait states) takes
480
; two cycles and an external memory read (with no wait states) takes
481
; one cycle.  However, an external read following an external write
482
; takes two cycles.  With internal memory, reads and writes take
483
; half a cycle.
484
; When a C4x address register is loaded it will not be available for
485
; an extra machine cycle.  Calculating with a C4x address register
486
; makes it unavailable for 2 machine cycles.
487
;
488
; Just some dummy definitions. The real work is done in c4x_adjust_cost.
489
; These are needed so the min/max READY_DELAY is known.
490
 
491
(define_insn_reservation "any_insn" 1 (const_int 1) "nothing")
492
(define_insn_reservation "slowest_insn" 3 (const_int 0) "nothing")
493
 
494
; The attribute setar0 is set to 1 for insns where ar0 is a dst operand.
495
; Note that the attributes unarycc and binarycc do not apply
496
; if ar0 is a dst operand (only loading an ext. prec. reg. sets CC)
497
(define_attr "setar0" ""
498
       (cond [(eq_attr "type" "unary,binary")
499
                       (if_then_else (match_operand 0 "ar0_reg_operand" "")
500
                                     (const_int 1) (const_int 0))]
501
             (const_int 0)))
502
 
503
(define_attr "setlda_ar0" ""
504
       (cond [(eq_attr "type" "lda")
505
                       (if_then_else (match_operand 0 "ar0_reg_operand" "")
506
                                     (const_int 1) (const_int 0))]
507
             (const_int 0)))
508
 
509
; The attribute usear0 is set to 1 for insns where ar0 is used
510
; for addressing, as a src operand, or as a dst operand.
511
(define_attr "usear0" ""
512
       (cond [(eq_attr "type" "compare,store")
513
                       (if_then_else (match_operand 0 "ar0_mem_operand" "")
514
                                     (const_int 1) (const_int 0))
515
              (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
516
                       (if_then_else (match_operand 1 "ar0_mem_operand" "")
517
                                     (const_int 1) (const_int 0))
518
              (eq_attr "type" "binary,binarycc")
519
                       (if_then_else (match_operand 2 "ar0_mem_operand" "")
520
                                     (const_int 1) (const_int 0))
521
              (eq_attr "type" "db,dbc")
522
                       (if_then_else (match_operand 0 "ar0_reg_operand" "")
523
                                     (const_int 1) (const_int 0))]
524
             (const_int 0)))
525
 
526
; The attribute readar0 is set to 1 for insns where ar0 is a src operand.
527
(define_attr "readar0" ""
528
       (cond [(eq_attr "type" "compare")
529
                       (if_then_else (match_operand 0 "ar0_reg_operand" "")
530
                                     (const_int 1) (const_int 0))
531
              (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
532
                       (if_then_else (match_operand 1 "ar0_reg_operand" "")
533
                                     (const_int 1) (const_int 0))
534
              (eq_attr "type" "binary,binarycc")
535
                       (if_then_else (match_operand 2 "ar0_reg_operand" "")
536
                                     (const_int 1) (const_int 0))]
537
             (const_int 0)))
538
 
539
(define_attr "setar1" ""
540
       (cond [(eq_attr "type" "unary,binary")
541
                       (if_then_else (match_operand 0 "ar1_reg_operand" "")
542
                                     (const_int 1) (const_int 0))]
543
             (const_int 0)))
544
 
545
(define_attr "setlda_ar1" ""
546
       (cond [(eq_attr "type" "lda")
547
                       (if_then_else (match_operand 0 "ar1_reg_operand" "")
548
                                     (const_int 1) (const_int 0))]
549
             (const_int 0)))
550
 
551
(define_attr "usear1" ""
552
       (cond [(eq_attr "type" "compare,store")
553
                       (if_then_else (match_operand 0 "ar1_mem_operand" "")
554
                                     (const_int 1) (const_int 0))
555
              (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
556
                       (if_then_else (match_operand 1 "ar1_mem_operand" "")
557
                                     (const_int 1) (const_int 0))
558
              (eq_attr "type" "binary,binarycc")
559
                       (if_then_else (match_operand 2 "ar1_mem_operand" "")
560
                                     (const_int 1) (const_int 0))
561
              (eq_attr "type" "db,dbc")
562
                       (if_then_else (match_operand 0 "ar1_reg_operand" "")
563
                                     (const_int 1) (const_int 0))]
564
             (const_int 0)))
565
 
566
(define_attr "readar1" ""
567
       (cond [(eq_attr "type" "compare")
568
                       (if_then_else (match_operand 0 "ar1_reg_operand" "")
569
                                     (const_int 1) (const_int 0))
570
              (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
571
                       (if_then_else (match_operand 1 "ar1_reg_operand" "")
572
                                     (const_int 1) (const_int 0))
573
              (eq_attr "type" "binary,binarycc")
574
                       (if_then_else (match_operand 2 "ar1_reg_operand" "")
575
                                     (const_int 1) (const_int 0))]
576
             (const_int 0)))
577
 
578
(define_attr "setar2" ""
579
       (cond [(eq_attr "type" "unary,binary")
580
                       (if_then_else (match_operand 0 "ar2_reg_operand" "")
581
                                     (const_int 1) (const_int 0))]
582
             (const_int 0)))
583
 
584
(define_attr "setlda_ar2" ""
585
       (cond [(eq_attr "type" "lda")
586
                       (if_then_else (match_operand 0 "ar2_reg_operand" "")
587
                                     (const_int 1) (const_int 0))]
588
             (const_int 0)))
589
 
590
(define_attr "usear2" ""
591
       (cond [(eq_attr "type" "compare,store")
592
                       (if_then_else (match_operand 0 "ar2_mem_operand" "")
593
                                     (const_int 1) (const_int 0))
594
              (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
595
                       (if_then_else (match_operand 1 "ar2_mem_operand" "")
596
                                     (const_int 1) (const_int 0))
597
              (eq_attr "type" "binary,binarycc")
598
                       (if_then_else (match_operand 2 "ar2_mem_operand" "")
599
                                     (const_int 1) (const_int 0))
600
              (eq_attr "type" "db,dbc")
601
                       (if_then_else (match_operand 0 "ar2_reg_operand" "")
602
                                     (const_int 1) (const_int 0))]
603
             (const_int 0)))
604
 
605
(define_attr "readar2" ""
606
       (cond [(eq_attr "type" "compare")
607
                       (if_then_else (match_operand 0 "ar2_reg_operand" "")
608
                                     (const_int 1) (const_int 0))
609
              (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
610
                       (if_then_else (match_operand 1 "ar2_reg_operand" "")
611
                                     (const_int 1) (const_int 0))
612
              (eq_attr "type" "binary,binarycc")
613
                       (if_then_else (match_operand 2 "ar2_reg_operand" "")
614
                                     (const_int 1) (const_int 0))]
615
             (const_int 0)))
616
 
617
(define_attr "setar3" ""
618
       (cond [(eq_attr "type" "unary,binary")
619
                       (if_then_else (match_operand 0 "ar3_reg_operand" "")
620
                                     (const_int 1) (const_int 0))]
621
             (const_int 0)))
622
 
623
(define_attr "setlda_ar3" ""
624
       (cond [(eq_attr "type" "lda")
625
                       (if_then_else (match_operand 0 "ar3_reg_operand" "")
626
                                     (const_int 1) (const_int 0))]
627
             (const_int 0)))
628
 
629
(define_attr "usear3" ""
630
       (cond [(eq_attr "type" "compare,store")
631
                       (if_then_else (match_operand 0 "ar3_mem_operand" "")
632
                                     (const_int 1) (const_int 0))
633
              (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
634
                       (if_then_else (match_operand 1 "ar3_mem_operand" "")
635
                                     (const_int 1) (const_int 0))
636
              (eq_attr "type" "binary,binarycc")
637
                       (if_then_else (match_operand 2 "ar3_mem_operand" "")
638
                                     (const_int 1) (const_int 0))
639
              (eq_attr "type" "db,dbc")
640
                       (if_then_else (match_operand 0 "ar3_reg_operand" "")
641
                                     (const_int 1) (const_int 0))]
642
             (const_int 0)))
643
 
644
(define_attr "readar3" ""
645
       (cond [(eq_attr "type" "compare")
646
                       (if_then_else (match_operand 0 "ar3_reg_operand" "")
647
                                     (const_int 1) (const_int 0))
648
              (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
649
                       (if_then_else (match_operand 1 "ar3_reg_operand" "")
650
                                     (const_int 1) (const_int 0))
651
              (eq_attr "type" "binary,binarycc")
652
                       (if_then_else (match_operand 2 "ar3_reg_operand" "")
653
                                     (const_int 1) (const_int 0))]
654
             (const_int 0)))
655
 
656
(define_attr "setar4" ""
657
       (cond [(eq_attr "type" "unary,binary")
658
                       (if_then_else (match_operand 0 "ar4_reg_operand" "")
659
                                     (const_int 1) (const_int 0))]
660
             (const_int 0)))
661
 
662
(define_attr "setlda_ar4" ""
663
       (cond [(eq_attr "type" "lda")
664
                       (if_then_else (match_operand 0 "ar4_reg_operand" "")
665
                                     (const_int 1) (const_int 0))]
666
             (const_int 0)))
667
 
668
(define_attr "usear4" ""
669
       (cond [(eq_attr "type" "compare,store")
670
                       (if_then_else (match_operand 0 "ar4_mem_operand" "")
671
                                     (const_int 1) (const_int 0))
672
              (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
673
                       (if_then_else (match_operand 1 "ar4_mem_operand" "")
674
                                     (const_int 1) (const_int 0))
675
              (eq_attr "type" "binary,binarycc")
676
                       (if_then_else (match_operand 2 "ar4_mem_operand" "")
677
                                     (const_int 1) (const_int 0))
678
              (eq_attr "type" "db,dbc")
679
                       (if_then_else (match_operand 0 "ar4_reg_operand" "")
680
                                     (const_int 1) (const_int 0))]
681
             (const_int 0)))
682
 
683
(define_attr "readar4" ""
684
       (cond [(eq_attr "type" "compare")
685
                       (if_then_else (match_operand 0 "ar4_reg_operand" "")
686
                                     (const_int 1) (const_int 0))
687
              (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
688
                       (if_then_else (match_operand 1 "ar4_reg_operand" "")
689
                                     (const_int 1) (const_int 0))
690
              (eq_attr "type" "binary,binarycc")
691
                       (if_then_else (match_operand 2 "ar4_reg_operand" "")
692
                                     (const_int 1) (const_int 0))]
693
             (const_int 0)))
694
 
695
(define_attr "setar5" ""
696
       (cond [(eq_attr "type" "unary,binary")
697
                       (if_then_else (match_operand 0 "ar5_reg_operand" "")
698
                                     (const_int 1) (const_int 0))]
699
             (const_int 0)))
700
 
701
(define_attr "setlda_ar5" ""
702
       (cond [(eq_attr "type" "lda")
703
                       (if_then_else (match_operand 0 "ar5_reg_operand" "")
704
                                     (const_int 1) (const_int 0))]
705
             (const_int 0)))
706
 
707
(define_attr "usear5" ""
708
       (cond [(eq_attr "type" "compare,store")
709
                       (if_then_else (match_operand 0 "ar5_mem_operand" "")
710
                                     (const_int 1) (const_int 0))
711
              (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
712
                       (if_then_else (match_operand 1 "ar5_mem_operand" "")
713
                                     (const_int 1) (const_int 0))
714
              (eq_attr "type" "binary,binarycc")
715
                       (if_then_else (match_operand 2 "ar5_mem_operand" "")
716
                                     (const_int 1) (const_int 0))
717
              (eq_attr "type" "db,dbc")
718
                       (if_then_else (match_operand 0 "ar5_reg_operand" "")
719
                                     (const_int 1) (const_int 0))]
720
             (const_int 0)))
721
 
722
(define_attr "readar5" ""
723
       (cond [(eq_attr "type" "compare")
724
                       (if_then_else (match_operand 0 "ar5_reg_operand" "")
725
                                     (const_int 1) (const_int 0))
726
              (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
727
                       (if_then_else (match_operand 1 "ar5_reg_operand" "")
728
                                     (const_int 1) (const_int 0))
729
              (eq_attr "type" "binary,binarycc")
730
                       (if_then_else (match_operand 2 "ar5_reg_operand" "")
731
                                     (const_int 1) (const_int 0))]
732
             (const_int 0)))
733
 
734
(define_attr "setar6" ""
735
       (cond [(eq_attr "type" "unary,binary")
736
                       (if_then_else (match_operand 0 "ar6_reg_operand" "")
737
                                     (const_int 1) (const_int 0))]
738
             (const_int 0)))
739
 
740
(define_attr "setlda_ar6" ""
741
       (cond [(eq_attr "type" "lda")
742
                       (if_then_else (match_operand 0 "ar6_reg_operand" "")
743
                                     (const_int 1) (const_int 0))]
744
             (const_int 0)))
745
 
746
(define_attr "usear6" ""
747
       (cond [(eq_attr "type" "compare,store")
748
                       (if_then_else (match_operand 0 "ar6_mem_operand" "")
749
                                     (const_int 1) (const_int 0))
750
              (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
751
                       (if_then_else (match_operand 1 "ar6_mem_operand" "")
752
                                     (const_int 1) (const_int 0))
753
              (eq_attr "type" "binary,binarycc")
754
                       (if_then_else (match_operand 2 "ar6_mem_operand" "")
755
                                     (const_int 1) (const_int 0))
756
              (eq_attr "type" "db,dbc")
757
                       (if_then_else (match_operand 0 "ar6_reg_operand" "")
758
                                     (const_int 1) (const_int 0))]
759
             (const_int 0)))
760
 
761
(define_attr "readar6" ""
762
       (cond [(eq_attr "type" "compare")
763
                       (if_then_else (match_operand 0 "ar6_reg_operand" "")
764
                                     (const_int 1) (const_int 0))
765
              (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
766
                       (if_then_else (match_operand 1 "ar6_reg_operand" "")
767
                                     (const_int 1) (const_int 0))
768
              (eq_attr "type" "binary,binarycc")
769
                       (if_then_else (match_operand 2 "ar6_reg_operand" "")
770
                                     (const_int 1) (const_int 0))]
771
             (const_int 0)))
772
 
773
(define_attr "setar7" ""
774
       (cond [(eq_attr "type" "unary,binary")
775
                       (if_then_else (match_operand 0 "ar7_reg_operand" "")
776
                                     (const_int 1) (const_int 0))]
777
             (const_int 0)))
778
 
779
(define_attr "setlda_ar7" ""
780
       (cond [(eq_attr "type" "lda")
781
                       (if_then_else (match_operand 0 "ar7_reg_operand" "")
782
                                     (const_int 1) (const_int 0))]
783
             (const_int 0)))
784
 
785
(define_attr "usear7" ""
786
       (cond [(eq_attr "type" "compare,store")
787
                       (if_then_else (match_operand 0 "ar7_mem_operand" "")
788
                                     (const_int 1) (const_int 0))
789
              (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
790
                       (if_then_else (match_operand 1 "ar7_mem_operand" "")
791
                                     (const_int 1) (const_int 0))
792
              (eq_attr "type" "binary,binarycc")
793
                       (if_then_else (match_operand 2 "ar7_mem_operand" "")
794
                                     (const_int 1) (const_int 0))
795
              (eq_attr "type" "db,dbc")
796
                       (if_then_else (match_operand 0 "ar7_reg_operand" "")
797
                                     (const_int 1) (const_int 0))]
798
             (const_int 0)))
799
 
800
(define_attr "readar7" ""
801
       (cond [(eq_attr "type" "compare")
802
                       (if_then_else (match_operand 0 "ar7_reg_operand" "")
803
                                     (const_int 1) (const_int 0))
804
              (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
805
                       (if_then_else (match_operand 1 "ar7_reg_operand" "")
806
                                     (const_int 1) (const_int 0))
807
              (eq_attr "type" "binary,binarycc")
808
                       (if_then_else (match_operand 2 "ar7_reg_operand" "")
809
                                     (const_int 1) (const_int 0))]
810
             (const_int 0)))
811
 
812
(define_attr "setir0" ""
813
       (cond [(eq_attr "type" "unary,binary")
814
                       (if_then_else (match_operand 0 "ir0_reg_operand" "")
815
                                     (const_int 1) (const_int 0))]
816
             (const_int 0)))
817
 
818
(define_attr "setlda_ir0" ""
819
       (cond [(eq_attr "type" "lda")
820
                       (if_then_else (match_operand 0 "ir0_reg_operand" "")
821
                                     (const_int 1) (const_int 0))]
822
             (const_int 0)))
823
 
824
(define_attr "useir0" ""
825
       (cond [(eq_attr "type" "compare,store")
826
                       (if_then_else (match_operand 0 "ir0_mem_operand" "")
827
                                     (const_int 1) (const_int 0))
828
              (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
829
                       (if_then_else (match_operand 1 "ir0_mem_operand" "")
830
                                     (const_int 1) (const_int 0))
831
              (eq_attr "type" "binary,binarycc")
832
                       (if_then_else (match_operand 2 "ir0_mem_operand" "")
833
                                     (const_int 1) (const_int 0))]
834
             (const_int 0)))
835
 
836
(define_attr "setir1" ""
837
       (cond [(eq_attr "type" "unary,binary")
838
                       (if_then_else (match_operand 0 "ir1_reg_operand" "")
839
                                     (const_int 1) (const_int 0))]
840
             (const_int 0)))
841
 
842
(define_attr "setlda_ir1" ""
843
       (cond [(eq_attr "type" "lda")
844
                       (if_then_else (match_operand 0 "ir1_reg_operand" "")
845
                                     (const_int 1) (const_int 0))]
846
             (const_int 0)))
847
 
848
(define_attr "useir1" ""
849
       (cond [(eq_attr "type" "compare,store")
850
                       (if_then_else (match_operand 0 "ir1_mem_operand" "")
851
                                     (const_int 1) (const_int 0))
852
              (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc")
853
                       (if_then_else (match_operand 1 "ir1_mem_operand" "")
854
                                     (const_int 1) (const_int 0))
855
              (eq_attr "type" "binary,binarycc")
856
                       (if_then_else (match_operand 2 "ir1_mem_operand" "")
857
                                     (const_int 1) (const_int 0))]
858
             (const_int 0)))
859
 
860
; With the C3x, things are simpler but slower, i.e. more pipeline conflicts :(
861
; There are three functional groups:
862
; (1) AR0-AR7, IR0-IR1, BK
863
; (2) DP
864
; (3) SP
865
;
866
; When a register in one of these functional groups is loaded,
867
; the contents of that or any other register in its group
868
; will not be available to the next instruction for 2 machine cycles.
869
; Similarly, when a register in one of the functional groups is read
870
; excepting (IR0-IR1, BK, DP) the contents of that or any other register
871
; in its group will not be available to the next instruction for
872
; 1 machine cycle.
873
;
874
; Let's ignore functional groups 2 and 3 for now, since they are not
875
; so important.
876
 
877
(define_attr "setgroup1" ""
878
       (cond [(eq_attr "type" "lda,unary,binary")
879
                  (if_then_else (match_operand 0 "group1_reg_operand" "")
880
                                (const_int 1) (const_int 0))]
881
             (const_int 0)))
882
 
883
(define_attr "usegroup1" ""
884
       (cond [(eq_attr "type" "compare,store,store_store,store_load")
885
              (if_then_else (match_operand 0 "group1_mem_operand" "")
886
                            (const_int 1) (const_int 0))
887
              (eq_attr "type" "compare,lda,unary,unarycc,binary,binarycc,load_load,load_store")
888
              (if_then_else (match_operand 1 "group1_mem_operand" "")
889
                            (const_int 1) (const_int 0))
890
              (eq_attr "type" "store_store,load_store")
891
              (if_then_else (match_operand 2 "group1_mem_operand" "")
892
                            (const_int 1) (const_int 0))
893
              (eq_attr "type" "load_load,store_load")
894
              (if_then_else (match_operand 3 "group1_mem_operand" "")
895
                            (const_int 1) (const_int 0))]
896
             (const_int 0)))
897
 
898
(define_attr "readarx" ""
899
       (cond [(eq_attr "type" "compare")
900
              (if_then_else (match_operand 0 "arx_reg_operand" "")
901
                            (const_int 1) (const_int 0))
902
              (eq_attr "type" "compare,store,lda,unary,unarycc,binary,binarycc")
903
              (if_then_else (match_operand 1 "arx_reg_operand" "")
904
                            (const_int 1) (const_int 0))
905
              (eq_attr "type" "binary,binarycc")
906
              (if_then_else (match_operand 2 "arx_reg_operand" "")
907
                            (const_int 1) (const_int 0))]
908
             (const_int 0)))
909
 
910
(include "predicates.md")
911
 
912
;
913
; C4x INSN PATTERNS:
914
;
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.
918
 
919
;
920
; TWO OPERAND INTEGER INSTRUCTIONS
921
;
922
 
923
;
924
; LDP/LDPK
925
;
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")])
932
 
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")])
939
 
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")])
946
 
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")])
954
 
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
  "")
962
 
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
  "
975
{
976
   operands[2] = GEN_INT (INTVAL (operands[1]) & ~0xffff);
977
   operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
978
}")
979
 
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
  "
991
{
992
   operands[2] = GEN_INT (INTVAL (operands[1]) & ~0xffff);
993
   operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
994
}")
995
 
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
  "
1009
{
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);
1015
}")
1016
 
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
  "
1029
{
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);
1035
}")
1036
 
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
  "
1049
{
1050
   /* Generate two's complement value of MSBs.  */
1051
   int shift = c4x_shiftable_constant (operands[1]);
1052
 
1053
   operands[2] = GEN_INT ((((INTVAL (operands[1]) >> shift) & 0xffff)
1054
                           - 0x8000) ^ ~0x7fff);
1055
   operands[3] = GEN_INT (shift);
1056
}")
1057
 
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
  "
1069
{
1070
   /* Generate two's complement value of MSBs.  */
1071
   int shift = c4x_shiftable_constant (operands[1]);
1072
 
1073
   operands[2] = GEN_INT ((((INTVAL (operands[1]) >> shift) & 0xffff)
1074
                            - 0x8000) ^ ~0x7fff);
1075
   operands[3] = GEN_INT (shift);
1076
}")
1077
 
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
  "
1091
{
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);
1099
}")
1100
 
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
  "
1113
{
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);
1121
}")
1122
 
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
  "
1136
{
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)));
1142
}")
1143
 
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
  "
1156
{
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)));
1162
}")
1163
 
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
  "
1172
{
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);
1177
}")
1178
 
1179
 
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")])
1189
 
1190
 
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
  "")
1199
 
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
  "
1215
{
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);
1223
}")
1224
 
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)));
1243
}")
1244
 
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")])
1252
 
1253
;
1254
; LDIU/LDA/STI/STIK
1255
;
1256
; The following moves will not set the condition codes register.
1257
;
1258
 
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")])
1266
 
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")])
1275
 
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\";
1288
 
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
     }
1294
 
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")])
1307
 
1308
;
1309
; LDI
1310
;
1311
 
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")])
1322
 
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")])
1333
 
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")])
1346
 
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.
1352
 
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.
1356
 
1357
(define_expand "movqi"
1358
  [(set (match_operand:QI 0 "general_operand" "")
1359
        (match_operand:QI 1 "general_operand" ""))]
1360
  ""
1361
  "
1362
{
1363
  if (c4x_emit_move_sequence (operands, QImode))
1364
    DONE;
1365
}")
1366
 
1367
 
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")])
1392
 
1393
;
1394
; PUSH/POP
1395
;
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")])
1402
 
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")])
1410
 
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")])
1418
 
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")])
1426
 
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")])
1434
 
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")])
1442
 
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")])
1451
 
1452
;
1453
; ABSI
1454
;
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
  "")
1461
 
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")])
1470
 
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")])
1478
 
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
  "")
1487
 
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")])
1497
 
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")])
1508
 
1509
;
1510
; NEGI
1511
;
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))])]
1516
""
1517
"")
1518
 
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")])
1527
 
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")])
1535
 
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
  "")
1544
 
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")])
1554
 
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")])
1565
 
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")])
1575
 
1576
;
1577
; NOT
1578
;
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
  "")
1585
 
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")])
1594
 
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")])
1602
 
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
  "")
1611
 
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")])
1621
 
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")])
1632
 
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")])
1643
 
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")])
1663
 
1664
;
1665
; ROL
1666
;
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;
1679
 
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.  */
1684
 
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
     }")
1695
 
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.
1705
 
1706
;
1707
; ROR
1708
;
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;
1721
 
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.  */
1726
 
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
     }")
1737
 
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.
1747
 
1748
 
1749
;
1750
; THREE OPERAND INTEGER INSTRUCTIONS
1751
;
1752
 
1753
;
1754
; ADDI
1755
;
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.
1758
;
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
   }")
1773
 
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.
1790
 
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.
1806
 
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
  "")
1817
 
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.
1831
 
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")])
1858
 
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.
1873
 
1874
 
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.
1899
 
1900
 
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.
1917
 
1918
 
1919
;
1920
; SUBI/SUBRI
1921
;
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);")
1929
 
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.
1947
 
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
  "")
1958
 
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.
1973
 
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.
2005
 
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.
2018
 
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.
2037
 
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.
2055
 
2056
;
2057
; MPYI
2058
;
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
  ")
2094
 
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.
2115
 
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.
2137
 
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.
2161
 
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.
2184
 
2185
 
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
  ")
2222
 
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
  ")
2284
 
2285
;
2286
; MPYSHI (C4x only)
2287
;
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
 ")
2305
 
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")])
2325
 
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")])
2341
 
2342
;
2343
; MPYUHI (C4x only)
2344
;
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
 ")
2364
 
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")])
2386
 
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")])
2404
 
2405
;
2406
; AND
2407
;
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);")
2415
 
2416
 
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")])
2425
 
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")])
2433
 
2434
 
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")])
2443
 
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")])
2451
 
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")])
2469
 
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")])
2482
 
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")])
2494
 
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
  "")
2505
 
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")])
2520
 
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")])
2553
 
2554
;
2555
; ANDN
2556
;
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")])
2575
 
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")])
2587
 
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
  "")
2598
 
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")])
2612
 
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")])
2628
 
2629
;
2630
; OR
2631
;
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);")
2639
 
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")])
2655
 
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
  "")
2666
 
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")])
2680
 
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")])
2711
 
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")])
2724
 
2725
;
2726
; XOR
2727
;
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);")
2735
 
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")])
2751
 
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")])
2763
 
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
  "")
2774
 
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")])
2788
 
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")])
2804
 
2805
;
2806
; LSH/ASH (left)
2807
;
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);")
2824
 
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.
2840
 
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.
2857
 
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.
2869
 
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
  "")
2880
 
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.
2898
 
2899
;
2900
; LSH (right)
2901
;
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.
2905
;
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);")
2913
 
2914
 
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")])
2923
 
2924
 
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")])
2933
 
2934
 
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")])
2943
 
2944
 
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")])
2953
 
2954
 
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")])
2969
 
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")])
2979
 
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")])
2996
 
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.
3012
 
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.
3024
 
3025
;
3026
; ASH (right)
3027
;
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.
3031
 
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);")
3039
 
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")])
3054
 
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")])
3064
 
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")])
3081
 
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.
3097
 
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.
3109
 
3110
;
3111
; CMPI
3112
;
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.
3122
;
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;")
3132
 
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")])
3143
 
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")])
3154
 
3155
 
3156
;
3157
; BIT-FIELD INSTRUCTIONS
3158
;
3159
 
3160
;
3161
; LBx/LHw (C4x only)
3162
;
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
 ")
3174
 
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")])
3195
 
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")])
3217
 
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")])
3242
 
3243
;
3244
; LBUx/LHUw (C4x only)
3245
;
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
 ")
3257
 
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")])
3278
 
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")])
3300
 
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")])
3327
 
3328
;
3329
; MBx/MHw (C4x only)
3330
;
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
 ")
3343
 
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")])
3372
 
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")])
3395
 
3396
 
3397
; TWO OPERAND FLOAT INSTRUCTIONS
3398
;
3399
 
3400
;
3401
; LDF/STF
3402
;
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
 ""
3412
 "
3413
{
3414
  if (c4x_emit_move_sequence (operands, QFmode))
3415
    DONE;
3416
}")
3417
 
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);")
3428
 
3429
 
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")])
3436
 
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
  "")
3448
 
3449
 
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")
3461
 
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")])
3469
 
3470
 
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);")
3481
 
3482
 
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")])
3489
 
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
  "")
3501
 
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")])
3509
 
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")])
3520
 
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")])
3528
 
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")])
3537
 
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")])
3547
 
3548
 
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")])
3561
 
3562
 
3563
;
3564
; PUSH/POP
3565
;
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")])
3572
 
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")])
3580
 
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")])
3589
 
3590
;
3591
; ABSF
3592
;
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))])]
3597
""
3598
"")
3599
 
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")])
3607
 
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")])
3616
 
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)))]
3623
 
3624
  ""
3625
  "absf\\t%1,%0"
3626
  [(set_attr "type" "unarycc")])
3627
 
3628
;
3629
; NEGF
3630
;
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))])]
3635
""
3636
"")
3637
 
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")])
3645
 
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")])
3654
 
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")])
3664
 
3665
;
3666
; FLOAT
3667
;
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")])
3675
 
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")])
3685
 
3686
; Unsigned conversions are a little tricky because we need to
3687
; add the value for the high bit if necessary.
3688
;
3689
;
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));")
3710
 
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));")
3731
 
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")])
3739
 
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")])
3749
 
3750
;
3751
; FIX
3752
;
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")])
3760
 
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")])
3770
 
3771
;
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
3774
;
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
 ")
3802
 
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;")
3810
 
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));")
3832
 
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;")
3841
 
3842
;
3843
; RCPF
3844
;
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")])
3852
 
3853
;
3854
; RSQRF
3855
;
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")])
3863
 
3864
;
3865
; RNDF
3866
;
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")])
3874
 
3875
 
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);")
3913
 
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;")
3921
 
3922
;
3923
; TOIEEE / FRIEEE
3924
;
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")
3931
 
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")
3938
 
3939
;
3940
; THREE OPERAND FLOAT INSTRUCTIONS
3941
;
3942
 
3943
;
3944
; ADDF
3945
;
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);")
3953
 
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")])
3965
 
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")])
3978
 
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")])
3993
 
3994
;
3995
; SUBF/SUBRF
3996
;
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);")
4004
 
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")])
4017
 
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")])
4031
 
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")])
4047
 
4048
;
4049
; MPYF
4050
;
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);")
4058
 
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")])
4070
 
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")])
4083
 
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")])
4098
 
4099
;
4100
; CMPF
4101
;
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;")
4111
 
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")])
4122
 
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")])
4133
 
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);")
4165
 
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;")
4174
 
4175
;
4176
; CONDITIONAL MOVES
4177
;
4178
 
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.
4182
 
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")])
4194
 
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")])
4210
 
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")])
4218
 
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).
4223
;
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")])
4251
 
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")])
4267
 
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;}")
4283
 
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")])
4295
 
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")])
4310
 
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;}")
4326
 
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);")
4336
 
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);")
4346
 
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;")
4357
 
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);")
4367
 
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;")
4378
 
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);")
4388
 
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;")
4399
 
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);")
4409
 
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;")
4420
 
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);")
4430
 
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
  "")
4441
 
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
  "")
4452
 
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")])
4459
 
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
 
4485
;
4486
; PARALLEL FLOAT INSTRUCTIONS
4487
;
4488
; This patterns are under development
4489
 
4490
;
4491
; ABSF/STF
4492
;
4493
 
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")])
4503
 
4504
;
4505
; ADDF/STF
4506
;
4507
 
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")])
4518
 
4519
;
4520
; FLOAT/STF
4521
;
4522
 
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")])
4532
 
4533
;
4534
; MPYF/ADDF
4535
;
4536
 
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")])
4548
 
4549
 
4550
;
4551
; MPYF/STF
4552
;
4553
 
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")])
4564
 
4565
;
4566
; MPYF/SUBF
4567
;
4568
 
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")])
4580
 
4581
;
4582
; MPYF/LDF 0
4583
;
4584
 
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")])
4595
 
4596
;
4597
; NEGF/STF
4598
;
4599
 
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")])
4609
 
4610
;
4611
; SUBF/STF
4612
;
4613
 
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")])
4624
 
4625
;
4626
; TOIEEE/STF
4627
;
4628
 
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")])
4638
 
4639
;
4640
; FRIEEE/STF
4641
;
4642
 
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")])
4652
 
4653
;
4654
; PARALLEL INTEGER INSTRUCTIONS
4655
;
4656
 
4657
;
4658
; ABSI/STI
4659
;
4660
 
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")])
4670
 
4671
;
4672
; ADDI/STI
4673
;
4674
 
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")])
4685
 
4686
;
4687
; AND/STI
4688
;
4689
 
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")])
4700
 
4701
;
4702
; ASH(left)/STI
4703
;
4704
 
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")])
4715
 
4716
;
4717
; ASH(right)/STI
4718
;
4719
 
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")])
4730
 
4731
;
4732
; FIX/STI
4733
;
4734
 
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")])
4744
 
4745
;
4746
; LSH(right)/STI
4747
;
4748
 
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")])
4759
 
4760
;
4761
; MPYI/ADDI
4762
;
4763
 
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")])
4776
 
4777
 
4778
;
4779
; MPYI/STI
4780
;
4781
 
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")])
4793
 
4794
;
4795
; MPYI/SUBI
4796
;
4797
 
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")])
4810
 
4811
;
4812
; MPYI/LDI 0
4813
;
4814
 
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")])
4825
 
4826
;
4827
; NEGI/STI
4828
;
4829
 
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")])
4839
 
4840
;
4841
; NOT/STI
4842
;
4843
 
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")])
4853
 
4854
;
4855
; OR/STI
4856
;
4857
 
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")])
4868
 
4869
;
4870
; SUBI/STI
4871
;
4872
 
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")])
4883
 
4884
;
4885
; XOR/STI
4886
;
4887
 
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")])
4898
 
4899
;
4900
; BRANCH/CALL INSTRUCTIONS
4901
;
4902
 
4903
;
4904
; Branch instructions
4905
;
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")])
4915
 
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")])
4925
 
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")])
4938
 
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")])
4951
 
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);")
4958
 
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);")
4965
 
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;")
4973
 
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);")
4980
 
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;")
4988
 
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);")
4995
 
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;")
5003
 
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);")
5010
 
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;")
5018
 
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);")
5025
 
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")])
5031
 
5032
(define_expand "indirect_jump"
5033
 [(set (pc) (match_operand:QI 0 "reg_operand" ""))]
5034
 ""
5035
 "")
5036
 
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")])
5043
 
5044
;
5045
; CALL
5046
;
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.
5052
 
5053
  "TARGET_C3X"
5054
  "call%U0\\t%C0"
5055
  [(set_attr "type" "call")])
5056
 
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.
5063
 
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")])
5072
 
5073
(define_expand "call"
5074
 [(parallel [(call (match_operand:QI 0 "" "")
5075
                   (match_operand:QI 1 "general_operand" ""))
5076
             (clobber (reg:QI 31))])]
5077
 ""
5078
 "
5079
{
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)));
5084
}")
5085
 
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")])
5092
 
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.
5100
 
5101
  "TARGET_C3X"
5102
  "call%U1\\t%C1"
5103
  [(set_attr "type" "call")])
5104
 
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.
5112
 
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")])
5121
 
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
 ""
5128
 "
5129
{
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)));
5134
}")
5135
 
5136
(define_insn "return"
5137
  [(return)]
5138
  "! c4x_null_epilogue_p ()"
5139
  "rets"
5140
  [(set_attr "type" "rets")])
5141
 
5142
(define_insn "return_from_epilogue"
5143
  [(return)]
5144
  "reload_completed && ! c4x_interrupt_function_p ()"
5145
  "rets"
5146
  [(set_attr "type" "rets")])
5147
 
5148
(define_insn "return_from_interrupt_epilogue"
5149
  [(return)]
5150
  "reload_completed && c4x_interrupt_function_p ()"
5151
  "reti"
5152
  [(set_attr "type" "rets")])
5153
 
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")])
5163
 
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")])
5177
 
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")])
5187
 
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")])
5201
 
5202
(define_insn "jump"
5203
  [(set (pc) (label_ref (match_operand 0 "" "")))]
5204
  ""
5205
  "br%#\\t%l0"
5206
  [(set_attr "type" "jump")])
5207
 
5208
(define_insn "trap"
5209
  [(trap_if (const_int 1) (const_int 31))]
5210
  ""
5211
  "trapu\\t31"
5212
  [(set_attr "type" "call")])
5213
 
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;}")
5227
 
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")])
5235
 
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")])
5246
 
5247
;
5248
; DBcond
5249
;
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")])
5282
 
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")])
5295
 
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
 
5318
 
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.
5324
 
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")])
5354
 
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")])
5368
 
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
  "")
5392
 
5393
;
5394
; MISC INSTRUCTIONS
5395
;
5396
 
5397
;
5398
; NOP
5399
;
5400
(define_insn "nop"
5401
  [(const_int 0)]
5402
  ""
5403
  "nop")
5404
; Default to misc type attr.
5405
 
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")])
5412
 
5413
(define_expand "prologue"
5414
  [(const_int 1)]
5415
  ""
5416
  "c4x_expand_prologue (); DONE;")
5417
 
5418
(define_expand "epilogue"
5419
  [(const_int 1)]
5420
  ""
5421
  "c4x_expand_epilogue (); DONE;")
5422
 
5423
;
5424
; RPTB
5425
;
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")])
5437
 
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")])
5449
 
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")])
5459
 
5460
 
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
  ")
5476
 
5477
 
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")])
5507
 
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
  "")
5534
 
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
  ")
5562
 
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
  "")
5577
 
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
  "
5586
 {
5587
    rtx src, dst, tmp;
5588
    rtx src_mem, dst_mem;
5589
    int len;
5590
    int i;
5591
 
5592
    dst = operands[0];
5593
    src = operands[1];
5594
    len = INTVAL (operands[2]);
5595
    tmp = operands[4];
5596
 
5597
    src_mem = gen_rtx_MEM (QImode, src);
5598
    dst_mem = gen_rtx_MEM (QImode, dst);
5599
 
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
  ")
5626
 
5627
 
5628
;
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
5637
 
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
  "*
5651
 {
5652
   int i;
5653
   int len = INTVAL (operands[2]);
5654
 
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")])
5683
 
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
  "
5692
 {
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
     }
5700
 
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
 }")
5715
 
5716
 
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
  "*
5727
 {
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
 }")
5733
 
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
  "
5744
{
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);
5754
}")
5755
 
5756
;
5757
; TWO OPERAND LONG DOUBLE INSTRUCTIONS
5758
;
5759
 
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;")
5766
 
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")])
5773
 
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")])
5780
 
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")])
5789
 
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")])
5799
 
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);")
5811
 
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);")
5823
 
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);")
5834
 
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")])
5841
 
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")])
5849
 
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")])
5856
 
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")])
5863
 
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")])
5870
 
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")])
5878
 
5879
;
5880
; PUSH/POP
5881
;
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")])
5888
 
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
 "")
5898
 
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")])
5905
 
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")])
5912
 
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")])
5921
 
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
 "")
5935
 
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")])
5944
 
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")])
5952
 
5953
;
5954
; FIX
5955
;
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));")
5977
 
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
 ")
6005
 
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")])
6015
 
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")])
6023
 
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;")
6031
 
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;")
6040
 
6041
;
6042
; ABSF
6043
;
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))])]
6048
""
6049
"")
6050
 
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")])
6058
 
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")])
6067
 
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)))]
6074
 
6075
  ""
6076
  "absf\\t%1,%0"
6077
  [(set_attr "type" "unarycc")])
6078
 
6079
;
6080
; NEGF
6081
;
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))])]
6086
""
6087
"")
6088
 
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")])
6096
 
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")])
6105
 
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")])
6115
 
6116
;
6117
; RCPF
6118
;
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")])
6126
 
6127
;
6128
; RSQRF
6129
;
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")])
6137
 
6138
;
6139
; RNDF
6140
;
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")])
6148
 
6149
 
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
  ")
6184
 
6185
 
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;")
6193
 
6194
;
6195
; THREE OPERAND LONG DOUBLE INSTRUCTIONS
6196
;
6197
 
6198
;
6199
; ADDF
6200
;
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")])
6211
 
6212
;
6213
; SUBF
6214
;
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")])
6226
 
6227
;
6228
; MULF
6229
;
6230
; The C3x MPYF only uses 24-bit precision while the C4x uses 32-bit precision.
6231
;
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
  "")
6239
 
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")])
6250
 
6251
;
6252
; CMPF
6253
;
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;")
6262
 
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")])
6270
 
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")])
6278
 
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
  ")
6306
 
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;")
6315
 
6316
 
6317
;
6318
; TWO OPERAND LONG LONG INSTRUCTIONS
6319
;
6320
 
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")])
6327
 
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;")
6336
 
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")])
6348
 
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
6356
;
6357
; We could convert this to
6358
; ldi *ar0(1), ar1
6359
; ldi *ar0, ar0
6360
;
6361
; However, things are likely to be very screwed up if we get this.
6362
 
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
     }")
6387
 
6388
 
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")])
6396
 
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);")
6408
 
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);")
6419
 
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")])
6427
 
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);")
6439
 
6440
;
6441
; PUSH/POP
6442
;
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")])
6449
 
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);")
6458
 
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")])
6466
 
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);")
6475
 
6476
;
6477
; NEG
6478
;
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")])
6486
 
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);")
6503
 
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")])
6511
 
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);")
6525
 
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;")
6533
 
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;")
6542
 
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;")
6550
 
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;")
6559
 
6560
 
6561
;
6562
; THREE OPERAND LONG LONG INSTRUCTIONS
6563
;
6564
 
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);")
6572
 
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")])
6581
 
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);")
6601
 
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);")
6609
 
6610
 
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")])
6619
 
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);")
6639
 
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);")
6647
 
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")])
6656
 
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);")
6673
 
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);")
6681
 
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")])
6690
 
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);")
6707
 
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);")
6715
 
6716
 
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")])
6725
 
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);")
6742
 
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));
6755
 
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
 ")
6768
 
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
 ")
6806
 
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));
6820
 
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;")
6832
 
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
 ")
6876
 
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));
6890
 
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;")
6902
 
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
 ")
6946
 
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;")
6956
 
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")])
6964
 
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")])
6972
 
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
  "")
6986
 
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
  "")
6998
 
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
  "")
7009
 
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
  "")
7019
 
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);
7034
 
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")])
7070
 
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);
7085
 
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")])
7121
 
7122
 
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")])
7138
 
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")])
7154
 
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;")
7164
 
7165
 
7166
;
7167
; PEEPHOLES
7168
;
7169
 
7170
; dbCC peepholes
7171
;
7172
; Turns
7173
;   loop:
7174
;           [ ... ]
7175
;           bCC label           ; abnormal loop termination
7176
;           dbu aN, loop        ; normal loop termination
7177
;
7178
; Into
7179
;   loop:
7180
;           [ ... ]
7181
;           dbCC aN, loop
7182
;           bCC label
7183
;
7184
; Which moves the bCC condition outside the inner loop for free.
7185
;
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")])
7207
 
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")])
7226
 
7227
;
7228
; Peepholes to convert 'call label; rets' into jump label
7229
;
7230
 
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")])
7243
 
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")])
7257
 
7258
 
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")
7270
 
7271
 
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++")
7283
 
7284
 
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")
7298
 
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")

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.