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

Subversion Repositories scarts

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

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

Line No. Rev Author Line
1 12 jlechner
;;- Machine description for Blackfin for GNU compiler
2
;;  Copyright 2005  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 2, 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 COPYING.  If not, write to
19
;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20
;; Boston, MA 02110-1301, USA.
21
 
22
; operand punctuation marks:
23
;
24
;     X -- integer value printed as log2
25
;     Y -- integer value printed as log2(~value) - for bitclear
26
;     h -- print half word register, low part
27
;     d -- print half word register, high part
28
;     D -- print operand as dregs pairs
29
;     w -- print operand as accumulator register word (a0w, a1w)
30
;     H -- high part of double mode operand
31
;     T -- byte register representation Oct. 02 2001
32
 
33
; constant operand classes
34
;
35
;     J   2**N       5bit imm scaled
36
;     Ks7 -64 .. 63  signed 7bit imm
37
;     Ku5 0..31      unsigned 5bit imm
38
;     Ks4 -8 .. 7    signed 4bit imm
39
;     Ks3 -4 .. 3    signed 3bit imm
40
;     Ku3 0 .. 7     unsigned 3bit imm
41
;     Pn  0, 1, 2    constants 0, 1 or 2, corresponding to n
42
;
43
; register operands
44
;     d  (r0..r7)
45
;     a  (p0..p5,fp,sp)
46
;     e  (a0, a1)
47
;     b  (i0..i3)
48
;     f  (m0..m3)
49
;     B
50
;     c (i0..i3,m0..m3) CIRCREGS
51
;     C (CC)            CCREGS
52
;
53
 
54
;; Define constants for hard registers.
55
 
56
(define_constants
57
  [(REG_R0 0)
58
   (REG_R1 1)
59
   (REG_R2 2)
60
   (REG_R3 3)
61
   (REG_R4 4)
62
   (REG_R5 5)
63
   (REG_R6 6)
64
   (REG_R7 7)
65
 
66
   (REG_P0 8)
67
   (REG_P1 9)
68
   (REG_P2 10)
69
   (REG_P3 11)
70
   (REG_P4 12)
71
   (REG_P5 13)
72
   (REG_P6 14)
73
   (REG_P7 15)
74
 
75
   (REG_SP 14)
76
   (REG_FP 15)
77
 
78
   (REG_I0 16)
79
   (REG_I1 17)
80
   (REG_I2 18)
81
   (REG_I3 19)
82
 
83
   (REG_B0 20)
84
   (REG_B1 21)
85
   (REG_B2 22)
86
   (REG_B3 23)
87
 
88
   (REG_L0 24)
89
   (REG_L1 25)
90
   (REG_L2 26)
91
   (REG_L3 27)
92
 
93
   (REG_M0 28)
94
   (REG_M1 29)
95
   (REG_M2 30)
96
   (REG_M3 31)
97
 
98
   (REG_A0 32)
99
   (REG_A1 33)
100
 
101
   (REG_CC 34)
102
   (REG_RETS 35)
103
   (REG_RETI 36)
104
   (REG_RETX 37)
105
   (REG_RETN 38)
106
   (REG_RETE 39)
107
 
108
   (REG_ASTAT 40)
109
   (REG_SEQSTAT 41)
110
   (REG_USP 42)
111
 
112
   (REG_ARGP 43)])
113
 
114
;; Constants used in UNSPECs and UNSPEC_VOLATILEs.
115
 
116
(define_constants
117
  [(UNSPEC_CBRANCH_TAKEN 0)
118
   (UNSPEC_CBRANCH_NOPS 1)
119
   (UNSPEC_RETURN 2)
120
   (UNSPEC_MOVE_PIC 3)
121
   (UNSPEC_LIBRARY_OFFSET 4)
122
   (UNSPEC_PUSH_MULTIPLE 5)])
123
 
124
(define_constants
125
  [(UNSPEC_VOLATILE_EH_RETURN 0)
126
   (UNSPEC_VOLATILE_CSYNC 1)
127
   (UNSPEC_VOLATILE_SSYNC 2)])
128
 
129
(define_attr "type"
130
  "move,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy"
131
  (const_string "misc"))
132
 
133
;; Scheduling definitions
134
 
135
(define_automaton "bfin")
136
 
137
(define_cpu_unit "core" "bfin")
138
 
139
(define_insn_reservation "alu" 1
140
  (eq_attr "type" "move,mvi,mcst,dsp32,alu0,shft,brcc,br,call,misc,sync,compare")
141
  "core")
142
 
143
(define_insn_reservation "imul" 3
144
  (eq_attr "type" "mult")
145
  "core*3")
146
 
147
(define_insn_reservation "load" 1
148
  (eq_attr "type" "mcld")
149
  "core")
150
 
151
;; Make sure genautomata knows about the maximum latency that can be produced
152
;; by the adjust_cost function.
153
(define_insn_reservation "dummy" 5
154
  (eq_attr "type" "mcld")
155
  "core")
156
 
157
;; Operand and operator predicates
158
 
159
(include "predicates.md")
160
 
161
 
162
;;; FRIO branches have been optimized for code density
163
;;; this comes at a slight cost of complexity when
164
;;; a compiler needs to generate branches in the general
165
;;; case.  In order to generate the correct branching
166
;;; mechanisms the compiler needs keep track of instruction
167
;;; lengths.  The follow table describes how to count instructions
168
;;; for the FRIO architecture.
169
;;;
170
;;; unconditional br are 12-bit imm pcrelative branches *2
171
;;; conditional   br are 10-bit imm pcrelative branches *2
172
;;; brcc 10-bit:
173
;;;   1024 10-bit imm *2 is 2048 (-1024..1022)
174
;;; br 12-bit  :
175
;;;   4096 12-bit imm *2 is 8192 (-4096..4094)
176
;;; NOTE : For brcc we generate instructions such as
177
;;;   if cc jmp; jump.[sl] offset
178
;;;   offset of jump.[sl] is from the jump instruction but
179
;;;     gcc calculates length from the if cc jmp instruction
180
;;;     furthermore gcc takes the end address of the branch instruction
181
;;;     as (pc) for a forward branch
182
;;;     hence our range is (-4094, 4092) instead of (-4096, 4094) for a br
183
;;;
184
;;; The way the (pc) rtx works in these calculations is somewhat odd;
185
;;; for backward branches it's the address of the current instruction,
186
;;; for forward branches it's the previously known address of the following
187
;;; instruction - we have to take this into account by reducing the range
188
;;; for a forward branch.
189
 
190
;; Lengths for type "mvi" insns are always defined by the instructions
191
;; themselves.
192
(define_attr "length" ""
193
  (cond [(eq_attr "type" "mcld")
194
         (if_then_else (match_operand 1 "effective_address_32bit_p" "")
195
                       (const_int 4) (const_int 2))
196
 
197
         (eq_attr "type" "mcst")
198
         (if_then_else (match_operand 0 "effective_address_32bit_p" "")
199
                       (const_int 4) (const_int 2))
200
 
201
         (eq_attr "type" "move") (const_int 2)
202
 
203
         (eq_attr "type" "dsp32") (const_int 4)
204
         (eq_attr "type" "call")  (const_int 4)
205
 
206
         (eq_attr "type" "br")
207
         (if_then_else (and
208
                          (le (minus (match_dup 0) (pc)) (const_int 4092))
209
                          (ge (minus (match_dup 0) (pc)) (const_int -4096)))
210
                  (const_int 2)
211
                  (const_int 4))
212
 
213
         (eq_attr "type" "brcc")
214
         (cond [(and
215
                    (le (minus (match_dup 3) (pc)) (const_int 1020))
216
                    (ge (minus (match_dup 3) (pc)) (const_int -1024)))
217
                  (const_int 2)
218
                (and
219
                    (le (minus (match_dup 3) (pc)) (const_int 4092))
220
                    (ge (minus (match_dup 3) (pc)) (const_int -4094)))
221
                  (const_int 4)]
222
               (const_int 6))
223
        ]
224
 
225
        (const_int 2)))
226
 
227
;; Conditional moves
228
 
229
(define_expand "movsicc"
230
  [(set (match_operand:SI 0 "register_operand" "")
231
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
232
                         (match_operand:SI 2 "register_operand" "")
233
                         (match_operand:SI 3 "register_operand" "")))]
234
  ""
235
{
236
  operands[1] = bfin_gen_compare (operands[1], SImode);
237
})
238
 
239
(define_insn "*movsicc_insn1"
240
  [(set (match_operand:SI 0 "register_operand" "=da,da,da")
241
        (if_then_else:SI
242
            (eq:BI (match_operand:BI 3 "cc_operand" "C,C,C")
243
                (const_int 0))
244
            (match_operand:SI 1 "register_operand" "da,0,da")
245
            (match_operand:SI 2 "register_operand" "0,da,da")))]
246
  ""
247
  "@
248
    if !cc %0 =%1; /* movsicc-1a */
249
    if cc %0 =%2; /* movsicc-1b */
250
    if !cc %0 =%1; if cc %0=%2; /* movsicc-1 */"
251
  [(set_attr "length" "2,2,4")
252
   (set_attr "type" "move")])
253
 
254
(define_insn "*movsicc_insn2"
255
  [(set (match_operand:SI 0 "register_operand" "=da,da,da")
256
        (if_then_else:SI
257
            (ne:BI (match_operand:BI 3 "cc_operand" "C,C,C")
258
                (const_int 0))
259
            (match_operand:SI 1 "register_operand" "0,da,da")
260
            (match_operand:SI 2 "register_operand" "da,0,da")))]
261
  ""
262
  "@
263
   if !cc %0 =%2; /* movsicc-2b */
264
   if cc %0 =%1; /* movsicc-2a */
265
   if cc %0 =%1; if !cc %0=%2; /* movsicc-1 */"
266
  [(set_attr "length" "2,2,4")
267
   (set_attr "type" "move")])
268
 
269
;; Insns to load HIGH and LO_SUM
270
 
271
(define_insn "movsi_high"
272
  [(set (match_operand:SI 0 "register_operand" "=x")
273
        (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
274
  "reload_completed"
275
  "%d0 = %d1;"
276
  [(set_attr "type" "mvi")
277
   (set_attr "length" "4")])
278
 
279
(define_insn "movstricthi_high"
280
  [(set (match_operand:SI 0 "register_operand" "+x")
281
        (ior:SI (and:SI (match_dup 0) (const_int 65535))
282
                (match_operand:SI 1 "immediate_operand" "i")))]
283
  "reload_completed"
284
  "%d0 = %d1;"
285
  [(set_attr "type" "mvi")
286
   (set_attr "length" "4")])
287
 
288
(define_insn "movsi_low"
289
  [(set (match_operand:SI 0 "register_operand" "=x")
290
        (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
291
                   (match_operand:SI 2 "immediate_operand" "i")))]
292
  "reload_completed"
293
  "%h0 = %h2;"
294
  [(set_attr "type" "mvi")
295
   (set_attr "length" "4")])
296
 
297
(define_insn "movsi_high_pic"
298
  [(set (match_operand:SI 0 "register_operand" "=x")
299
        (high:SI (unspec:SI [(match_operand:SI 1 "" "")]
300
                            UNSPEC_MOVE_PIC)))]
301
  ""
302
  "%d0 = %1@GOT_LOW;"
303
  [(set_attr "type" "mvi")
304
   (set_attr "length" "4")])
305
 
306
(define_insn "movsi_low_pic"
307
  [(set (match_operand:SI 0 "register_operand" "=x")
308
        (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
309
                   (unspec:SI [(match_operand:SI 2 "" "")]
310
                              UNSPEC_MOVE_PIC)))]
311
  ""
312
  "%h0 = %h2@GOT_HIGH;"
313
  [(set_attr "type" "mvi")
314
   (set_attr "length" "4")])
315
 
316
;;; Move instructions
317
 
318
(define_insn_and_split "movdi_insn"
319
  [(set (match_operand:DI 0 "nonimmediate_operand" "=x,mx,r")
320
        (match_operand:DI 1 "general_operand" "iFx,r,mx"))]
321
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
322
  "#"
323
  "reload_completed"
324
  [(set (match_dup 2) (match_dup 3))
325
   (set (match_dup 4) (match_dup 5))]
326
{
327
  rtx lo_half[2], hi_half[2];
328
  split_di (operands, 2, lo_half, hi_half);
329
 
330
  if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
331
    {
332
      operands[2] = hi_half[0];
333
      operands[3] = hi_half[1];
334
      operands[4] = lo_half[0];
335
      operands[5] = lo_half[1];
336
    }
337
  else
338
    {
339
      operands[2] = lo_half[0];
340
      operands[3] = lo_half[1];
341
      operands[4] = hi_half[0];
342
      operands[5] = hi_half[1];
343
    }
344
})
345
 
346
(define_insn "movbi"
347
  [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,mr,C,d,C")
348
        (match_operand:BI 1 "general_operand" "x,xKs3,mr,d,d,C,P0"))]
349
 
350
  ""
351
  "@
352
   %0 = %1;
353
   %0 = %1 (X);
354
   %0 = %1;
355
   %0 = %1;
356
   CC = %1;
357
   %0 = CC;
358
   R0 = R0 | R0; CC = AC0;"
359
  [(set_attr "type" "move,mvi,mcld,mcst,compare,compare,alu0")
360
   (set_attr "length" "2,2,*,*,2,2,4")])
361
 
362
(define_insn "movpdi"
363
  [(set (match_operand:PDI 0 "nonimmediate_operand" "=e,<,e")
364
        (match_operand:PDI 1 "general_operand" " e,e,>"))]
365
  ""
366
  "@
367
   %0 = %1;
368
   %0 = %x1; %0 = %w1;
369
   %w0 = %1; %x0 = %1;"
370
  [(set_attr "type" "move,mcst,mcld")])
371
 
372
(define_insn "*pushsi_insn"
373
  [(set (mem:SI (pre_dec:SI (reg:SI REG_SP)))
374
        (match_operand:SI 0 "register_operand" "xy"))]
375
  ""
376
  "[--SP] = %0;"
377
  [(set_attr "type" "mcst")
378
   (set_attr "length" "2")])
379
 
380
(define_insn "*popsi_insn"
381
  [(set (match_operand:SI 0 "register_operand" "=xy")
382
        (mem:SI (post_inc:SI (reg:SI REG_SP))))]
383
  ""
384
  "%0 = [SP++];"
385
  [(set_attr "type" "mcld")
386
   (set_attr "length" "2")])
387
 
388
;; The first alternative is used to make reload choose a limited register
389
;; class when faced with a movsi_insn that had its input operand replaced
390
;; with a PLUS.  We generally require fewer secondary reloads this way.
391
(define_insn "*movsi_insn"
392
  [(set (match_operand:SI 0 "nonimmediate_operand" "=da,x*y,da,x,x,x,da,mr")
393
        (match_operand:SI 1 "general_operand" "da,x*y,xKs7,xKsh,xKuh,ix,mr,da"))]
394
 
395
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
396
  "@
397
   %0 = %1;
398
   %0 = %1;
399
   %0 = %1 (X);
400
   %0 = %1 (X);
401
   %0 = %1 (Z);
402
   #
403
   %0 = %1;
404
   %0 = %1;"
405
  [(set_attr "type" "move,move,mvi,mvi,mvi,*,mcld,mcst")
406
   (set_attr "length" "2,2,2,4,4,*,*,*")])
407
 
408
(define_insn "*movv2hi_insn"
409
  [(set (match_operand:V2HI 0 "nonimmediate_operand" "=da,d,m")
410
        (match_operand:V2HI 1 "general_operand" "d,m,d"))]
411
 
412
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
413
  "%0 = %1;"
414
  [(set_attr "type" "move,mcld,mcst")
415
   (set_attr "length" "2,*,*")])
416
 
417
(define_insn "*movhi_insn"
418
  [(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr")
419
        (match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
420
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
421
  "@
422
   %0 = %1;
423
   %0 = %1 (X);
424
   %0 = %1 (X);
425
   %0 = W %1 (X);
426
   W %0 = %1;"
427
  [(set_attr "type" "move,mvi,mvi,mcld,mcst")
428
   (set_attr "length" "2,2,4,*,*")])
429
 
430
(define_insn "*movqi_insn"
431
  [(set (match_operand:QI 0 "nonimmediate_operand" "=x,da,x,d,mr")
432
        (match_operand:QI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
433
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
434
  "@
435
   %0 = %1;
436
   %0 = %1 (X);
437
   %0 = %1 (X);
438
   %0 = B %1 (X);
439
   B %0 = %1;"
440
  [(set_attr "type" "move,mvi,mvi,mcld,mcst")
441
   (set_attr "length" "2,2,4,*,*")])
442
 
443
(define_insn "*movsf_insn"
444
  [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,da,mr")
445
        (match_operand:SF 1 "general_operand" "x,Fx,mr,da"))]
446
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
447
  "@
448
   %0 = %1;
449
   #
450
   %0 = %1;
451
   %0 = %1;"
452
  [(set_attr "type" "move,*,mcld,mcst")])
453
 
454
(define_insn_and_split "movdf_insn"
455
  [(set (match_operand:DF 0 "nonimmediate_operand" "=x,mx,r")
456
        (match_operand:DF 1 "general_operand" "iFx,r,mx"))]
457
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
458
  "#"
459
  "reload_completed"
460
  [(set (match_dup 2) (match_dup 3))
461
   (set (match_dup 4) (match_dup 5))]
462
{
463
  rtx lo_half[2], hi_half[2];
464
  split_di (operands, 2, lo_half, hi_half);
465
 
466
  if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
467
    {
468
      operands[2] = hi_half[0];
469
      operands[3] = hi_half[1];
470
      operands[4] = lo_half[0];
471
      operands[5] = lo_half[1];
472
    }
473
  else
474
    {
475
      operands[2] = lo_half[0];
476
      operands[3] = lo_half[1];
477
      operands[4] = hi_half[0];
478
      operands[5] = hi_half[1];
479
    }
480
})
481
 
482
;; This is the main "hook" for PIC code.  When generating
483
;; PIC, movsi is responsible for determining when the source address
484
;; needs PIC relocation and appropriately calling legitimize_pic_address
485
;; to perform the actual relocation.
486
 
487
(define_expand "movsi"
488
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
489
        (match_operand:SI 1 "general_operand" ""))]
490
  ""
491
  "expand_move (operands, SImode);")
492
 
493
(define_expand "movv2hi"
494
  [(set (match_operand:V2HI 0 "nonimmediate_operand" "")
495
        (match_operand:V2HI 1 "general_operand" ""))]
496
  ""
497
  "expand_move (operands, V2HImode);")
498
 
499
(define_expand "movdi"
500
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
501
        (match_operand:DI 1 "general_operand" ""))]
502
  ""
503
  "expand_move (operands, DImode);")
504
 
505
(define_expand "movsf"
506
 [(set (match_operand:SF 0 "nonimmediate_operand" "")
507
       (match_operand:SF 1 "general_operand" ""))]
508
  ""
509
  "expand_move (operands, SFmode);")
510
 
511
(define_expand "movdf"
512
 [(set (match_operand:DF 0 "nonimmediate_operand" "")
513
       (match_operand:DF 1 "general_operand" ""))]
514
  ""
515
  "expand_move (operands, DFmode);")
516
 
517
(define_expand "movhi"
518
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
519
        (match_operand:HI 1 "general_operand" ""))]
520
  ""
521
  "expand_move (operands, HImode);")
522
 
523
(define_expand "movqi"
524
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
525
        (match_operand:QI 1 "general_operand" ""))]
526
  ""
527
  " expand_move (operands, QImode); ")
528
 
529
;; Some define_splits to break up SI/SFmode loads of immediate constants.
530
 
531
(define_split
532
  [(set (match_operand:SI 0 "register_operand" "")
533
        (match_operand:SI 1 "symbolic_or_const_operand" ""))]
534
  "reload_completed
535
   /* Always split symbolic operands; split integer constants that are
536
      too large for a single instruction.  */
537
   && (GET_CODE (operands[1]) != CONST_INT
538
       || (INTVAL (operands[1]) < -32768
539
           || INTVAL (operands[1]) >= 65536
540
           || (INTVAL (operands[1]) >= 32768 && PREG_P (operands[0]))))"
541
  [(set (match_dup 0) (high:SI (match_dup 1)))
542
   (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))]
543
{
544
  if (GET_CODE (operands[1]) == CONST_INT
545
      && split_load_immediate (operands))
546
    DONE;
547
  /* ??? Do something about TARGET_LOW_64K.  */
548
})
549
 
550
(define_split
551
  [(set (match_operand:SF 0 "register_operand" "")
552
        (match_operand:SF 1 "immediate_operand" ""))]
553
  "reload_completed"
554
  [(set (match_dup 2) (high:SI (match_dup 3)))
555
   (set (match_dup 2) (lo_sum:SI (match_dup 2) (match_dup 3)))]
556
{
557
  long values;
558
  REAL_VALUE_TYPE value;
559
 
560
  gcc_assert (GET_CODE (operands[1]) == CONST_DOUBLE);
561
 
562
  REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
563
  REAL_VALUE_TO_TARGET_SINGLE (value, values);
564
 
565
  operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0]));
566
  operands[3] = GEN_INT (trunc_int_for_mode (values, SImode));
567
  if (values >= -32768 && values < 65536)
568
    {
569
      emit_move_insn (operands[2], operands[3]);
570
      DONE;
571
    }
572
  if (split_load_immediate (operands + 2))
573
    DONE;
574
})
575
 
576
;; Sadly, this can't be a proper named movstrict pattern, since the compiler
577
;; expects to be able to use registers for operand 1.
578
;; Note that the asm instruction is defined by the manual to take an unsigned
579
;; constant, but it doesn't matter to the assembler, and the compiler only
580
;; deals with sign-extended constants.  Hence "Ksh".
581
(define_insn "*movstricthi"
582
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+x"))
583
        (match_operand:HI 1 "immediate_operand" "Ksh"))]
584
  ""
585
  "%h0 = %1;"
586
  [(set_attr "type" "mvi")
587
   (set_attr "length" "4")])
588
 
589
;; Sign and zero extensions
590
 
591
(define_insn "extendhisi2"
592
  [(set (match_operand:SI 0 "register_operand" "=d, d")
593
        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
594
  ""
595
  "@
596
   %0 = %h1 (X);
597
   %0 = W %h1 (X);"
598
  [(set_attr "type" "alu0,mcld")])
599
 
600
(define_insn "zero_extendhisi2"
601
  [(set (match_operand:SI 0 "register_operand" "=d, d")
602
        (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
603
  ""
604
  "@
605
   %0 = %h1 (Z);
606
   %0 = W%h1 (Z);"
607
  [(set_attr "type" "alu0,mcld")])
608
 
609
(define_insn "zero_extendbisi2"
610
  [(set (match_operand:SI 0 "register_operand" "=d")
611
        (zero_extend:SI (match_operand:BI 1 "nonimmediate_operand" "C")))]
612
  ""
613
  "%0 = %1;"
614
  [(set_attr "type" "compare")])
615
 
616
(define_insn "extendqihi2"
617
  [(set (match_operand:HI 0 "register_operand" "=d, d")
618
        (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
619
  ""
620
  "@
621
   %0 = B %1 (X);
622
   %0 = %T1 (X);"
623
  [(set_attr "type" "mcld,alu0")])
624
 
625
(define_insn "extendqisi2"
626
  [(set (match_operand:SI 0 "register_operand" "=d, d")
627
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
628
  ""
629
  "@
630
   %0 = B %1 (X);
631
   %0 = %T1 (X);"
632
  [(set_attr "type" "mcld,alu0")])
633
 
634
 
635
(define_insn "zero_extendqihi2"
636
  [(set (match_operand:HI 0 "register_operand" "=d, d")
637
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
638
  ""
639
  "@
640
   %0 = B %1 (Z);
641
   %0 = %T1 (Z);"
642
  [(set_attr "type" "mcld,alu0")])
643
 
644
 
645
(define_insn "zero_extendqisi2"
646
  [(set (match_operand:SI 0 "register_operand" "=d, d")
647
        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
648
  ""
649
  "@
650
   %0 = B %1 (Z);
651
   %0 = %T1 (Z);"
652
  [(set_attr "type" "mcld,alu0")])
653
 
654
;; DImode logical operations
655
 
656
(define_code_macro any_logical [and ior xor])
657
(define_code_attr optab [(and "and")
658
                         (ior "ior")
659
                         (xor "xor")])
660
(define_code_attr op [(and "&")
661
                      (ior "|")
662
                      (xor "^")])
663
(define_code_attr high_result [(and "0")
664
                               (ior "%H1")
665
                               (xor "%H1")])
666
 
667
(define_insn "di3"
668
  [(set (match_operand:DI 0 "register_operand" "=d")
669
        (any_logical:DI (match_operand:DI 1 "register_operand" "0")
670
                        (match_operand:DI 2 "register_operand" "d")))]
671
  ""
672
  "%0 = %1  %2;\\n\\t%H0 = %H1  %H2;"
673
  [(set_attr "length" "4")])
674
 
675
(define_insn "*di_zesidi_di"
676
  [(set (match_operand:DI 0 "register_operand" "=d")
677
        (any_logical:DI (zero_extend:DI
678
                         (match_operand:SI 2 "register_operand" "d"))
679
                        (match_operand:DI 1 "register_operand" "d")))]
680
  ""
681
  "%0 = %1   %2;\\n\\t%H0 = ;"
682
  [(set_attr "length" "4")])
683
 
684
(define_insn "*di_sesdi_di"
685
  [(set (match_operand:DI 0 "register_operand" "=d")
686
        (any_logical:DI (sign_extend:DI
687
                         (match_operand:SI 2 "register_operand" "d"))
688
                        (match_operand:DI 1 "register_operand" "0")))
689
   (clobber (match_scratch:SI 3 "=&d"))]
690
  ""
691
  "%0 = %1  %2;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1  %3;"
692
  [(set_attr "length" "8")])
693
 
694
(define_insn "negdi2"
695
  [(set (match_operand:DI 0 "register_operand" "=d")
696
        (neg:DI (match_operand:DI 1 "register_operand" "d")))
697
   (clobber (match_scratch:SI 2 "=&d"))
698
   (clobber (reg:CC REG_CC))]
699
  ""
700
  "%2 = 0; %2 = %2 - %1; cc = ac0; cc = !cc; %2 = cc;\\n\\t%0 = -%1; %H0 = -%H1; %H0 = %H0 - %2;"
701
  [(set_attr "length" "16")])
702
 
703
(define_insn "one_cmpldi2"
704
  [(set (match_operand:DI 0 "register_operand" "=d")
705
        (not:DI (match_operand:DI 1 "register_operand" "d")))]
706
  ""
707
  "%0 = ~%1;\\n\\t%H0 = ~%H1;"
708
  [(set_attr "length" "4")])
709
 
710
;; DImode zero and sign extend patterns
711
 
712
(define_insn_and_split "zero_extendsidi2"
713
  [(set (match_operand:DI 0 "register_operand" "=d")
714
        (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
715
  ""
716
  "#"
717
  "reload_completed"
718
  [(set (match_dup 3) (const_int 0))]
719
{
720
  split_di (operands, 1, operands + 2, operands + 3);
721
  if (REGNO (operands[0]) != REGNO (operands[1]))
722
    emit_move_insn (operands[2], operands[1]);
723
})
724
 
725
(define_insn "zero_extendqidi2"
726
  [(set (match_operand:DI 0 "register_operand" "=d")
727
        (zero_extend:DI (match_operand:QI 1 "register_operand" "d")))]
728
  ""
729
  "%0 = %T1 (Z);\\n\\t%H0 = 0;"
730
  [(set_attr "length" "4")])
731
 
732
(define_insn "zero_extendhidi2"
733
  [(set (match_operand:DI 0 "register_operand" "=d")
734
        (zero_extend:DI (match_operand:HI 1 "register_operand" "d")))]
735
  ""
736
  "%0 = %h1 (Z);\\n\\t%H0 = 0;"
737
  [(set_attr "length" "4")])
738
 
739
(define_insn_and_split "extendsidi2"
740
  [(set (match_operand:DI 0 "register_operand" "=d")
741
        (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))]
742
  ""
743
  "#"
744
  "reload_completed"
745
  [(set (match_dup 3) (match_dup 1))
746
   (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
747
{
748
  split_di (operands, 1, operands + 2, operands + 3);
749
  if (REGNO (operands[0]) != REGNO (operands[1]))
750
    emit_move_insn (operands[2], operands[1]);
751
})
752
 
753
(define_insn_and_split "extendqidi2"
754
  [(set (match_operand:DI 0 "register_operand" "=d")
755
        (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
756
  ""
757
  "#"
758
  "reload_completed"
759
  [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
760
   (set (match_dup 3) (sign_extend:SI (match_dup 1)))
761
   (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
762
{
763
  split_di (operands, 1, operands + 2, operands + 3);
764
})
765
 
766
(define_insn_and_split "extendhidi2"
767
  [(set (match_operand:DI 0 "register_operand" "=d")
768
        (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
769
  ""
770
  "#"
771
  "reload_completed"
772
  [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
773
   (set (match_dup 3) (sign_extend:SI (match_dup 1)))
774
   (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
775
{
776
  split_di (operands, 1, operands + 2, operands + 3);
777
})
778
 
779
;; DImode arithmetic operations
780
 
781
(define_insn "adddi3"
782
  [(set (match_operand:DI 0 "register_operand" "=&d,&d,&d")
783
        (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
784
                 (match_operand:DI 2 "nonmemory_operand" "Kn7,Ks7,d")))
785
   (clobber (match_scratch:SI 3 "=&d,&d,&d"))
786
   (clobber (reg:CC 34))]
787
  ""
788
  "@
789
   %0 += %2; cc = ac0; %3 = cc; %H0 += -1; %H0 = %H0 + %3;
790
   %0 += %2; cc = ac0; %3 = cc; %H0 = %H0 + %3;
791
   %0 = %0 + %2; cc = ac0; %3 = cc; %H0 = %H0 + %H2; %H0 = %H0 + %3;"
792
  [(set_attr "type" "alu0")
793
   (set_attr "length" "10,8,10")])
794
 
795
(define_insn "subdi3"
796
  [(set (match_operand:DI 0 "register_operand" "=&d")
797
        (minus:DI (match_operand:DI 1 "register_operand" "0")
798
                  (match_operand:DI 2 "register_operand" "d")))
799
   (clobber (reg:CC 34))]
800
  ""
801
  "%0 = %1-%2;\\n\\tcc = ac0;\\n\\t%H0 = %H1-%H2;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:"
802
  [(set_attr "length" "10")])
803
 
804
(define_insn "*subdi_di_zesidi"
805
  [(set (match_operand:DI 0 "register_operand" "=d")
806
        (minus:DI (match_operand:DI 1 "register_operand" "0")
807
                  (zero_extend:DI
808
                  (match_operand:SI 2 "register_operand" "d"))))
809
   (clobber (match_scratch:SI 3 "=&d"))
810
   (clobber (reg:CC 34))]
811
  ""
812
  "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%H0 = %H1 - %3;"
813
  [(set_attr "length" "10")])
814
 
815
(define_insn "*subdi_zesidi_di"
816
  [(set (match_operand:DI 0 "register_operand" "=d")
817
        (minus:DI (zero_extend:DI
818
                  (match_operand:SI 2 "register_operand" "d"))
819
                  (match_operand:DI 1 "register_operand" "0")))
820
   (clobber (match_scratch:SI 3 "=&d"))
821
   (clobber (reg:CC 34))]
822
  ""
823
  "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%3 = -%3;\\n\\t%H0 = %3 - %H1"
824
  [(set_attr "length" "12")])
825
 
826
(define_insn "*subdi_di_sesidi"
827
  [(set (match_operand:DI 0 "register_operand" "=d")
828
        (minus:DI (match_operand:DI 1 "register_operand" "0")
829
                  (sign_extend:DI
830
                  (match_operand:SI 2 "register_operand" "d"))))
831
   (clobber (match_scratch:SI 3 "=&d"))
832
   (clobber (reg:CC 34))]
833
  ""
834
  "%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:"
835
  [(set_attr "length" "14")])
836
 
837
(define_insn "*subdi_sesidi_di"
838
  [(set (match_operand:DI 0 "register_operand" "=d")
839
        (minus:DI (sign_extend:DI
840
                  (match_operand:SI 2 "register_operand" "d"))
841
                  (match_operand:DI 1 "register_operand" "0")))
842
   (clobber (match_scratch:SI 3 "=&d"))
843
   (clobber (reg:CC 34))]
844
  ""
845
  "%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:"
846
  [(set_attr "length" "14")])
847
 
848
;; Combined shift/add instructions
849
 
850
(define_insn ""
851
  [(set (match_operand:SI 0 "register_operand" "=a,d")
852
        (ashift:SI (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
853
                            (match_operand:SI 2 "register_operand" "a,d"))
854
                   (match_operand:SI 3 "pos_scale_operand" "P1P2,P1P2")))]
855
  ""
856
  "%0 = (%0 + %2) << %3;" /* "shadd %0,%2,%3;" */
857
  [(set_attr "type" "alu0")])
858
 
859
(define_insn ""
860
  [(set (match_operand:SI 0 "register_operand" "=a")
861
        (plus:SI (match_operand:SI 1 "register_operand" "a")
862
                 (mult:SI (match_operand:SI 2 "register_operand" "a")
863
                          (match_operand:SI 3 "scale_by_operand" "i"))))]
864
  ""
865
  "%0 = %1 + (%2 << %X3);"
866
  [(set_attr "type" "alu0")])
867
 
868
(define_insn ""
869
  [(set (match_operand:SI 0 "register_operand" "=a")
870
        (plus:SI (match_operand:SI 1 "register_operand" "a")
871
                 (ashift:SI (match_operand:SI 2 "register_operand" "a")
872
                            (match_operand:SI 3 "pos_scale_operand" "i"))))]
873
  ""
874
  "%0 = %1 + (%2 << %3);"
875
  [(set_attr "type" "alu0")])
876
 
877
(define_insn ""
878
  [(set (match_operand:SI 0 "register_operand" "=a")
879
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "a")
880
                          (match_operand:SI 2 "scale_by_operand" "i"))
881
                 (match_operand:SI 3 "register_operand" "a")))]
882
  ""
883
  "%0 = %3 + (%1 << %X2);"
884
  [(set_attr "type" "alu0")])
885
 
886
(define_insn ""
887
  [(set (match_operand:SI 0 "register_operand" "=a")
888
        (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "a")
889
                            (match_operand:SI 2 "pos_scale_operand" "i"))
890
                 (match_operand:SI 3 "register_operand" "a")))]
891
  ""
892
  "%0 = %3 + (%1 << %2);"
893
  [(set_attr "type" "alu0")])
894
 
895
(define_insn "mulhisi3"
896
  [(set (match_operand:SI 0 "register_operand" "=d")
897
        (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%d"))
898
                 (sign_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
899
  ""
900
  "%0 = %h1 * %h2 (IS);"
901
  [(set_attr "type" "dsp32")])
902
 
903
(define_insn "umulhisi3"
904
  [(set (match_operand:SI 0 "register_operand" "=d")
905
        (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%d"))
906
                 (zero_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
907
  ""
908
  "%0 = %h1 * %h2 (FU);"
909
  [(set_attr "type" "dsp32")])
910
 
911
;; The processor also supports ireg += mreg or ireg -= mreg, but these
912
;; are unusable if we don't ensure that the corresponding lreg is zero.
913
;; The same applies to the add/subtract constant versions involving
914
;; iregs
915
 
916
(define_insn "addsi3"
917
  [(set (match_operand:SI 0 "register_operand" "=ad,a,d")
918
        (plus:SI (match_operand:SI 1 "register_operand" "%0, a,d")
919
                 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7, a,d")))]
920
  ""
921
  "@
922
   %0 += %2;
923
   %0 = %1 + %2;
924
   %0 = %1 + %2;"
925
  [(set_attr "type" "alu0")
926
   (set_attr "length" "2,2,2")])
927
 
928
(define_expand "subsi3"
929
  [(set (match_operand:SI 0 "register_operand" "")
930
        (minus:SI (match_operand:SI 1 "register_operand" "")
931
                  (match_operand:SI 2 "reg_or_7bit_operand" "")))]
932
  ""
933
  "")
934
 
935
(define_insn ""
936
  [(set (match_operand:SI 0 "register_operand" "=da,d,a")
937
        (minus:SI (match_operand:SI 1 "register_operand" "0,d,0")
938
                  (match_operand:SI 2 "reg_or_7bit_operand" "Ks7,d,a")))]
939
  "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -64"
940
{
941
  static const char *const strings_subsi3[] = {
942
    "%0 += -%2;",
943
    "%0 = %1 - %2;",
944
    "%0 -= %2;",
945
  };
946
 
947
  if (CONSTANT_P (operands[2]) && INTVAL (operands[2]) < 0) {
948
     rtx tmp_op = operands[2];
949
     operands[2] = GEN_INT (-INTVAL (operands[2]));
950
     output_asm_insn ("%0 += %2;", operands);
951
     operands[2] = tmp_op;
952
     return "";
953
  }
954
 
955
  return strings_subsi3[which_alternative];
956
}
957
  [(set_attr "type" "alu0")])
958
 
959
;; Bit test instructions
960
 
961
(define_insn "*not_bittst"
962
 [(set (match_operand:BI 0 "cc_operand" "=C")
963
       (eq:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
964
                               (const_int 1)
965
                               (match_operand:SI 2 "immediate_operand" "Ku5"))
966
              (const_int 0)))]
967
 ""
968
 "cc = !BITTST (%1,%2);"
969
  [(set_attr "type" "alu0")])
970
 
971
(define_insn "*bittst"
972
 [(set (match_operand:BI 0 "cc_operand" "=C")
973
       (ne:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
974
                               (const_int 1)
975
                               (match_operand:SI 2 "immediate_operand" "Ku5"))
976
                (const_int 0)))]
977
 ""
978
 "cc = BITTST (%1,%2);"
979
  [(set_attr "type" "alu0")])
980
 
981
(define_insn_and_split "*bit_extract"
982
  [(set (match_operand:SI 0 "register_operand" "=d")
983
        (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
984
                         (const_int 1)
985
                         (match_operand:SI 2 "immediate_operand" "Ku5")))
986
   (clobber (reg:BI REG_CC))]
987
  ""
988
  "#"
989
  ""
990
  [(set (reg:BI REG_CC)
991
        (ne:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
992
               (const_int 0)))
993
   (set (match_dup 0)
994
        (ne:SI (reg:BI REG_CC) (const_int 0)))])
995
 
996
(define_insn_and_split "*not_bit_extract"
997
  [(set (match_operand:SI 0 "register_operand" "=d")
998
        (zero_extract:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
999
                         (const_int 1)
1000
                         (match_operand:SI 2 "immediate_operand" "Ku5")))
1001
   (clobber (reg:BI REG_CC))]
1002
  ""
1003
  "#"
1004
  ""
1005
  [(set (reg:BI REG_CC)
1006
        (eq:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1007
               (const_int 0)))
1008
   (set (match_dup 0)
1009
        (ne:SI (reg:BI REG_CC) (const_int 0)))])
1010
 
1011
(define_insn "*andsi_insn"
1012
  [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
1013
        (and:SI (match_operand:SI 1 "register_operand" "%0,d,d,d")
1014
                (match_operand:SI 2 "rhs_andsi3_operand" "L,M1,M2,d")))]
1015
  ""
1016
  "@
1017
   BITCLR (%0,%Y2);
1018
   %0 = %T1 (Z);
1019
   %0 = %h1 (Z);
1020
   %0 = %1 & %2;"
1021
  [(set_attr "type" "alu0")])
1022
 
1023
(define_expand "andsi3"
1024
  [(set (match_operand:SI 0 "register_operand" "")
1025
        (and:SI (match_operand:SI 1 "register_operand" "")
1026
                (match_operand:SI 2 "general_operand" "")))]
1027
  ""
1028
{
1029
  if (highbits_operand (operands[2], SImode))
1030
    {
1031
      operands[2] = GEN_INT (exact_log2 (-INTVAL (operands[2])));
1032
      emit_insn (gen_ashrsi3 (operands[0], operands[1], operands[2]));
1033
      emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
1034
      DONE;
1035
    }
1036
  if (! rhs_andsi3_operand (operands[2], SImode))
1037
    operands[2] = force_reg (SImode, operands[2]);
1038
})
1039
 
1040
(define_insn "iorsi3"
1041
  [(set (match_operand:SI 0 "register_operand" "=d,d")
1042
        (ior:SI (match_operand:SI 1 "register_operand" "%0,d")
1043
                (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1044
  ""
1045
  "@
1046
   BITSET (%0, %X2);
1047
   %0 = %1 | %2;"
1048
  [(set_attr "type" "alu0")])
1049
 
1050
(define_insn "xorsi3"
1051
  [(set (match_operand:SI 0 "register_operand" "=d,d")
1052
        (xor:SI (match_operand:SI 1 "register_operand" "%0,d")
1053
                  (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1054
  ""
1055
  "@
1056
   BITTGL (%0, %X2);
1057
   %0 = %1 ^ %2;"
1058
  [(set_attr "type" "alu0")])
1059
 
1060
(define_insn "smaxsi3"
1061
  [(set (match_operand:SI 0 "register_operand" "=d")
1062
        (smax:SI (match_operand:SI 1 "register_operand" "d")
1063
                 (match_operand:SI 2 "register_operand" "d")))]
1064
  ""
1065
  "%0 =max(%1,%2);"
1066
  [(set_attr "type" "dsp32")])
1067
 
1068
(define_insn "sminsi3"
1069
  [(set (match_operand:SI 0 "register_operand" "=d")
1070
        (smin:SI (match_operand:SI 1 "register_operand" "d")
1071
                 (match_operand:SI 2 "register_operand" "d")))]
1072
  ""
1073
  "%0 =min(%1,%2);"
1074
  [(set_attr "type" "dsp32")])
1075
 
1076
(define_insn "abssi2"
1077
  [(set (match_operand:SI 0 "register_operand" "=d")
1078
        (abs:SI (match_operand:SI 1 "register_operand" " d")))]
1079
  ""
1080
  "%0 =abs %1;"
1081
  [(set_attr "type" "dsp32")])
1082
 
1083
 
1084
(define_insn "negsi2"
1085
  [(set (match_operand:SI 0 "register_operand" "=d")
1086
        (neg:SI (match_operand:SI 1 "register_operand" " d")))]
1087
  ""
1088
  "%0 =-%1;"
1089
  [(set_attr "type" "alu0")])
1090
 
1091
(define_insn "one_cmplsi2"
1092
  [(set (match_operand:SI 0 "register_operand" "=d")
1093
        (not:SI (match_operand:SI 1 "register_operand" " d")))]
1094
  ""
1095
  "%0 =~%1;"
1096
  [(set_attr "type" "alu0")])
1097
 
1098
(define_insn "mulsi3"
1099
  [(set (match_operand:SI 0 "register_operand" "=d")
1100
        (mult:SI (match_operand:SI 1 "register_operand" "%0")
1101
                 (match_operand:SI 2 "register_operand" "d")))]
1102
  ""
1103
  "%0 *=%2;"
1104
  [(set_attr "type" "mult")])
1105
 
1106
(define_expand "ashlsi3"
1107
  [(set (match_operand:SI 0 "register_operand" "")
1108
        (ashift:SI (match_operand:SI 1 "register_operand" "")
1109
                   (match_operand:SI 2 "nonmemory_operand" "")))]
1110
  ""
1111
{
1112
 if (GET_CODE (operands[2]) == CONST_INT
1113
     && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1114
   {
1115
     emit_insn (gen_movsi (operands[0], const0_rtx));
1116
     DONE;
1117
   }
1118
})
1119
 
1120
(define_insn_and_split "*ashlsi3_insn"
1121
  [(set (match_operand:SI 0 "register_operand" "=d,a,a,a")
1122
        (ashift:SI (match_operand:SI 1 "register_operand" "0,a,a,a")
1123
                   (match_operand:SI 2 "nonmemory_operand" "dKu5,P1,P2,?P3P4")))]
1124
  ""
1125
  "@
1126
   %0 <<= %2;
1127
   %0 = %1 + %1;
1128
   %0 = %1 << %2;
1129
   #"
1130
  "PREG_P (operands[0]) && INTVAL (operands[2]) > 2"
1131
  [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
1132
   (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
1133
  "operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
1134
  [(set_attr "type" "shft")])
1135
 
1136
(define_insn "ashrsi3"
1137
  [(set (match_operand:SI 0 "register_operand" "=d")
1138
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1139
                     (match_operand:SI 2 "nonmemory_operand" "dKu5")))]
1140
  ""
1141
  "%0 >>>= %2;"
1142
  [(set_attr "type" "shft")])
1143
 
1144
(define_insn "ror_one"
1145
  [(set (match_operand:SI 0 "register_operand" "=d")
1146
        (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1147
                (ashift:SI (zero_extend:SI (reg:BI REG_CC)) (const_int 31))))
1148
   (set (reg:BI REG_CC)
1149
        (zero_extract:BI (match_dup 1) (const_int 1) (const_int 0)))]
1150
  ""
1151
  "%0 = ROT %1 BY -1;"
1152
  [(set_attr "type" "shft")
1153
   (set_attr "length" "4")])
1154
 
1155
(define_insn "rol_one"
1156
  [(set (match_operand:SI 0 "register_operand" "+d")
1157
        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1158
                (zero_extend:SI (reg:BI REG_CC))))
1159
   (set (reg:BI REG_CC)
1160
        (zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))]
1161
  ""
1162
  "%0 = ROT %1 BY 1;"
1163
  [(set_attr "type" "shft")
1164
   (set_attr "length" "4")])
1165
 
1166
(define_expand "lshrdi3"
1167
  [(set (match_operand:DI 0 "register_operand" "")
1168
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1169
                     (match_operand:DI 2 "general_operand" "")))]
1170
  ""
1171
{
1172
  rtx lo_half[2], hi_half[2];
1173
 
1174
  if (operands[2] != const1_rtx)
1175
    FAIL;
1176
  if (! rtx_equal_p (operands[0], operands[1]))
1177
    emit_move_insn (operands[0], operands[1]);
1178
 
1179
  split_di (operands, 2, lo_half, hi_half);
1180
 
1181
  emit_move_insn (bfin_cc_rtx, const0_rtx);
1182
  emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1183
  emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1184
  DONE;
1185
})
1186
 
1187
(define_expand "ashrdi3"
1188
  [(set (match_operand:DI 0 "register_operand" "")
1189
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1190
                     (match_operand:DI 2 "general_operand" "")))]
1191
  ""
1192
{
1193
  rtx lo_half[2], hi_half[2];
1194
 
1195
  if (operands[2] != const1_rtx)
1196
    FAIL;
1197
  if (! rtx_equal_p (operands[0], operands[1]))
1198
    emit_move_insn (operands[0], operands[1]);
1199
 
1200
  split_di (operands, 2, lo_half, hi_half);
1201
 
1202
  emit_insn (gen_compare_lt (gen_rtx_REG (BImode, REG_CC),
1203
                             hi_half[1], const0_rtx));
1204
  emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1205
  emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1206
  DONE;
1207
})
1208
 
1209
(define_expand "ashldi3"
1210
  [(set (match_operand:DI 0 "register_operand" "")
1211
        (ashift:DI (match_operand:DI 1 "register_operand" "")
1212
                   (match_operand:DI 2 "general_operand" "")))]
1213
  ""
1214
{
1215
  rtx lo_half[2], hi_half[2];
1216
 
1217
  if (operands[2] != const1_rtx)
1218
    FAIL;
1219
  if (! rtx_equal_p (operands[0], operands[1]))
1220
    emit_move_insn (operands[0], operands[1]);
1221
 
1222
  split_di (operands, 2, lo_half, hi_half);
1223
 
1224
  emit_move_insn (bfin_cc_rtx, const0_rtx);
1225
  emit_insn (gen_rol_one (lo_half[0], lo_half[0]));
1226
  emit_insn (gen_rol_one (hi_half[0], hi_half[0]));
1227
  DONE;
1228
})
1229
 
1230
(define_insn "lshrsi3"
1231
  [(set (match_operand:SI 0 "register_operand" "=d,a")
1232
        (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0,a")
1233
                     (match_operand:SI 2 "nonmemory_operand" "dKu5,P1P2")))]
1234
  ""
1235
  "@
1236
   %0 >>= %2;
1237
   %0 = %1 >> %2;"
1238
  [(set_attr "type" "shft")])
1239
 
1240
;; A pattern to reload the equivalent of
1241
;;   (set (Dreg) (plus (FP) (large_constant)))
1242
;; or
1243
;;   (set (dagreg) (plus (FP) (arbitrary_constant)))
1244
;; using a scratch register
1245
(define_expand "reload_insi"
1246
  [(parallel [(set (match_operand:SI 0 "register_operand" "=w")
1247
                   (match_operand:SI 1 "fp_plus_const_operand" ""))
1248
              (clobber (match_operand:SI 2 "register_operand" "=&a"))])]
1249
  ""
1250
{
1251
  rtx fp_op = XEXP (operands[1], 0);
1252
  rtx const_op = XEXP (operands[1], 1);
1253
  rtx primary = operands[0];
1254
  rtx scratch = operands[2];
1255
 
1256
  emit_move_insn (scratch, const_op);
1257
  emit_insn (gen_addsi3 (scratch, scratch, fp_op));
1258
  emit_move_insn (primary, scratch);
1259
  DONE;
1260
})
1261
 
1262
;; Jump instructions
1263
 
1264
(define_insn "jump"
1265
  [(set (pc)
1266
        (label_ref (match_operand 0 "" "")))]
1267
  ""
1268
{
1269
  if (get_attr_length (insn) == 2)
1270
    return "jump.s %0;";
1271
  else
1272
    return "jump.l %0;";
1273
}
1274
  [(set_attr "type" "br")])
1275
 
1276
(define_insn "indirect_jump"
1277
  [(set (pc)
1278
        (match_operand:SI 0 "register_operand" "a"))]
1279
  ""
1280
  "jump (%0);"
1281
  [(set_attr "type" "misc")])
1282
 
1283
(define_expand "tablejump"
1284
  [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1285
              (use (label_ref (match_operand 1 "" "")))])]
1286
  ""
1287
{
1288
  /* In PIC mode, the table entries are stored PC relative.
1289
     Convert the relative address to an absolute address.  */
1290
  if (flag_pic)
1291
    {
1292
      rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1293
 
1294
      operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1295
                                         op1, NULL_RTX, 0, OPTAB_DIRECT);
1296
    }
1297
})
1298
 
1299
(define_insn "*tablejump_internal"
1300
  [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1301
   (use (label_ref (match_operand 1 "" "")))]
1302
  ""
1303
  "jump (%0);"
1304
  [(set_attr "type" "misc")])
1305
 
1306
;;  Call instructions..
1307
 
1308
(define_expand "call"
1309
  [(parallel [(call (match_operand:SI 0 "" "")
1310
                    (match_operand 1 "" ""))
1311
              (use (match_operand 2 "" ""))])]
1312
  ""
1313
{
1314
  bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 0);
1315
  DONE;
1316
})
1317
 
1318
(define_expand "sibcall"
1319
  [(parallel [(call (match_operand:SI 0 "" "")
1320
                    (match_operand 1 "" ""))
1321
              (use (match_operand 2 "" ""))
1322
              (return)])]
1323
  ""
1324
{
1325
  bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 1);
1326
  DONE;
1327
})
1328
 
1329
(define_expand "call_value"
1330
  [(parallel [(set (match_operand 0 "register_operand" "")
1331
                   (call (match_operand:SI 1 "" "")
1332
                         (match_operand 2 "" "")))
1333
              (use (match_operand 3 "" ""))])]
1334
  ""
1335
{
1336
  bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 0);
1337
  DONE;
1338
})
1339
 
1340
(define_expand "sibcall_value"
1341
  [(parallel [(set (match_operand 0 "register_operand" "")
1342
                   (call (match_operand:SI 1 "" "")
1343
                         (match_operand 2 "" "")))
1344
              (use (match_operand 3 "" ""))
1345
              (return)])]
1346
  ""
1347
{
1348
  bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 1);
1349
  DONE;
1350
})
1351
 
1352
(define_insn "*call_symbol"
1353
  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1354
         (match_operand 1 "general_operand" "g"))
1355
   (use (match_operand 2 "" ""))]
1356
  "! SIBLING_CALL_P (insn)
1357
   && !TARGET_ID_SHARED_LIBRARY
1358
   && GET_CODE (operands[0]) == SYMBOL_REF
1359
   && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
1360
  "call %0;"
1361
  [(set_attr "type" "call")
1362
   (set_attr "length" "4")])
1363
 
1364
(define_insn "*sibcall_symbol"
1365
  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
1366
         (match_operand 1 "general_operand" "g"))
1367
   (use (match_operand 2 "" ""))
1368
   (return)]
1369
  "SIBLING_CALL_P (insn)
1370
   && !TARGET_ID_SHARED_LIBRARY
1371
   && GET_CODE (operands[0]) == SYMBOL_REF
1372
   && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
1373
  "jump.l %0;"
1374
  [(set_attr "type" "br")
1375
   (set_attr "length" "4")])
1376
 
1377
(define_insn "*call_value_symbol"
1378
  [(set (match_operand 0 "register_operand" "=d")
1379
        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1380
              (match_operand 2 "general_operand" "g")))
1381
   (use (match_operand 3 "" ""))]
1382
  "! SIBLING_CALL_P (insn)
1383
   && !TARGET_ID_SHARED_LIBRARY
1384
   && GET_CODE (operands[1]) == SYMBOL_REF
1385
   && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
1386
  "call %1;"
1387
  [(set_attr "type" "call")
1388
   (set_attr "length" "4")])
1389
 
1390
(define_insn "*sibcall_value_symbol"
1391
  [(set (match_operand 0 "register_operand" "=d")
1392
         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
1393
               (match_operand 2 "general_operand" "g")))
1394
   (use (match_operand 3 "" ""))
1395
   (return)]
1396
  "SIBLING_CALL_P (insn)
1397
   && !TARGET_ID_SHARED_LIBRARY
1398
   && GET_CODE (operands[1]) == SYMBOL_REF
1399
   && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
1400
  "jump.l %1;"
1401
  [(set_attr "type" "br")
1402
   (set_attr "length" "4")])
1403
 
1404
(define_insn "*call_insn"
1405
  [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a"))
1406
         (match_operand 1 "general_operand" "g"))
1407
   (use (match_operand 2 "" ""))]
1408
  "! SIBLING_CALL_P (insn)"
1409
  "call (%0);"
1410
  [(set_attr "type" "call")
1411
   (set_attr "length" "2")])
1412
 
1413
(define_insn "*sibcall_insn"
1414
  [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "z"))
1415
         (match_operand 1 "general_operand" "g"))
1416
   (use (match_operand 2 "" ""))
1417
   (return)]
1418
  "SIBLING_CALL_P (insn)"
1419
  "jump (%0);"
1420
  [(set_attr "type" "br")
1421
   (set_attr "length" "2")])
1422
 
1423
(define_insn "*call_value_insn"
1424
  [(set (match_operand 0 "register_operand" "=d")
1425
        (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a"))
1426
              (match_operand 2 "general_operand" "g")))
1427
   (use (match_operand 3 "" ""))]
1428
  "! SIBLING_CALL_P (insn)"
1429
  "call (%1);"
1430
  [(set_attr "type" "call")
1431
   (set_attr "length" "2")])
1432
 
1433
(define_insn "*sibcall_value_insn"
1434
  [(set (match_operand 0 "register_operand" "=d")
1435
         (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "z"))
1436
               (match_operand 2 "general_operand" "g")))
1437
   (use (match_operand 3 "" ""))
1438
   (return)]
1439
  "SIBLING_CALL_P (insn)"
1440
  "jump (%1);"
1441
  [(set_attr "type" "br")
1442
   (set_attr "length" "2")])
1443
 
1444
;; Block move patterns
1445
 
1446
;; We cheat.  This copies one more word than operand 2 indicates.
1447
 
1448
(define_insn "rep_movsi"
1449
  [(set (match_operand:SI 0 "register_operand" "=&a")
1450
        (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1451
                          (ashift:SI (match_operand:SI 2 "register_operand" "a")
1452
                                     (const_int 2)))
1453
                 (const_int 4)))
1454
   (set (match_operand:SI 1 "register_operand" "=&b")
1455
        (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1456
                          (ashift:SI (match_dup 2) (const_int 2)))
1457
                 (const_int 4)))
1458
   (set (mem:BLK (match_dup 3))
1459
        (mem:BLK (match_dup 4)))
1460
   (use (match_dup 2))
1461
   (clobber (match_scratch:HI 5 "=&d"))]
1462
  ""
1463
  "%5 = [%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || [%3++] = %5 || %5 = [%4++]; [%3++] = %5;"
1464
  [(set_attr "type" "misc")
1465
   (set_attr "length" "16")])
1466
 
1467
(define_insn "rep_movhi"
1468
  [(set (match_operand:SI 0 "register_operand" "=&a")
1469
        (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
1470
                          (ashift:SI (match_operand:SI 2 "register_operand" "a")
1471
                                     (const_int 1)))
1472
                 (const_int 2)))
1473
   (set (match_operand:SI 1 "register_operand" "=&b")
1474
        (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
1475
                          (ashift:SI (match_dup 2) (const_int 1)))
1476
                 (const_int 2)))
1477
   (set (mem:BLK (match_dup 3))
1478
        (mem:BLK (match_dup 4)))
1479
   (use (match_dup 2))
1480
   (clobber (match_scratch:HI 5 "=&d"))]
1481
  ""
1482
  "%h5 = W[%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || W [%3++] = %5 || %h5 = W [%4++]; W [%3++] = %5;"
1483
  [(set_attr "type" "misc")
1484
   (set_attr "length" "16")])
1485
 
1486
(define_expand "movmemsi"
1487
  [(match_operand:BLK 0 "general_operand" "")
1488
   (match_operand:BLK 1 "general_operand" "")
1489
   (match_operand:SI 2 "const_int_operand" "")
1490
   (match_operand:SI 3 "const_int_operand" "")]
1491
  ""
1492
{
1493
  if (bfin_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
1494
    DONE;
1495
  FAIL;
1496
})
1497
 
1498
;; Conditional branch patterns
1499
;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
1500
 
1501
;; The only outcome of this pattern is that global variables
1502
;; bfin_compare_op[01] are set for use in bcond patterns.
1503
 
1504
(define_expand "cmpbi"
1505
 [(set (cc0) (compare (match_operand:BI 0 "register_operand" "")
1506
                      (match_operand:BI 1 "immediate_operand" "")))]
1507
 ""
1508
{
1509
  bfin_compare_op0 = operands[0];
1510
  bfin_compare_op1 = operands[1];
1511
  DONE;
1512
})
1513
 
1514
(define_expand "cmpsi"
1515
 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
1516
                      (match_operand:SI 1 "reg_or_const_int_operand" "")))]
1517
 ""
1518
{
1519
  bfin_compare_op0 = operands[0];
1520
  bfin_compare_op1 = operands[1];
1521
  DONE;
1522
})
1523
 
1524
(define_insn "compare_eq"
1525
  [(set (match_operand:BI 0 "cc_operand" "=C,C")
1526
        (eq:BI (match_operand:SI 1 "register_operand" "d,a")
1527
               (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
1528
  ""
1529
  "cc =%1==%2;"
1530
  [(set_attr "type" "compare")])
1531
 
1532
(define_insn "compare_ne"
1533
  [(set (match_operand:BI 0 "cc_operand" "=C,C")
1534
        (ne:BI (match_operand:SI 1 "register_operand" "d,a")
1535
               (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
1536
  "0"
1537
  "cc =%1!=%2;"
1538
  [(set_attr "type" "compare")])
1539
 
1540
(define_insn "compare_lt"
1541
  [(set (match_operand:BI 0 "cc_operand" "=C,C")
1542
        (lt:BI (match_operand:SI 1 "register_operand" "d,a")
1543
               (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
1544
  ""
1545
  "cc =%1<%2;"
1546
  [(set_attr "type" "compare")])
1547
 
1548
(define_insn "compare_le"
1549
  [(set (match_operand:BI 0 "cc_operand" "=C,C")
1550
        (le:BI (match_operand:SI 1 "register_operand" "d,a")
1551
               (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
1552
  ""
1553
  "cc =%1<=%2;"
1554
  [(set_attr "type" "compare")])
1555
 
1556
(define_insn "compare_leu"
1557
  [(set (match_operand:BI 0 "cc_operand" "=C,C")
1558
        (leu:BI (match_operand:SI 1 "register_operand" "d,a")
1559
                (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
1560
  ""
1561
  "cc =%1<=%2 (iu);"
1562
  [(set_attr "type" "compare")])
1563
 
1564
(define_insn "compare_ltu"
1565
  [(set (match_operand:BI 0 "cc_operand" "=C,C")
1566
        (ltu:BI (match_operand:SI 1 "register_operand" "d,a")
1567
                (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
1568
  ""
1569
  "cc =%1<%2 (iu);"
1570
  [(set_attr "type" "compare")])
1571
 
1572
(define_expand "beq"
1573
  [(set (match_dup 1) (match_dup 2))
1574
   (set (pc)
1575
        (if_then_else (match_dup 3)
1576
                   (label_ref (match_operand 0 "" ""))
1577
                   (pc)))]
1578
  ""
1579
{
1580
  rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1581
  operands[1] = bfin_cc_rtx;    /* hard register: CC */
1582
  operands[2] = gen_rtx_EQ (BImode, op0, op1);
1583
  /* If we have a BImode input, then we already have a compare result, and
1584
     do not need to emit another comparison.  */
1585
  if (GET_MODE (bfin_compare_op0) == BImode)
1586
    {
1587
      gcc_assert (bfin_compare_op1 == const0_rtx);
1588
      emit_insn (gen_cbranchbi4 (operands[2], op0, op1, operands[0]));
1589
      DONE;
1590
    }
1591
 
1592
  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1593
})
1594
 
1595
(define_expand "bne"
1596
  [(set (match_dup 1) (match_dup 2))
1597
   (set (pc)
1598
        (if_then_else (match_dup 3)
1599
                      (label_ref (match_operand 0 "" ""))
1600
                    (pc)))]
1601
  ""
1602
{
1603
  rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
1604
  /* If we have a BImode input, then we already have a compare result, and
1605
     do not need to emit another comparison.  */
1606
  if (GET_MODE (bfin_compare_op0) == BImode)
1607
    {
1608
      rtx cmp = gen_rtx_NE (BImode, op0, op1);
1609
 
1610
      gcc_assert (bfin_compare_op1 == const0_rtx);
1611
      emit_insn (gen_cbranchbi4 (cmp, op0, op1, operands[0]));
1612
      DONE;
1613
    }
1614
 
1615
  operands[1] = bfin_cc_rtx;    /* hard register: CC */
1616
  operands[2] = gen_rtx_EQ (BImode, op0, op1);
1617
  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1618
})
1619
 
1620
(define_expand "bgt"
1621
  [(set (match_dup 1) (match_dup 2))
1622
   (set (pc)
1623
        (if_then_else (match_dup 3)
1624
                      (label_ref (match_operand 0 "" ""))
1625
                    (pc)))]
1626
  ""
1627
{
1628
  operands[1] = bfin_cc_rtx;
1629
  operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1630
  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1631
})
1632
 
1633
(define_expand "bgtu"
1634
  [(set (match_dup 1) (match_dup 2))
1635
   (set (pc)
1636
        (if_then_else (match_dup 3)
1637
                      (label_ref (match_operand 0 "" ""))
1638
                    (pc)))]
1639
  ""
1640
{
1641
  operands[1] = bfin_cc_rtx;
1642
  operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1643
  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1644
})
1645
 
1646
(define_expand "blt"
1647
  [(set (match_dup 1) (match_dup 2))
1648
   (set (pc)
1649
        (if_then_else (match_dup 3)
1650
                      (label_ref (match_operand 0 "" ""))
1651
                    (pc)))]
1652
  ""
1653
{
1654
  operands[1] = bfin_cc_rtx;
1655
  operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1656
  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1657
})
1658
 
1659
(define_expand "bltu"
1660
  [(set (match_dup 1) (match_dup 2))
1661
   (set (pc)
1662
        (if_then_else (match_dup 3)
1663
                      (label_ref (match_operand 0 "" ""))
1664
                      (pc)))]
1665
  ""
1666
{
1667
  operands[1] = bfin_cc_rtx;
1668
  operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1669
  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1670
})
1671
 
1672
 
1673
(define_expand "bge"
1674
  [(set (match_dup 1) (match_dup 2))
1675
   (set (pc)
1676
        (if_then_else (match_dup 3)
1677
                      (label_ref (match_operand 0 "" ""))
1678
                      (pc)))]
1679
  ""
1680
{
1681
  operands[1] = bfin_cc_rtx;
1682
  operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
1683
  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1684
})
1685
 
1686
(define_expand "bgeu"
1687
  [(set (match_dup 1) (match_dup 2))
1688
   (set (pc)
1689
        (if_then_else (match_dup 3)
1690
                      (label_ref (match_operand 0 "" ""))
1691
                      (pc)))]
1692
  ""
1693
{
1694
  operands[1] = bfin_cc_rtx;
1695
  operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
1696
  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
1697
})
1698
 
1699
(define_expand "ble"
1700
  [(set (match_dup 1) (match_dup 2))
1701
   (set (pc)
1702
        (if_then_else (match_dup 3)
1703
                      (label_ref (match_operand 0 "" ""))
1704
                      (pc)))]
1705
  ""
1706
{
1707
  operands[1] = bfin_cc_rtx;
1708
  operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
1709
  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1710
})
1711
 
1712
(define_expand "bleu"
1713
  [(set (match_dup 1) (match_dup 2))
1714
   (set (pc)
1715
        (if_then_else (match_dup 3)
1716
                      (label_ref (match_operand 0 "" ""))
1717
                      (pc)))
1718
  ]
1719
  ""
1720
{
1721
  operands[1] = bfin_cc_rtx;
1722
  operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
1723
  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
1724
})
1725
 
1726
(define_insn "cbranchbi4"
1727
  [(set (pc)
1728
        (if_then_else
1729
         (match_operator 0 "bfin_cbranch_operator"
1730
                         [(match_operand:BI 1 "cc_operand" "C")
1731
                          (match_operand:BI 2 "immediate_operand" "P0")])
1732
         (label_ref (match_operand 3 "" ""))
1733
         (pc)))]
1734
  ""
1735
{
1736
  asm_conditional_branch (insn, operands, 0, 0);
1737
  return "";
1738
}
1739
  [(set_attr "type" "brcc")])
1740
 
1741
;; Special cbranch patterns to deal with the speculative load problem - see
1742
;; bfin_reorg for details.
1743
 
1744
(define_insn "cbranch_predicted_taken"
1745
  [(set (pc)
1746
        (if_then_else
1747
         (match_operator 0 "bfin_cbranch_operator"
1748
                         [(match_operand:BI 1 "cc_operand" "C")
1749
                          (match_operand:BI 2 "immediate_operand" "P0")])
1750
         (label_ref (match_operand 3 "" ""))
1751
         (pc)))
1752
   (unspec [(const_int 0)] UNSPEC_CBRANCH_TAKEN)]
1753
  ""
1754
{
1755
  asm_conditional_branch (insn, operands, 0, 1);
1756
  return "";
1757
}
1758
  [(set_attr "type" "brcc")])
1759
 
1760
(define_insn "cbranch_with_nops"
1761
  [(set (pc)
1762
        (if_then_else
1763
         (match_operator 0 "bfin_cbranch_operator"
1764
                         [(match_operand:BI 1 "cc_operand" "C")
1765
                          (match_operand:BI 2 "immediate_operand" "P0")])
1766
         (label_ref (match_operand 3 "" ""))
1767
         (pc)))
1768
   (unspec [(match_operand 4 "immediate_operand" "")] UNSPEC_CBRANCH_NOPS)]
1769
  "reload_completed"
1770
{
1771
  asm_conditional_branch (insn, operands, INTVAL (operands[4]), 0);
1772
  return "";
1773
}
1774
  [(set_attr "type" "brcc")
1775
   (set_attr "length" "6")])
1776
 
1777
;; setcc insns.  */
1778
(define_expand "seq"
1779
  [(set (match_dup 1) (eq:BI (match_dup 2) (match_dup 3)))
1780
   (set (match_operand:SI 0 "register_operand" "")
1781
        (ne:SI (match_dup 1) (const_int 0)))]
1782
  ""
1783
{
1784
  operands[2] = bfin_compare_op0;
1785
  operands[3] = bfin_compare_op1;
1786
  operands[1] = bfin_cc_rtx;
1787
})
1788
 
1789
(define_expand "slt"
1790
  [(set (match_dup 1) (lt:BI (match_dup 2) (match_dup 3)))
1791
   (set (match_operand:SI 0 "register_operand" "")
1792
        (ne:SI (match_dup 1) (const_int 0)))]
1793
  ""
1794
{
1795
   operands[2] = bfin_compare_op0;
1796
   operands[3] = bfin_compare_op1;
1797
   operands[1] = bfin_cc_rtx;
1798
})
1799
 
1800
(define_expand "sle"
1801
  [(set (match_dup 1) (le:BI (match_dup 2) (match_dup 3)))
1802
   (set (match_operand:SI 0 "register_operand" "")
1803
        (ne:SI (match_dup 1) (const_int 0)))]
1804
  ""
1805
{
1806
   operands[2] = bfin_compare_op0;
1807
   operands[3] = bfin_compare_op1;
1808
   operands[1] = bfin_cc_rtx;
1809
})
1810
 
1811
(define_expand "sltu"
1812
  [(set (match_dup 1) (ltu:BI (match_dup 2) (match_dup 3)))
1813
   (set (match_operand:SI 0 "register_operand" "")
1814
        (ne:SI (match_dup 1) (const_int 0)))]
1815
  ""
1816
{
1817
   operands[2] = bfin_compare_op0;
1818
   operands[3] = bfin_compare_op1;
1819
   operands[1] = bfin_cc_rtx;
1820
})
1821
 
1822
(define_expand "sleu"
1823
  [(set (match_dup 1) (leu:BI (match_dup 2) (match_dup 3)))
1824
   (set (match_operand:SI 0 "register_operand" "")
1825
        (ne:SI (match_dup 1) (const_int 0)))]
1826
  ""
1827
{
1828
   operands[2] = bfin_compare_op0;
1829
   operands[3] = bfin_compare_op1;
1830
   operands[1] = bfin_cc_rtx;
1831
})
1832
 
1833
(define_insn "nop"
1834
  [(const_int 0)]
1835
  ""
1836
  "nop;")
1837
 
1838
;;;;;;;;;;;;;;;;;;;;   CC2dreg   ;;;;;;;;;;;;;;;;;;;;;;;;;
1839
(define_insn "movsibi"
1840
  [(set (match_operand:BI 0 "cc_operand" "=C")
1841
        (ne:BI (match_operand:SI 1 "register_operand" "d")
1842
               (const_int 0)))]
1843
  ""
1844
  "CC = %1;"
1845
  [(set_attr "length" "2")])
1846
 
1847
(define_insn "movbisi"
1848
  [(set (match_operand:SI 0 "register_operand" "=d")
1849
        (ne:SI (match_operand:BI 1 "cc_operand" "C")
1850
               (const_int 0)))]
1851
  ""
1852
  "%0 = CC;"
1853
  [(set_attr "length" "2")])
1854
 
1855
(define_insn ""
1856
  [(set (match_operand:BI 0 "cc_operand" "=C")
1857
        (eq:BI (match_operand:BI 1 "cc_operand" " 0")
1858
               (const_int 0)))]
1859
  ""
1860
  "%0 = ! %0;"    /*  NOT CC;"  */
1861
  [(set_attr "type" "compare")])
1862
 
1863
;; Vector and DSP insns
1864
 
1865
(define_insn ""
1866
  [(set (match_operand:SI 0 "register_operand" "=d")
1867
        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1868
                           (const_int 24))
1869
                (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1870
                             (const_int 8))))]
1871
  ""
1872
  "%0 = ALIGN8(%1, %2);"
1873
  [(set_attr "type" "dsp32")])
1874
 
1875
(define_insn ""
1876
  [(set (match_operand:SI 0 "register_operand" "=d")
1877
        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1878
                           (const_int 16))
1879
                (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1880
                             (const_int 16))))]
1881
  ""
1882
  "%0 = ALIGN16(%1, %2);"
1883
  [(set_attr "type" "dsp32")])
1884
 
1885
(define_insn ""
1886
  [(set (match_operand:SI 0 "register_operand" "=d")
1887
        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
1888
                           (const_int 8))
1889
                (lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
1890
                             (const_int 24))))]
1891
  ""
1892
  "%0 = ALIGN24(%1, %2);"
1893
  [(set_attr "type" "dsp32")])
1894
 
1895
;; Prologue and epilogue.
1896
 
1897
(define_expand "prologue"
1898
  [(const_int 1)]
1899
  ""
1900
  "bfin_expand_prologue (); DONE;")
1901
 
1902
(define_expand "epilogue"
1903
  [(const_int 1)]
1904
  ""
1905
  "bfin_expand_epilogue (1, 0); DONE;")
1906
 
1907
(define_expand "sibcall_epilogue"
1908
  [(const_int 1)]
1909
  ""
1910
  "bfin_expand_epilogue (0, 0); DONE;")
1911
 
1912
(define_expand "eh_return"
1913
  [(unspec_volatile [(match_operand:SI 0 "register_operand" "")]
1914
                    UNSPEC_VOLATILE_EH_RETURN)]
1915
  ""
1916
{
1917
  emit_move_insn (EH_RETURN_HANDLER_RTX, operands[0]);
1918
  emit_insn (gen_eh_return_internal ());
1919
  emit_barrier ();
1920
  DONE;
1921
})
1922
 
1923
(define_insn_and_split "eh_return_internal"
1924
  [(unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN)]
1925
  ""
1926
  "#"
1927
  "reload_completed"
1928
  [(const_int 1)]
1929
  "bfin_expand_epilogue (1, 1); DONE;")
1930
 
1931
(define_insn "link"
1932
  [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS))
1933
   (set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:SI REG_FP))
1934
   (set (reg:SI REG_FP)
1935
        (plus:SI (reg:SI REG_SP) (const_int -8)))
1936
   (set (reg:SI REG_SP)
1937
        (plus:SI (reg:SI REG_SP) (match_operand:SI 0 "immediate_operand" "i")))]
1938
  ""
1939
  "LINK %Z0;"
1940
  [(set_attr "length" "4")])
1941
 
1942
(define_insn "unlink"
1943
  [(set (reg:SI REG_FP) (mem:SI (reg:SI REG_FP)))
1944
   (set (reg:SI REG_RETS) (mem:SI (plus:SI (reg:SI REG_FP) (const_int 4))))
1945
   (set (reg:SI REG_SP) (plus:SI (reg:SI REG_FP) (const_int 8)))]
1946
  ""
1947
  "UNLINK;"
1948
  [(set_attr "length" "4")])
1949
 
1950
;; This pattern is slightly clumsy.  The stack adjust must be the final SET in
1951
;; the pattern, otherwise dwarf2out becomes very confused about which reg goes
1952
;; where on the stack, since it goes through all elements of the parallel in
1953
;; sequence.
1954
(define_insn "push_multiple"
1955
  [(match_parallel 0 "push_multiple_operation"
1956
    [(unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_PUSH_MULTIPLE)])]
1957
  ""
1958
{
1959
  output_push_multiple (insn, operands);
1960
  return "";
1961
})
1962
 
1963
(define_insn "pop_multiple"
1964
  [(match_parallel 0 "pop_multiple_operation"
1965
    [(set (reg:SI REG_SP)
1966
          (plus:SI (reg:SI REG_SP) (match_operand:SI 1 "immediate_operand" "i")))])]
1967
  ""
1968
{
1969
  output_pop_multiple (insn, operands);
1970
  return "";
1971
})
1972
 
1973
(define_insn "return_internal"
1974
  [(return)
1975
   (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)]
1976
  "reload_completed"
1977
{
1978
  switch (INTVAL (operands[0]))
1979
    {
1980
    case EXCPT_HANDLER:
1981
      return "rtx;";
1982
    case NMI_HANDLER:
1983
      return "rtn;";
1984
    case INTERRUPT_HANDLER:
1985
      return "rti;";
1986
    case SUBROUTINE:
1987
      return "rts;";
1988
    }
1989
  gcc_unreachable ();
1990
})
1991
 
1992
(define_insn "csync"
1993
  [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
1994
  ""
1995
  "csync;"
1996
  [(set_attr "type" "sync")])
1997
 
1998
(define_insn "ssync"
1999
  [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_SSYNC)]
2000
  ""
2001
  "ssync;"
2002
  [(set_attr "type" "sync")])
2003
 
2004
(define_insn "trap"
2005
  [(trap_if (const_int 1) (const_int 3))]
2006
  ""
2007
  "excpt 3;"
2008
  [(set_attr "type" "misc")
2009
   (set_attr "length" "2")])
2010
 
2011
(define_insn "trapifcc"
2012
  [(trap_if (reg:BI REG_CC) (const_int 3))]
2013
  ""
2014
  "if !cc jump 4 (bp); excpt 3;"
2015
  [(set_attr "type" "misc")
2016
   (set_attr "length" "4")])
2017
 
2018
;;; Vector instructions
2019
 
2020
(define_insn "addv2hi3"
2021
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2022
        (plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2023
                   (match_operand:V2HI 2 "register_operand" "d")))]
2024
  ""
2025
  "%0 = %1 +|+ %2;"
2026
  [(set_attr "type" "dsp32")])
2027
 
2028
(define_insn "subv2hi3"
2029
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2030
        (minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2031
                   (match_operand:V2HI 2 "register_operand" "d")))]
2032
  ""
2033
  "%0 = %1 -|- %2;"
2034
  [(set_attr "type" "dsp32")])
2035
 
2036
(define_insn "sminv2hi3"
2037
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2038
        (smin:V2HI (match_operand:V2HI 1 "register_operand" "d")
2039
                   (match_operand:V2HI 2 "register_operand" "d")))]
2040
  ""
2041
  "%0 = MIN (%1, %2) (V);"
2042
  [(set_attr "type" "dsp32")])
2043
 
2044
(define_insn "smaxv2hi3"
2045
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2046
        (smax:V2HI (match_operand:V2HI 1 "register_operand" "d")
2047
                   (match_operand:V2HI 2 "register_operand" "d")))]
2048
  ""
2049
  "%0 = MAX (%1, %2) (V);"
2050
  [(set_attr "type" "dsp32")])
2051
 
2052
(define_insn "mulv2hi3"
2053
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2054
        (mult:V2HI (match_operand:V2HI 1 "register_operand" "d")
2055
                   (match_operand:V2HI 2 "register_operand" "d")))]
2056
  ""
2057
  "%h0 = %h1 * %h2, %d0 = %d1 * %d2 (IS);"
2058
  [(set_attr "type" "dsp32")])
2059
 
2060
(define_insn "negv2hi2"
2061
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2062
        (neg:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
2063
  ""
2064
  "%0 = - %1 (V);"
2065
  [(set_attr "type" "dsp32")])
2066
 
2067
(define_insn "absv2hi2"
2068
  [(set (match_operand:V2HI 0 "register_operand" "=d")
2069
        (abs:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
2070
  ""
2071
  "%0 = ABS %1 (V);"
2072
  [(set_attr "type" "dsp32")])
2073
 

powered by: WebSVN 2.1.0

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