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