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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [config/] [bfin/] [bfin.md] - Blame information for rev 154

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
;;- Machine description for Blackfin for GNU compiler
2
;;  Copyright 2005, 2006, 2007 Free Software Foundation, Inc.
3
;;  Contributed by Analog Devices.
4
 
5
;; This file is part of GCC.
6
 
7
;; GCC is free software; you can redistribute it and/or modify it
8
;; under the terms of the GNU General Public License as published
9
;; by the Free Software Foundation; either version 3, or (at your
10
;; option) any later version.
11
 
12
;; GCC is distributed in the hope that it will be useful, but WITHOUT
13
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
;; License for more details.
16
 
17
;; You should have received a copy of the GNU General Public License
18
;; along with GCC; see the file COPYING3.  If not see
19
;; .
20
 
21
; operand punctuation marks:
22
;
23
;     X -- integer value printed as log2
24
;     Y -- integer value printed as log2(~value) - for bitclear
25
;     h -- print half word register, low part
26
;     d -- print half word register, high part
27
;     D -- print operand as dregs pairs
28
;     w -- print operand as accumulator register word (a0w, a1w)
29
;     H -- high part of double mode operand
30
;     T -- byte register representation Oct. 02 2001
31
 
32
; constant operand classes
33
;
34
;     J   2**N       5bit imm scaled
35
;     Ks7 -64 .. 63  signed 7bit imm
36
;     Ku5 0..31      unsigned 5bit imm
37
;     Ks4 -8 .. 7    signed 4bit imm
38
;     Ks3 -4 .. 3    signed 3bit imm
39
;     Ku3 0 .. 7     unsigned 3bit imm
40
;     Pn  0, 1, 2    constants 0, 1 or 2, corresponding to n
41
;
42
; register operands
43
;     d  (r0..r7)
44
;     a  (p0..p5,fp,sp)
45
;     e  (a0, a1)
46
;     b  (i0..i3)
47
;     f  (m0..m3)
48
;     v  (b0..b3)
49
;     c  (i0..i3,m0..m3) CIRCREGS
50
;     C  (CC)            CCREGS
51
;     t  (lt0,lt1)
52
;     k  (lc0,lc1)
53
;     u  (lb0,lb1)
54
;
55
 
56
;; Define constants for hard registers.
57
 
58
(define_constants
59
  [(REG_R0 0)
60
   (REG_R1 1)
61
   (REG_R2 2)
62
   (REG_R3 3)
63
   (REG_R4 4)
64
   (REG_R5 5)
65
   (REG_R6 6)
66
   (REG_R7 7)
67
 
68
   (REG_P0 8)
69
   (REG_P1 9)
70
   (REG_P2 10)
71
   (REG_P3 11)
72
   (REG_P4 12)
73
   (REG_P5 13)
74
   (REG_P6 14)
75
   (REG_P7 15)
76
 
77
   (REG_SP 14)
78
   (REG_FP 15)
79
 
80
   (REG_I0 16)
81
   (REG_I1 17)
82
   (REG_I2 18)
83
   (REG_I3 19)
84
 
85
   (REG_B0 20)
86
   (REG_B1 21)
87
   (REG_B2 22)
88
   (REG_B3 23)
89
 
90
   (REG_L0 24)
91
   (REG_L1 25)
92
   (REG_L2 26)
93
   (REG_L3 27)
94
 
95
   (REG_M0 28)
96
   (REG_M1 29)
97
   (REG_M2 30)
98
   (REG_M3 31)
99
 
100
   (REG_A0 32)
101
   (REG_A1 33)
102
 
103
   (REG_CC 34)
104
   (REG_RETS 35)
105
   (REG_RETI 36)
106
   (REG_RETX 37)
107
   (REG_RETN 38)
108
   (REG_RETE 39)
109
 
110
   (REG_ASTAT 40)
111
   (REG_SEQSTAT 41)
112
   (REG_USP 42)
113
 
114
   (REG_ARGP 43)
115
 
116
   (REG_LT0 44)
117
   (REG_LT1 45)
118
   (REG_LC0 46)
119
   (REG_LC1 47)
120
   (REG_LB0 48)
121
   (REG_LB1 49)])
122
 
123
;; Constants used in UNSPECs and UNSPEC_VOLATILEs.
124
 
125
(define_constants
126
  [(UNSPEC_CBRANCH_TAKEN 0)
127
   (UNSPEC_CBRANCH_NOPS 1)
128
   (UNSPEC_RETURN 2)
129
   (UNSPEC_MOVE_PIC 3)
130
   (UNSPEC_LIBRARY_OFFSET 4)
131
   (UNSPEC_PUSH_MULTIPLE 5)
132
   ;; Multiply or MAC with extra CONST_INT operand specifying the macflag
133
   (UNSPEC_MUL_WITH_FLAG 6)
134
   (UNSPEC_MAC_WITH_FLAG 7)
135
   (UNSPEC_MOVE_FDPIC 8)
136
   (UNSPEC_FUNCDESC_GOT17M4 9)
137
   (UNSPEC_LSETUP_END 10)])
138
 
139
(define_constants
140
  [(UNSPEC_VOLATILE_EH_RETURN 0)
141
   (UNSPEC_VOLATILE_CSYNC 1)
142
   (UNSPEC_VOLATILE_SSYNC 2)
143
   (UNSPEC_VOLATILE_LOAD_FUNCDESC 3)])
144
 
145
(define_constants
146
  [(MACFLAG_NONE 0)
147
   (MACFLAG_T 1)
148
   (MACFLAG_FU 2)
149
   (MACFLAG_TFU 3)
150
   (MACFLAG_IS 4)
151
   (MACFLAG_IU 5)
152
   (MACFLAG_W32 6)
153
   (MACFLAG_M 7)
154
   (MACFLAG_S2RND 8)
155
   (MACFLAG_ISS2 9)
156
   (MACFLAG_IH 10)])
157
 
158
(define_attr "type"
159
  "move,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy"
160
  (const_string "misc"))
161
 
162
;; Scheduling definitions
163
 
164
(define_automaton "bfin")
165
 
166
(define_cpu_unit "core" "bfin")
167
 
168
(define_insn_reservation "alu" 1
169
  (eq_attr "type" "move,mvi,mcst,dsp32,alu0,shft,brcc,br,call,misc,sync,compare")
170
  "core")
171
 
172
(define_insn_reservation "imul" 3
173
  (eq_attr "type" "mult")
174
  "core*3")
175
 
176
(define_insn_reservation "load" 1
177
  (eq_attr "type" "mcld")
178
  "core")
179
 
180
;; Make sure genautomata knows about the maximum latency that can be produced
181
;; by the adjust_cost function.
182
(define_insn_reservation "dummy" 5
183
  (eq_attr "type" "mcld")
184
  "core")
185
 
186
;; Operand and operator predicates
187
 
188
(include "predicates.md")
189
 
190
 
191
;;; FRIO branches have been optimized for code density
192
;;; this comes at a slight cost of complexity when
193
;;; a compiler needs to generate branches in the general
194
;;; case.  In order to generate the correct branching
195
;;; mechanisms the compiler needs keep track of instruction
196
;;; lengths.  The follow table describes how to count instructions
197
;;; for the FRIO architecture.
198
;;;
199
;;; unconditional br are 12-bit imm pcrelative branches *2
200
;;; conditional   br are 10-bit imm pcrelative branches *2
201
;;; brcc 10-bit:
202
;;;   1024 10-bit imm *2 is 2048 (-1024..1022)
203
;;; br 12-bit  :
204
;;;   4096 12-bit imm *2 is 8192 (-4096..4094)
205
;;; NOTE : For brcc we generate instructions such as
206
;;;   if cc jmp; jump.[sl] offset
207
;;;   offset of jump.[sl] is from the jump instruction but
208
;;;     gcc calculates length from the if cc jmp instruction
209
;;;     furthermore gcc takes the end address of the branch instruction
210
;;;     as (pc) for a forward branch
211
;;;     hence our range is (-4094, 4092) instead of (-4096, 4094) for a br
212
;;;
213
;;; The way the (pc) rtx works in these calculations is somewhat odd;
214
;;; for backward branches it's the address of the current instruction,
215
;;; for forward branches it's the previously known address of the following
216
;;; instruction - we have to take this into account by reducing the range
217
;;; for a forward branch.
218
 
219
;; Lengths for type "mvi" insns are always defined by the instructions
220
;; themselves.
221
(define_attr "length" ""
222
  (cond [(eq_attr "type" "mcld")
223
         (if_then_else (match_operand 1 "effective_address_32bit_p" "")
224
                       (const_int 4) (const_int 2))
225
 
226
         (eq_attr "type" "mcst")
227
         (if_then_else (match_operand 0 "effective_address_32bit_p" "")
228
                       (const_int 4) (const_int 2))
229
 
230
         (eq_attr "type" "move") (const_int 2)
231
 
232
         (eq_attr "type" "dsp32") (const_int 4)
233
         (eq_attr "type" "call")  (const_int 4)
234
 
235
         (eq_attr "type" "br")
236
         (if_then_else (and
237
                          (le (minus (match_dup 0) (pc)) (const_int 4092))
238
                          (ge (minus (match_dup 0) (pc)) (const_int -4096)))
239
                  (const_int 2)
240
                  (const_int 4))
241
 
242
         (eq_attr "type" "brcc")
243
         (cond [(and
244
                    (le (minus (match_dup 3) (pc)) (const_int 1020))
245
                    (ge (minus (match_dup 3) (pc)) (const_int -1024)))
246
                  (const_int 2)
247
                (and
248
                    (le (minus (match_dup 3) (pc)) (const_int 4092))
249
                    (ge (minus (match_dup 3) (pc)) (const_int -4094)))
250
                  (const_int 4)]
251
               (const_int 6))
252
        ]
253
 
254
        (const_int 2)))
255
 
256
 
257
;; Classify the insns into those that are one instruction and those that
258
;; are more than one in sequence.
259
(define_attr "seq_insns" "single,multi"
260
  (const_string "single"))
261
 
262
;; Conditional moves
263
 
264
(define_expand "movsicc"
265
  [(set (match_operand:SI 0 "register_operand" "")
266
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
267
                         (match_operand:SI 2 "register_operand" "")
268
                         (match_operand:SI 3 "register_operand" "")))]
269
  ""
270
{
271
  operands[1] = bfin_gen_compare (operands[1], SImode);
272
})
273
 
274
(define_insn "*movsicc_insn1"
275
  [(set (match_operand:SI 0 "register_operand" "=da,da,da")
276
        (if_then_else:SI
277
            (eq:BI (match_operand:BI 3 "register_operand" "C,C,C")
278
                (const_int 0))
279
            (match_operand:SI 1 "register_operand" "da,0,da")
280
            (match_operand:SI 2 "register_operand" "0,da,da")))]
281
  ""
282
  "@
283
    if !cc %0 =%1; /* movsicc-1a */
284
    if cc %0 =%2; /* movsicc-1b */
285
    if !cc %0 =%1; if cc %0=%2; /* movsicc-1 */"
286
  [(set_attr "length" "2,2,4")
287
   (set_attr "type" "move")
288
   (set_attr "seq_insns" "*,*,multi")])
289
 
290
(define_insn "*movsicc_insn2"
291
  [(set (match_operand:SI 0 "register_operand" "=da,da,da")
292
        (if_then_else:SI
293
            (ne:BI (match_operand:BI 3 "register_operand" "C,C,C")
294
                (const_int 0))
295
            (match_operand:SI 1 "register_operand" "0,da,da")
296
            (match_operand:SI 2 "register_operand" "da,0,da")))]
297
  ""
298
  "@
299
   if !cc %0 =%2; /* movsicc-2b */
300
   if cc %0 =%1; /* movsicc-2a */
301
   if cc %0 =%1; if !cc %0=%2; /* movsicc-1 */"
302
  [(set_attr "length" "2,2,4")
303
   (set_attr "type" "move")
304
   (set_attr "seq_insns" "*,*,multi")])
305
 
306
;; Insns to load HIGH and LO_SUM
307
 
308
(define_insn "movsi_high"
309
  [(set (match_operand:SI 0 "register_operand" "=x")
310
        (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
311
  "reload_completed"
312
  "%d0 = %d1;"
313
  [(set_attr "type" "mvi")
314
   (set_attr "length" "4")])
315
 
316
(define_insn "movstricthi_high"
317
  [(set (match_operand:SI 0 "register_operand" "+x")
318
        (ior:SI (and:SI (match_dup 0) (const_int 65535))
319
                (match_operand:SI 1 "immediate_operand" "i")))]
320
  "reload_completed"
321
  "%d0 = %d1;"
322
  [(set_attr "type" "mvi")
323
   (set_attr "length" "4")])
324
 
325
(define_insn "movsi_low"
326
  [(set (match_operand:SI 0 "register_operand" "=x")
327
        (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
328
                   (match_operand:SI 2 "immediate_operand" "i")))]
329
  "reload_completed"
330
  "%h0 = %h2;"
331
  [(set_attr "type" "mvi")
332
   (set_attr "length" "4")])
333
 
334
(define_insn "movsi_high_pic"
335
  [(set (match_operand:SI 0 "register_operand" "=x")
336
        (high:SI (unspec:SI [(match_operand:SI 1 "" "")]
337
                            UNSPEC_MOVE_PIC)))]
338
  ""
339
  "%d0 = %1@GOT_LOW;"
340
  [(set_attr "type" "mvi")
341
   (set_attr "length" "4")])
342
 
343
(define_insn "movsi_low_pic"
344
  [(set (match_operand:SI 0 "register_operand" "=x")
345
        (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
346
                   (unspec:SI [(match_operand:SI 2 "" "")]
347
                              UNSPEC_MOVE_PIC)))]
348
  ""
349
  "%h0 = %h2@GOT_HIGH;"
350
  [(set_attr "type" "mvi")
351
   (set_attr "length" "4")])
352
 
353
;;; Move instructions
354
 
355
(define_insn_and_split "movdi_insn"
356
  [(set (match_operand:DI 0 "nonimmediate_operand" "=x,mx,r")
357
        (match_operand:DI 1 "general_operand" "iFx,r,mx"))]
358
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
359
  "#"
360
  "reload_completed"
361
  [(set (match_dup 2) (match_dup 3))
362
   (set (match_dup 4) (match_dup 5))]
363
{
364
  rtx lo_half[2], hi_half[2];
365
  split_di (operands, 2, lo_half, hi_half);
366
 
367
  if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
368
    {
369
      operands[2] = hi_half[0];
370
      operands[3] = hi_half[1];
371
      operands[4] = lo_half[0];
372
      operands[5] = lo_half[1];
373
    }
374
  else
375
    {
376
      operands[2] = lo_half[0];
377
      operands[3] = lo_half[1];
378
      operands[4] = hi_half[0];
379
      operands[5] = hi_half[1];
380
    }
381
})
382
 
383
(define_insn "movbi"
384
  [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,md,C,d,C")
385
        (match_operand:BI 1 "general_operand" "x,xKs3,md,d,d,C,P0"))]
386
 
387
  ""
388
  "@
389
   %0 = %1;
390
   %0 = %1 (X);
391
   %0 = B %1 (Z);
392
   B %0 = %1;
393
   CC = %1;
394
   %0 = CC;
395
   R0 = R0 | R0; CC = AC0;"
396
  [(set_attr "type" "move,mvi,mcld,mcst,compare,compare,alu0")
397
   (set_attr "length" "2,2,*,*,2,2,4")
398
   (set_attr "seq_insns" "*,*,*,*,*,*,multi")])
399
 
400
(define_insn "movpdi"
401
  [(set (match_operand:PDI 0 "nonimmediate_operand" "=e,<,e")
402
        (match_operand:PDI 1 "general_operand" " e,e,>"))]
403
  ""
404
  "@
405
   %0 = %1;
406
   %0 = %x1; %0 = %w1;
407
   %w0 = %1; %x0 = %1;"
408
  [(set_attr "type" "move,mcst,mcld")
409
   (set_attr "seq_insns" "*,multi,multi")])
410
 
411
(define_insn "load_accumulator"
412
  [(set (match_operand:PDI 0 "register_operand" "=e")
413
        (sign_extend:PDI (match_operand:SI 1 "register_operand" "d")))]
414
  ""
415
  "%0 = %1;"
416
  [(set_attr "type" "move")])
417
 
418
(define_insn_and_split "load_accumulator_pair"
419
  [(set (match_operand:V2PDI 0 "register_operand" "=e")
420
        (sign_extend:V2PDI (vec_concat:V2SI
421
                            (match_operand:SI 1 "register_operand" "d")
422
                            (match_operand:SI 2 "register_operand" "d"))))]
423
  ""
424
  "#"
425
  "reload_completed"
426
  [(set (match_dup 3) (sign_extend:PDI (match_dup 1)))
427
   (set (match_dup 4) (sign_extend:PDI (match_dup 2)))]
428
{
429
  operands[3] = gen_rtx_REG (PDImode, REGNO (operands[0]));
430
  operands[4] = gen_rtx_REG (PDImode, REGNO (operands[0]) + 1);
431
})
432
 
433
(define_insn "*pushsi_insn"
434
  [(set (mem:SI (pre_dec:SI (reg:SI REG_SP)))
435
        (match_operand:SI 0 "register_operand" "xy"))]
436
  ""
437
  "[--SP] = %0;"
438
  [(set_attr "type" "mcst")
439
   (set_attr "length" "2")])
440
 
441
(define_insn "*popsi_insn"
442
  [(set (match_operand:SI 0 "register_operand" "=xy")
443
        (mem:SI (post_inc:SI (reg:SI REG_SP))))]
444
  ""
445
  "%0 = [SP++];"
446
  [(set_attr "type" "mcld")
447
   (set_attr "length" "2")])
448
 
449
;; The first alternative is used to make reload choose a limited register
450
;; class when faced with a movsi_insn that had its input operand replaced
451
;; with a PLUS.  We generally require fewer secondary reloads this way.
452
 
453
(define_insn "*movsi_insn"
454
  [(set (match_operand:SI 0 "nonimmediate_operand" "=da,x*y,*k,da,da,x,x,x,da,mr")
455
        (match_operand:SI 1 "general_operand" "da,x*y,da,*k,xKs7,xKsh,xKuh,ix,mr,da"))]
456
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
457
 "@
458
   %0 = %1;
459
   %0 = %1;
460
   %0 = %1;
461
   %0 = %1;
462
   %0 = %1 (X);
463
   %0 = %1 (X);
464
   %0 = %1 (Z);
465
   #
466
   %0 = %1;
467
   %0 = %1;"
468
  [(set_attr "type" "move,move,move,move,mvi,mvi,mvi,*,mcld,mcst")
469
   (set_attr "length" "2,2,2,2,2,4,4,*,*,*")])
470
 
471
(define_insn_and_split "*movv2hi_insn"
472
  [(set (match_operand:V2HI 0 "nonimmediate_operand" "=da,da,d,dm")
473
        (match_operand:V2HI 1 "general_operand" "i,di,md,d"))]
474
 
475
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
476
  "@
477
   #
478
   %0 = %1;
479
   %0 = %1;
480
   %0 = %1;"
481
  "reload_completed && GET_CODE (operands[1]) == CONST_VECTOR"
482
  [(set (match_dup 0) (high:SI (match_dup 2)))
483
   (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 3)))]
484
{
485
  HOST_WIDE_INT intval = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
486
  intval |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
487
 
488
  operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
489
  operands[2] = operands[3] = GEN_INT (trunc_int_for_mode (intval, SImode));
490
}
491
  [(set_attr "type" "move,move,mcld,mcst")
492
   (set_attr "length" "2,2,*,*")])
493
 
494
(define_insn "*movhi_insn"
495
  [(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr")
496
        (match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
497
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
498
{
499
  static const char *templates[] = {
500
    "%0 = %1;",
501
    "%0 = %1 (X);",
502
    "%0 = %1 (X);",
503
    "%0 = W %1 (X);",
504
    "W %0 = %1;",
505
    "%h0 = W %1;",
506
    "W %0 = %h1;"
507
  };
508
  int alt = which_alternative;
509
  rtx mem = (MEM_P (operands[0]) ? operands[0]
510
             : MEM_P (operands[1]) ? operands[1] : NULL_RTX);
511
  if (mem && bfin_dsp_memref_p (mem))
512
    alt += 2;
513
  return templates[alt];
514
}
515
  [(set_attr "type" "move,mvi,mvi,mcld,mcst")
516
   (set_attr "length" "2,2,4,*,*")])
517
 
518
(define_insn "*movqi_insn"
519
  [(set (match_operand:QI 0 "nonimmediate_operand" "=x,da,x,d,mr")
520
        (match_operand:QI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
521
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
522
  "@
523
   %0 = %1;
524
   %0 = %1 (X);
525
   %0 = %1 (X);
526
   %0 = B %1 (X);
527
   B %0 = %1;"
528
  [(set_attr "type" "move,mvi,mvi,mcld,mcst")
529
   (set_attr "length" "2,2,4,*,*")])
530
 
531
(define_insn "*movsf_insn"
532
  [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,da,mr")
533
        (match_operand:SF 1 "general_operand" "x,Fx,mr,da"))]
534
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
535
  "@
536
   %0 = %1;
537
   #
538
   %0 = %1;
539
   %0 = %1;"
540
  [(set_attr "type" "move,*,mcld,mcst")])
541
 
542
(define_insn_and_split "movdf_insn"
543
  [(set (match_operand:DF 0 "nonimmediate_operand" "=x,mx,r")
544
        (match_operand:DF 1 "general_operand" "iFx,r,mx"))]
545
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
546
  "#"
547
  "reload_completed"
548
  [(set (match_dup 2) (match_dup 3))
549
   (set (match_dup 4) (match_dup 5))]
550
{
551
  rtx lo_half[2], hi_half[2];
552
  split_di (operands, 2, lo_half, hi_half);
553
 
554
  if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
555
    {
556
      operands[2] = hi_half[0];
557
      operands[3] = hi_half[1];
558
      operands[4] = lo_half[0];
559
      operands[5] = lo_half[1];
560
    }
561
  else
562
    {
563
      operands[2] = lo_half[0];
564
      operands[3] = lo_half[1];
565
      operands[4] = hi_half[0];
566
      operands[5] = hi_half[1];
567
    }
568
})
569
 
570
;; Storing halfwords.
571
(define_insn "*movsi_insv"
572
  [(set (zero_extract:SI (match_operand 0 "register_operand" "+d,x")
573
                         (const_int 16)
574
                         (const_int 16))
575
        (match_operand:SI 1 "nonmemory_operand" "d,n"))]
576
  ""
577
  "@
578
   %d0 = %h1 << 0;
579
   %d0 = %1;"
580
  [(set_attr "type" "dsp32,mvi")])
581
 
582
(define_expand "insv"
583
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
584
                         (match_operand:SI 1 "immediate_operand" "")
585
                         (match_operand:SI 2 "immediate_operand" ""))
586
        (match_operand:SI 3 "nonmemory_operand" ""))]
587
  ""
588
{
589
  if (INTVAL (operands[1]) != 16 || INTVAL (operands[2]) != 16)
590
    FAIL;
591
 
592
  /* From mips.md: insert_bit_field doesn't verify that our source
593
     matches the predicate, so check it again here.  */
594
  if (! register_operand (operands[0], VOIDmode))
595
    FAIL;
596
})
597
 
598
;; This is the main "hook" for PIC code.  When generating
599
;; PIC, movsi is responsible for determining when the source address
600
;; needs PIC relocation and appropriately calling legitimize_pic_address
601
;; to perform the actual relocation.
602
 
603
(define_expand "movsi"
604
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
605
        (match_operand:SI 1 "general_operand" ""))]
606
  ""
607
  "expand_move (operands, SImode);")
608
 
609
(define_expand "movv2hi"
610
  [(set (match_operand:V2HI 0 "nonimmediate_operand" "")
611
        (match_operand:V2HI 1 "general_operand" ""))]
612
  ""
613
  "expand_move (operands, V2HImode);")
614
 
615
(define_expand "movdi"
616
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
617
        (match_operand:DI 1 "general_operand" ""))]
618
  ""
619
  "expand_move (operands, DImode);")
620
 
621
(define_expand "movsf"
622
 [(set (match_operand:SF 0 "nonimmediate_operand" "")
623
       (match_operand:SF 1 "general_operand" ""))]
624
  ""
625
  "expand_move (operands, SFmode);")
626
 
627
(define_expand "movdf"
628
 [(set (match_operand:DF 0 "nonimmediate_operand" "")
629
       (match_operand:DF 1 "general_operand" ""))]
630
  ""
631
  "expand_move (operands, DFmode);")
632
 
633
(define_expand "movhi"
634
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
635
        (match_operand:HI 1 "general_operand" ""))]
636
  ""
637
  "expand_move (operands, HImode);")
638
 
639
(define_expand "movqi"
640
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
641
        (match_operand:QI 1 "general_operand" ""))]
642
  ""
643
  " expand_move (operands, QImode); ")
644
 
645
;; Some define_splits to break up SI/SFmode loads of immediate constants.
646
 
647
(define_split
648
  [(set (match_operand:SI 0 "register_operand" "")
649
        (match_operand:SI 1 "symbolic_or_const_operand" ""))]
650
  "reload_completed
651
   /* Always split symbolic operands; split integer constants that are
652
      too large for a single instruction.  */
653
   && (GET_CODE (operands[1]) != CONST_INT
654
       || (INTVAL (operands[1]) < -32768
655
           || INTVAL (operands[1]) >= 65536
656
           || (INTVAL (operands[1]) >= 32768 && PREG_P (operands[0]))))"
657
  [(set (match_dup 0) (high:SI (match_dup 1)))
658
   (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))]
659
{
660
  if (GET_CODE (operands[1]) == CONST_INT
661
      && split_load_immediate (operands))
662
    DONE;
663
  /* ??? Do something about TARGET_LOW_64K.  */
664
})
665
 
666
(define_split
667
  [(set (match_operand:SF 0 "register_operand" "")
668
        (match_operand:SF 1 "immediate_operand" ""))]
669
  "reload_completed"
670
  [(set (match_dup 2) (high:SI (match_dup 3)))
671
   (set (match_dup 2) (lo_sum:SI (match_dup 2) (match_dup 3)))]
672
{
673
  long values;
674
  REAL_VALUE_TYPE value;
675
 
676
  gcc_assert (GET_CODE (operands[1]) == CONST_DOUBLE);
677
 
678
  REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
679
  REAL_VALUE_TO_TARGET_SINGLE (value, values);
680
 
681
  operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0]));
682
  operands[3] = GEN_INT (trunc_int_for_mode (values, SImode));
683
  if (values >= -32768 && values < 65536)
684
    {
685
      emit_move_insn (operands[2], operands[3]);
686
      DONE;
687
    }
688
  if (split_load_immediate (operands + 2))
689
    DONE;
690
})
691
 
692
;; Sadly, this can't be a proper named movstrict pattern, since the compiler
693
;; expects to be able to use registers for operand 1.
694
;; Note that the asm instruction is defined by the manual to take an unsigned
695
;; constant, but it doesn't matter to the assembler, and the compiler only
696
;; deals with sign-extended constants.  Hence "Ksh".
697
(define_insn "movstricthi_1"
698
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+x"))
699
        (match_operand:HI 1 "immediate_operand" "Ksh"))]
700
  ""
701
  "%h0 = %1;"
702
  [(set_attr "type" "mvi")
703
   (set_attr "length" "4")])
704
 
705
;; Sign and zero extensions
706
 
707
(define_insn_and_split "extendhisi2"
708
  [(set (match_operand:SI 0 "register_operand" "=d, d")
709
        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
710
  ""
711
  "@
712
   %0 = %h1 (X);
713
   %0 = W %h1 (X);"
714
  "reload_completed && bfin_dsp_memref_p (operands[1])"
715
  [(set (match_dup 2) (match_dup 1))
716
   (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
717
{
718
  operands[2] = gen_lowpart (HImode, operands[0]);
719
}
720
  [(set_attr "type" "alu0,mcld")])
721
 
722
(define_insn_and_split "zero_extendhisi2"
723
  [(set (match_operand:SI 0 "register_operand" "=d, d")
724
        (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
725
  ""
726
  "@
727
   %0 = %h1 (Z);
728
   %0 = W %h1 (Z);"
729
  "reload_completed && bfin_dsp_memref_p (operands[1])"
730
  [(set (match_dup 2) (match_dup 1))
731
   (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
732
{
733
  operands[2] = gen_lowpart (HImode, operands[0]);
734
}
735
  [(set_attr "type" "alu0,mcld")])
736
 
737
(define_insn "zero_extendbisi2"
738
  [(set (match_operand:SI 0 "register_operand" "=d")
739
        (zero_extend:SI (match_operand:BI 1 "nonimmediate_operand" "C")))]
740
  ""
741
  "%0 = %1;"
742
  [(set_attr "type" "compare")])
743
 
744
(define_insn "extendqihi2"
745
  [(set (match_operand:HI 0 "register_operand" "=d, d")
746
        (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
747
  ""
748
  "@
749
   %0 = B %1 (X);
750
   %0 = %T1 (X);"
751
  [(set_attr "type" "mcld,alu0")])
752
 
753
(define_insn "extendqisi2"
754
  [(set (match_operand:SI 0 "register_operand" "=d, d")
755
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
756
  ""
757
  "@
758
   %0 = B %1 (X);
759
   %0 = %T1 (X);"
760
  [(set_attr "type" "mcld,alu0")])
761
 
762
 
763
(define_insn "zero_extendqihi2"
764
  [(set (match_operand:HI 0 "register_operand" "=d, d")
765
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
766
  ""
767
  "@
768
   %0 = B %1 (Z);
769
   %0 = %T1 (Z);"
770
  [(set_attr "type" "mcld,alu0")])
771
 
772
 
773
(define_insn "zero_extendqisi2"
774
  [(set (match_operand:SI 0 "register_operand" "=d, d")
775
        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
776
  ""
777
  "@
778
   %0 = B %1 (Z);
779
   %0 = %T1 (Z);"
780
  [(set_attr "type" "mcld,alu0")])
781
 
782
;; DImode logical operations
783
 
784
(define_code_macro any_logical [and ior xor])
785
(define_code_attr optab [(and "and")
786
                         (ior "ior")
787
                         (xor "xor")])
788
(define_code_attr op [(and "&")
789
                      (ior "|")
790
                      (xor "^")])
791
(define_code_attr high_result [(and "0")
792
                               (ior "%H1")
793
                               (xor "%H1")])
794
 
795
(define_insn "di3"
796
  [(set (match_operand:DI 0 "register_operand" "=d")
797
        (any_logical:DI (match_operand:DI 1 "register_operand" "0")
798
                        (match_operand:DI 2 "register_operand" "d")))]
799
  ""
800
  "%0 = %1  %2;\\n\\t%H0 = %H1  %H2;"
801
  [(set_attr "length" "4")
802
   (set_attr "seq_insns" "multi")])
803
 
804
(define_insn "*di_zesidi_di"
805
  [(set (match_operand:DI 0 "register_operand" "=d")
806
        (any_logical:DI (zero_extend:DI
807
                         (match_operand:SI 2 "register_operand" "d"))
808
                        (match_operand:DI 1 "register_operand" "d")))]
809
  ""
810
  "%0 = %1   %2;\\n\\t%H0 = ;"
811
  [(set_attr "length" "4")
812
   (set_attr "seq_insns" "multi")])
813
 
814
(define_insn "*di_sesdi_di"
815
  [(set (match_operand:DI 0 "register_operand" "=d")
816
        (any_logical:DI (sign_extend:DI
817
                         (match_operand:SI 2 "register_operand" "d"))
818
                        (match_operand:DI 1 "register_operand" "0")))
819
   (clobber (match_scratch:SI 3 "=&d"))]
820
  ""
821
  "%0 = %1  %2;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1  %3;"
822
  [(set_attr "length" "8")
823
   (set_attr "seq_insns" "multi")])
824
 
825
(define_insn "negdi2"
826
  [(set (match_operand:DI 0 "register_operand" "=d")
827
        (neg:DI (match_operand:DI 1 "register_operand" "d")))
828
   (clobber (match_scratch:SI 2 "=&d"))
829
   (clobber (reg:CC REG_CC))]
830
  ""
831
  "%2 = 0; %2 = %2 - %1; cc = ac0; cc = !cc; %2 = cc;\\n\\t%0 = -%1; %H0 = -%H1; %H0 = %H0 - %2;"
832
  [(set_attr "length" "16")
833
   (set_attr "seq_insns" "multi")])
834
 
835
(define_insn "one_cmpldi2"
836
  [(set (match_operand:DI 0 "register_operand" "=d")
837
        (not:DI (match_operand:DI 1 "register_operand" "d")))]
838
  ""
839
  "%0 = ~%1;\\n\\t%H0 = ~%H1;"
840
  [(set_attr "length" "4")
841
   (set_attr "seq_insns" "multi")])
842
 
843
;; DImode zero and sign extend patterns
844
 
845
(define_insn_and_split "zero_extendsidi2"
846
  [(set (match_operand:DI 0 "register_operand" "=d")
847
        (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
848
  ""
849
  "#"
850
  "reload_completed"
851
  [(set (match_dup 3) (const_int 0))]
852
{
853
  split_di (operands, 1, operands + 2, operands + 3);
854
  if (REGNO (operands[0]) != REGNO (operands[1]))
855
    emit_move_insn (operands[2], operands[1]);
856
})
857
 
858
(define_insn "zero_extendqidi2"
859
  [(set (match_operand:DI 0 "register_operand" "=d")
860
        (zero_extend:DI (match_operand:QI 1 "register_operand" "d")))]
861
  ""
862
  "%0 = %T1 (Z);\\n\\t%H0 = 0;"
863
  [(set_attr "length" "4")
864
   (set_attr "seq_insns" "multi")])
865
 
866
(define_insn "zero_extendhidi2"
867
  [(set (match_operand:DI 0 "register_operand" "=d")
868
        (zero_extend:DI (match_operand:HI 1 "register_operand" "d")))]
869
  ""
870
  "%0 = %h1 (Z);\\n\\t%H0 = 0;"
871
  [(set_attr "length" "4")
872
   (set_attr "seq_insns" "multi")])
873
 
874
(define_insn_and_split "extendsidi2"
875
  [(set (match_operand:DI 0 "register_operand" "=d")
876
        (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))]
877
  ""
878
  "#"
879
  "reload_completed"
880
  [(set (match_dup 3) (match_dup 1))
881
   (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
882
{
883
  split_di (operands, 1, operands + 2, operands + 3);
884
  if (REGNO (operands[0]) != REGNO (operands[1]))
885
    emit_move_insn (operands[2], operands[1]);
886
})
887
 
888
(define_insn_and_split "extendqidi2"
889
  [(set (match_operand:DI 0 "register_operand" "=d")
890
        (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
891
  ""
892
  "#"
893
  "reload_completed"
894
  [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
895
   (set (match_dup 3) (sign_extend:SI (match_dup 1)))
896
   (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
897
{
898
  split_di (operands, 1, operands + 2, operands + 3);
899
})
900
 
901
(define_insn_and_split "extendhidi2"
902
  [(set (match_operand:DI 0 "register_operand" "=d")
903
        (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
904
  ""
905
  "#"
906
  "reload_completed"
907
  [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
908
   (set (match_dup 3) (sign_extend:SI (match_dup 1)))
909
   (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
910
{
911
  split_di (operands, 1, operands + 2, operands + 3);
912
})
913
 
914
;; DImode arithmetic operations
915
 
916
(define_insn "adddi3"
917
  [(set (match_operand:DI 0 "register_operand" "=&d,&d,&d")
918
        (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
919
                 (match_operand:DI 2 "nonmemory_operand" "Kn7,Ks7,d")))
920
   (clobber (match_scratch:SI 3 "=&d,&d,&d"))
921
   (clobber (reg:CC 34))]
922
  ""
923
  "@
924
   %0 += %2; cc = ac0; %3 = cc; %H0 += -1; %H0 = %H0 + %3;
925
   %0 += %2; cc = ac0; %3 = cc; %H0 = %H0 + %3;
926
   %0 = %0 + %2; cc = ac0; %3 = cc; %H0 = %H0 + %H2; %H0 = %H0 + %3;"
927
  [(set_attr "type" "alu0")
928
   (set_attr "length" "10,8,10")
929
   (set_attr "seq_insns" "multi,multi,multi")])
930
 
931
(define_insn "subdi3"
932
  [(set (match_operand:DI 0 "register_operand" "=&d")
933
        (minus:DI (match_operand:DI 1 "register_operand" "0")
934
                  (match_operand:DI 2 "register_operand" "d")))
935
   (clobber (reg:CC 34))]
936
  ""
937
  "%0 = %1-%2;\\n\\tcc = ac0;\\n\\t%H0 = %H1-%H2;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
938
  [(set_attr "length" "10")
939
   (set_attr "seq_insns" "multi")])
940
 
941
(define_insn "*subdi_di_zesidi"
942
  [(set (match_operand:DI 0 "register_operand" "=d")
943
        (minus:DI (match_operand:DI 1 "register_operand" "0")
944
                  (zero_extend:DI
945
                  (match_operand:SI 2 "register_operand" "d"))))
946
   (clobber (match_scratch:SI 3 "=&d"))
947
   (clobber (reg:CC 34))]
948
  ""
949
  "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%H0 = %H1 - %3;"
950
  [(set_attr "length" "10")
951
   (set_attr "seq_insns" "multi")])
952
 
953
(define_insn "*subdi_zesidi_di"
954
  [(set (match_operand:DI 0 "register_operand" "=d")
955
        (minus:DI (zero_extend:DI
956
                  (match_operand:SI 2 "register_operand" "d"))
957
                  (match_operand:DI 1 "register_operand" "0")))
958
   (clobber (match_scratch:SI 3 "=&d"))
959
   (clobber (reg:CC 34))]
960
  ""
961
  "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%3 = -%3;\\n\\t%H0 = %3 - %H1"
962
  [(set_attr "length" "12")
963
   (set_attr "seq_insns" "multi")])
964
 
965
(define_insn "*subdi_di_sesidi"
966
  [(set (match_operand:DI 0 "register_operand" "=d")
967
        (minus:DI (match_operand:DI 1 "register_operand" "0")
968
                  (sign_extend:DI
969
                  (match_operand:SI 2 "register_operand" "d"))))
970
   (clobber (match_scratch:SI 3 "=&d"))
971
   (clobber (reg:CC 34))]
972
  ""
973
  "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 - %3;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
974
  [(set_attr "length" "14")
975
   (set_attr "seq_insns" "multi")])
976
 
977
(define_insn "*subdi_sesidi_di"
978
  [(set (match_operand:DI 0 "register_operand" "=d")
979
        (minus:DI (sign_extend:DI
980
                  (match_operand:SI 2 "register_operand" "d"))
981
                  (match_operand:DI 1 "register_operand" "0")))
982
   (clobber (match_scratch:SI 3 "=&d"))
983
   (clobber (reg:CC 34))]
984
  ""
985
  "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %3 - %H1;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
986
  [(set_attr "length" "14")
987
   (set_attr "seq_insns" "multi")])
988
 
989
;; Combined shift/add instructions
990
 
991
(define_insn ""
992
  [(set (match_operand:SI 0 "register_operand" "=a,d")
993
        (ashift:SI (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
994
                            (match_operand:SI 2 "register_operand" "a,d"))
995
                   (match_operand:SI 3 "pos_scale_operand" "P1P2,P1P2")))]
996
  ""
997
  "%0 = (%0 + %2) << %3;" /* "shadd %0,%2,%3;" */
998
  [(set_attr "type" "alu0")])
999
 
1000
(define_insn ""
1001
  [(set (match_operand:SI 0 "register_operand" "=a")
1002
        (plus:SI (match_operand:SI 1 "register_operand" "a")
1003
                 (mult:SI (match_operand:SI 2 "register_operand" "a")
1004
                          (match_operand:SI 3 "scale_by_operand" "i"))))]
1005
  ""
1006
  "%0 = %1 + (%2 << %X3);"
1007
  [(set_attr "type" "alu0")])
1008
 
1009
(define_insn ""
1010
  [(set (match_operand:SI 0 "register_operand" "=a")
1011
        (plus:SI (match_operand:SI 1 "register_operand" "a")
1012
                 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1013
                            (match_operand:SI 3 "pos_scale_operand" "i"))))]
1014
  ""
1015
  "%0 = %1 + (%2 << %3);"
1016
  [(set_attr "type" "alu0")])
1017
 
1018
(define_insn ""
1019
  [(set (match_operand:SI 0 "register_operand" "=a")
1020
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "a")
1021
                          (match_operand:SI 2 "scale_by_operand" "i"))
1022
                 (match_operand:SI 3 "register_operand" "a")))]
1023
  ""
1024
  "%0 = %3 + (%1 << %X2);"
1025
  [(set_attr "type" "alu0")])
1026
 
1027
(define_insn ""
1028
  [(set (match_operand:SI 0 "register_operand" "=a")
1029
        (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "a")
1030
                            (match_operand:SI 2 "pos_scale_operand" "i"))
1031
                 (match_operand:SI 3 "register_operand" "a")))]
1032
  ""
1033
  "%0 = %3 + (%1 << %2);"
1034
  [(set_attr "type" "alu0")])
1035
 
1036
(define_insn "mulhisi3"
1037
  [(set (match_operand:SI 0 "register_operand" "=d")
1038
        (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%d"))
1039
                 (sign_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
1040
  ""
1041
  "%0 = %h1 * %h2 (IS);"
1042
  [(set_attr "type" "dsp32")])
1043
 
1044
(define_insn "umulhisi3"
1045
  [(set (match_operand:SI 0 "register_operand" "=d")
1046
        (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%d"))
1047
                 (zero_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
1048
  ""
1049
  "%0 = %h1 * %h2 (FU);"
1050
  [(set_attr "type" "dsp32")])
1051
 
1052
(define_insn "usmulhisi3"
1053
  [(set (match_operand:SI 0 "register_operand" "=W")
1054
        (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "W"))
1055
                 (sign_extend:SI (match_operand:HI 2 "register_operand" "W"))))]
1056
  ""
1057
  "%0 = %h2 * %h1 (IS,M);"
1058
  [(set_attr "type" "dsp32")])
1059
 
1060
;; The processor also supports ireg += mreg or ireg -= mreg, but these
1061
;; are unusable if we don't ensure that the corresponding lreg is zero.
1062
;; The same applies to the add/subtract constant versions involving
1063
;; iregs
1064
 
1065
(define_insn "addsi3"
1066
  [(set (match_operand:SI 0 "register_operand" "=ad,a,d")
1067
        (plus:SI (match_operand:SI 1 "register_operand" "%0, a,d")
1068
                 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7, a,d")))]
1069
  ""
1070
  "@
1071
   %0 += %2;
1072
   %0 = %1 + %2;
1073
   %0 = %1 + %2;"
1074
  [(set_attr "type" "alu0")
1075
   (set_attr "length" "2,2,2")])
1076
 
1077
(define_insn "ssaddsi3"
1078
  [(set (match_operand:SI 0 "register_operand" "=d")
1079
        (ss_plus:SI (match_operand:SI 1 "register_operand" "d")
1080
                    (match_operand:SI 2 "register_operand" "d")))]
1081
  ""
1082
  "%0 = %1 + %2 (S);"
1083
  [(set_attr "type" "dsp32")])
1084
 
1085
(define_insn "subsi3"
1086
  [(set (match_operand:SI 0 "register_operand" "=da,d,a")
1087
        (minus:SI (match_operand:SI 1 "register_operand" "0,d,0")
1088
                  (match_operand:SI 2 "reg_or_neg7bit_operand" "KN7,d,a")))]
1089
  ""
1090
{
1091
  static const char *const strings_subsi3[] = {
1092
    "%0 += -%2;",
1093
    "%0 = %1 - %2;",
1094
    "%0 -= %2;",
1095
  };
1096
 
1097
  if (CONSTANT_P (operands[2]) && INTVAL (operands[2]) < 0) {
1098
     rtx tmp_op = operands[2];
1099
     operands[2] = GEN_INT (-INTVAL (operands[2]));
1100
     output_asm_insn ("%0 += %2;", operands);
1101
     operands[2] = tmp_op;
1102
     return "";
1103
  }
1104
 
1105
  return strings_subsi3[which_alternative];
1106
}
1107
  [(set_attr "type" "alu0")])
1108
 
1109
(define_insn "sssubsi3"
1110
  [(set (match_operand:SI 0 "register_operand" "=d")
1111
        (ss_minus:SI (match_operand:SI 1 "register_operand" "d")
1112
                     (match_operand:SI 2 "register_operand" "d")))]
1113
  ""
1114
  "%0 = %1 - %2 (S);"
1115
  [(set_attr "type" "dsp32")])
1116
 
1117
;; Bit test instructions
1118
 
1119
(define_insn "*not_bittst"
1120
 [(set (match_operand:BI 0 "register_operand" "=C")
1121
       (eq:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1122
                               (const_int 1)
1123
                               (match_operand:SI 2 "immediate_operand" "Ku5"))
1124
              (const_int 0)))]
1125
 ""
1126
 "cc = !BITTST (%1,%2);"
1127
  [(set_attr "type" "alu0")])
1128
 
1129
(define_insn "*bittst"
1130
 [(set (match_operand:BI 0 "register_operand" "=C")
1131
       (ne:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1132
                               (const_int 1)
1133
                               (match_operand:SI 2 "immediate_operand" "Ku5"))
1134
                (const_int 0)))]
1135
 ""
1136
 "cc = BITTST (%1,%2);"
1137
  [(set_attr "type" "alu0")])
1138
 
1139
(define_insn_and_split "*bit_extract"
1140
  [(set (match_operand:SI 0 "register_operand" "=d")
1141
        (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1142
                         (const_int 1)
1143
                         (match_operand:SI 2 "immediate_operand" "Ku5")))
1144
   (clobber (reg:BI REG_CC))]
1145
  ""
1146
  "#"
1147
  ""
1148
  [(set (reg:BI REG_CC)
1149
        (ne:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1150
               (const_int 0)))
1151
   (set (match_dup 0)
1152
        (ne:SI (reg:BI REG_CC) (const_int 0)))])
1153
 
1154
(define_insn_and_split "*not_bit_extract"
1155
  [(set (match_operand:SI 0 "register_operand" "=d")
1156
        (zero_extract:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1157
                         (const_int 1)
1158
                         (match_operand:SI 2 "immediate_operand" "Ku5")))
1159
   (clobber (reg:BI REG_CC))]
1160
  ""
1161
  "#"
1162
  ""
1163
  [(set (reg:BI REG_CC)
1164
        (eq:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1165
               (const_int 0)))
1166
   (set (match_dup 0)
1167
        (ne:SI (reg:BI REG_CC) (const_int 0)))])
1168
 
1169
(define_insn "*andsi_insn"
1170
  [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
1171
        (and:SI (match_operand:SI 1 "register_operand" "%0,d,d,d")
1172
                (match_operand:SI 2 "rhs_andsi3_operand" "L,M1,M2,d")))]
1173
  ""
1174
  "@
1175
   BITCLR (%0,%Y2);
1176
   %0 = %T1 (Z);
1177
   %0 = %h1 (Z);
1178
   %0 = %1 & %2;"
1179
  [(set_attr "type" "alu0")])
1180
 
1181
(define_expand "andsi3"
1182
  [(set (match_operand:SI 0 "register_operand" "")
1183
        (and:SI (match_operand:SI 1 "register_operand" "")
1184
                (match_operand:SI 2 "general_operand" "")))]
1185
  ""
1186
{
1187
  if (highbits_operand (operands[2], SImode))
1188
    {
1189
      operands[2] = GEN_INT (exact_log2 (-INTVAL (operands[2])));
1190
      emit_insn (gen_ashrsi3 (operands[0], operands[1], operands[2]));
1191
      emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
1192
      DONE;
1193
    }
1194
  if (! rhs_andsi3_operand (operands[2], SImode))
1195
    operands[2] = force_reg (SImode, operands[2]);
1196
})
1197
 
1198
(define_insn "iorsi3"
1199
  [(set (match_operand:SI 0 "register_operand" "=d,d")
1200
        (ior:SI (match_operand:SI 1 "register_operand" "%0,d")
1201
                (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1202
  ""
1203
  "@
1204
   BITSET (%0, %X2);
1205
   %0 = %1 | %2;"
1206
  [(set_attr "type" "alu0")])
1207
 
1208
(define_insn "xorsi3"
1209
  [(set (match_operand:SI 0 "register_operand" "=d,d")
1210
        (xor:SI (match_operand:SI 1 "register_operand" "%0,d")
1211
                  (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1212
  ""
1213
  "@
1214
   BITTGL (%0, %X2);
1215
   %0 = %1 ^ %2;"
1216
  [(set_attr "type" "alu0")])
1217
 
1218
(define_insn "smaxsi3"
1219
  [(set (match_operand:SI 0 "register_operand" "=d")
1220
        (smax:SI (match_operand:SI 1 "register_operand" "d")
1221
                 (match_operand:SI 2 "register_operand" "d")))]
1222
  ""
1223
  "%0 = max(%1,%2);"
1224
  [(set_attr "type" "dsp32")])
1225
 
1226
(define_insn "sminsi3"
1227
  [(set (match_operand:SI 0 "register_operand" "=d")
1228
        (smin:SI (match_operand:SI 1 "register_operand" "d")
1229
                 (match_operand:SI 2 "register_operand" "d")))]
1230
  ""
1231
  "%0 = min(%1,%2);"
1232
  [(set_attr "type" "dsp32")])
1233
 
1234
(define_insn "abssi2"
1235
  [(set (match_operand:SI 0 "register_operand" "=d")
1236
        (abs:SI (match_operand:SI 1 "register_operand" "d")))]
1237
  ""
1238
  "%0 = abs %1;"
1239
  [(set_attr "type" "dsp32")])
1240
 
1241
(define_insn "negsi2"
1242
  [(set (match_operand:SI 0 "register_operand" "=d")
1243
        (neg:SI (match_operand:SI 1 "register_operand" "d")))]
1244
  ""
1245
  "%0 = -%1;"
1246
  [(set_attr "type" "alu0")])
1247
 
1248
(define_insn "ssnegsi2"
1249
  [(set (match_operand:SI 0 "register_operand" "=d")
1250
        (ss_neg:SI (match_operand:SI 1 "register_operand" "d")))]
1251
  ""
1252
  "%0 = -%1 (S);"
1253
  [(set_attr "type" "dsp32")])
1254
 
1255
(define_insn "one_cmplsi2"
1256
  [(set (match_operand:SI 0 "register_operand" "=d")
1257
        (not:SI (match_operand:SI 1 "register_operand" "d")))]
1258
  ""
1259
  "%0 = ~%1;"
1260
  [(set_attr "type" "alu0")])
1261
 
1262
(define_insn "signbitssi2"
1263
  [(set (match_operand:HI 0 "register_operand" "=d")
1264
        (if_then_else:HI
1265
         (lt (match_operand:SI 1 "register_operand" "d") (const_int 0))
1266
         (clz:HI (not:SI (match_dup 1)))
1267
         (clz:HI (match_dup 1))))]
1268
  ""
1269
  "%h0 = signbits %1;"
1270
  [(set_attr "type" "dsp32")])
1271
 
1272
(define_insn "smaxhi3"
1273
  [(set (match_operand:HI 0 "register_operand" "=d")
1274
        (smax:HI (match_operand:HI 1 "register_operand" "d")
1275
                 (match_operand:HI 2 "register_operand" "d")))]
1276
  ""
1277
  "%0 = max(%1,%2) (V);"
1278
  [(set_attr "type" "dsp32")])
1279
 
1280
(define_insn "sminhi3"
1281
  [(set (match_operand:HI 0 "register_operand" "=d")
1282
        (smin:HI (match_operand:HI 1 "register_operand" "d")
1283
                 (match_operand:HI 2 "register_operand" "d")))]
1284
  ""
1285
  "%0 = min(%1,%2) (V);"
1286
  [(set_attr "type" "dsp32")])
1287
 
1288
(define_insn "abshi2"
1289
  [(set (match_operand:HI 0 "register_operand" "=d")
1290
        (abs:HI (match_operand:HI 1 "register_operand" "d")))]
1291
  ""
1292
  "%0 = abs %1 (V);"
1293
  [(set_attr "type" "dsp32")])
1294
 
1295
(define_insn "neghi2"
1296
  [(set (match_operand:HI 0 "register_operand" "=d")
1297
        (neg:HI (match_operand:HI 1 "register_operand" "d")))]
1298
  ""
1299
  "%0 = -%1;"
1300
  [(set_attr "type" "dsp32")])
1301
 
1302
(define_insn "ssneghi2"
1303
  [(set (match_operand:HI 0 "register_operand" "=d")
1304
        (ss_neg:HI (match_operand:HI 1 "register_operand" "d")))]
1305
  ""
1306
  "%0 = -%1 (V);"
1307
  [(set_attr "type" "dsp32")])
1308
 
1309
(define_insn "signbitshi2"
1310
  [(set (match_operand:HI 0 "register_operand" "=d")
1311
        (if_then_else:HI
1312
         (lt (match_operand:HI 1 "register_operand" "d") (const_int 0))
1313
         (clz:HI (not:HI (match_dup 1)))
1314
         (clz:HI (match_dup 1))))]
1315
  ""
1316
  "%h0 = signbits %h1;"
1317
  [(set_attr "type" "dsp32")])
1318
 
1319
(define_insn "mulsi3"
1320
  [(set (match_operand:SI 0 "register_operand" "=d")
1321
        (mult:SI (match_operand:SI 1 "register_operand" "%0")
1322
                 (match_operand:SI 2 "register_operand" "d")))]
1323
  ""
1324
  "%0 *= %2;"
1325
  [(set_attr "type" "mult")])
1326
 
1327
(define_expand "ashlsi3"
1328
  [(set (match_operand:SI 0 "register_operand" "")
1329
        (ashift:SI (match_operand:SI 1 "register_operand" "")
1330
                   (match_operand:SI 2 "nonmemory_operand" "")))]
1331
  ""
1332
{
1333
 if (GET_CODE (operands[2]) == CONST_INT
1334
     && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1335
   {
1336
     emit_insn (gen_movsi (operands[0], const0_rtx));
1337
     DONE;
1338
   }
1339
})
1340
 
1341
(define_insn_and_split "*ashlsi3_insn"
1342
  [(set (match_operand:SI 0 "register_operand" "=d,a,a,a")
1343
        (ashift:SI (match_operand:SI 1 "register_operand" "0,a,a,a")
1344
                   (match_operand:SI 2 "nonmemory_operand" "dKu5,P1,P2,?P3P4")))]
1345
  ""
1346
  "@
1347
   %0 <<= %2;
1348
   %0 = %1 + %1;
1349
   %0 = %1 << %2;
1350
   #"
1351
  "PREG_P (operands[0]) && INTVAL (operands[2]) > 2"
1352
  [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
1353
   (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
1354
  "operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
1355
  [(set_attr "type" "shft")])
1356
 
1357
(define_insn "ashrsi3"
1358
  [(set (match_operand:SI 0 "register_operand" "=d")
1359
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1360
                     (match_operand:SI 2 "nonmemory_operand" "dKu5")))]
1361
  ""
1362
  "%0 >>>= %2;"
1363
  [(set_attr "type" "shft")])
1364
 
1365
(define_insn "ror_one"
1366
  [(set (match_operand:SI 0 "register_operand" "=d")
1367
        (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1368
                (ashift:SI (zero_extend:SI (reg:BI REG_CC)) (const_int 31))))
1369
   (set (reg:BI REG_CC)
1370
        (zero_extract:BI (match_dup 1) (const_int 1) (const_int 0)))]
1371
  ""
1372
  "%0 = ROT %1 BY -1;"
1373
  [(set_attr "type" "shft")
1374
   (set_attr "length" "4")])
1375
 
1376
(define_insn "rol_one"
1377
  [(set (match_operand:SI 0 "register_operand" "+d")
1378
        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1379
                (zero_extend:SI (reg:BI REG_CC))))
1380
   (set (reg:BI REG_CC)
1381
        (zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))]
1382
  ""
1383
  "%0 = ROT %1 BY 1;"
1384
  [(set_attr "type" "shft")
1385
   (set_attr "length" "4")])
1386
 
1387
(define_expand "lshrdi3"
1388
  [(set (match_operand:DI 0 "register_operand" "")
1389
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1390
                     (match_operand:DI 2 "general_operand" "")))]
1391
  ""
1392
{
1393
  rtx lo_half[2], hi_half[2];
1394
 
1395
  if (operands[2] != const1_rtx)
1396
    FAIL;
1397
  if (! rtx_equal_p (operands[0], operands[1]))
1398
    emit_move_insn (operands[0], operands[1]);
1399
 
1400
  split_di (operands, 2, lo_half, hi_half);
1401
 
1402
  emit_move_insn (bfin_cc_rtx, const0_rtx);
1403
  emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1404
  emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1405
  DONE;
1406
})
1407
 
1408
(define_expand "ashrdi3"
1409
  [(set (match_operand:DI 0 "register_operand" "")
1410
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1411
                     (match_operand:DI 2 "general_operand" "")))]
1412
  ""
1413
{
1414
  rtx lo_half[2], hi_half[2];
1415
 
1416
  if (operands[2] != const1_rtx)
1417
    FAIL;
1418
  if (! rtx_equal_p (operands[0], operands[1]))
1419
    emit_move_insn (operands[0], operands[1]);
1420
 
1421
  split_di (operands, 2, lo_half, hi_half);
1422
 
1423
  emit_insn (gen_compare_lt (gen_rtx_REG (BImode, REG_CC),
1424
                             hi_half[1], const0_rtx));
1425
  emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1426
  emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1427
  DONE;
1428
})
1429
 
1430
(define_expand "ashldi3"
1431
  [(set (match_operand:DI 0 "register_operand" "")
1432
        (ashift:DI (match_operand:DI 1 "register_operand" "")
1433
                   (match_operand:DI 2 "general_operand" "")))]
1434
  ""
1435
{
1436
  rtx lo_half[2], hi_half[2];
1437
 
1438
  if (operands[2] != const1_rtx)
1439
    FAIL;
1440
  if (! rtx_equal_p (operands[0], operands[1]))
1441
    emit_move_insn (operands[0], operands[1]);
1442
 
1443
  split_di (operands, 2, lo_half, hi_half);
1444
 
1445
  emit_move_insn (bfin_cc_rtx, const0_rtx);
1446
  emit_insn (gen_rol_one (lo_half[0], lo_half[0]));
1447
  emit_insn (gen_rol_one (hi_half[0], hi_half[0]));
1448
  DONE;
1449
})
1450
 
1451
(define_insn "lshrsi3"
1452
  [(set (match_operand:SI 0 "register_operand" "=d,a")
1453
        (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0,a")
1454
                     (match_operand:SI 2 "nonmemory_operand" "dKu5,P1P2")))]
1455
  ""
1456
  "@
1457
   %0 >>= %2;
1458
   %0 = %1 >> %2;"
1459
  [(set_attr "type" "shft")])
1460
 
1461
;; A pattern to reload the equivalent of
1462
;;   (set (Dreg) (plus (FP) (large_constant)))
1463
;; or
1464
;;   (set (dagreg) (plus (FP) (arbitrary_constant)))
1465
;; using a scratch register
1466
(define_expand "reload_insi"
1467
  [(parallel [(set (match_operand:SI 0 "register_operand" "=w")
1468
                   (match_operand:SI 1 "fp_plus_const_operand" ""))
1469
              (clobber (match_operand:SI 2 "register_operand" "=&a"))])]
1470
  ""
1471
{
1472
  rtx fp_op = XEXP (operands[1], 0);
1473
  rtx const_op = XEXP (operands[1], 1);
1474
  rtx primary = operands[0];
1475
  rtx scratch = operands[2];
1476
 
1477
  emit_move_insn (scratch, const_op);
1478
  emit_insn (gen_addsi3 (scratch, scratch, fp_op));
1479
  emit_move_insn (primary, scratch);
1480
  DONE;
1481
})
1482
 
1483
;; Jump instructions
1484
 
1485
(define_insn "jump"
1486
  [(set (pc)
1487
        (label_ref (match_operand 0 "" "")))]
1488
  ""
1489
{
1490
  if (get_attr_length (insn) == 2)
1491
    return "jump.s %0;";
1492
  else
1493
    return "jump.l %0;";
1494
}
1495
  [(set_attr "type" "br")])
1496
 
1497
(define_insn "indirect_jump"
1498
  [(set (pc)
1499
        (match_operand:SI 0 "register_operand" "a"))]
1500
  ""
1501
  "jump (%0);"
1502
  [(set_attr "type" "misc")])
1503
 
1504
(define_expand "tablejump"
1505
  [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1506
              (use (label_ref (match_operand 1 "" "")))])]
1507
  ""
1508
{
1509
  /* In PIC mode, the table entries are stored PC relative.
1510
     Convert the relative address to an absolute address.  */
1511
  if (flag_pic)
1512
    {
1513
      rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1514
 
1515
      operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1516
                                         op1, NULL_RTX, 0, OPTAB_DIRECT);
1517
    }
1518
})
1519
 
1520
(define_insn "*tablejump_internal"
1521
  [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1522
   (use (label_ref (match_operand 1 "" "")))]
1523
  ""
1524
  "jump (%0);"
1525
  [(set_attr "type" "misc")])
1526
 
1527
;;  Hardware loop
1528
 
1529
; operand 0 is the loop count pseudo register
1530
; operand 1 is the number of loop iterations or 0 if it is unknown
1531
; operand 2 is the maximum number of loop iterations
1532
; operand 3 is the number of levels of enclosed loops
1533
; operand 4 is the label to jump to at the top of the loop
1534
(define_expand "doloop_end"
1535
  [(parallel [(set (pc) (if_then_else
1536
                          (ne (match_operand:SI 0 "" "")
1537
                              (const_int 1))
1538
                          (label_ref (match_operand 4 "" ""))
1539
                          (pc)))
1540
              (set (match_dup 0)
1541
                   (plus:SI (match_dup 0)
1542
                            (const_int -1)))
1543
              (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1544
              (clobber (match_scratch:SI 5 ""))])]
1545
  ""
1546
  {bfin_hardware_loop ();})
1547
 
1548
(define_insn "loop_end"
1549
  [(set (pc)
1550
        (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+a*d,*b*v*f,m")
1551
                          (const_int 1))
1552
                      (label_ref (match_operand 1 "" ""))
1553
                      (pc)))
1554
   (set (match_dup 0)
1555
        (plus (match_dup 0)
1556
              (const_int -1)))
1557
   (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1558
   (clobber (match_scratch:SI 2 "=X,&r,&r"))]
1559
  ""
1560
  "@
1561
   /* loop end %0 %l1 */
1562
   #
1563
   #"
1564
  [(set_attr "length" "6,10,14")])
1565
 
1566
(define_split
1567
  [(set (pc)
1568
        (if_then_else (ne (match_operand:SI 0 "nondp_reg_or_memory_operand" "")
1569
                          (const_int 1))
1570
                      (label_ref (match_operand 1 "" ""))
1571
                      (pc)))
1572
   (set (match_dup 0)
1573
        (plus (match_dup 0)
1574
              (const_int -1)))
1575
   (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1576
   (clobber (match_scratch:SI 2 "=&r"))]
1577
  "reload_completed"
1578
  [(set (match_dup 2) (match_dup 0))
1579
   (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
1580
   (set (match_dup 0) (match_dup 2))
1581
   (set (reg:BI REG_CC) (eq:BI (match_dup 2) (const_int 0)))
1582
   (set (pc)
1583
        (if_then_else (eq (reg:BI REG_CC)
1584
                          (const_int 0))
1585
                      (label_ref (match_dup 1))
1586
                      (pc)))]
1587
  "")
1588
 
1589
(define_insn "lsetup_with_autoinit"
1590
  [(set (match_operand:SI 0 "lt_register_operand" "=t")
1591
        (label_ref (match_operand 1 "" "")))
1592
   (set (match_operand:SI 2 "lb_register_operand" "=u")
1593
        (label_ref (match_operand 3 "" "")))
1594
   (set (match_operand:SI 4 "lc_register_operand" "=k")
1595
        (match_operand:SI 5 "register_operand" "a"))]
1596
  ""
1597
  "LSETUP (%1, %3) %4 = %5;"
1598
  [(set_attr "length" "4")])
1599
 
1600
(define_insn "lsetup_without_autoinit"
1601
  [(set (match_operand:SI 0 "lt_register_operand" "=t")
1602
        (label_ref (match_operand 1 "" "")))
1603
   (set (match_operand:SI 2 "lb_register_operand" "=u")
1604
        (label_ref (match_operand 3 "" "")))
1605
   (use (match_operand:SI 4 "lc_register_operand" "k"))]
1606
  ""
1607
  "LSETUP (%1, %3) %4;"
1608
  [(set_attr "length" "4")])
1609
 
1610
;;  Call instructions..
1611
 
1612
;; The explicit MEM inside the UNSPEC prevents the compiler from moving
1613
;; the load before a branch after a NULL test, or before a store that
1614
;; initializes a function descriptor.
1615
 
1616
(define_insn_and_split "load_funcdescsi"
1617
  [(set (match_operand:SI 0 "register_operand" "=a")
1618
        (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
1619
                            UNSPEC_VOLATILE_LOAD_FUNCDESC))]
1620
  ""
1621
  "#"
1622
  "reload_completed"
1623
  [(set (match_dup 0) (mem:SI (match_dup 1)))])
1624
 
1625
(define_expand "call"
1626
  [(parallel [(call (match_operand:SI 0 "" "")
1627
                    (match_operand 1 "" ""))
1628
              (use (match_operand 2 "" ""))])]
1629
  ""
1630
{
1631
  bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 0);
1632
  DONE;
1633
})
1634
 
1635
(define_expand "sibcall"
1636
  [(parallel [(call (match_operand:SI 0 "" "")
1637
                    (match_operand 1 "" ""))
1638
              (use (match_operand 2 "" ""))
1639
              (return)])]
1640
  ""
1641
{
1642
  bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 1);
1643
  DONE;
1644
})
1645
 
1646
(define_expand "call_value"
1647
  [(parallel [(set (match_operand 0 "register_operand" "")
1648
                   (call (match_operand:SI 1 "" "")
1649
                         (match_operand 2 "" "")))
1650
              (use (match_operand 3 "" ""))])]
1651
  ""
1652
{
1653
  bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 0);
1654
  DONE;
1655
})
1656
 
1657
(define_expand "sibcall_value"
1658
  [(parallel [(set (match_operand 0 "register_operand" "")
1659
                   (call (match_operand:SI 1 "" "")
1660
                         (match_operand 2 "" "")))
1661
              (use (match_operand 3 "" ""))
1662
              (return)])]
1663
  ""
1664
{
1665
  bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 1);
1666
  DONE;
1667
})
1668
 
1669
(define_insn "*call_symbol_fdpic"
1670
  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1671
         (match_operand 1 "general_operand" "g"))
1672
   (use (match_operand:SI 2 "register_operand" "Z"))
1673
   (use (match_operand 3 "" ""))]
1674
  "! SIBLING_CALL_P (insn)
1675
   && GET_CODE (operands[0]) == SYMBOL_REF
1676
   && !bfin_longcall_p (operands[0], INTVAL (operands[3]))"
1677
  "call %0;"
1678
  [(set_attr "type" "call")
1679
   (set_attr "length" "4")])
1680
 
1681
(define_insn "*sibcall_symbol_fdpic"
1682
  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1683
         (match_operand 1 "general_operand" "g"))
1684
   (use (match_operand:SI 2 "register_operand" "Z"))
1685
   (use (match_operand 3 "" ""))
1686
   (return)]
1687
  "SIBLING_CALL_P (insn)
1688
   && GET_CODE (operands[0]) == SYMBOL_REF
1689
   && !bfin_longcall_p (operands[0], INTVAL (operands[3]))"
1690
  "jump.l %0;"
1691
  [(set_attr "type" "br")
1692
   (set_attr "length" "4")])
1693
 
1694
(define_insn "*call_value_symbol_fdpic"
1695
  [(set (match_operand 0 "register_operand" "=d")
1696
        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1697
              (match_operand 2 "general_operand" "g")))
1698
   (use (match_operand:SI 3 "register_operand" "Z"))
1699
   (use (match_operand 4 "" ""))]
1700
  "! SIBLING_CALL_P (insn)
1701
   && GET_CODE (operands[1]) == SYMBOL_REF
1702
   && !bfin_longcall_p (operands[1], INTVAL (operands[4]))"
1703
  "call %1;"
1704
  [(set_attr "type" "call")
1705
   (set_attr "length" "4")])
1706
 
1707
(define_insn "*sibcall_value_symbol_fdpic"
1708
  [(set (match_operand 0 "register_operand" "=d")
1709
         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1710
               (match_operand 2 "general_operand" "g")))
1711
   (use (match_operand:SI 3 "register_operand" "Z"))
1712
   (use (match_operand 4 "" ""))
1713
   (return)]
1714
  "SIBLING_CALL_P (insn)
1715
   && GET_CODE (operands[1]) == SYMBOL_REF
1716
   && !bfin_longcall_p (operands[1], INTVAL (operands[4]))"
1717
  "jump.l %1;"
1718
  [(set_attr "type" "br")
1719
   (set_attr "length" "4")])
1720
 
1721
(define_insn "*call_insn_fdpic"
1722
  [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y"))
1723
         (match_operand 1 "general_operand" "g"))
1724
   (use (match_operand:SI 2 "register_operand" "Z"))
1725
   (use (match_operand 3 "" ""))]
1726
  "! SIBLING_CALL_P (insn)"
1727
  "call (%0);"
1728
  [(set_attr "type" "call")
1729
   (set_attr "length" "2")])
1730
 
1731
(define_insn "*sibcall_insn_fdpic"
1732
  [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y"))
1733
         (match_operand 1 "general_operand" "g"))
1734
   (use (match_operand:SI 2 "register_operand" "Z"))
1735
   (use (match_operand 3 "" ""))
1736
   (return)]
1737
  "SIBLING_CALL_P (insn)"
1738
  "jump (%0);"
1739
  [(set_attr "type" "br")
1740
   (set_attr "length" "2")])
1741
 
1742
(define_insn "*call_value_insn_fdpic"
1743
  [(set (match_operand 0 "register_operand" "=d")
1744
        (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y"))
1745
              (match_operand 2 "general_operand" "g")))
1746
   (use (match_operand:SI 3 "register_operand" "Z"))
1747
   (use (match_operand 4 "" ""))]
1748
  "! SIBLING_CALL_P (insn)"
1749
  "call (%1);"
1750
  [(set_attr "type" "call")
1751
   (set_attr "length" "2")])
1752
 
1753
(define_insn "*sibcall_value_insn_fdpic"
1754
  [(set (match_operand 0 "register_operand" "=d")
1755
         (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y"))
1756
               (match_operand 2 "general_operand" "g")))
1757
   (use (match_operand:SI 3 "register_operand" "Z"))
1758
   (use (match_operand 4 "" ""))
1759
   (return)]
1760
  "SIBLING_CALL_P (insn)"
1761
  "jump (%1);"
1762
  [(set_attr "type" "br")
1763
   (set_attr "length" "2")])
1764
 
1765
(define_insn "*call_symbol"
1766
  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1767
         (match_operand 1 "general_operand" "g"))
1768
   (use (match_operand 2 "" ""))]
1769
  "! SIBLING_CALL_P (insn)
1770
   && !TARGET_ID_SHARED_LIBRARY
1771
   && GET_CODE (operands[0]) == SYMBOL_REF
1772
   && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
1773
  "call %0;"
1774
  [(set_attr "type" "call")
1775
   (set_attr "length" "4")])
1776
 
1777
(define_insn "*sibcall_symbol"
1778
  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1779
         (match_operand 1 "general_operand" "g"))
1780
   (use (match_operand 2 "" ""))
1781
   (return)]
1782
  "SIBLING_CALL_P (insn)
1783
   && !TARGET_ID_SHARED_LIBRARY
1784
   && GET_CODE (operands[0]) == SYMBOL_REF
1785
   && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
1786
  "jump.l %0;"
1787
  [(set_attr "type" "br")
1788
   (set_attr "length" "4")])
1789
 
1790
(define_insn "*call_value_symbol"
1791
  [(set (match_operand 0 "register_operand" "=d")
1792
        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1793
              (match_operand 2 "general_operand" "g")))
1794
   (use (match_operand 3 "" ""))]
1795
  "! SIBLING_CALL_P (insn)
1796
   && !TARGET_ID_SHARED_LIBRARY
1797
   && GET_CODE (operands[1]) == SYMBOL_REF
1798
   && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
1799
  "call %1;"
1800
  [(set_attr "type" "call")
1801
   (set_attr "length" "4")])
1802
 
1803
(define_insn "*sibcall_value_symbol"
1804
  [(set (match_operand 0 "register_operand" "=d")
1805
         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1806
               (match_operand 2 "general_operand" "g")))
1807
   (use (match_operand 3 "" ""))
1808
   (return)]
1809
  "SIBLING_CALL_P (insn)
1810
   && !TARGET_ID_SHARED_LIBRARY
1811
   && GET_CODE (operands[1]) == SYMBOL_REF
1812
   && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
1813
  "jump.l %1;"
1814
  [(set_attr "type" "br")
1815
   (set_attr "length" "4")])
1816
 
1817
(define_insn "*call_insn"
1818
  [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a"))
1819
         (match_operand 1 "general_operand" "g"))
1820
   (use (match_operand 2 "" ""))]
1821
  "! SIBLING_CALL_P (insn)"
1822
  "call (%0);"
1823
  [(set_attr "type" "call")
1824
   (set_attr "length" "2")])
1825
 
1826
(define_insn "*sibcall_insn"
1827
  [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "z"))
1828
         (match_operand 1 "general_operand" "g"))
1829
   (use (match_operand 2 "" ""))
1830
   (return)]
1831
  "SIBLING_CALL_P (insn)"
1832
  "jump (%0);"
1833
  [(set_attr "type" "br")
1834
   (set_attr "length" "2")])
1835
 
1836
(define_insn "*call_value_insn"
1837
  [(set (match_operand 0 "register_operand" "=d")
1838
        (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a"))
1839
              (match_operand 2 "general_operand" "g")))
1840
   (use (match_operand 3 "" ""))]
1841
  "! SIBLING_CALL_P (insn)"
1842
  "call (%1);"
1843
  [(set_attr "type" "call")
1844
   (set_attr "length" "2")])
1845
 
1846
(define_insn "*sibcall_value_insn"
1847
  [(set (match_operand 0 "register_operand" "=d")
1848
         (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "z"))
1849
               (match_operand 2 "general_operand" "g")))
1850
   (use (match_operand 3 "" ""))
1851
   (return)]
1852
  "SIBLING_CALL_P (insn)"
1853
  "jump (%1);"
1854
  [(set_attr "type" "br")
1855
   (set_attr "length" "2")])
1856
 
1857
;; Block move patterns
1858
 
1859
;; We cheat.  This copies one more word than operand 2 indicates.
1860
 
1861
(define_insn "rep_movsi"
1862
  [(set (match_operand:SI 0 "register_operand" "=&a")
1863
        (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1864
                          (ashift:SI (match_operand:SI 2 "register_operand" "a")
1865
                                     (const_int 2)))
1866
                 (const_int 4)))
1867
   (set (match_operand:SI 1 "register_operand" "=&b")
1868
        (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1869
                          (ashift:SI (match_dup 2) (const_int 2)))
1870
                 (const_int 4)))
1871
   (set (mem:BLK (match_dup 3))
1872
        (mem:BLK (match_dup 4)))
1873
   (use (match_dup 2))
1874
   (clobber (match_scratch:HI 5 "=&d"))
1875
   (clobber (reg:SI REG_LT1))
1876
   (clobber (reg:SI REG_LC1))
1877
   (clobber (reg:SI REG_LB1))]
1878
  ""
1879
  "%5 = [%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || [%3++] = %5 || %5 = [%4++]; [%3++] = %5;"
1880
  [(set_attr "type" "misc")
1881
   (set_attr "length" "16")
1882
   (set_attr "seq_insns" "multi")])
1883
 
1884
(define_insn "rep_movhi"
1885
  [(set (match_operand:SI 0 "register_operand" "=&a")
1886
        (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1887
                          (ashift:SI (match_operand:SI 2 "register_operand" "a")
1888
                                     (const_int 1)))
1889
                 (const_int 2)))
1890
   (set (match_operand:SI 1 "register_operand" "=&b")
1891
        (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1892
                          (ashift:SI (match_dup 2) (const_int 1)))
1893
                 (const_int 2)))
1894
   (set (mem:BLK (match_dup 3))
1895
        (mem:BLK (match_dup 4)))
1896
   (use (match_dup 2))
1897
   (clobber (match_scratch:HI 5 "=&d"))
1898
   (clobber (reg:SI REG_LT1))
1899
   (clobber (reg:SI REG_LC1))
1900
   (clobber (reg:SI REG_LB1))]
1901
  ""
1902
  "%h5 = W[%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || W [%3++] = %5 || %h5 = W [%4++]; W [%3++] = %5;"
1903
  [(set_attr "type" "misc")
1904
   (set_attr "length" "16")
1905
   (set_attr "seq_insns" "multi")])
1906
 
1907
(define_expand "movmemsi"
1908
  [(match_operand:BLK 0 "general_operand" "")
1909
   (match_operand:BLK 1 "general_operand" "")
1910
   (match_operand:SI 2 "const_int_operand" "")
1911
   (match_operand:SI 3 "const_int_operand" "")]
1912
  ""
1913
{
1914
  if (bfin_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
1915
    DONE;
1916
  FAIL;
1917
})
1918
 
1919
;; Conditional branch patterns
1920
;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
1921
 
1922
;; The only outcome of this pattern is that global variables
1923
;; bfin_compare_op[01] are set for use in bcond patterns.
1924
 
1925
(define_expand "cmpbi"
1926
 [(set (cc0) (compare (match_operand:BI 0 "register_operand" "")
1927
                      (match_operand:BI 1 "immediate_operand" "")))]
1928
 ""
1929
{
1930
  bfin_compare_op0 = operands[0];
1931
  bfin_compare_op1 = operands[1];
1932
  DONE;
1933
})
1934
 
1935
(define_expand "cmpsi"
1936
 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
1937
                      (match_operand:SI 1 "reg_or_const_int_operand" "")))]
1938
 ""
1939
{
1940
  bfin_compare_op0 = operands[0];
1941
  bfin_compare_op1 = operands[1];
1942
  DONE;
1943
})
1944
 
1945
(define_insn "compare_eq"
1946
  [(set (match_operand:BI 0 "register_operand" "=C,C")
1947
        (eq:BI (match_operand:SI 1 "register_operand" "d,a")
1948
               (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
1949
  ""
1950
  "cc =%1==%2;"
1951
  [(set_attr "type" "compare")])
1952
 
1953
(define_insn "compare_ne"
1954
  [(set (match_operand:BI 0 "register_operand" "=C,C")
1955
        (ne:BI (match_operand:SI 1 "register_operand" "d,a")
1956
               (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
1957
  "0"
1958
  "cc =%1!=%2;"
1959
  [(set_attr "type" "compare")])
1960
 
1961
(define_insn "compare_lt"
1962
  [(set (match_operand:BI 0 "register_operand" "=C,C")
1963
        (lt:BI (match_operand:SI 1 "register_operand" "d,a")
1964
               (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
1965
  ""
1966
  "cc =%1<%2;"
1967
  [(set_attr "type" "compare")])
1968
 
1969
(define_insn "compare_le"
1970
  [(set (match_operand:BI 0 "register_operand" "=C,C")
1971
        (le:BI (match_operand:SI 1 "register_operand" "d,a")
1972
               (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
1973
  ""
1974
  "cc =%1<=%2;"
1975
  [(set_attr "type" "compare")])
1976
 
1977
(define_insn "compare_leu"
1978
  [(set (match_operand:BI 0 "register_operand" "=C,C")
1979
        (leu:BI (match_operand:SI 1 "register_operand" "d,a")
1980
                (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
1981
  ""
1982
  "cc =%1<=%2 (iu);"
1983
  [(set_attr "type" "compare")])
1984
 
1985
(define_insn "compare_ltu"
1986
  [(set (match_operand:BI 0 "register_operand" "=C,C")
1987
        (ltu:BI (match_operand:SI 1 "register_operand" "d,a")
1988
                (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
1989
  ""
1990
  "cc =%1<%2 (iu);"
1991
  [(set_attr "type" "compare")])
1992
 
1993
(define_expand "beq"
1994
  [(set (match_dup 1) (match_dup 2))
1995
   (set (pc)
1996
        (if_then_else (match_dup 3)
1997
                   (label_ref (match_operand 0 "" ""))
1998
                   (pc)))]
1999
  ""
2000
{
2001
  rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
2002
  operands[1] = bfin_cc_rtx;    /* hard register: CC */
2003
  operands[2] = gen_rtx_EQ (BImode, op0, op1);
2004
  /* If we have a BImode input, then we already have a compare result, and
2005
     do not need to emit another comparison.  */
2006
  if (GET_MODE (bfin_compare_op0) == BImode)
2007
    {
2008
      gcc_assert (bfin_compare_op1 == const0_rtx);
2009
      emit_insn (gen_cbranchbi4 (operands[2], op0, op1, operands[0]));
2010
      DONE;
2011
    }
2012
 
2013
  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2014
})
2015
 
2016
(define_expand "bne"
2017
  [(set (match_dup 1) (match_dup 2))
2018
   (set (pc)
2019
        (if_then_else (match_dup 3)
2020
                      (label_ref (match_operand 0 "" ""))
2021
                    (pc)))]
2022
  ""
2023
{
2024
  rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
2025
  /* If we have a BImode input, then we already have a compare result, and
2026
     do not need to emit another comparison.  */
2027
  if (GET_MODE (bfin_compare_op0) == BImode)
2028
    {
2029
      rtx cmp = gen_rtx_NE (BImode, op0, op1);
2030
 
2031
      gcc_assert (bfin_compare_op1 == const0_rtx);
2032
      emit_insn (gen_cbranchbi4 (cmp, op0, op1, operands[0]));
2033
      DONE;
2034
    }
2035
 
2036
  operands[1] = bfin_cc_rtx;    /* hard register: CC */
2037
  operands[2] = gen_rtx_EQ (BImode, op0, op1);
2038
  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2039
})
2040
 
2041
(define_expand "bgt"
2042
  [(set (match_dup 1) (match_dup 2))
2043
   (set (pc)
2044
        (if_then_else (match_dup 3)
2045
                      (label_ref (match_operand 0 "" ""))
2046
                    (pc)))]
2047
  ""
2048
{
2049
  operands[1] = bfin_cc_rtx;
2050
  operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
2051
  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2052
})
2053
 
2054
(define_expand "bgtu"
2055
  [(set (match_dup 1) (match_dup 2))
2056
   (set (pc)
2057
        (if_then_else (match_dup 3)
2058
                      (label_ref (match_operand 0 "" ""))
2059
                    (pc)))]
2060
  ""
2061
{
2062
  operands[1] = bfin_cc_rtx;
2063
  operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
2064
  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2065
})
2066
 
2067
(define_expand "blt"
2068
  [(set (match_dup 1) (match_dup 2))
2069
   (set (pc)
2070
        (if_then_else (match_dup 3)
2071
                      (label_ref (match_operand 0 "" ""))
2072
                    (pc)))]
2073
  ""
2074
{
2075
  operands[1] = bfin_cc_rtx;
2076
  operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
2077
  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2078
})
2079
 
2080
(define_expand "bltu"
2081
  [(set (match_dup 1) (match_dup 2))
2082
   (set (pc)
2083
        (if_then_else (match_dup 3)
2084
                      (label_ref (match_operand 0 "" ""))
2085
                      (pc)))]
2086
  ""
2087
{
2088
  operands[1] = bfin_cc_rtx;
2089
  operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
2090
  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2091
})
2092
 
2093
 
2094
(define_expand "bge"
2095
  [(set (match_dup 1) (match_dup 2))
2096
   (set (pc)
2097
        (if_then_else (match_dup 3)
2098
                      (label_ref (match_operand 0 "" ""))
2099
                      (pc)))]
2100
  ""
2101
{
2102
  operands[1] = bfin_cc_rtx;
2103
  operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
2104
  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2105
})
2106
 
2107
(define_expand "bgeu"
2108
  [(set (match_dup 1) (match_dup 2))
2109
   (set (pc)
2110
        (if_then_else (match_dup 3)
2111
                      (label_ref (match_operand 0 "" ""))
2112
                      (pc)))]
2113
  ""
2114
{
2115
  operands[1] = bfin_cc_rtx;
2116
  operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
2117
  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
2118
})
2119
 
2120
(define_expand "ble"
2121
  [(set (match_dup 1) (match_dup 2))
2122
   (set (pc)
2123
        (if_then_else (match_dup 3)
2124
                      (label_ref (match_operand 0 "" ""))
2125
                      (pc)))]
2126
  ""
2127
{
2128
  operands[1] = bfin_cc_rtx;
2129
  operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
2130
  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2131
})
2132
 
2133
(define_expand "bleu"
2134
  [(set (match_dup 1) (match_dup 2))
2135
   (set (pc)
2136
        (if_then_else (match_dup 3)
2137
                      (label_ref (match_operand 0 "" ""))
2138
                      (pc)))
2139
  ]
2140
  ""
2141
{
2142
  operands[1] = bfin_cc_rtx;
2143
  operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
2144
  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
2145
})
2146
 
2147
(define_insn "cbranchbi4"
2148
  [(set (pc)
2149
        (if_then_else
2150
         (match_operator 0 "bfin_cbranch_operator"
2151
                         [(match_operand:BI 1 "register_operand" "C")
2152
                          (match_operand:BI 2 "immediate_operand" "P0")])
2153
         (label_ref (match_operand 3 "" ""))
2154
         (pc)))]
2155
  ""
2156
{
2157
  asm_conditional_branch (insn, operands, 0, 0);
2158
  return "";
2159
}
2160
  [(set_attr "type" "brcc")])
2161
 
2162
;; Special cbranch patterns to deal with the speculative load problem - see
2163
;; bfin_reorg for details.
2164
 
2165
(define_insn "cbranch_predicted_taken"
2166
  [(set (pc)
2167
        (if_then_else
2168
         (match_operator 0 "bfin_cbranch_operator"
2169
                         [(match_operand:BI 1 "register_operand" "C")
2170
                          (match_operand:BI 2 "immediate_operand" "P0")])
2171
         (label_ref (match_operand 3 "" ""))
2172
         (pc)))
2173
   (unspec [(const_int 0)] UNSPEC_CBRANCH_TAKEN)]
2174
  ""
2175
{
2176
  asm_conditional_branch (insn, operands, 0, 1);
2177
  return "";
2178
}
2179
  [(set_attr "type" "brcc")])
2180
 
2181
(define_insn "cbranch_with_nops"
2182
  [(set (pc)
2183
        (if_then_else
2184
         (match_operator 0 "bfin_cbranch_operator"
2185
                         [(match_operand:BI 1 "register_operand" "C")
2186
                          (match_operand:BI 2 "immediate_operand" "P0")])
2187
         (label_ref (match_operand 3 "" ""))
2188
         (pc)))
2189
   (unspec [(match_operand 4 "immediate_operand" "")] UNSPEC_CBRANCH_NOPS)]
2190
  "reload_completed"
2191
{
2192
  asm_conditional_branch (insn, operands, INTVAL (operands[4]), 0);
2193
  return "";
2194
}
2195
  [(set_attr "type" "brcc")
2196
   (set_attr "length" "6")])
2197
 
2198
;; setcc insns.  */
2199
(define_expand "seq"
2200
  [(set (match_dup 1) (eq:BI (match_dup 2) (match_dup 3)))
2201
   (set (match_operand:SI 0 "register_operand" "")
2202
        (ne:SI (match_dup 1) (const_int 0)))]
2203
  ""
2204
{
2205
  operands[2] = bfin_compare_op0;
2206
  operands[3] = bfin_compare_op1;
2207
  operands[1] = bfin_cc_rtx;
2208
})
2209
 
2210
(define_expand "slt"
2211
  [(set (match_dup 1) (lt:BI (match_dup 2) (match_dup 3)))
2212
   (set (match_operand:SI 0 "register_operand" "")
2213
        (ne:SI (match_dup 1) (const_int 0)))]
2214
  ""
2215
{
2216
   operands[2] = bfin_compare_op0;
2217
   operands[3] = bfin_compare_op1;
2218
   operands[1] = bfin_cc_rtx;
2219
})
2220
 
2221
(define_expand "sle"
2222
  [(set (match_dup 1) (le:BI (match_dup 2) (match_dup 3)))
2223
   (set (match_operand:SI 0 "register_operand" "")
2224
        (ne:SI (match_dup 1) (const_int 0)))]
2225
  ""
2226
{
2227
   operands[2] = bfin_compare_op0;
2228
   operands[3] = bfin_compare_op1;
2229
   operands[1] = bfin_cc_rtx;
2230
})
2231
 
2232
(define_expand "sltu"
2233
  [(set (match_dup 1) (ltu:BI (match_dup 2) (match_dup 3)))
2234
   (set (match_operand:SI 0 "register_operand" "")
2235
        (ne:SI (match_dup 1) (const_int 0)))]
2236
  ""
2237
{
2238
   operands[2] = bfin_compare_op0;
2239
   operands[3] = bfin_compare_op1;
2240
   operands[1] = bfin_cc_rtx;
2241
})
2242
 
2243
(define_expand "sleu"
2244
  [(set (match_dup 1) (leu:BI (match_dup 2) (match_dup 3)))
2245
   (set (match_operand:SI 0 "register_operand" "")
2246
        (ne:SI (match_dup 1) (const_int 0)))]
2247
  ""
2248
{
2249
   operands[2] = bfin_compare_op0;
2250
   operands[3] = bfin_compare_op1;
2251
   operands[1] = bfin_cc_rtx;
2252
})
2253
 
2254
(define_insn "nop"
2255
  [(const_int 0)]
2256
  ""
2257
  "nop;")
2258
 
2259
;;;;;;;;;;;;;;;;;;;;   CC2dreg   ;;;;;;;;;;;;;;;;;;;;;;;;;
2260
(define_insn "movsibi"
2261
  [(set (match_operand:BI 0 "register_operand" "=C")
2262
        (ne:BI (match_operand:SI 1 "register_operand" "d")
2263
               (const_int 0)))]
2264
  ""
2265
  "CC = %1;"
2266
  [(set_attr "length" "2")])
2267
 
2268
(define_insn "movbisi"
2269
  [(set (match_operand:SI 0 "register_operand" "=d")
2270
        (ne:SI (match_operand:BI 1 "register_operand" "C")
2271
               (const_int 0)))]
2272
  ""
2273
  "%0 = CC;"
2274
  [(set_attr "length" "2")])
2275
 
2276
(define_insn ""
2277
  [(set (match_operand:BI 0 "register_operand" "=C")
2278
        (eq:BI (match_operand:BI 1 "register_operand" " 0")
2279
               (const_int 0)))]
2280
  ""
2281
  "%0 = ! %0;"    /*  NOT CC;"  */
2282
  [(set_attr "type" "compare")])
2283
 
2284
;; Vector and DSP insns
2285
 
2286
(define_insn ""
2287
  [(set (match_operand:SI 0 "register_operand" "=d")
2288
        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2289
                           (const_int 24))
2290
                (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2291
                             (const_int 8))))]
2292
  ""
2293
  "%0 = ALIGN8(%1, %2);"
2294
  [(set_attr "type" "dsp32")])
2295
 
2296
(define_insn ""
2297
  [(set (match_operand:SI 0 "register_operand" "=d")
2298
        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2299
                           (const_int 16))
2300
                (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2301
                             (const_int 16))))]
2302
  ""
2303
  "%0 = ALIGN16(%1, %2);"
2304
  [(set_attr "type" "dsp32")])
2305
 
2306
(define_insn ""
2307
  [(set (match_operand:SI 0 "register_operand" "=d")
2308
        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2309
                           (const_int 8))
2310
                (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2311
                             (const_int 24))))]
2312
  ""
2313
  "%0 = ALIGN24(%1, %2);"
2314
  [(set_attr "type" "dsp32")])
2315
 
2316
;; Prologue and epilogue.
2317
 
2318
(define_expand "prologue"
2319
  [(const_int 1)]
2320
  ""
2321
  "bfin_expand_prologue (); DONE;")
2322
 
2323
(define_expand "epilogue"
2324
  [(const_int 1)]
2325
  ""
2326
  "bfin_expand_epilogue (1, 0); DONE;")
2327
 
2328
(define_expand "sibcall_epilogue"
2329
  [(const_int 1)]
2330
  ""
2331
  "bfin_expand_epilogue (0, 0); DONE;")
2332
 
2333
(define_expand "eh_return"
2334
  [(unspec_volatile [(match_operand:SI 0 "register_operand" "")]
2335
                    UNSPEC_VOLATILE_EH_RETURN)]
2336
  ""
2337
{
2338
  emit_move_insn (EH_RETURN_HANDLER_RTX, operands[0]);
2339
  emit_jump_insn (gen_eh_return_internal ());
2340
  emit_barrier ();
2341
  DONE;
2342
})
2343
 
2344
(define_insn_and_split "eh_return_internal"
2345
  [(set (pc)
2346
        (unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN))]
2347
  ""
2348
  "#"
2349
  "reload_completed"
2350
  [(const_int 1)]
2351
  "bfin_expand_epilogue (1, 1); DONE;")
2352
 
2353
(define_insn "link"
2354
  [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS))
2355
   (set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:SI REG_FP))
2356
   (set (reg:SI REG_FP)
2357
        (plus:SI (reg:SI REG_SP) (const_int -8)))
2358
   (set (reg:SI REG_SP)
2359
        (plus:SI (reg:SI REG_SP) (match_operand:SI 0 "immediate_operand" "i")))]
2360
  ""
2361
  "LINK %Z0;"
2362
  [(set_attr "length" "4")])
2363
 
2364
(define_insn "unlink"
2365
  [(set (reg:SI REG_FP) (mem:SI (reg:SI REG_FP)))
2366
   (set (reg:SI REG_RETS) (mem:SI (plus:SI (reg:SI REG_FP) (const_int 4))))
2367
   (set (reg:SI REG_SP) (plus:SI (reg:SI REG_FP) (const_int 8)))]
2368
  ""
2369
  "UNLINK;"
2370
  [(set_attr "length" "4")])
2371
 
2372
;; This pattern is slightly clumsy.  The stack adjust must be the final SET in
2373
;; the pattern, otherwise dwarf2out becomes very confused about which reg goes
2374
;; where on the stack, since it goes through all elements of the parallel in
2375
;; sequence.
2376
(define_insn "push_multiple"
2377
  [(match_parallel 0 "push_multiple_operation"
2378
    [(unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_PUSH_MULTIPLE)])]
2379
  ""
2380
{
2381
  output_push_multiple (insn, operands);
2382
  return "";
2383
})
2384
 
2385
(define_insn "pop_multiple"
2386
  [(match_parallel 0 "pop_multiple_operation"
2387
    [(set (reg:SI REG_SP)
2388
          (plus:SI (reg:SI REG_SP) (match_operand:SI 1 "immediate_operand" "i")))])]
2389
  ""
2390
{
2391
  output_pop_multiple (insn, operands);
2392
  return "";
2393
})
2394
 
2395
(define_insn "return_internal"
2396
  [(return)
2397
   (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)]
2398
  "reload_completed"
2399
{
2400
  switch (INTVAL (operands[0]))
2401
    {
2402
    case EXCPT_HANDLER:
2403
      return "rtx;";
2404
    case NMI_HANDLER:
2405
      return "rtn;";
2406
    case INTERRUPT_HANDLER:
2407
      return "rti;";
2408
    case SUBROUTINE:
2409
      return "rts;";
2410
    }
2411
  gcc_unreachable ();
2412
})
2413
 
2414
(define_insn "csync"
2415
  [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
2416
  ""
2417
  "csync;"
2418
  [(set_attr "type" "sync")])
2419
 
2420
(define_insn "ssync"
2421
  [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_SSYNC)]
2422
  ""
2423
  "ssync;"
2424
  [(set_attr "type" "sync")])
2425
 
2426
(define_insn "trap"
2427
  [(trap_if (const_int 1) (const_int 3))]
2428
  ""
2429
  "excpt 3;"
2430
  [(set_attr "type" "misc")
2431
   (set_attr "length" "2")])
2432
 
2433
(define_insn "trapifcc"
2434
  [(trap_if (reg:BI REG_CC) (const_int 3))]
2435
  ""
2436
  "if !cc jump 4 (bp); excpt 3;"
2437
  [(set_attr "type" "misc")
2438
   (set_attr "length" "4")
2439
   (set_attr "seq_insns" "multi")])
2440
 
2441
;;; Vector instructions
2442
 
2443
;; First, all sorts of move variants
2444
 
2445
(define_insn "movhi_low2high"
2446
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2447
        (vec_concat:V2HI
2448
         (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2449
                        (parallel [(const_int 0)]))
2450
         (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2451
                        (parallel [(const_int 0)]))))]
2452
  ""
2453
  "%d0 = %h2 << 0;"
2454
  [(set_attr "type" "dsp32")])
2455
 
2456
(define_insn "movhi_high2high"
2457
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2458
        (vec_concat:V2HI
2459
         (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2460
                        (parallel [(const_int 0)]))
2461
         (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2462
                        (parallel [(const_int 1)]))))]
2463
  ""
2464
  "%d0 = %d2 << 0;"
2465
  [(set_attr "type" "dsp32")])
2466
 
2467
(define_insn "movhi_low2low"
2468
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2469
        (vec_concat:V2HI
2470
         (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2471
                        (parallel [(const_int 0)]))
2472
         (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2473
                        (parallel [(const_int 1)]))))]
2474
  ""
2475
  "%h0 = %h2 << 0;"
2476
  [(set_attr "type" "dsp32")])
2477
 
2478
(define_insn "movhi_high2low"
2479
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2480
        (vec_concat:V2HI
2481
         (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2482
                        (parallel [(const_int 1)]))
2483
         (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2484
                        (parallel [(const_int 1)]))))]
2485
  ""
2486
  "%h0 = %d2 << 0;"
2487
  [(set_attr "type" "dsp32")])
2488
 
2489
(define_insn "movhiv2hi_low"
2490
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2491
        (vec_concat:V2HI
2492
         (match_operand:HI 2 "register_operand" "d")
2493
         (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2494
                        (parallel [(const_int 1)]))))]
2495
  ""
2496
  "%h0 = %h2 << 0;"
2497
  [(set_attr "type" "dsp32")])
2498
 
2499
(define_insn "movhiv2hi_high"
2500
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2501
        (vec_concat:V2HI
2502
         (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2503
                        (parallel [(const_int 0)]))
2504
         (match_operand:HI 2 "register_operand" "d")))]
2505
  ""
2506
  "%d0 = %h2 << 0;"
2507
  [(set_attr "type" "dsp32")])
2508
 
2509
;; No earlyclobber on alternative two since our sequence ought to be safe.
2510
;; The order of operands is intentional to match the VDSP builtin (high word
2511
;; is passed first).
2512
(define_insn_and_split "composev2hi"
2513
  [(set (match_operand:V2HI 0 "register_operand" "=d,d")
2514
        (vec_concat:V2HI (match_operand:HI 2 "register_operand" "0,d")
2515
                         (match_operand:HI 1 "register_operand" "d,d")))]
2516
  ""
2517
  "@
2518
   %d0 = %h2 << 0;
2519
   #"
2520
  "reload_completed"
2521
  [(set (match_dup 0)
2522
        (vec_concat:V2HI
2523
         (vec_select:HI (match_dup 0) (parallel [(const_int 0)]))
2524
         (match_dup 2)))
2525
   (set (match_dup 0)
2526
        (vec_concat:V2HI
2527
         (match_dup 1)
2528
         (vec_select:HI (match_dup 0) (parallel [(const_int 1)]))))]
2529
  ""
2530
  [(set_attr "type" "dsp32")])
2531
 
2532
; Like composev2hi, but operating on elements of V2HI vectors.
2533
; Useful on its own, and as a combiner bridge for the multiply and
2534
; mac patterns.
2535
(define_insn "packv2hi"
2536
  [(set (match_operand:V2HI 0 "register_operand" "=d,d,d,d")
2537
        (vec_concat:V2HI (vec_select:HI
2538
                          (match_operand:V2HI 1 "register_operand" "d,d,d,d")
2539
                          (parallel [(match_operand 3 "const01_operand" "P0,P1,P0,P1")]))
2540
                         (vec_select:HI
2541
                          (match_operand:V2HI 2 "register_operand" "d,d,d,d")
2542
                          (parallel [(match_operand 4 "const01_operand" "P0,P0,P1,P1")]))))]
2543
  ""
2544
  "@
2545
   %0 = PACK (%h2,%h1);
2546
   %0 = PACK (%h2,%d1);
2547
   %0 = PACK (%d2,%h1);
2548
   %0 = PACK (%d2,%d1);"
2549
  [(set_attr "type" "dsp32")])
2550
 
2551
(define_insn "movv2hi_hi"
2552
  [(set (match_operand:HI 0 "register_operand" "=d,d,d")
2553
        (vec_select:HI (match_operand:V2HI 1 "register_operand" "0,d,d")
2554
                       (parallel [(match_operand 2 "const01_operand" "P0,P0,P1")])))]
2555
  ""
2556
  "@
2557
   /* optimized out */
2558
   %h0 = %h1 << 0;
2559
   %h0 = %d1 << 0;"
2560
  [(set_attr "type" "dsp32")])
2561
 
2562
(define_expand "movv2hi_hi_low"
2563
  [(set (match_operand:HI 0 "register_operand" "")
2564
        (vec_select:HI (match_operand:V2HI 1 "register_operand" "")
2565
                       (parallel [(const_int 0)])))]
2566
  ""
2567
  "")
2568
 
2569
(define_expand "movv2hi_hi_high"
2570
  [(set (match_operand:HI 0 "register_operand" "")
2571
        (vec_select:HI (match_operand:V2HI 1 "register_operand" "")
2572
                       (parallel [(const_int 1)])))]
2573
  ""
2574
  "")
2575
 
2576
;; Unusual arithmetic operations on 16 bit registers.
2577
 
2578
(define_insn "ssaddhi3"
2579
  [(set (match_operand:HI 0 "register_operand" "=d")
2580
        (ss_plus:HI (match_operand:HI 1 "register_operand" "d")
2581
                    (match_operand:HI 2 "register_operand" "d")))]
2582
  ""
2583
  "%h0 = %h1 + %h2 (S);"
2584
  [(set_attr "type" "dsp32")])
2585
 
2586
(define_insn "sssubhi3"
2587
  [(set (match_operand:HI 0 "register_operand" "=d")
2588
        (ss_minus:HI (match_operand:HI 1 "register_operand" "d")
2589
                     (match_operand:HI 2 "register_operand" "d")))]
2590
  ""
2591
  "%h0 = %h1 - %h2 (S);"
2592
  [(set_attr "type" "dsp32")])
2593
 
2594
;; V2HI vector insns
2595
 
2596
(define_insn "addv2hi3"
2597
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2598
        (plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2599
                   (match_operand:V2HI 2 "register_operand" "d")))]
2600
  ""
2601
  "%0 = %1 +|+ %2;"
2602
  [(set_attr "type" "dsp32")])
2603
 
2604
(define_insn "ssaddv2hi3"
2605
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2606
        (ss_plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2607
                      (match_operand:V2HI 2 "register_operand" "d")))]
2608
  ""
2609
  "%0 = %1 +|+ %2 (S);"
2610
  [(set_attr "type" "dsp32")])
2611
 
2612
(define_insn "subv2hi3"
2613
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2614
        (minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2615
                   (match_operand:V2HI 2 "register_operand" "d")))]
2616
  ""
2617
  "%0 = %1 -|- %2;"
2618
  [(set_attr "type" "dsp32")])
2619
 
2620
(define_insn "sssubv2hi3"
2621
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2622
        (ss_minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2623
                       (match_operand:V2HI 2 "register_operand" "d")))]
2624
  ""
2625
  "%0 = %1 -|- %2 (S);"
2626
  [(set_attr "type" "dsp32")])
2627
 
2628
(define_insn "addsubv2hi3"
2629
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2630
        (vec_concat:V2HI
2631
         (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2632
                                 (parallel [(const_int 0)]))
2633
                  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2634
                                 (parallel [(const_int 0)])))
2635
         (minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2636
                   (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2637
  ""
2638
  "%0 = %1 +|- %2;"
2639
  [(set_attr "type" "dsp32")])
2640
 
2641
(define_insn "subaddv2hi3"
2642
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2643
        (vec_concat:V2HI
2644
         (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2645
                                  (parallel [(const_int 0)]))
2646
                   (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2647
                                  (parallel [(const_int 0)])))
2648
         (plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2649
                  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2650
  ""
2651
  "%0 = %1 -|+ %2;"
2652
  [(set_attr "type" "dsp32")])
2653
 
2654
(define_insn "ssaddsubv2hi3"
2655
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2656
        (vec_concat:V2HI
2657
         (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2658
                                    (parallel [(const_int 0)]))
2659
                     (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2660
                                    (parallel [(const_int 0)])))
2661
         (ss_minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2662
                      (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2663
  ""
2664
  "%0 = %1 +|- %2 (S);"
2665
  [(set_attr "type" "dsp32")])
2666
 
2667
(define_insn "sssubaddv2hi3"
2668
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2669
        (vec_concat:V2HI
2670
         (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2671
                                     (parallel [(const_int 0)]))
2672
                      (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2673
                                     (parallel [(const_int 0)])))
2674
         (ss_plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
2675
                     (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
2676
  ""
2677
  "%0 = %1 -|+ %2 (S);"
2678
  [(set_attr "type" "dsp32")])
2679
 
2680
(define_insn "sublohiv2hi3"
2681
  [(set (match_operand:HI 0 "register_operand" "=d")
2682
        (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2683
                                 (parallel [(const_int 1)]))
2684
                  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2685
                                 (parallel [(const_int 0)]))))]
2686
  ""
2687
  "%h0 = %d1 - %h2;"
2688
  [(set_attr "type" "dsp32")])
2689
 
2690
(define_insn "subhilov2hi3"
2691
  [(set (match_operand:HI 0 "register_operand" "=d")
2692
        (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2693
                                 (parallel [(const_int 0)]))
2694
                  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2695
                                 (parallel [(const_int 1)]))))]
2696
  ""
2697
  "%h0 = %h1 - %d2;"
2698
  [(set_attr "type" "dsp32")])
2699
 
2700
(define_insn "sssublohiv2hi3"
2701
  [(set (match_operand:HI 0 "register_operand" "=d")
2702
        (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2703
                                    (parallel [(const_int 1)]))
2704
                     (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2705
                                    (parallel [(const_int 0)]))))]
2706
  ""
2707
  "%h0 = %d1 - %h2 (S);"
2708
  [(set_attr "type" "dsp32")])
2709
 
2710
(define_insn "sssubhilov2hi3"
2711
  [(set (match_operand:HI 0 "register_operand" "=d")
2712
        (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2713
                                    (parallel [(const_int 0)]))
2714
                     (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2715
                                    (parallel [(const_int 1)]))))]
2716
  ""
2717
  "%h0 = %h1 - %d2 (S);"
2718
  [(set_attr "type" "dsp32")])
2719
 
2720
(define_insn "addlohiv2hi3"
2721
  [(set (match_operand:HI 0 "register_operand" "=d")
2722
        (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2723
                                (parallel [(const_int 1)]))
2724
                 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2725
                                (parallel [(const_int 0)]))))]
2726
  ""
2727
  "%h0 = %d1 + %h2;"
2728
  [(set_attr "type" "dsp32")])
2729
 
2730
(define_insn "addhilov2hi3"
2731
  [(set (match_operand:HI 0 "register_operand" "=d")
2732
        (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2733
                                (parallel [(const_int 0)]))
2734
                 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2735
                                (parallel [(const_int 1)]))))]
2736
  ""
2737
  "%h0 = %h1 + %d2;"
2738
  [(set_attr "type" "dsp32")])
2739
 
2740
(define_insn "ssaddlohiv2hi3"
2741
  [(set (match_operand:HI 0 "register_operand" "=d")
2742
        (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2743
                                   (parallel [(const_int 1)]))
2744
                    (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2745
                                   (parallel [(const_int 0)]))))]
2746
  ""
2747
  "%h0 = %d1 + %h2 (S);"
2748
  [(set_attr "type" "dsp32")])
2749
 
2750
(define_insn "ssaddhilov2hi3"
2751
  [(set (match_operand:HI 0 "register_operand" "=d")
2752
        (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
2753
                                   (parallel [(const_int 0)]))
2754
                    (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2755
                                   (parallel [(const_int 1)]))))]
2756
  ""
2757
  "%h0 = %h1 + %d2 (S);"
2758
  [(set_attr "type" "dsp32")])
2759
 
2760
(define_insn "sminv2hi3"
2761
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2762
        (smin:V2HI (match_operand:V2HI 1 "register_operand" "d")
2763
                   (match_operand:V2HI 2 "register_operand" "d")))]
2764
  ""
2765
  "%0 = MIN (%1, %2) (V);"
2766
  [(set_attr "type" "dsp32")])
2767
 
2768
(define_insn "smaxv2hi3"
2769
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2770
        (smax:V2HI (match_operand:V2HI 1 "register_operand" "d")
2771
                   (match_operand:V2HI 2 "register_operand" "d")))]
2772
  ""
2773
  "%0 = MAX (%1, %2) (V);"
2774
  [(set_attr "type" "dsp32")])
2775
 
2776
;; Multiplications.
2777
 
2778
;; The Blackfin allows a lot of different options, and we need many patterns to
2779
;; cover most of the hardware's abilities.
2780
;; There are a few simple patterns using MULT rtx codes, but most of them use
2781
;; an unspec with a const_int operand that determines which flag to use in the
2782
;; instruction.
2783
;; There are variants for single and parallel multiplications.
2784
;; There are variants which just use 16 bit lowparts as inputs, and variants
2785
;; which allow the user to choose just which halves to use as input values.
2786
;; There are variants which set D registers, variants which set accumulators,
2787
;; variants which set both, some of them optionally using the accumulators as
2788
;; inputs for multiply-accumulate operations.
2789
 
2790
(define_insn "flag_mulhi"
2791
  [(set (match_operand:HI 0 "register_operand" "=d")
2792
        (unspec:HI [(match_operand:HI 1 "register_operand" "d")
2793
                    (match_operand:HI 2 "register_operand" "d")
2794
                    (match_operand 3 "const_int_operand" "n")]
2795
                   UNSPEC_MUL_WITH_FLAG))]
2796
  ""
2797
  "%h0 = %h1 * %h2 %M3;"
2798
  [(set_attr "type" "dsp32")])
2799
 
2800
(define_insn "flag_mulhisi"
2801
  [(set (match_operand:SI 0 "register_operand" "=d")
2802
        (unspec:SI [(match_operand:HI 1 "register_operand" "d")
2803
                    (match_operand:HI 2 "register_operand" "d")
2804
                    (match_operand 3 "const_int_operand" "n")]
2805
                   UNSPEC_MUL_WITH_FLAG))]
2806
  ""
2807
  "%0 = %h1 * %h2 %M3;"
2808
  [(set_attr "type" "dsp32")])
2809
 
2810
(define_insn "flag_mulhisi_parts"
2811
  [(set (match_operand:SI 0 "register_operand" "=d")
2812
        (unspec:SI [(vec_select:HI
2813
                     (match_operand:V2HI 1 "register_operand" "d")
2814
                     (parallel [(match_operand 3 "const01_operand" "P0P1")]))
2815
                    (vec_select:HI
2816
                     (match_operand:V2HI 2 "register_operand" "d")
2817
                     (parallel [(match_operand 4 "const01_operand" "P0P1")]))
2818
                    (match_operand 5 "const_int_operand" "n")]
2819
                   UNSPEC_MUL_WITH_FLAG))]
2820
  ""
2821
{
2822
  const char *templates[] = {
2823
    "%0 = %h1 * %h2 %M5;",
2824
    "%0 = %d1 * %h2 %M5;",
2825
    "%0 = %h1 * %d2 %M5;",
2826
    "%0 = %d1 * %d2 %M5;" };
2827
  int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
2828
  return templates[alt];
2829
}
2830
  [(set_attr "type" "dsp32")])
2831
 
2832
(define_insn "flag_machi"
2833
  [(set (match_operand:HI 0 "register_operand" "=d")
2834
        (unspec:HI [(match_operand:HI 1 "register_operand" "d")
2835
                    (match_operand:HI 2 "register_operand" "d")
2836
                    (match_operand 3 "register_operand" "A")
2837
                    (match_operand 4 "const01_operand" "P0P1")
2838
                    (match_operand 5 "const_int_operand" "n")]
2839
                   UNSPEC_MAC_WITH_FLAG))
2840
   (set (match_operand:PDI 6 "register_operand" "=A")
2841
        (unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)
2842
                     (match_dup 4) (match_dup 5)]
2843
                    UNSPEC_MAC_WITH_FLAG))]
2844
  ""
2845
  "%h0 = (A0 %b4 %h1 * %h2) %M6;"
2846
  [(set_attr "type" "dsp32")])
2847
 
2848
(define_insn "flag_machi_acconly"
2849
  [(set (match_operand:PDI 0 "register_operand" "=e")
2850
        (unspec:PDI [(match_operand:HI 1 "register_operand" "d")
2851
                     (match_operand:HI 2 "register_operand" "d")
2852
                     (match_operand 3 "register_operand" "A")
2853
                     (match_operand 4 "const01_operand" "P0P1")
2854
                     (match_operand 5 "const_int_operand" "n")]
2855
                    UNSPEC_MAC_WITH_FLAG))]
2856
  ""
2857
  "%0 %b4 %h1 * %h2 %M6;"
2858
  [(set_attr "type" "dsp32")])
2859
 
2860
(define_insn "flag_macinithi"
2861
  [(set (match_operand:HI 0 "register_operand" "=d")
2862
        (unspec:HI [(match_operand:HI 1 "register_operand" "d")
2863
                    (match_operand:HI 2 "register_operand" "d")
2864
                    (match_operand 3 "const_int_operand" "n")]
2865
                   UNSPEC_MAC_WITH_FLAG))
2866
   (set (match_operand:PDI 4 "register_operand" "=A")
2867
        (unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)]
2868
                    UNSPEC_MAC_WITH_FLAG))]
2869
  ""
2870
  "%h0 = (A0 = %h1 * %h2) %M3;"
2871
  [(set_attr "type" "dsp32")])
2872
 
2873
(define_insn "flag_macinit1hi"
2874
  [(set (match_operand:PDI 0 "register_operand" "=e")
2875
        (unspec:PDI [(match_operand:HI 1 "register_operand" "d")
2876
                     (match_operand:HI 2 "register_operand" "d")
2877
                     (match_operand 3 "const_int_operand" "n")]
2878
                    UNSPEC_MAC_WITH_FLAG))]
2879
  ""
2880
  "%0 = %h1 * %h2 %M3;"
2881
  [(set_attr "type" "dsp32")])
2882
 
2883
(define_insn "mulv2hi3"
2884
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2885
        (mult:V2HI (match_operand:V2HI 1 "register_operand" "d")
2886
                   (match_operand:V2HI 2 "register_operand" "d")))]
2887
  ""
2888
  "%h0 = %h1 * %h2, %d0 = %d1 * %d2 (IS);"
2889
  [(set_attr "type" "dsp32")])
2890
 
2891
(define_insn "flag_mulv2hi"
2892
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2893
        (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "d")
2894
                      (match_operand:V2HI 2 "register_operand" "d")
2895
                      (match_operand 3 "const_int_operand" "n")]
2896
                     UNSPEC_MUL_WITH_FLAG))]
2897
  ""
2898
  "%h0 = %h1 * %h2, %d0 = %d1 * %d2 %M3;"
2899
  [(set_attr "type" "dsp32")])
2900
 
2901
(define_insn "flag_mulv2hi_parts"
2902
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2903
        (unspec:V2HI [(vec_concat:V2HI
2904
                       (vec_select:HI
2905
                        (match_operand:V2HI 1 "register_operand" "d")
2906
                        (parallel [(match_operand 3 "const01_operand" "P0P1")]))
2907
                       (vec_select:HI
2908
                        (match_dup 1)
2909
                        (parallel [(match_operand 4 "const01_operand" "P0P1")])))
2910
                      (vec_concat:V2HI
2911
                       (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2912
                        (parallel [(match_operand 5 "const01_operand" "P0P1")]))
2913
                       (vec_select:HI (match_dup 2)
2914
                        (parallel [(match_operand 6 "const01_operand" "P0P1")])))
2915
                      (match_operand 7 "const_int_operand" "n")]
2916
                     UNSPEC_MUL_WITH_FLAG))]
2917
  ""
2918
{
2919
  const char *templates[] = {
2920
    "%h0 = %h1 * %h2, %d0 = %h1 * %h2 %M7;",
2921
    "%h0 = %d1 * %h2, %d0 = %h1 * %h2 %M7;",
2922
    "%h0 = %h1 * %h2, %d0 = %d1 * %h2 %M7;",
2923
    "%h0 = %d1 * %h2, %d0 = %d1 * %h2 %M7;",
2924
    "%h0 = %h1 * %d2, %d0 = %h1 * %h2 %M7;",
2925
    "%h0 = %d1 * %d2, %d0 = %h1 * %h2 %M7;",
2926
    "%h0 = %h1 * %d2, %d0 = %d1 * %h2 %M7;",
2927
    "%h0 = %d1 * %d2, %d0 = %d1 * %h2 %M7;",
2928
    "%h0 = %h1 * %h2, %d0 = %h1 * %d2 %M7;",
2929
    "%h0 = %d1 * %h2, %d0 = %h1 * %d2 %M7;",
2930
    "%h0 = %h1 * %h2, %d0 = %d1 * %d2 %M7;",
2931
    "%h0 = %d1 * %h2, %d0 = %d1 * %d2 %M7;",
2932
    "%h0 = %h1 * %d2, %d0 = %h1 * %d2 %M7;",
2933
    "%h0 = %d1 * %d2, %d0 = %h1 * %d2 %M7;",
2934
    "%h0 = %h1 * %d2, %d0 = %d1 * %d2 %M7;",
2935
    "%h0 = %d1 * %d2, %d0 = %d1 * %d2 %M7;" };
2936
  int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
2937
             + (INTVAL (operands[5]) << 2)  + (INTVAL (operands[6]) << 3));
2938
  return templates[alt];
2939
}
2940
  [(set_attr "type" "dsp32")])
2941
 
2942
;; A slightly complicated pattern.
2943
;; Operand 0 is the halfword output; operand 11 is the accumulator output
2944
;; Halfword inputs are operands 1 and 2; operands 3, 4, 5 and 6 specify which
2945
;; parts of these 2x16 bit registers to use.
2946
;; Operand 7 is the accumulator input.
2947
;; Operands 8/9 specify whether low/high parts are mac (0) or msu (1)
2948
;; Operand 10 is the macflag to be used.
2949
(define_insn "flag_macv2hi_parts"
2950
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2951
        (unspec:V2HI [(vec_concat:V2HI
2952
                       (vec_select:HI
2953
                        (match_operand:V2HI 1 "register_operand" "d")
2954
                        (parallel [(match_operand 3 "const01_operand" "P0P1")]))
2955
                       (vec_select:HI
2956
                        (match_dup 1)
2957
                        (parallel [(match_operand 4 "const01_operand" "P0P1")])))
2958
                      (vec_concat:V2HI
2959
                       (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
2960
                        (parallel [(match_operand 5 "const01_operand" "P0P1")]))
2961
                       (vec_select:HI (match_dup 2)
2962
                        (parallel [(match_operand 6 "const01_operand" "P0P1")])))
2963
                      (match_operand:V2PDI 7 "register_operand" "e")
2964
                      (match_operand 8 "const01_operand" "P0P1")
2965
                      (match_operand 9 "const01_operand" "P0P1")
2966
                      (match_operand 10 "const_int_operand" "n")]
2967
                     UNSPEC_MAC_WITH_FLAG))
2968
   (set (match_operand:V2PDI 11 "register_operand" "=e")
2969
        (unspec:V2PDI [(vec_concat:V2HI
2970
                        (vec_select:HI (match_dup 1) (parallel [(match_dup 3)]))
2971
                        (vec_select:HI (match_dup 1) (parallel [(match_dup 4)])))
2972
                       (vec_concat:V2HI
2973
                        (vec_select:HI (match_dup 2) (parallel [(match_dup 5)]))
2974
                        (vec_select:HI (match_dup 2) (parallel [(match_dup 5)])))
2975
                       (match_dup 7) (match_dup 8) (match_dup 9) (match_dup 10)]
2976
                      UNSPEC_MAC_WITH_FLAG))]
2977
  ""
2978
{
2979
  const char *templates[] = {
2980
    "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %h1 * %h2) %M10;",
2981
    "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %h1 * %h2) %M10;",
2982
    "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %d1 * %h2) %M10;",
2983
    "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %d1 * %h2) %M10;",
2984
    "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %h1 * %h2) %M10;",
2985
    "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %h1 * %h2) %M10;",
2986
    "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %d1 * %h2) %M10;",
2987
    "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %d1 * %h2) %M10;",
2988
    "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %h1 * %d2) %M10;",
2989
    "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %h1 * %d2) %M10;",
2990
    "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %d1 * %d2) %M10;",
2991
    "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %d1 * %d2) %M10;",
2992
    "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %h1 * %d2) %M10;",
2993
    "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %h1 * %d2) %M10;",
2994
    "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %d1 * %d2) %M10;",
2995
    "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %d1 * %d2) %M10;" };
2996
  int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
2997
             + (INTVAL (operands[5]) << 2)  + (INTVAL (operands[6]) << 3));
2998
  return templates[alt];
2999
}
3000
  [(set_attr "type" "dsp32")])
3001
 
3002
(define_insn "flag_macv2hi_parts_acconly"
3003
  [(set (match_operand:V2PDI 0 "register_operand" "=e")
3004
        (unspec:V2PDI [(vec_concat:V2HI
3005
                        (vec_select:HI
3006
                         (match_operand:V2HI 1 "register_operand" "d")
3007
                         (parallel [(match_operand 3 "const01_operand" "P0P1")]))
3008
                        (vec_select:HI
3009
                         (match_dup 1)
3010
                         (parallel [(match_operand 4 "const01_operand" "P0P1")])))
3011
                       (vec_concat:V2HI
3012
                        (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3013
                                       (parallel [(match_operand 5 "const01_operand" "P0P1")]))
3014
                        (vec_select:HI (match_dup 2)
3015
                                       (parallel [(match_operand 6 "const01_operand" "P0P1")])))
3016
                       (match_operand:V2PDI 7 "register_operand" "e")
3017
                       (match_operand 8 "const01_operand" "P0P1")
3018
                       (match_operand 9 "const01_operand" "P0P1")
3019
                       (match_operand 10 "const_int_operand" "n")]
3020
                      UNSPEC_MAC_WITH_FLAG))]
3021
  ""
3022
{
3023
  const char *templates[] = {
3024
    "A0 %b8 %h1 * %h2, A1 %b9 %h1 * %h2 %M10;",
3025
    "A0 %b8 %d1 * %h2, A1 %b9 %h1 * %h2 %M10;",
3026
    "A0 %b8 %h1 * %h2, A1 %b9 %d1 * %h2 %M10;",
3027
    "A0 %b8 %d1 * %h2, A1 %b9 %d1 * %h2 %M10;",
3028
    "A0 %b8 %h1 * %d2, A1 %b9 %h1 * %h2 %M10;",
3029
    "A0 %b8 %d1 * %d2, A1 %b9 %h1 * %h2 %M10;",
3030
    "A0 %b8 %h1 * %d2, A1 %b9 %d1 * %h2 %M10;",
3031
    "A0 %b8 %d1 * %d2, A1 %b9 %d1 * %h2 %M10;",
3032
    "A0 %b8 %h1 * %h2, A1 %b9 %h1 * %d2 %M10;",
3033
    "A0 %b8 %d1 * %h2, A1 %b9 %h1 * %d2 %M10;",
3034
    "A0 %b8 %h1 * %h2, A1 %b9 %d1 * %d2 %M10;",
3035
    "A0 %b8 %d1 * %h2, A1 %b9 %d1 * %d2 %M10;",
3036
    "A0 %b8 %h1 * %d2, A1 %b9 %h1 * %d2 %M10;",
3037
    "A0 %b8 %d1 * %d2, A1 %b9 %h1 * %d2 %M10;",
3038
    "A0 %b8 %h1 * %d2, A1 %b9 %d1 * %d2 %M10;",
3039
    "A0 %b8 %d1 * %d2, A1 %b9 %d1 * %d2 %M10;" };
3040
  int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3041
             + (INTVAL (operands[5]) << 2)  + (INTVAL (operands[6]) << 3));
3042
  return templates[alt];
3043
}
3044
  [(set_attr "type" "dsp32")])
3045
 
3046
;; Same as above, but initializing the accumulators and therefore a couple fewer
3047
;; necessary operands.
3048
(define_insn "flag_macinitv2hi_parts"
3049
  [(set (match_operand:V2HI 0 "register_operand" "=d")
3050
        (unspec:V2HI [(vec_concat:V2HI
3051
                       (vec_select:HI
3052
                        (match_operand:V2HI 1 "register_operand" "d")
3053
                        (parallel [(match_operand 3 "const01_operand" "P0P1")]))
3054
                       (vec_select:HI
3055
                        (match_dup 1)
3056
                        (parallel [(match_operand 4 "const01_operand" "P0P1")])))
3057
                      (vec_concat:V2HI
3058
                       (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3059
                        (parallel [(match_operand 5 "const01_operand" "P0P1")]))
3060
                       (vec_select:HI (match_dup 2)
3061
                        (parallel [(match_operand 6 "const01_operand" "P0P1")])))
3062
                      (match_operand 7 "const_int_operand" "n")]
3063
                     UNSPEC_MAC_WITH_FLAG))
3064
   (set (match_operand:V2PDI 8 "register_operand" "=e")
3065
        (unspec:V2PDI [(vec_concat:V2HI
3066
                        (vec_select:HI (match_dup 1) (parallel [(match_dup 3)]))
3067
                        (vec_select:HI (match_dup 1) (parallel [(match_dup 4)])))
3068
                       (vec_concat:V2HI
3069
                        (vec_select:HI (match_dup 2) (parallel [(match_dup 5)]))
3070
                        (vec_select:HI (match_dup 2) (parallel [(match_dup 5)])))
3071
                       (match_dup 7)]
3072
                      UNSPEC_MAC_WITH_FLAG))]
3073
  ""
3074
{
3075
  const char *templates[] = {
3076
    "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %h1 * %h2) %M7;",
3077
    "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %h1 * %h2) %M7;",
3078
    "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %d1 * %h2) %M7;",
3079
    "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %d1 * %h2) %M7;",
3080
    "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %h1 * %h2) %M7;",
3081
    "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %h1 * %h2) %M7;",
3082
    "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %d1 * %h2) %M7;",
3083
    "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %d1 * %h2) %M7;",
3084
    "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %h1 * %d2) %M7;",
3085
    "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %h1 * %d2) %M7;",
3086
    "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %d1 * %d2) %M7;",
3087
    "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %d1 * %d2) %M7;",
3088
    "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %h1 * %d2) %M7;",
3089
    "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %h1 * %d2) %M7;",
3090
    "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %d1 * %d2) %M7;",
3091
    "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %d1 * %d2) %M7;" };
3092
  int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3093
             + (INTVAL (operands[5]) << 2)  + (INTVAL (operands[6]) << 3));
3094
  return templates[alt];
3095
}
3096
  [(set_attr "type" "dsp32")])
3097
 
3098
(define_insn "flag_macinit1v2hi_parts"
3099
  [(set (match_operand:V2PDI 0 "register_operand" "=e")
3100
        (unspec:V2PDI [(vec_concat:V2HI
3101
                       (vec_select:HI
3102
                        (match_operand:V2HI 1 "register_operand" "d")
3103
                        (parallel [(match_operand 3 "const01_operand" "P0P1")]))
3104
                       (vec_select:HI
3105
                        (match_dup 1)
3106
                        (parallel [(match_operand 4 "const01_operand" "P0P1")])))
3107
                      (vec_concat:V2HI
3108
                       (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3109
                        (parallel [(match_operand 5 "const01_operand" "P0P1")]))
3110
                       (vec_select:HI (match_dup 2)
3111
                        (parallel [(match_operand 6 "const01_operand" "P0P1")])))
3112
                      (match_operand 7 "const_int_operand" "n")]
3113
                     UNSPEC_MAC_WITH_FLAG))]
3114
  ""
3115
{
3116
  const char *templates[] = {
3117
    "A0 = %h1 * %h2, A1 = %h1 * %h2 %M7;",
3118
    "A0 = %d1 * %h2, A1 = %h1 * %h2 %M7;",
3119
    "A0 = %h1 * %h2, A1 = %d1 * %h2 %M7;",
3120
    "A0 = %d1 * %h2, A1 = %d1 * %h2 %M7;",
3121
    "A0 = %h1 * %d2, A1 = %h1 * %h2 %M7;",
3122
    "A0 = %d1 * %d2, A1 = %h1 * %h2 %M7;",
3123
    "A0 = %h1 * %d2, A1 = %d1 * %h2 %M7;",
3124
    "A0 = %d1 * %d2, A1 = %d1 * %h2 %M7;",
3125
    "A0 = %h1 * %h2, A1 = %h1 * %d2 %M7;",
3126
    "A0 = %d1 * %h2, A1 = %h1 * %d2 %M7;",
3127
    "A0 = %h1 * %h2, A1 = %d1 * %d2 %M7;",
3128
    "A0 = %d1 * %h2, A1 = %d1 * %d2 %M7;",
3129
    "A0 = %h1 * %d2, A1 = %h1 * %d2 %M7;",
3130
    "A0 = %d1 * %d2, A1 = %h1 * %d2 %M7;",
3131
    "A0 = %h1 * %d2, A1 = %d1 * %d2 %M7;",
3132
    "A0 = %d1 * %d2, A1 = %d1 * %d2 %M7;" };
3133
  int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3134
             + (INTVAL (operands[5]) << 2)  + (INTVAL (operands[6]) << 3));
3135
  return templates[alt];
3136
}
3137
  [(set_attr "type" "dsp32")])
3138
 
3139
(define_insn "mulhisi_ll"
3140
  [(set (match_operand:SI 0 "register_operand" "=d")
3141
        (mult:SI (sign_extend:SI
3142
                  (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3143
                                 (parallel [(const_int 0)])))
3144
                 (sign_extend:SI
3145
                  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3146
                                 (parallel [(const_int 0)])))))]
3147
  ""
3148
  "%0 = %h1 * %h2 (IS);"
3149
  [(set_attr "type" "dsp32")])
3150
 
3151
(define_insn "mulhisi_lh"
3152
  [(set (match_operand:SI 0 "register_operand" "=d")
3153
        (mult:SI (sign_extend:SI
3154
                  (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3155
                                 (parallel [(const_int 0)])))
3156
                 (sign_extend:SI
3157
                  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3158
                                 (parallel [(const_int 1)])))))]
3159
  ""
3160
  "%0 = %h1 * %d2 (IS);"
3161
  [(set_attr "type" "dsp32")])
3162
 
3163
(define_insn "mulhisi_hl"
3164
  [(set (match_operand:SI 0 "register_operand" "=d")
3165
        (mult:SI (sign_extend:SI
3166
                  (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3167
                                 (parallel [(const_int 1)])))
3168
                 (sign_extend:SI
3169
                  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3170
                                 (parallel [(const_int 0)])))))]
3171
  ""
3172
  "%0 = %d1 * %h2 (IS);"
3173
  [(set_attr "type" "dsp32")])
3174
 
3175
(define_insn "mulhisi_hh"
3176
  [(set (match_operand:SI 0 "register_operand" "=d")
3177
        (mult:SI (sign_extend:SI
3178
                  (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3179
                                 (parallel [(const_int 1)])))
3180
                 (sign_extend:SI
3181
                  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3182
                                 (parallel [(const_int 1)])))))]
3183
  ""
3184
  "%0 = %d1 * %d2 (IS);"
3185
  [(set_attr "type" "dsp32")])
3186
 
3187
(define_insn "ssnegv2hi2"
3188
  [(set (match_operand:V2HI 0 "register_operand" "=d")
3189
        (ss_neg:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
3190
  ""
3191
  "%0 = - %1 (V);"
3192
  [(set_attr "type" "dsp32")])
3193
 
3194
(define_insn "absv2hi2"
3195
  [(set (match_operand:V2HI 0 "register_operand" "=d")
3196
        (abs:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
3197
  ""
3198
  "%0 = ABS %1 (V);"
3199
  [(set_attr "type" "dsp32")])
3200
 
3201
;; Shifts.
3202
 
3203
(define_insn "ssashiftv2hi3"
3204
  [(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
3205
        (if_then_else:V2HI
3206
         (lt (match_operand:SI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
3207
         (ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" "d,d,d")
3208
                        (match_dup 2))
3209
         (ss_ashift:V2HI (match_dup 1) (match_dup 2))))]
3210
  ""
3211
  "@
3212
   %0 = ASHIFT %1 BY %2 (V, S);
3213
   %0 = %1 >>> %2 (V,S);
3214
   %0 = %1 << %2 (V,S);"
3215
  [(set_attr "type" "dsp32")])
3216
 
3217
(define_insn "ssashifthi3"
3218
  [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3219
        (if_then_else:HI
3220
         (lt (match_operand:SI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
3221
         (ashiftrt:HI (match_operand:HI 1 "register_operand" "d,d,d")
3222
                      (match_dup 2))
3223
         (ss_ashift:HI (match_dup 1) (match_dup 2))))]
3224
  ""
3225
  "@
3226
   %0 = ASHIFT %1 BY %2 (V, S);
3227
   %0 = %1 >>> %2 (V,S);
3228
   %0 = %1 << %2 (V,S);"
3229
  [(set_attr "type" "dsp32")])
3230
 
3231
(define_insn "lshiftv2hi3"
3232
  [(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
3233
        (if_then_else:V2HI
3234
         (lt (match_operand:SI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
3235
         (lshiftrt:V2HI (match_operand:V2HI 1 "register_operand" "d,d,d")
3236
                        (match_dup 2))
3237
         (ashift:V2HI (match_dup 1) (match_dup 2))))]
3238
  ""
3239
  "@
3240
   %0 = LSHIFT %1 BY %2 (V);
3241
   %0 = %1 >> %2 (V);
3242
   %0 = %1 << %2 (V);"
3243
  [(set_attr "type" "dsp32")])
3244
 
3245
(define_insn "lshifthi3"
3246
  [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3247
        (if_then_else:HI
3248
         (lt (match_operand:SI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
3249
         (lshiftrt:HI (match_operand:HI 1 "register_operand" "d,d,d")
3250
                      (match_dup 2))
3251
         (ashift:HI (match_dup 1) (match_dup 2))))]
3252
  ""
3253
  "@
3254
   %0 = LSHIFT %1 BY %2 (V);
3255
   %0 = %1 >> %2 (V);
3256
   %0 = %1 << %2 (V);"
3257
  [(set_attr "type" "dsp32")])
3258
 

powered by: WebSVN 2.1.0

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