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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [c4x/] [c4x.md] - Blame information for rev 820

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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