1;;- Machine description for Blackfin for GNU compiler
2;;  Copyright (C) 2005-2021 Free Software Foundation, Inc.
3;;  Contributed by Analog Devices.
4
5;; This file is part of GCC.
6
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published
9;; by the Free Software Foundation; either version 3, or (at your
10;; option) any later version.
11
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15;; License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3.  If not see
19;; <http://www.gnu.org/licenses/>.
20
21; operand punctuation marks:
22;
23;     X -- integer value printed as log2
24;     Y -- integer value printed as log2(~value) - for bitclear
25;     h -- print half word register, low part
26;     d -- print half word register, high part
27;     D -- print operand as dregs pairs
28;     w -- print operand as accumulator register word (a0w, a1w)
29;     H -- high part of double mode operand
30;     T -- byte register representation Oct. 02 2001
31
32; constant operand classes
33;
34;     J   2**N       5bit imm scaled
35;     Ks7 -64 .. 63  signed 7bit imm
36;     Ku5 0..31      unsigned 5bit imm
37;     Ks4 -8 .. 7    signed 4bit imm
38;     Ks3 -4 .. 3    signed 3bit imm
39;     Ku3 0 .. 7     unsigned 3bit imm
40;     Pn  0, 1, 2    constants 0, 1 or 2, corresponding to n
41;
42; register operands
43;     d  (r0..r7)
44;     a  (p0..p5,fp,sp)
45;     e  (a0, a1)
46;     b  (i0..i3)
47;     f  (m0..m3)
48;     v  (b0..b3)
49;     c  (i0..i3,m0..m3) CIRCREGS
50;     C  (CC)            CCREGS
51;     t  (lt0,lt1)
52;     k  (lc0,lc1)
53;     u  (lb0,lb1)
54;
55
56;; Define constants for hard registers.
57
58(define_constants
59  [(REG_R0 0)
60   (REG_R1 1)
61   (REG_R2 2)
62   (REG_R3 3)
63   (REG_R4 4)
64   (REG_R5 5)
65   (REG_R6 6)
66   (REG_R7 7)
67
68   (REG_P0 8)
69   (REG_P1 9)
70   (REG_P2 10)
71   (REG_P3 11)
72   (REG_P4 12)
73   (REG_P5 13)
74   (REG_P6 14)
75   (REG_P7 15)
76
77   (REG_SP 14)
78   (REG_FP 15)
79
80   (REG_I0 16)
81   (REG_I1 17)
82   (REG_I2 18)
83   (REG_I3 19)
84
85   (REG_B0 20)
86   (REG_B1 21)
87   (REG_B2 22)
88   (REG_B3 23)
89
90   (REG_L0 24)
91   (REG_L1 25)
92   (REG_L2 26)
93   (REG_L3 27)
94
95   (REG_M0 28)
96   (REG_M1 29)
97   (REG_M2 30)
98   (REG_M3 31)
99
100   (REG_A0 32)
101   (REG_A1 33)
102
103   (REG_CC 34)
104   (REG_RETS 35)
105   (REG_RETI 36)
106   (REG_RETX 37)
107   (REG_RETN 38)
108   (REG_RETE 39)
109
110   (REG_ASTAT 40)
111   (REG_SEQSTAT 41)
112   (REG_USP 42)
113
114   (REG_ARGP 43)
115
116   (REG_LT0 44)
117   (REG_LT1 45)
118   (REG_LC0 46)
119   (REG_LC1 47)
120   (REG_LB0 48)
121   (REG_LB1 49)])
122
123;; Constants used in UNSPECs and UNSPEC_VOLATILEs.
124
125(define_constants
126  [(UNSPEC_CBRANCH_TAKEN 0)
127   (UNSPEC_CBRANCH_NOPS 1)
128   (UNSPEC_RETURN 2)
129   (UNSPEC_MOVE_PIC 3)
130   (UNSPEC_LIBRARY_OFFSET 4)
131   (UNSPEC_PUSH_MULTIPLE 5)
132   ;; Multiply or MAC with extra CONST_INT operand specifying the macflag
133   (UNSPEC_MUL_WITH_FLAG 6)
134   (UNSPEC_MAC_WITH_FLAG 7)
135   (UNSPEC_MOVE_FDPIC 8)
136   (UNSPEC_FUNCDESC_GOT17M4 9)
137   (UNSPEC_LSETUP_END 10)
138   ;; Distinguish a 32-bit version of an insn from a 16-bit version.
139   (UNSPEC_32BIT 11)
140   (UNSPEC_NOP 12)
141   (UNSPEC_ONES 13)
142   (UNSPEC_ATOMIC 14)])
143
144(define_constants
145  [(UNSPEC_VOLATILE_CSYNC 1)
146   (UNSPEC_VOLATILE_SSYNC 2)
147   (UNSPEC_VOLATILE_LOAD_FUNCDESC 3)
148   (UNSPEC_VOLATILE_STORE_EH_HANDLER 4)
149   (UNSPEC_VOLATILE_DUMMY 5)
150   (UNSPEC_VOLATILE_STALL 6)])
151
152(define_constants
153  [(MACFLAG_NONE 0)
154   (MACFLAG_T 1)
155   (MACFLAG_FU 2)
156   (MACFLAG_TFU 3)
157   (MACFLAG_IS 4)
158   (MACFLAG_IU 5)
159   (MACFLAG_W32 6)
160   (MACFLAG_M 7)
161   (MACFLAG_IS_M 8)
162   (MACFLAG_S2RND 9)
163   (MACFLAG_ISS2 10)
164   (MACFLAG_IH 11)])
165
166(define_attr "type"
167  "move,movcc,mvi,mcld,mcst,dsp32,dsp32shiftimm,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy,stall"
168  (const_string "misc"))
169
170(define_attr "addrtype" "32bit,preg,spreg,ireg"
171  (cond [(and (eq_attr "type" "mcld")
172	      (and (match_operand 0 "dp_register_operand" "")
173		   (match_operand 1 "mem_p_address_operand" "")))
174	   (const_string "preg")
175	 (and (eq_attr "type" "mcld")
176	      (and (match_operand 0 "dp_register_operand" "")
177		   (match_operand 1 "mem_spfp_address_operand" "")))
178	   (const_string "spreg")
179	 (and (eq_attr "type" "mcld")
180	      (and (match_operand 0 "dp_register_operand" "")
181		   (match_operand 1 "mem_i_address_operand" "")))
182	   (const_string "ireg")
183	 (and (eq_attr "type" "mcst")
184	      (and (match_operand 1 "dp_register_operand" "")
185		   (match_operand 0 "mem_p_address_operand" "")))
186	   (const_string "preg")
187	 (and (eq_attr "type" "mcst")
188	      (and (match_operand 1 "dp_register_operand" "")
189		   (match_operand 0 "mem_spfp_address_operand" "")))
190	   (const_string "spreg")
191	 (and (eq_attr "type" "mcst")
192	      (and (match_operand 1 "dp_register_operand" "")
193		   (match_operand 0 "mem_i_address_operand" "")))
194	   (const_string "ireg")]
195	(const_string "32bit")))
196
197(define_attr "storereg" "preg,other"
198  (cond [(and (eq_attr "type" "mcst")
199	      (match_operand 1 "p_register_operand" ""))
200	   (const_string "preg")]
201	(const_string "other")))
202
203;; Scheduling definitions
204
205(define_automaton "bfin")
206
207(define_cpu_unit "slot0" "bfin")
208(define_cpu_unit "slot1" "bfin")
209(define_cpu_unit "slot2" "bfin")
210
211;; Three units used to enforce parallel issue restrictions:
212;; only one of the 16-bit slots can use a P register in an address,
213;; and only one them can be a store.
214(define_cpu_unit "store" "bfin")
215(define_cpu_unit "pregs" "bfin")
216
217;; A dummy unit used to delay scheduling of loads after a conditional
218;; branch.
219(define_cpu_unit "load" "bfin")
220
221;; A logical unit used to work around anomaly 05000074.
222(define_cpu_unit "anomaly_05000074" "bfin")
223
224(define_reservation "core" "slot0+slot1+slot2")
225
226(define_insn_reservation "alu" 1
227  (eq_attr "type" "move,movcc,mvi,alu0,shft,brcc,br,call,misc,sync,compare")
228  "core")
229
230(define_insn_reservation "imul" 3
231  (eq_attr "type" "mult")
232  "core*3")
233
234(define_insn_reservation "dsp32" 1
235  (eq_attr "type" "dsp32")
236  "slot0")
237
238(define_insn_reservation "dsp32shiftimm" 1
239  (and (eq_attr "type" "dsp32shiftimm")
240       (not (match_test "ENABLE_WA_05000074")))
241  "slot0")
242
243(define_insn_reservation "dsp32shiftimm_anomaly_05000074" 1
244  (and (eq_attr "type" "dsp32shiftimm")
245       (match_test "ENABLE_WA_05000074"))
246  "slot0+anomaly_05000074")
247
248(define_insn_reservation "load32" 1
249  (and (not (eq_attr "seq_insns" "multi"))
250       (and (eq_attr "type" "mcld") (eq_attr "addrtype" "32bit")))
251  "core+load")
252
253(define_insn_reservation "loadp" 1
254  (and (not (eq_attr "seq_insns" "multi"))
255       (and (eq_attr "type" "mcld") (eq_attr "addrtype" "preg")))
256  "slot1+pregs+load")
257
258(define_insn_reservation "loadsp" 1
259  (and (not (eq_attr "seq_insns" "multi"))
260       (and (eq_attr "type" "mcld") (eq_attr "addrtype" "spreg")))
261  "slot1+pregs")
262
263(define_insn_reservation "loadi" 1
264  (and (not (eq_attr "seq_insns" "multi"))
265       (and (eq_attr "type" "mcld") (eq_attr "addrtype" "ireg")))
266  "(slot1|slot2)+load")
267
268(define_insn_reservation "store32" 1
269  (and (not (eq_attr "seq_insns" "multi"))
270       (and (eq_attr "type" "mcst") (eq_attr "addrtype" "32bit")))
271  "core")
272
273(define_insn_reservation "storep" 1
274  (and (and (not (eq_attr "seq_insns" "multi"))
275	    (and (eq_attr "type" "mcst")
276		 (ior (eq_attr "addrtype" "preg")
277		      (eq_attr "addrtype" "spreg"))))
278       (ior (not (match_test "ENABLE_WA_05000074"))
279	    (eq_attr "storereg" "other")))
280  "slot1+pregs+store")
281
282(define_insn_reservation "storep_anomaly_05000074" 1
283  (and (and (not (eq_attr "seq_insns" "multi"))
284	    (and (eq_attr "type" "mcst")
285		 (ior (eq_attr "addrtype" "preg")
286		      (eq_attr "addrtype" "spreg"))))
287       (and (match_test "ENABLE_WA_05000074")
288	    (eq_attr "storereg" "preg")))
289  "slot1+anomaly_05000074+pregs+store")
290
291(define_insn_reservation "storei" 1
292  (and (and (not (eq_attr "seq_insns" "multi"))
293	    (and (eq_attr "type" "mcst") (eq_attr "addrtype" "ireg")))
294       (ior (not (match_test "ENABLE_WA_05000074"))
295	    (eq_attr "storereg" "other")))
296  "(slot1|slot2)+store")
297
298(define_insn_reservation "storei_anomaly_05000074" 1
299  (and (and (not (eq_attr "seq_insns" "multi"))
300	    (and (eq_attr "type" "mcst") (eq_attr "addrtype" "ireg")))
301       (and (match_test "ENABLE_WA_05000074")
302	    (eq_attr "storereg" "preg")))
303  "((slot1+anomaly_05000074)|slot2)+store")
304
305(define_insn_reservation "multi" 2
306  (eq_attr "seq_insns" "multi")
307  "core")
308
309(define_insn_reservation "load_stall1" 1
310  (and (eq_attr "type" "stall")
311       (match_operand 0 "const1_operand" ""))
312  "core+load*2")
313
314(define_insn_reservation "load_stall3" 1
315  (and (eq_attr "type" "stall")
316       (match_operand 0 "const3_operand" ""))
317  "core+load*4")
318
319(absence_set "slot0" "slot1,slot2")
320(absence_set "slot1" "slot2")
321
322;; Make sure genautomata knows about the maximum latency that can be produced
323;; by the adjust_cost function.
324(define_insn_reservation "dummy" 5
325  (eq_attr "type" "dummy")
326  "core")
327
328;; Operand and operator predicates
329
330(include "predicates.md")
331(include "constraints.md")
332
333;;; FRIO branches have been optimized for code density
334;;; this comes at a slight cost of complexity when
335;;; a compiler needs to generate branches in the general
336;;; case.  In order to generate the correct branching
337;;; mechanisms the compiler needs keep track of instruction
338;;; lengths.  The follow table describes how to count instructions
339;;; for the FRIO architecture.
340;;;
341;;; unconditional br are 12-bit imm pcrelative branches *2
342;;; conditional   br are 10-bit imm pcrelative branches *2
343;;; brcc 10-bit:
344;;;   1024 10-bit imm *2 is 2048 (-1024..1022)
345;;; br 12-bit  :
346;;;   4096 12-bit imm *2 is 8192 (-4096..4094)
347;;; NOTE : For brcc we generate instructions such as
348;;;   if cc jmp; jump.[sl] offset
349;;;   offset of jump.[sl] is from the jump instruction but
350;;;     gcc calculates length from the if cc jmp instruction
351;;;     furthermore gcc takes the end address of the branch instruction
352;;;     as (pc) for a forward branch
353;;;     hence our range is (-4094, 4092) instead of (-4096, 4094) for a br
354;;;
355;;; The way the (pc) rtx works in these calculations is somewhat odd;
356;;; for backward branches it's the address of the current instruction,
357;;; for forward branches it's the previously known address of the following
358;;; instruction - we have to take this into account by reducing the range
359;;; for a forward branch.
360
361;; Lengths for type "mvi" insns are always defined by the instructions
362;; themselves.
363(define_attr "length" ""
364  (cond [(eq_attr "type" "mcld")
365         (if_then_else (match_operand 1 "effective_address_32bit_p" "")
366                       (const_int 4) (const_int 2))
367
368	 (eq_attr "type" "mcst")
369	 (if_then_else (match_operand 0 "effective_address_32bit_p" "")
370		       (const_int 4) (const_int 2))
371
372	 (eq_attr "type" "move") (const_int 2)
373
374	 (eq_attr "type" "dsp32") (const_int 4)
375	 (eq_attr "type" "dsp32shiftimm") (const_int 4)
376	 (eq_attr "type" "call")  (const_int 4)
377
378         (eq_attr "type" "br")
379  	 (if_then_else (and
380	                  (le (minus (match_dup 0) (pc)) (const_int 4092))
381	                  (ge (minus (match_dup 0) (pc)) (const_int -4096)))
382        	  (const_int 2)
383                  (const_int 4))
384
385         (eq_attr "type" "brcc")
386	 (cond [(and
387	            (le (minus (match_dup 3) (pc)) (const_int 1020))
388	            (ge (minus (match_dup 3) (pc)) (const_int -1024)))
389		  (const_int 2)
390		(and
391	            (le (minus (match_dup 3) (pc)) (const_int 4092))
392	            (ge (minus (match_dup 3) (pc)) (const_int -4094)))
393		  (const_int 4)]
394	       (const_int 6))
395        ]
396
397	(const_int 2)))
398
399;; Classify the insns into those that are one instruction and those that
400;; are more than one in sequence.
401(define_attr "seq_insns" "single,multi"
402  (const_string "single"))
403
404;; Describe a user's asm statement.
405(define_asm_attributes
406  [(set_attr "type" "misc")
407   (set_attr "seq_insns" "multi")
408   (set_attr "length" "4")])
409
410;; Conditional moves
411
412(define_mode_iterator CCMOV [QI HI SI])
413
414(define_expand "mov<mode>cc"
415  [(set (match_operand:CCMOV 0 "register_operand" "")
416        (if_then_else:CCMOV (match_operand 1 "comparison_operator" "")
417			    (match_operand:CCMOV 2 "register_operand" "")
418			    (match_operand:CCMOV 3 "register_operand" "")))]
419  ""
420{
421  operands[1] = bfin_gen_compare (operands[1], <MODE>mode);
422})
423
424(define_insn "*mov<mode>cc_insn1"
425  [(set (match_operand:CCMOV 0 "register_operand" "=da,da,da")
426        (if_then_else:CCMOV
427	    (eq:BI (match_operand:BI 3 "register_operand" "C,C,C")
428		(const_int 0))
429	    (match_operand:CCMOV 1 "register_operand" "da,0,da")
430	    (match_operand:CCMOV 2 "register_operand" "0,da,da")))]
431  ""
432  "@
433    if !cc %0 = %1;
434    if cc %0 = %2;
435    if !cc %0 = %1; if cc %0 = %2;"
436  [(set_attr "length" "2,2,4")
437   (set_attr "type" "movcc")
438   (set_attr "seq_insns" "*,*,multi")])
439
440(define_insn "*mov<mode>cc_insn2"
441  [(set (match_operand:CCMOV 0 "register_operand" "=da,da,da")
442        (if_then_else:CCMOV
443	    (ne:BI (match_operand:BI 3 "register_operand" "C,C,C")
444		(const_int 0))
445	    (match_operand:CCMOV 1 "register_operand" "0,da,da")
446	    (match_operand:CCMOV 2 "register_operand" "da,0,da")))]
447  ""
448  "@
449   if !cc %0 = %2;
450   if cc %0 = %1;
451   if cc %0 = %1; if !cc %0 = %2;"
452  [(set_attr "length" "2,2,4")
453   (set_attr "type" "movcc")
454   (set_attr "seq_insns" "*,*,multi")])
455
456;; Insns to load HIGH and LO_SUM
457
458(define_insn "movsi_high"
459  [(set (match_operand:SI 0 "register_operand" "=x")
460	(high:SI (match_operand:SI 1 "immediate_operand" "i")))]
461  "reload_completed"
462  "%d0 = %d1;"
463  [(set_attr "type" "mvi")
464   (set_attr "length" "4")])
465
466(define_insn "movstricthi_high"
467  [(set (match_operand:SI 0 "register_operand" "+x")
468	(ior:SI (and:SI (match_dup 0) (const_int 65535))
469		(match_operand:SI 1 "immediate_operand" "i")))]
470  "reload_completed"
471  "%d0 = %d1;"
472  [(set_attr "type" "mvi")
473   (set_attr "length" "4")])
474
475(define_insn "movsi_low"
476  [(set (match_operand:SI 0 "register_operand" "=x")
477	(lo_sum:SI (match_operand:SI 1 "register_operand" "0")
478		   (match_operand:SI 2 "immediate_operand" "i")))]
479  "reload_completed"
480  "%h0 = %h2;"
481  [(set_attr "type" "mvi")
482   (set_attr "length" "4")])
483
484(define_insn "movsi_high_pic"
485  [(set (match_operand:SI 0 "register_operand" "=x")
486	(high:SI (unspec:SI [(match_operand:SI 1 "" "")]
487			    UNSPEC_MOVE_PIC)))]
488  ""
489  "%d0 = %1@GOT_LOW;"
490  [(set_attr "type" "mvi")
491   (set_attr "length" "4")])
492
493(define_insn "movsi_low_pic"
494  [(set (match_operand:SI 0 "register_operand" "=x")
495	(lo_sum:SI (match_operand:SI 1 "register_operand" "0")
496		   (unspec:SI [(match_operand:SI 2 "" "")]
497			      UNSPEC_MOVE_PIC)))]
498  ""
499  "%h0 = %h2@GOT_HIGH;"
500  [(set_attr "type" "mvi")
501   (set_attr "length" "4")])
502
503;;; Move instructions
504
505(define_insn_and_split "movdi_insn"
506  [(set (match_operand:DI 0 "nonimmediate_operand" "=x,mx,r")
507	(match_operand:DI 1 "general_operand" "iFx,r,mx"))]
508  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
509  "#"
510  "reload_completed"
511  [(set (match_dup 2) (match_dup 3))
512   (set (match_dup 4) (match_dup 5))]
513{
514  rtx lo_half[2], hi_half[2];
515  split_di (operands, 2, lo_half, hi_half);
516
517  if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
518    {
519      operands[2] = hi_half[0];
520      operands[3] = hi_half[1];
521      operands[4] = lo_half[0];
522      operands[5] = lo_half[1];
523    }
524  else
525    {
526      operands[2] = lo_half[0];
527      operands[3] = lo_half[1];
528      operands[4] = hi_half[0];
529      operands[5] = hi_half[1];
530    }
531})
532
533(define_insn "movbi"
534  [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,md,C,d,C,P1")
535        (match_operand:BI 1 "general_operand" "x,xKs3,md,d,d,C,P0,P1"))]
536
537  ""
538  "@
539   %0 = %1;
540   %0 = %1 (X);
541   %0 = B %1 (Z)%!
542   B %0 = %1;
543   CC = %1;
544   %0 = CC;
545   CC = R0 < R0;
546   CC = R0 == R0;"
547  [(set_attr "type" "move,mvi,mcld,mcst,compare,compare,compare,compare")
548   (set_attr "length" "2,2,*,*,2,2,2,2")
549   (set_attr "seq_insns" "*,*,*,*,*,*,*,*")])
550
551(define_insn "movpdi"
552  [(set (match_operand:PDI 0 "nonimmediate_operand" "=e,<,e")
553        (match_operand:PDI 1 "general_operand" " e,e,>"))]
554  ""
555  "@
556   %0 = %1;
557   %0 = %x1; %0 = %w1;
558   %w0 = %1; %x0 = %1;"
559  [(set_attr "type" "move,mcst,mcld")
560   (set_attr "length" "4,*,*")
561   (set_attr "seq_insns" "*,multi,multi")])
562
563(define_insn "load_accumulator"
564  [(set (match_operand:PDI 0 "register_operand" "=e")
565        (sign_extend:PDI (match_operand:SI 1 "register_operand" "d")))]
566  ""
567  "%0 = %1;"
568  [(set_attr "type" "move")])
569
570(define_insn_and_split "load_accumulator_pair"
571  [(set (match_operand:V2PDI 0 "register_operand" "=e")
572        (sign_extend:V2PDI (vec_concat:V2SI
573			    (match_operand:SI 1 "register_operand" "d")
574			    (match_operand:SI 2 "register_operand" "d"))))]
575  ""
576  "#"
577  "reload_completed"
578  [(set (match_dup 3) (sign_extend:PDI (match_dup 1)))
579   (set (match_dup 4) (sign_extend:PDI (match_dup 2)))]
580{
581  operands[3] = gen_rtx_REG (PDImode, REGNO (operands[0]));
582  operands[4] = gen_rtx_REG (PDImode, REGNO (operands[0]) + 1);
583})
584
585(define_insn "*pushsi_insn"
586  [(set (mem:SI (pre_dec:SI (reg:SI REG_SP)))
587        (match_operand:SI 0 "register_operand" "xy"))]
588  ""
589  "[--SP] = %0;"
590  [(set_attr "type" "mcst")
591   (set_attr "addrtype" "32bit")
592   (set_attr "length" "2")])
593
594(define_insn "*popsi_insn"
595  [(set (match_operand:SI 0 "register_operand" "=d,xy")
596        (mem:SI (post_inc:SI (reg:SI REG_SP))))]
597  ""
598  "%0 = [SP++]%!"
599  [(set_attr "type" "mcld")
600   (set_attr "addrtype" "preg,32bit")
601   (set_attr "length" "2")])
602
603;; The first alternative is used to make reload choose a limited register
604;; class when faced with a movsi_insn that had its input operand replaced
605;; with a PLUS.  We generally require fewer secondary reloads this way.
606
607(define_insn "*movsi_insn"
608  [(set (match_operand:SI 0 "nonimmediate_operand" "=da,x,da,y,da,x,x,x,da,mr")
609	(match_operand:SI 1 "general_operand" "da,x,y,da,xKs7,xKsh,xKuh,ix,mr,da"))]
610  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
611 "@
612   %0 = %1;
613   %0 = %1;
614   %0 = %1;
615   %0 = %1;
616   %0 = %1 (X);
617   %0 = %1 (X);
618   %0 = %1 (Z);
619   #
620   %0 = %1%!
621   %0 = %1%!"
622  [(set_attr "type" "move,move,move,move,mvi,mvi,mvi,*,mcld,mcst")
623   (set_attr "length" "2,2,2,2,2,4,4,*,*,*")])
624
625(define_insn "*movsi_insn32"
626  [(set (match_operand:SI 0 "register_operand" "=d,d")
627	(unspec:SI [(match_operand:SI 1 "nonmemory_operand" "d,P0")] UNSPEC_32BIT))]
628  ""
629 "@
630   %0 = ROT %1 BY 0%!
631   %0 = %0 -|- %0%!"
632  [(set_attr "type" "dsp32shiftimm,dsp32")])
633
634(define_split
635  [(set (match_operand:SI 0 "d_register_operand" "")
636	(const_int 0))]
637  "splitting_for_sched && !optimize_size"
638  [(set (match_dup 0) (unspec:SI [(const_int 0)] UNSPEC_32BIT))])
639
640(define_split
641  [(set (match_operand:SI 0 "d_register_operand" "")
642	(match_operand:SI 1 "d_register_operand" ""))]
643  "splitting_for_sched && !optimize_size"
644  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_32BIT))])
645
646(define_insn_and_split "*movv2hi_insn"
647  [(set (match_operand:V2HI 0 "nonimmediate_operand" "=da,da,d,dm")
648        (match_operand:V2HI 1 "general_operand" "i,di,md,d"))]
649
650  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
651  "@
652   #
653   %0 = %1;
654   %0 = %1%!
655   %0 = %1%!"
656  "reload_completed && GET_CODE (operands[1]) == CONST_VECTOR"
657  [(set (match_dup 0) (high:SI (match_dup 2)))
658   (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 3)))]
659{
660  HOST_WIDE_INT intval = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
661  intval |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
662
663  operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
664  operands[2] = operands[3] = GEN_INT (trunc_int_for_mode (intval, SImode));
665}
666  [(set_attr "type" "move,move,mcld,mcst")
667   (set_attr "length" "2,2,*,*")])
668
669(define_insn "*movhi_insn"
670  [(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr")
671        (match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
672  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
673{
674  static const char *templates[] = {
675    "%0 = %1;",
676    "%0 = %1 (X);",
677    "%0 = %1 (X);",
678    "%0 = W %1 (X)%!",
679    "W %0 = %1%!",
680    "%h0 = W %1%!",
681    "W %0 = %h1%!"
682  };
683  int alt = which_alternative;
684  rtx mem = (MEM_P (operands[0]) ? operands[0]
685	     : MEM_P (operands[1]) ? operands[1] : NULL_RTX);
686  if (mem && bfin_dsp_memref_p (mem))
687    alt += 2;
688  return templates[alt];
689}
690  [(set_attr "type" "move,mvi,mvi,mcld,mcst")
691   (set_attr "length" "2,2,4,*,*")])
692
693(define_insn "*movqi_insn"
694  [(set (match_operand:QI 0 "nonimmediate_operand" "=x,da,x,d,mr")
695        (match_operand:QI 1 "general_operand" "x,xKs7,xKsh,mr,d"))]
696  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
697  "@
698   %0 = %1;
699   %0 = %1 (X);
700   %0 = %1 (X);
701   %0 = B %1 (X)%!
702   B %0 = %1%!"
703  [(set_attr "type" "move,mvi,mvi,mcld,mcst")
704   (set_attr "length" "2,2,4,*,*")])
705
706(define_insn "*movsf_insn"
707  [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,da,mr")
708        (match_operand:SF 1 "general_operand" "x,Fx,mr,da"))]
709  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
710  "@
711   %0 = %1;
712   #
713   %0 = %1%!
714   %0 = %1%!"
715  [(set_attr "type" "move,*,mcld,mcst")])
716
717(define_insn_and_split "movdf_insn"
718  [(set (match_operand:DF 0 "nonimmediate_operand" "=x,mx,r")
719	(match_operand:DF 1 "general_operand" "iFx,r,mx"))]
720  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) == REG"
721  "#"
722  "reload_completed"
723  [(set (match_dup 2) (match_dup 3))
724   (set (match_dup 4) (match_dup 5))]
725{
726  rtx lo_half[2], hi_half[2];
727  split_di (operands, 2, lo_half, hi_half);
728
729  if (reg_overlap_mentioned_p (lo_half[0], hi_half[1]))
730    {
731      operands[2] = hi_half[0];
732      operands[3] = hi_half[1];
733      operands[4] = lo_half[0];
734      operands[5] = lo_half[1];
735    }
736  else
737    {
738      operands[2] = lo_half[0];
739      operands[3] = lo_half[1];
740      operands[4] = hi_half[0];
741      operands[5] = hi_half[1];
742    }
743})
744
745;; Storing halfwords.
746(define_insn "*movsi_insv"
747  [(set (zero_extract:SI (match_operand 0 "register_operand" "+d,x")
748			 (const_int 16)
749			 (const_int 16))
750	(match_operand:SI 1 "nonmemory_operand" "d,n"))]
751  ""
752  "@
753   %d0 = %h1 << 0%!
754   %d0 = %1;"
755  [(set_attr "type" "dsp32shiftimm,mvi")
756   (set_attr "length" "*,4")])
757
758(define_expand "insv"
759  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
760			 (match_operand:SI 1 "immediate_operand" "")
761			 (match_operand:SI 2 "immediate_operand" ""))
762        (match_operand:SI 3 "nonmemory_operand" ""))]
763  ""
764{
765  if (INTVAL (operands[1]) != 16 || INTVAL (operands[2]) != 16)
766    FAIL;
767
768  /* From mips.md: insert_bit_field doesn't verify that our source
769     matches the predicate, so check it again here.  */
770  if (! register_operand (operands[0], VOIDmode))
771    FAIL;
772})
773
774;; This is the main "hook" for PIC code.  When generating
775;; PIC, movsi is responsible for determining when the source address
776;; needs PIC relocation and appropriately calling legitimize_pic_address
777;; to perform the actual relocation.
778
779(define_expand "movsi"
780  [(set (match_operand:SI 0 "nonimmediate_operand" "")
781	(match_operand:SI 1 "general_operand" ""))]
782  ""
783{
784  if (expand_move (operands, SImode))
785    DONE;
786})
787
788(define_expand "movv2hi"
789  [(set (match_operand:V2HI 0 "nonimmediate_operand" "")
790	(match_operand:V2HI 1 "general_operand" ""))]
791  ""
792  "expand_move (operands, V2HImode);")
793
794(define_expand "movdi"
795  [(set (match_operand:DI 0 "nonimmediate_operand" "")
796	(match_operand:DI 1 "general_operand" ""))]
797  ""
798  "expand_move (operands, DImode);")
799
800(define_expand "movsf"
801 [(set (match_operand:SF 0 "nonimmediate_operand" "")
802       (match_operand:SF 1 "general_operand" ""))]
803  ""
804  "expand_move (operands, SFmode);")
805
806(define_expand "movdf"
807 [(set (match_operand:DF 0 "nonimmediate_operand" "")
808       (match_operand:DF 1 "general_operand" ""))]
809  ""
810  "expand_move (operands, DFmode);")
811
812(define_expand "movhi"
813  [(set (match_operand:HI 0 "nonimmediate_operand" "")
814	(match_operand:HI 1 "general_operand" ""))]
815  ""
816  "expand_move (operands, HImode);")
817
818(define_expand "movqi"
819  [(set (match_operand:QI 0 "nonimmediate_operand" "")
820	(match_operand:QI 1 "general_operand" ""))]
821  ""
822  " expand_move (operands, QImode); ")
823
824;; Some define_splits to break up SI/SFmode loads of immediate constants.
825
826(define_split
827  [(set (match_operand:SI 0 "register_operand" "")
828	(match_operand:SI 1 "symbolic_or_const_operand" ""))]
829  "reload_completed
830   /* Always split symbolic operands; split integer constants that are
831      too large for a single instruction.  */
832   && (GET_CODE (operands[1]) != CONST_INT
833       || (INTVAL (operands[1]) < -32768
834 	   || INTVAL (operands[1]) >= 65536
835	   || (INTVAL (operands[1]) >= 32768 && PREG_P (operands[0]))))"
836  [(set (match_dup 0) (high:SI (match_dup 1)))
837   (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))]
838{
839  if (GET_CODE (operands[1]) == CONST_INT
840      && split_load_immediate (operands))
841    DONE;
842  /* ??? Do something about TARGET_LOW_64K.  */
843})
844
845(define_split
846  [(set (match_operand:SF 0 "register_operand" "")
847	(match_operand:SF 1 "immediate_operand" ""))]
848  "reload_completed"
849  [(set (match_dup 2) (high:SI (match_dup 3)))
850   (set (match_dup 2) (lo_sum:SI (match_dup 2) (match_dup 3)))]
851{
852  long values;
853
854  gcc_assert (GET_CODE (operands[1]) == CONST_DOUBLE);
855
856  REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), values);
857
858  operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0]));
859  operands[3] = GEN_INT (trunc_int_for_mode (values, SImode));
860  if (values >= -32768 && values < 65536)
861    {
862      emit_move_insn (operands[2], operands[3]);
863      DONE;
864    }
865  if (split_load_immediate (operands + 2))
866    DONE;
867})
868
869;; Sadly, this can't be a proper named movstrict pattern, since the compiler
870;; expects to be able to use registers for operand 1.
871;; Note that the asm instruction is defined by the manual to take an unsigned
872;; constant, but it doesn't matter to the assembler, and the compiler only
873;; deals with sign-extended constants.  Hence "Ksh".
874(define_insn "movstricthi_1"
875  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+x"))
876	(match_operand:HI 1 "immediate_operand" "Ksh"))]
877  ""
878  "%h0 = %1;"
879  [(set_attr "type" "mvi")
880   (set_attr "length" "4")])
881
882;; Sign and zero extensions
883
884(define_insn_and_split "extendhisi2"
885  [(set (match_operand:SI 0 "register_operand" "=d, d")
886	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
887  ""
888  "@
889   %0 = %h1 (X);
890   %0 = W %h1 (X)%!"
891  "reload_completed && bfin_dsp_memref_p (operands[1])"
892  [(set (match_dup 2) (match_dup 1))
893   (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
894{
895  operands[2] = gen_lowpart (HImode, operands[0]);
896}
897  [(set_attr "type" "alu0,mcld")])
898
899(define_insn_and_split "zero_extendhisi2"
900  [(set (match_operand:SI 0 "register_operand" "=d, d")
901	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))]
902  ""
903  "@
904   %0 = %h1 (Z);
905   %0 = W %h1 (Z)%!"
906  "reload_completed && bfin_dsp_memref_p (operands[1])"
907  [(set (match_dup 2) (match_dup 1))
908   (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
909{
910  operands[2] = gen_lowpart (HImode, operands[0]);
911}
912  [(set_attr "type" "alu0,mcld")])
913
914(define_insn "zero_extendbisi2"
915  [(set (match_operand:SI 0 "register_operand" "=d")
916	(zero_extend:SI (match_operand:BI 1 "nonimmediate_operand" "C")))]
917  ""
918  "%0 = %1;"
919  [(set_attr "type" "compare")])
920
921(define_insn "extendqihi2"
922  [(set (match_operand:HI 0 "register_operand" "=d, d")
923	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
924  ""
925  "@
926   %0 = B %1 (X)%!
927   %0 = %T1 (X);"
928  [(set_attr "type" "mcld,alu0")])
929
930(define_insn "extendqisi2"
931  [(set (match_operand:SI 0 "register_operand" "=d, d")
932	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
933  ""
934  "@
935   %0 = B %1 (X)%!
936   %0 = %T1 (X);"
937  [(set_attr "type" "mcld,alu0")])
938
939
940(define_insn "zero_extendqihi2"
941  [(set (match_operand:HI 0 "register_operand" "=d, d")
942	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
943  ""
944  "@
945   %0 = B %1 (Z)%!
946   %0 = %T1 (Z);"
947  [(set_attr "type" "mcld,alu0")])
948
949
950(define_insn "zero_extendqisi2"
951  [(set (match_operand:SI 0 "register_operand" "=d, d")
952	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))]
953  ""
954  "@
955   %0 = B %1 (Z)%!
956   %0 = %T1 (Z);"
957  [(set_attr "type" "mcld,alu0")])
958
959;; DImode logical operations
960
961(define_code_iterator any_logical [and ior xor])
962(define_code_attr optab [(and "and")
963			 (ior "ior")
964			 (xor "xor")])
965(define_code_attr op [(and "&")
966		      (ior "|")
967		      (xor "^")])
968(define_code_attr high_result [(and "0")
969			       (ior "%H1")
970			       (xor "%H1")])
971
972;; Keep this pattern around to avoid generating NO_CONFLICT blocks.
973(define_expand "<optab>di3"
974  [(set (match_operand:DI 0 "register_operand" "=d")
975        (any_logical:DI (match_operand:DI 1 "register_operand" "0")
976			(match_operand:DI 2 "general_operand" "d")))]
977  ""
978{
979  rtx hi_half[3], lo_half[3];
980  enum insn_code icode = CODE_FOR_<optab>si3;
981  if (!reg_overlap_mentioned_p (operands[0], operands[1])
982      && !reg_overlap_mentioned_p (operands[0], operands[2]))
983    emit_clobber (operands[0]);
984  split_di (operands, 3, lo_half, hi_half);
985  if (!(*insn_data[icode].operand[2].predicate) (lo_half[2], SImode))
986    lo_half[2] = force_reg (SImode, lo_half[2]);
987  emit_insn (GEN_FCN (icode) (lo_half[0], lo_half[1], lo_half[2]));
988  if (!(*insn_data[icode].operand[2].predicate) (hi_half[2], SImode))
989    hi_half[2] = force_reg (SImode, hi_half[2]);
990  emit_insn (GEN_FCN (icode) (hi_half[0], hi_half[1], hi_half[2]));
991  DONE;
992})
993
994(define_insn "zero_extendqidi2"
995  [(set (match_operand:DI 0 "register_operand" "=d")
996        (zero_extend:DI (match_operand:QI 1 "register_operand" "d")))]
997  ""
998  "%0 = %T1 (Z);\\n\\t%H0 = 0;"
999  [(set_attr "length" "4")
1000   (set_attr "seq_insns" "multi")])
1001
1002(define_insn "zero_extendhidi2"
1003  [(set (match_operand:DI 0 "register_operand" "=d")
1004        (zero_extend:DI (match_operand:HI 1 "register_operand" "d")))]
1005  ""
1006  "%0 = %h1 (Z);\\n\\t%H0 = 0;"
1007  [(set_attr "length" "4")
1008   (set_attr "seq_insns" "multi")])
1009
1010(define_insn_and_split "extendsidi2"
1011  [(set (match_operand:DI 0 "register_operand" "=d")
1012        (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))]
1013  ""
1014  "#"
1015  "reload_completed"
1016  [(set (match_dup 3) (match_dup 1))
1017   (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
1018{
1019  split_di (operands, 1, operands + 2, operands + 3);
1020  if (REGNO (operands[0]) != REGNO (operands[1]))
1021    emit_move_insn (operands[2], operands[1]);
1022})
1023
1024(define_insn_and_split "extendqidi2"
1025  [(set (match_operand:DI 0 "register_operand" "=d")
1026        (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
1027  ""
1028  "#"
1029  "reload_completed"
1030  [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
1031   (set (match_dup 3) (sign_extend:SI (match_dup 1)))
1032   (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
1033{
1034  split_di (operands, 1, operands + 2, operands + 3);
1035})
1036
1037(define_insn_and_split "extendhidi2"
1038  [(set (match_operand:DI 0 "register_operand" "=d")
1039        (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
1040  ""
1041  "#"
1042  "reload_completed"
1043  [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
1044   (set (match_dup 3) (sign_extend:SI (match_dup 1)))
1045   (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))]
1046{
1047  split_di (operands, 1, operands + 2, operands + 3);
1048})
1049
1050;; DImode arithmetic operations
1051
1052(define_insn "add_with_carry"
1053  [(set (match_operand:SI 0 "register_operand" "=d,d")
1054        (plus:SI (match_operand:SI 1 "register_operand" "%0,d")
1055                 (match_operand:SI 2 "nonmemory_operand" "Ks7,d")))
1056   (set (match_operand:BI 3 "register_operand" "=C,C")
1057	(ltu:BI (not:SI (match_dup 1)) (match_dup 2)))]
1058  ""
1059  "@
1060   %0 += %2; cc = ac0;
1061   %0 = %1 + %2; cc = ac0;"
1062  [(set_attr "type" "alu0")
1063   (set_attr "length" "4")
1064   (set_attr "seq_insns" "multi")])
1065
1066(define_insn "sub_with_carry"
1067  [(set (match_operand:SI 0 "register_operand" "=d")
1068        (minus:SI (match_operand:SI 1 "register_operand" "%d")
1069		  (match_operand:SI 2 "nonmemory_operand" "d")))
1070   (set (match_operand:BI 3 "register_operand" "=C")
1071	(leu:BI (match_dup 2) (match_dup 1)))]
1072  ""
1073  "%0 = %1 - %2; cc = ac0;"
1074  [(set_attr "type" "alu0")
1075   (set_attr "length" "4")
1076   (set_attr "seq_insns" "multi")])
1077
1078(define_expand "adddi3"
1079  [(set (match_operand:DI 0 "register_operand" "")
1080        (plus:DI (match_operand:DI 1 "register_operand" "")
1081                 (match_operand:DI 2 "nonmemory_operand" "")))
1082   (clobber (match_scratch:SI 3 ""))
1083   (clobber (reg:CC 34))]
1084  ""
1085{
1086  rtx xops[8];
1087  xops[0] = gen_lowpart (SImode, operands[0]);
1088  xops[1] = simplify_gen_subreg (SImode, operands[0], DImode, 4);
1089  xops[2] = gen_lowpart (SImode, operands[1]);
1090  xops[3] = simplify_gen_subreg (SImode, operands[1], DImode, 4);
1091  xops[4] = gen_lowpart (SImode, operands[2]);
1092  xops[5] = simplify_gen_subreg (SImode, operands[2], DImode, 4);
1093  xops[6] = gen_reg_rtx (SImode);
1094  xops[7] = gen_rtx_REG (BImode, REG_CC);
1095  if (!register_operand (xops[4], SImode)
1096      && (GET_CODE (xops[4]) != CONST_INT
1097          || !satisfies_constraint_Ks7 (xops[4])))
1098    xops[4] = force_reg (SImode, xops[4]);
1099  if (!reg_overlap_mentioned_p (operands[0], operands[1])
1100      && !reg_overlap_mentioned_p (operands[0], operands[2]))
1101    emit_clobber (operands[0]);
1102  emit_insn (gen_add_with_carry (xops[0], xops[2], xops[4], xops[7]));
1103  emit_insn (gen_movbisi (xops[6], xops[7]));
1104  if (!register_operand (xops[5], SImode)
1105      && (GET_CODE (xops[5]) != CONST_INT
1106          || !satisfies_constraint_Ks7 (xops[5])))
1107    xops[5] = force_reg (SImode, xops[5]);
1108  if (xops[5] != const0_rtx)
1109    emit_insn (gen_addsi3 (xops[1], xops[3], xops[5]));
1110  else
1111    emit_move_insn (xops[1], xops[3]);
1112  emit_insn (gen_addsi3 (xops[1], xops[1], xops[6]));
1113  DONE;
1114})
1115
1116(define_expand "subdi3"
1117  [(set (match_operand:DI 0 "register_operand" "")
1118        (minus:DI (match_operand:DI 1 "register_operand" "")
1119                  (match_operand:DI 2 "register_operand" "")))
1120   (clobber (reg:CC 34))]
1121  ""
1122{
1123  rtx xops[8];
1124  xops[0] = gen_lowpart (SImode, operands[0]);
1125  xops[1] = simplify_gen_subreg (SImode, operands[0], DImode, 4);
1126  xops[2] = gen_lowpart (SImode, operands[1]);
1127  xops[3] = simplify_gen_subreg (SImode, operands[1], DImode, 4);
1128  xops[4] = gen_lowpart (SImode, operands[2]);
1129  xops[5] = simplify_gen_subreg (SImode, operands[2], DImode, 4);
1130  xops[6] = gen_reg_rtx (SImode);
1131  xops[7] = gen_rtx_REG (BImode, REG_CC);
1132  if (!reg_overlap_mentioned_p (operands[0], operands[1])
1133      && !reg_overlap_mentioned_p (operands[0], operands[2]))
1134    emit_clobber (operands[0]);
1135  emit_insn (gen_sub_with_carry (xops[0], xops[2], xops[4], xops[7]));
1136  emit_insn (gen_notbi (xops[7], xops[7]));
1137  emit_insn (gen_movbisi (xops[6], xops[7]));
1138  emit_insn (gen_subsi3 (xops[1], xops[3], xops[5]));
1139  emit_insn (gen_subsi3 (xops[1], xops[1], xops[6]));
1140  DONE;
1141})
1142
1143;; Combined shift/add instructions
1144
1145(define_insn ""
1146  [(set (match_operand:SI 0 "register_operand" "=a,d")
1147	(ashift:SI (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
1148		            (match_operand:SI 2 "register_operand" "a,d"))
1149		   (match_operand:SI 3 "pos_scale_operand" "P1P2,P1P2")))]
1150  ""
1151  "%0 = (%0 + %2) << %3;" /* "shadd %0,%2,%3;" */
1152  [(set_attr "type" "alu0")])
1153
1154(define_insn ""
1155  [(set (match_operand:SI 0 "register_operand" "=a")
1156	(plus:SI (match_operand:SI 1 "register_operand" "a")
1157		 (mult:SI (match_operand:SI 2 "register_operand" "a")
1158			  (match_operand:SI 3 "scale_by_operand" "i"))))]
1159  ""
1160  "%0 = %1 + (%2 << %X3);"
1161  [(set_attr "type" "alu0")])
1162
1163(define_insn ""
1164  [(set (match_operand:SI 0 "register_operand" "=a")
1165	(plus:SI (match_operand:SI 1 "register_operand" "a")
1166		 (ashift:SI (match_operand:SI 2 "register_operand" "a")
1167			    (match_operand:SI 3 "pos_scale_operand" "i"))))]
1168  ""
1169  "%0 = %1 + (%2 << %3);"
1170  [(set_attr "type" "alu0")])
1171
1172(define_insn ""
1173  [(set (match_operand:SI 0 "register_operand" "=a")
1174	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "a")
1175			  (match_operand:SI 2 "scale_by_operand" "i"))
1176		 (match_operand:SI 3 "register_operand" "a")))]
1177  ""
1178  "%0 = %3 + (%1 << %X2);"
1179  [(set_attr "type" "alu0")])
1180
1181(define_insn ""
1182  [(set (match_operand:SI 0 "register_operand" "=a")
1183	(plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "a")
1184			    (match_operand:SI 2 "pos_scale_operand" "i"))
1185		 (match_operand:SI 3 "register_operand" "a")))]
1186  ""
1187  "%0 = %3 + (%1 << %2);"
1188  [(set_attr "type" "alu0")])
1189
1190(define_insn "mulhisi3"
1191  [(set (match_operand:SI 0 "register_operand" "=d")
1192	(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%d"))
1193		 (sign_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
1194  ""
1195  "%0 = %h1 * %h2 (IS)%!"
1196  [(set_attr "type" "dsp32")])
1197
1198(define_insn "umulhisi3"
1199  [(set (match_operand:SI 0 "register_operand" "=d")
1200	(mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%d"))
1201		 (zero_extend:SI (match_operand:HI 2 "register_operand" "d"))))]
1202  ""
1203  "%0 = %h1 * %h2 (FU)%!"
1204  [(set_attr "type" "dsp32")])
1205
1206(define_insn "usmulhisi3"
1207  [(set (match_operand:SI 0 "register_operand" "=W")
1208	(mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "W"))
1209		 (sign_extend:SI (match_operand:HI 2 "register_operand" "W"))))]
1210  ""
1211  "%0 = %h2 * %h1 (IS,M)%!"
1212  [(set_attr "type" "dsp32")])
1213
1214;; The alternative involving IREGS requires that the corresponding L register
1215;; is zero.
1216
1217(define_insn "addsi3"
1218  [(set (match_operand:SI 0 "register_operand" "=ad,a,d,b")
1219       (plus:SI (match_operand:SI 1 "register_operand" "%0, a,d,0")
1220                (match_operand:SI 2 "reg_or_7bit_operand" "Ks7, a,d,fP2P4")))]
1221  ""
1222  "@
1223   %0 += %2;
1224   %0 = %1 + %2;
1225   %0 = %1 + %2;
1226   %0 += %2;"
1227  [(set_attr "type" "alu0")
1228   (set_attr "length" "2,2,2,2")])
1229
1230(define_insn "ssaddsi3"
1231  [(set (match_operand:SI 0 "register_operand" "=d")
1232	(ss_plus:SI (match_operand:SI 1 "register_operand" "d")
1233		    (match_operand:SI 2 "register_operand" "d")))]
1234  ""
1235  "%0 = %1 + %2 (S)%!"
1236  [(set_attr "type" "dsp32")])
1237
1238(define_insn "subsi3"
1239  [(set (match_operand:SI 0 "register_operand" "=da,d,a")
1240	(minus:SI (match_operand:SI 1 "register_operand" "0,d,0")
1241		  (match_operand:SI 2 "reg_or_neg7bit_operand" "KN7,d,a")))]
1242  ""
1243{
1244  static const char *const strings_subsi3[] = {
1245    "%0 += -%2;",
1246    "%0 = %1 - %2;",
1247    "%0 -= %2;",
1248  };
1249
1250  if (CONSTANT_P (operands[2]) && INTVAL (operands[2]) < 0) {
1251     rtx tmp_op = operands[2];
1252     operands[2] = GEN_INT (-INTVAL (operands[2]));
1253     output_asm_insn ("%0 += %2;", operands);
1254     operands[2] = tmp_op;
1255     return "";
1256  }
1257
1258  return strings_subsi3[which_alternative];
1259}
1260  [(set_attr "type" "alu0")])
1261
1262(define_insn "sssubsi3"
1263  [(set (match_operand:SI 0 "register_operand" "=d")
1264	(ss_minus:SI (match_operand:SI 1 "register_operand" "d")
1265		     (match_operand:SI 2 "register_operand" "d")))]
1266  ""
1267  "%0 = %1 - %2 (S)%!"
1268  [(set_attr "type" "dsp32")])
1269
1270;; Accumulator addition
1271
1272(define_insn "addpdi3"
1273  [(set (match_operand:PDI 0 "register_operand" "=A")
1274        (ss_plus:PDI (match_operand:PDI 1 "register_operand" "%0")
1275		     (match_operand:PDI 2 "nonmemory_operand" "B")))]
1276  ""
1277  "A0 += A1%!"
1278  [(set_attr "type" "dsp32")])
1279
1280(define_insn "sum_of_accumulators"
1281  [(set (match_operand:SI 0 "register_operand" "=d")
1282	(ss_truncate:SI
1283	 (ss_plus:PDI (match_operand:PDI 2 "register_operand" "1")
1284		      (match_operand:PDI 3 "register_operand" "B"))))
1285   (set (match_operand:PDI 1 "register_operand" "=A")
1286	 (ss_plus:PDI (match_dup 2) (match_dup 3)))]
1287  ""
1288  "%0 = (A0 += A1)%!"
1289  [(set_attr "type" "dsp32")])
1290
1291(define_insn "us_truncpdisi2"
1292  [(set (match_operand:SI 0 "register_operand" "=D,W")
1293	(us_truncate:SI (match_operand:PDI 1 "register_operand" "A,B")))]
1294  ""
1295  "%0 = %1 (FU)%!"
1296  [(set_attr "type" "dsp32")])
1297
1298;; Bit test instructions
1299
1300(define_insn "*not_bittst"
1301 [(set (match_operand:BI 0 "register_operand" "=C")
1302       (eq:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1303			       (const_int 1)
1304			       (match_operand:SI 2 "immediate_operand" "Ku5"))
1305	      (const_int 0)))]
1306 ""
1307 "cc = !BITTST (%1,%2);"
1308  [(set_attr "type" "alu0")])
1309
1310(define_insn "*bittst"
1311 [(set (match_operand:BI 0 "register_operand" "=C")
1312       (ne:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1313			       (const_int 1)
1314			       (match_operand:SI 2 "immediate_operand" "Ku5"))
1315		(const_int 0)))]
1316 ""
1317 "cc = BITTST (%1,%2);"
1318  [(set_attr "type" "alu0")])
1319
1320(define_insn_and_split "*bit_extract"
1321  [(set (match_operand:SI 0 "register_operand" "=d")
1322	(zero_extract:SI (match_operand:SI 1 "register_operand" "d")
1323			 (const_int 1)
1324			 (match_operand:SI 2 "immediate_operand" "Ku5")))
1325   (clobber (reg:BI REG_CC))]
1326  ""
1327  "#"
1328  ""
1329  [(set (reg:BI REG_CC)
1330	(ne:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1331	       (const_int 0)))
1332   (set (match_dup 0)
1333	(ne:SI (reg:BI REG_CC) (const_int 0)))])
1334
1335(define_insn_and_split "*not_bit_extract"
1336  [(set (match_operand:SI 0 "register_operand" "=d")
1337	(zero_extract:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1338			 (const_int 1)
1339			 (match_operand:SI 2 "immediate_operand" "Ku5")))
1340   (clobber (reg:BI REG_CC))]
1341  ""
1342  "#"
1343  ""
1344  [(set (reg:BI REG_CC)
1345	(eq:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))
1346	       (const_int 0)))
1347   (set (match_dup 0)
1348	(ne:SI (reg:BI REG_CC) (const_int 0)))])
1349
1350(define_insn "*andsi_insn"
1351  [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
1352	(and:SI (match_operand:SI 1 "register_operand" "%0,d,d,d")
1353		(match_operand:SI 2 "rhs_andsi3_operand" "L,M1,M2,d")))]
1354  ""
1355  "@
1356   BITCLR (%0,%Y2);
1357   %0 = %T1 (Z);
1358   %0 = %h1 (Z);
1359   %0 = %1 & %2;"
1360  [(set_attr "type" "alu0")])
1361
1362(define_expand "andsi3"
1363  [(set (match_operand:SI 0 "register_operand" "")
1364	(and:SI (match_operand:SI 1 "register_operand" "")
1365		(match_operand:SI 2 "general_operand" "")))]
1366  ""
1367{
1368  if (highbits_operand (operands[2], SImode))
1369    {
1370      operands[2] = GEN_INT (exact_log2 (-INTVAL (operands[2])));
1371      emit_insn (gen_ashrsi3 (operands[0], operands[1], operands[2]));
1372      emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2]));
1373      DONE;
1374    }
1375  if (! rhs_andsi3_operand (operands[2], SImode))
1376    operands[2] = force_reg (SImode, operands[2]);
1377})
1378
1379(define_insn "iorsi3"
1380  [(set (match_operand:SI 0 "register_operand" "=d,d")
1381	(ior:SI (match_operand:SI 1 "register_operand" "%0,d")
1382		(match_operand:SI 2 "regorlog2_operand" "J,d")))]
1383  ""
1384  "@
1385   BITSET (%0, %X2);
1386   %0 = %1 | %2;"
1387  [(set_attr "type" "alu0")])
1388
1389(define_insn "xorsi3"
1390  [(set (match_operand:SI 0 "register_operand" "=d,d")
1391	(xor:SI (match_operand:SI 1 "register_operand" "%0,d")
1392		  (match_operand:SI 2 "regorlog2_operand" "J,d")))]
1393  ""
1394  "@
1395   BITTGL (%0, %X2);
1396   %0 = %1 ^ %2;"
1397  [(set_attr "type" "alu0")])
1398
1399(define_insn "ones"
1400  [(set (match_operand:HI 0 "register_operand" "=d")
1401	(unspec:HI [(match_operand:SI 1 "register_operand" "d")]
1402		UNSPEC_ONES))]
1403  ""
1404  "%h0 = ONES %1;"
1405  [(set_attr "type" "alu0")])
1406
1407(define_insn "smaxsi3"
1408  [(set (match_operand:SI 0 "register_operand" "=d")
1409	(smax:SI (match_operand:SI 1 "register_operand" "d")
1410		 (match_operand:SI 2 "register_operand" "d")))]
1411  ""
1412  "%0 = max(%1,%2)%!"
1413  [(set_attr "type" "dsp32")])
1414
1415(define_insn "sminsi3"
1416  [(set (match_operand:SI 0 "register_operand" "=d")
1417	(smin:SI (match_operand:SI 1 "register_operand" "d")
1418		 (match_operand:SI 2 "register_operand" "d")))]
1419  ""
1420  "%0 = min(%1,%2)%!"
1421  [(set_attr "type" "dsp32")])
1422
1423(define_insn "abssi2"
1424  [(set (match_operand:SI 0 "register_operand" "=d")
1425	(abs:SI (match_operand:SI 1 "register_operand" "d")))]
1426  ""
1427  "%0 = abs %1%!"
1428  [(set_attr "type" "dsp32")])
1429
1430(define_insn "ssabssi2"
1431  [(set (match_operand:SI 0 "register_operand" "=d")
1432	(ss_abs:SI (match_operand:SI 1 "register_operand" "d")))]
1433  ""
1434  "%0 = abs %1%!"
1435  [(set_attr "type" "dsp32")])
1436
1437(define_insn "negsi2"
1438  [(set (match_operand:SI 0 "register_operand" "=d")
1439	(neg:SI (match_operand:SI 1 "register_operand" "d")))]
1440  ""
1441  "%0 = -%1;"
1442  [(set_attr "type" "alu0")])
1443
1444(define_insn "ssnegsi2"
1445  [(set (match_operand:SI 0 "register_operand" "=d")
1446	(ss_neg:SI (match_operand:SI 1 "register_operand" "d")))]
1447  ""
1448  "%0 = -%1 (S)%!"
1449  [(set_attr "type" "dsp32")])
1450
1451(define_insn "one_cmplsi2"
1452  [(set (match_operand:SI 0 "register_operand" "=d")
1453	(not:SI (match_operand:SI 1 "register_operand" "d")))]
1454  ""
1455  "%0 = ~%1;"
1456  [(set_attr "type" "alu0")])
1457
1458(define_expand "clrsbsi2"
1459  [(set (match_dup 2)
1460	(truncate:HI (clrsb:SI (match_operand:SI 1 "register_operand" "d"))))
1461   (set (match_operand:SI 0 "register_operand")
1462	(zero_extend:SI (match_dup 2)))]
1463  ""
1464{
1465  operands[2] = gen_reg_rtx (HImode);
1466})
1467
1468(define_insn "signbitssi2"
1469  [(set (match_operand:HI 0 "register_operand" "=d")
1470	(truncate:HI (clrsb:SI (match_operand:SI 1 "register_operand" "d"))))]
1471  ""
1472  "%h0 = signbits %1%!"
1473  [(set_attr "type" "dsp32")])
1474
1475(define_insn "ssroundsi2"
1476  [(set (match_operand:HI 0 "register_operand" "=d")
1477	(truncate:HI
1478	 (lshiftrt:SI (ss_plus:SI (match_operand:SI 1 "register_operand" "d")
1479				  (const_int 32768))
1480		      (const_int 16))))]
1481  ""
1482  "%h0 = %1 (RND)%!"
1483  [(set_attr "type" "dsp32")])
1484
1485(define_insn "smaxhi3"
1486  [(set (match_operand:HI 0 "register_operand" "=d")
1487	(smax:HI (match_operand:HI 1 "register_operand" "d")
1488		 (match_operand:HI 2 "register_operand" "d")))]
1489  ""
1490  "%0 = max(%1,%2) (V)%!"
1491  [(set_attr "type" "dsp32")])
1492
1493(define_insn "sminhi3"
1494  [(set (match_operand:HI 0 "register_operand" "=d")
1495	(smin:HI (match_operand:HI 1 "register_operand" "d")
1496		 (match_operand:HI 2 "register_operand" "d")))]
1497  ""
1498  "%0 = min(%1,%2) (V)%!"
1499  [(set_attr "type" "dsp32")])
1500
1501(define_insn "abshi2"
1502  [(set (match_operand:HI 0 "register_operand" "=d")
1503	(abs:HI (match_operand:HI 1 "register_operand" "d")))]
1504  ""
1505  "%0 = abs %1 (V)%!"
1506  [(set_attr "type" "dsp32")])
1507
1508(define_insn "neghi2"
1509  [(set (match_operand:HI 0 "register_operand" "=d")
1510	(neg:HI (match_operand:HI 1 "register_operand" "d")))]
1511  ""
1512  "%0 = -%1;"
1513  [(set_attr "type" "alu0")])
1514
1515(define_insn "ssneghi2"
1516  [(set (match_operand:HI 0 "register_operand" "=d")
1517	(ss_neg:HI (match_operand:HI 1 "register_operand" "d")))]
1518  ""
1519  "%0 = -%1 (V)%!"
1520  [(set_attr "type" "dsp32")])
1521
1522(define_insn "clrsbhi2"
1523  [(set (match_operand:HI 0 "register_operand" "=d")
1524	(clrsb:HI (match_operand:HI 1 "register_operand" "d")))]
1525  ""
1526  "%h0 = signbits %h1%!"
1527  [(set_attr "type" "dsp32")])
1528
1529(define_insn "mulsi3"
1530  [(set (match_operand:SI 0 "register_operand" "=d")
1531	(mult:SI (match_operand:SI 1 "register_operand" "%0")
1532		 (match_operand:SI 2 "register_operand" "d")))]
1533  ""
1534  "%0 *= %2;"
1535  [(set_attr "type" "mult")])
1536
1537(define_expand "umulsi3_highpart"
1538  [(parallel
1539    [(set (match_operand:SI 0 "register_operand" "")
1540	  (truncate:SI
1541	   (lshiftrt:DI
1542	    (mult:DI (zero_extend:DI
1543		      (match_operand:SI 1 "nonimmediate_operand" ""))
1544		     (zero_extend:DI
1545		      (match_operand:SI 2 "register_operand" "")))
1546	    (const_int 32))))
1547     (clobber (reg:PDI REG_A0))
1548     (clobber (reg:PDI REG_A1))])]
1549  ""
1550{
1551  if (!optimize_size)
1552    {
1553      rtx a1reg = gen_rtx_REG (PDImode, REG_A1);
1554      rtx a0reg = gen_rtx_REG (PDImode, REG_A0);
1555      emit_insn (gen_flag_macinit1hi (a1reg,
1556				      gen_lowpart (HImode, operands[1]),
1557				      gen_lowpart (HImode, operands[2]),
1558				      GEN_INT (MACFLAG_FU)));
1559      emit_insn (gen_lshrpdi3 (a1reg, a1reg, GEN_INT (16)));
1560      emit_insn (gen_flag_mul_macv2hi_parts_acconly (a0reg, a1reg,
1561						     gen_lowpart (V2HImode, operands[1]),
1562						     gen_lowpart (V2HImode, operands[2]),
1563						     const1_rtx, const1_rtx,
1564						     const1_rtx, const0_rtx, a1reg,
1565						     const0_rtx, GEN_INT (MACFLAG_FU),
1566						     GEN_INT (MACFLAG_FU)));
1567      emit_insn (gen_flag_machi_parts_acconly (a1reg,
1568					       gen_lowpart (V2HImode, operands[2]),
1569					       gen_lowpart (V2HImode, operands[1]),
1570					       const1_rtx, const0_rtx,
1571					       a1reg, const0_rtx, GEN_INT (MACFLAG_FU)));
1572      emit_insn (gen_lshrpdi3 (a1reg, a1reg, GEN_INT (16)));
1573      emit_insn (gen_addpdi3 (a0reg, a0reg, a1reg));
1574      emit_insn (gen_us_truncpdisi2 (operands[0], a0reg));
1575    }
1576  else
1577    {
1578      rtx umulsi3_highpart_libfunc
1579	= init_one_libfunc ("__umulsi3_highpart");
1580
1581      emit_library_call_value (umulsi3_highpart_libfunc,
1582			       operands[0], LCT_NORMAL, SImode,
1583			       operands[1], SImode, operands[2], SImode);
1584    }
1585  DONE;
1586})
1587
1588(define_expand "smulsi3_highpart"
1589  [(parallel
1590    [(set (match_operand:SI 0 "register_operand" "")
1591	  (truncate:SI
1592	   (lshiftrt:DI
1593	    (mult:DI (sign_extend:DI
1594		      (match_operand:SI 1 "nonimmediate_operand" ""))
1595		     (sign_extend:DI
1596		      (match_operand:SI 2 "register_operand" "")))
1597	    (const_int 32))))
1598     (clobber (reg:PDI REG_A0))
1599     (clobber (reg:PDI REG_A1))])]
1600  ""
1601{
1602  if (!optimize_size)
1603    {
1604      rtx a1reg = gen_rtx_REG (PDImode, REG_A1);
1605      rtx a0reg = gen_rtx_REG (PDImode, REG_A0);
1606      emit_insn (gen_flag_macinit1hi (a1reg,
1607				      gen_lowpart (HImode, operands[1]),
1608				      gen_lowpart (HImode, operands[2]),
1609				      GEN_INT (MACFLAG_FU)));
1610      emit_insn (gen_lshrpdi3 (a1reg, a1reg, GEN_INT (16)));
1611      emit_insn (gen_flag_mul_macv2hi_parts_acconly (a0reg, a1reg,
1612						     gen_lowpart (V2HImode, operands[1]),
1613						     gen_lowpart (V2HImode, operands[2]),
1614						     const1_rtx, const1_rtx,
1615						     const1_rtx, const0_rtx, a1reg,
1616						     const0_rtx, GEN_INT (MACFLAG_IS),
1617						     GEN_INT (MACFLAG_IS_M)));
1618      emit_insn (gen_flag_machi_parts_acconly (a1reg,
1619					       gen_lowpart (V2HImode, operands[2]),
1620					       gen_lowpart (V2HImode, operands[1]),
1621					       const1_rtx, const0_rtx,
1622					       a1reg, const0_rtx, GEN_INT (MACFLAG_IS_M)));
1623      emit_insn (gen_ashrpdi3 (a1reg, a1reg, GEN_INT (16)));
1624      emit_insn (gen_sum_of_accumulators (operands[0], a0reg, a0reg, a1reg));
1625    }
1626  else
1627    {
1628      rtx smulsi3_highpart_libfunc
1629	= init_one_libfunc ("__smulsi3_highpart");
1630
1631      emit_library_call_value (smulsi3_highpart_libfunc,
1632			       operands[0], LCT_NORMAL, SImode,
1633			       operands[1], SImode, operands[2], SImode);
1634    }
1635  DONE;
1636})
1637
1638(define_expand "ashlsi3"
1639  [(set (match_operand:SI 0 "register_operand" "")
1640        (ashift:SI (match_operand:SI 1 "register_operand" "")
1641                   (match_operand:SI 2 "nonmemory_operand" "")))]
1642  ""
1643{
1644 if (GET_CODE (operands[2]) == CONST_INT
1645     && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1646   {
1647     emit_insn (gen_movsi (operands[0], const0_rtx));
1648     DONE;
1649   }
1650})
1651
1652(define_insn_and_split "*ashlsi3_insn"
1653  [(set (match_operand:SI 0 "register_operand" "=d,d,a,a,a")
1654	(ashift:SI (match_operand:SI 1 "register_operand" "0,d,a,a,a")
1655		   (match_operand:SI 2 "nonmemory_operand" "dKu5,Ku5,P1,P2,?P3P4")))]
1656  ""
1657  "@
1658   %0 <<= %2;
1659   %0 = %1 << %2%!
1660   %0 = %1 + %1;
1661   %0 = %1 << %2;
1662   #"
1663  "PREG_P (operands[0]) && INTVAL (operands[2]) > 2"
1664  [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
1665   (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
1666  "operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
1667  [(set_attr "type" "shft,dsp32shiftimm,shft,shft,*")])
1668
1669(define_insn "ashrsi3"
1670  [(set (match_operand:SI 0 "register_operand" "=d,d")
1671	(ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
1672		     (match_operand:SI 2 "nonmemory_operand" "dKu5,Ku5")))]
1673  ""
1674  "@
1675   %0 >>>= %2;
1676   %0 = %1 >>> %2%!"
1677  [(set_attr "type" "shft,dsp32shiftimm")])
1678
1679(define_insn "rotl16"
1680  [(set (match_operand:SI 0 "register_operand" "=d")
1681	(rotate:SI (match_operand:SI 1 "register_operand" "d")
1682		   (const_int 16)))]
1683  ""
1684  "%0 = PACK (%h1, %d1)%!"
1685  [(set_attr "type" "dsp32")])
1686
1687(define_expand "rotlsi3"
1688  [(set (match_operand:SI 0 "register_operand" "")
1689	(rotate:SI (match_operand:SI 1 "register_operand" "")
1690		   (match_operand:SI 2 "const_int_operand" "")))]
1691  ""
1692{
1693  if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 16)
1694    FAIL;
1695})
1696
1697(define_expand "rotrsi3"
1698  [(set (match_operand:SI 0 "register_operand" "")
1699	(rotatert:SI (match_operand:SI 1 "register_operand" "")
1700		     (match_operand:SI 2 "const_int_operand" "")))]
1701  ""
1702{
1703  if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 16)
1704    FAIL;
1705  emit_insn (gen_rotl16 (operands[0], operands[1]));
1706  DONE;
1707})
1708
1709
1710(define_insn "ror_one"
1711  [(set (match_operand:SI 0 "register_operand" "=d")
1712	(ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1713		(ashift:SI (zero_extend:SI (reg:BI REG_CC)) (const_int 31))))
1714   (set (reg:BI REG_CC)
1715	(zero_extract:BI (match_dup 1) (const_int 1) (const_int 0)))]
1716  ""
1717  "%0 = ROT %1 BY -1%!"
1718  [(set_attr "type" "dsp32shiftimm")])
1719
1720(define_insn "rol_one"
1721  [(set (match_operand:SI 0 "register_operand" "+d")
1722	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
1723		(zero_extend:SI (reg:BI REG_CC))))
1724   (set (reg:BI REG_CC)
1725	(zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))]
1726  ""
1727  "%0 = ROT %1 BY 1%!"
1728  [(set_attr "type" "dsp32shiftimm")])
1729
1730(define_expand "lshrdi3"
1731  [(set (match_operand:DI 0 "register_operand" "")
1732	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1733		     (match_operand:DI 2 "general_operand" "")))]
1734  ""
1735{
1736  rtx lo_half[2], hi_half[2];
1737
1738  if (operands[2] != const1_rtx)
1739    FAIL;
1740  if (! rtx_equal_p (operands[0], operands[1]))
1741    emit_move_insn (operands[0], operands[1]);
1742
1743  split_di (operands, 2, lo_half, hi_half);
1744
1745  emit_move_insn (bfin_cc_rtx, const0_rtx);
1746  emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1747  emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1748  DONE;
1749})
1750
1751(define_expand "ashrdi3"
1752  [(set (match_operand:DI 0 "register_operand" "")
1753	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1754		     (match_operand:DI 2 "general_operand" "")))]
1755  ""
1756{
1757  rtx lo_half[2], hi_half[2];
1758
1759  if (operands[2] != const1_rtx)
1760    FAIL;
1761  if (! rtx_equal_p (operands[0], operands[1]))
1762    emit_move_insn (operands[0], operands[1]);
1763
1764  split_di (operands, 2, lo_half, hi_half);
1765
1766  emit_insn (gen_compare_lt (gen_rtx_REG (BImode, REG_CC),
1767			     hi_half[1], const0_rtx));
1768  emit_insn (gen_ror_one (hi_half[0], hi_half[0]));
1769  emit_insn (gen_ror_one (lo_half[0], lo_half[0]));
1770  DONE;
1771})
1772
1773(define_expand "ashldi3"
1774  [(set (match_operand:DI 0 "register_operand" "")
1775	(ashift:DI (match_operand:DI 1 "register_operand" "")
1776		   (match_operand:DI 2 "general_operand" "")))]
1777  ""
1778{
1779  rtx lo_half[2], hi_half[2];
1780
1781  if (operands[2] != const1_rtx)
1782    FAIL;
1783  if (! rtx_equal_p (operands[0], operands[1]))
1784    emit_move_insn (operands[0], operands[1]);
1785
1786  split_di (operands, 2, lo_half, hi_half);
1787
1788  emit_move_insn (bfin_cc_rtx, const0_rtx);
1789  emit_insn (gen_rol_one (lo_half[0], lo_half[0]));
1790  emit_insn (gen_rol_one (hi_half[0], hi_half[0]));
1791  DONE;
1792})
1793
1794(define_insn "lshrsi3"
1795  [(set (match_operand:SI 0 "register_operand" "=d,d,a")
1796	(lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d,a")
1797		     (match_operand:SI 2 "nonmemory_operand" "dKu5,Ku5,P1P2")))]
1798  ""
1799  "@
1800   %0 >>= %2;
1801   %0 = %1 >> %2%!
1802   %0 = %1 >> %2;"
1803  [(set_attr "type" "shft,dsp32shiftimm,shft")])
1804
1805(define_insn "lshrpdi3"
1806  [(set (match_operand:PDI 0 "register_operand" "=e")
1807	(lshiftrt:PDI (match_operand:PDI 1 "register_operand" "0")
1808		      (match_operand:SI 2 "nonmemory_operand" "Ku5")))]
1809  ""
1810  "%0 = %1 >> %2%!"
1811  [(set_attr "type" "dsp32shiftimm")])
1812
1813(define_insn "ashrpdi3"
1814  [(set (match_operand:PDI 0 "register_operand" "=e")
1815	(ashiftrt:PDI (match_operand:PDI 1 "register_operand" "0")
1816		      (match_operand:SI 2 "nonmemory_operand" "Ku5")))]
1817  ""
1818  "%0 = %1 >>> %2%!"
1819  [(set_attr "type" "dsp32shiftimm")])
1820
1821;; A pattern to reload the equivalent of
1822;;   (set (Dreg) (plus (FP) (large_constant)))
1823;; or
1824;;   (set (dagreg) (plus (FP) (arbitrary_constant)))
1825;; using a scratch register
1826(define_expand "reload_insi"
1827  [(parallel [(set (match_operand:SI 0 "register_operand" "=w")
1828                   (match_operand:SI 1 "fp_plus_const_operand" ""))
1829              (clobber (match_operand:SI 2 "register_operand" "=&a"))])]
1830  ""
1831{
1832  rtx fp_op = XEXP (operands[1], 0);
1833  rtx const_op = XEXP (operands[1], 1);
1834  rtx primary = operands[0];
1835  rtx scratch = operands[2];
1836
1837  emit_move_insn (scratch, const_op);
1838  emit_insn (gen_addsi3 (scratch, scratch, fp_op));
1839  emit_move_insn (primary, scratch);
1840  DONE;
1841})
1842
1843(define_mode_iterator AREG [PDI V2PDI])
1844
1845(define_insn "reload_in<mode>"
1846  [(set (match_operand:AREG 0 "register_operand" "=e")
1847	(match_operand:AREG 1 "memory_operand" "m"))
1848   (clobber (match_operand:SI 2 "register_operand" "=d"))]
1849  ""
1850{
1851  rtx xops[4];
1852  xops[0] = operands[0];
1853  xops[1] = operands[2];
1854  split_di (operands + 1, 1, xops + 2, xops + 3);
1855  output_asm_insn ("%1 = %2;", xops);
1856  output_asm_insn ("%w0 = %1;", xops);
1857  output_asm_insn ("%1 = %3;", xops);
1858  output_asm_insn ("%x0 = %1;", xops);
1859  return "";
1860}
1861 [(set_attr "seq_insns" "multi")
1862  (set_attr "type" "mcld")
1863  (set_attr "length" "12")])
1864
1865(define_insn "reload_out<mode>"
1866  [(set (match_operand:AREG 0 "memory_operand" "=m")
1867	(match_operand:AREG 1 "register_operand" "e"))
1868   (clobber (match_operand:SI 2 "register_operand" "=d"))]
1869  ""
1870{
1871  rtx xops[4];
1872  xops[0] = operands[1];
1873  xops[1] = operands[2];
1874  split_di (operands, 1, xops + 2, xops + 3);
1875  output_asm_insn ("%1 = %w0;", xops);
1876  output_asm_insn ("%2 = %1;", xops);
1877  output_asm_insn ("%1 = %x0;", xops);
1878  output_asm_insn ("%3 = %1;", xops);
1879  return "";
1880}
1881 [(set_attr "seq_insns" "multi")
1882  (set_attr "type" "mcld")
1883  (set_attr "length" "12")])
1884
1885;; Jump instructions
1886
1887(define_insn "jump"
1888  [(set (pc)
1889	(label_ref (match_operand 0 "" "")))]
1890  ""
1891{
1892  if (get_attr_length (insn) == 2)
1893    return "jump.s %0;";
1894  else
1895    return "jump.l %0;";
1896}
1897  [(set_attr "type" "br")])
1898
1899(define_insn "indirect_jump"
1900  [(set (pc)
1901	(match_operand:SI 0 "register_operand" "a"))]
1902  ""
1903  "jump (%0);"
1904  [(set_attr "type" "misc")])
1905
1906(define_expand "tablejump"
1907  [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1908              (use (label_ref (match_operand 1 "" "")))])]
1909  ""
1910{
1911  /* In PIC mode, the table entries are stored PC relative.
1912     Convert the relative address to an absolute address.  */
1913  if (flag_pic)
1914    {
1915      rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1916
1917      operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1918					 op1, NULL_RTX, 0, OPTAB_DIRECT);
1919    }
1920})
1921
1922(define_insn "*tablejump_internal"
1923  [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1924   (use (label_ref (match_operand 1 "" "")))]
1925  ""
1926  "jump (%0);"
1927  [(set_attr "type" "misc")])
1928
1929;;  Hardware loop
1930
1931; operand 0 is the loop count pseudo register
1932; operand 1 is the label to jump to at the top of the loop
1933(define_expand "doloop_end"
1934  [(parallel [(set (pc) (if_then_else
1935			  (ne (match_operand:SI 0 "" "")
1936			      (const_int 1))
1937			  (label_ref (match_operand 1 "" ""))
1938			  (pc)))
1939	      (set (match_dup 0)
1940		   (plus:SI (match_dup 0)
1941			    (const_int -1)))
1942	      (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1943	      (clobber (match_dup 2))])] ; match_scratch
1944  ""
1945{
1946  /* The loop optimizer doesn't check the predicates... */
1947  if (GET_MODE (operands[0]) != SImode)
1948    FAIL;
1949  bfin_hardware_loop ();
1950  operands[2] = gen_rtx_SCRATCH (SImode);
1951})
1952
1953(define_insn "loop_end"
1954  [(set (pc)
1955	(if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,0,0")
1956			  (const_int 1))
1957		      (label_ref (match_operand 1 "" ""))
1958		      (pc)))
1959   (set (match_operand:SI 0 "nonimmediate_operand" "=a*d,*b*v*f,m")
1960	(plus (match_dup 2)
1961	      (const_int -1)))
1962   (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1963   (clobber (match_scratch:SI 3 "=X,&r,&r"))]
1964  ""
1965  "@
1966   /* loop end %0 %l1 */
1967   #
1968   #"
1969  [(set_attr "length" "6,10,14")])
1970
1971(define_split
1972  [(set (pc)
1973	(if_then_else (ne (match_operand:SI 0 "nondp_reg_or_memory_operand")
1974			  (const_int 1))
1975		      (label_ref (match_operand 1 ""))
1976		      (pc)))
1977   (set (match_dup 0)
1978	(plus (match_dup 0)
1979	      (const_int -1)))
1980   (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1981   (clobber (match_scratch:SI 2))]
1982  "memory_operand (operands[0], SImode) || splitting_loops"
1983  [(set (match_dup 2) (match_dup 0))
1984   (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
1985   (set (match_dup 0) (match_dup 2))
1986   (set (reg:BI REG_CC) (eq:BI (match_dup 2) (const_int 0)))
1987   (set (pc)
1988	(if_then_else (eq (reg:BI REG_CC)
1989			  (const_int 0))
1990		      (label_ref (match_dup 1))
1991		      (pc)))]
1992  "")
1993
1994(define_insn "lsetup_with_autoinit"
1995  [(set (match_operand:SI 0 "lt_register_operand" "=t")
1996	(label_ref (match_operand 1 "" "")))
1997   (set (match_operand:SI 2 "lb_register_operand" "=u")
1998	(label_ref (match_operand 3 "" "")))
1999   (set (match_operand:SI 4 "lc_register_operand" "=k")
2000	(match_operand:SI 5 "register_operand" "a"))]
2001  ""
2002  "LSETUP (%1, %3) %4 = %5;"
2003  [(set_attr "length" "4")])
2004
2005(define_insn "lsetup_without_autoinit"
2006  [(set (match_operand:SI 0 "lt_register_operand" "=t")
2007	(label_ref (match_operand 1 "" "")))
2008   (set (match_operand:SI 2 "lb_register_operand" "=u")
2009	(label_ref (match_operand 3 "" "")))
2010   (use (match_operand:SI 4 "lc_register_operand" "k"))]
2011  ""
2012  "LSETUP (%1, %3) %4;"
2013  [(set_attr "length" "4")])
2014
2015;;  Call instructions..
2016
2017;; The explicit MEM inside the UNSPEC prevents the compiler from moving
2018;; the load before a branch after a NULL test, or before a store that
2019;; initializes a function descriptor.
2020
2021(define_insn_and_split "load_funcdescsi"
2022  [(set (match_operand:SI 0 "register_operand" "=a")
2023	(unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
2024			    UNSPEC_VOLATILE_LOAD_FUNCDESC))]
2025  ""
2026  "#"
2027  "reload_completed"
2028  [(set (match_dup 0) (mem:SI (match_dup 1)))])
2029
2030(define_expand "call"
2031  [(parallel [(call (match_operand:SI 0 "" "")
2032		    (match_operand 1 "" ""))
2033	      (use (match_operand 2 "" ""))])]
2034  ""
2035{
2036  bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 0);
2037  DONE;
2038})
2039
2040(define_expand "sibcall"
2041  [(parallel [(call (match_operand:SI 0 "" "")
2042		    (match_operand 1 "" ""))
2043	      (use (match_operand 2 "" ""))
2044	      (return)])]
2045  ""
2046{
2047  bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 1);
2048  DONE;
2049})
2050
2051(define_expand "call_value"
2052  [(parallel [(set (match_operand 0 "register_operand" "")
2053		   (call (match_operand:SI 1 "" "")
2054			 (match_operand 2 "" "")))
2055	      (use (match_operand 3 "" ""))])]
2056  ""
2057{
2058  bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 0);
2059  DONE;
2060})
2061
2062(define_expand "sibcall_value"
2063  [(parallel [(set (match_operand 0 "register_operand" "")
2064		   (call (match_operand:SI 1 "" "")
2065			 (match_operand 2 "" "")))
2066	      (use (match_operand 3 "" ""))
2067	      (return)])]
2068  ""
2069{
2070  bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 1);
2071  DONE;
2072})
2073
2074(define_insn "*call_symbol_fdpic"
2075  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
2076	 (match_operand 1 "general_operand" "g"))
2077   (use (match_operand:SI 2 "register_operand" "Z"))
2078   (use (match_operand 3 "" ""))
2079   (clobber (reg:SI REG_RETS))]
2080  "! SIBLING_CALL_P (insn)
2081   && GET_CODE (operands[0]) == SYMBOL_REF
2082   && !bfin_longcall_p (operands[0], INTVAL (operands[3]))"
2083  "call %0;"
2084  [(set_attr "type" "call")
2085   (set_attr "length" "4")])
2086
2087(define_insn "*sibcall_symbol_fdpic"
2088  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
2089	 (match_operand 1 "general_operand" "g"))
2090   (use (match_operand:SI 2 "register_operand" "Z"))
2091   (use (match_operand 3 "" ""))
2092   (return)]
2093  "SIBLING_CALL_P (insn)
2094   && GET_CODE (operands[0]) == SYMBOL_REF
2095   && !bfin_longcall_p (operands[0], INTVAL (operands[3]))"
2096  "jump.l %0;"
2097  [(set_attr "type" "br")
2098   (set_attr "length" "4")])
2099
2100(define_insn "*call_value_symbol_fdpic"
2101  [(set (match_operand 0 "register_operand" "=d")
2102        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
2103	      (match_operand 2 "general_operand" "g")))
2104   (use (match_operand:SI 3 "register_operand" "Z"))
2105   (use (match_operand 4 "" ""))
2106   (clobber (reg:SI REG_RETS))]
2107  "! SIBLING_CALL_P (insn)
2108   && GET_CODE (operands[1]) == SYMBOL_REF
2109   && !bfin_longcall_p (operands[1], INTVAL (operands[4]))"
2110  "call %1;"
2111  [(set_attr "type" "call")
2112   (set_attr "length" "4")])
2113
2114(define_insn "*sibcall_value_symbol_fdpic"
2115  [(set (match_operand 0 "register_operand" "=d")
2116         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
2117	       (match_operand 2 "general_operand" "g")))
2118   (use (match_operand:SI 3 "register_operand" "Z"))
2119   (use (match_operand 4 "" ""))
2120   (return)]
2121  "SIBLING_CALL_P (insn)
2122   && GET_CODE (operands[1]) == SYMBOL_REF
2123   && !bfin_longcall_p (operands[1], INTVAL (operands[4]))"
2124  "jump.l %1;"
2125  [(set_attr "type" "br")
2126   (set_attr "length" "4")])
2127
2128(define_insn "*call_insn_fdpic"
2129  [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y"))
2130	 (match_operand 1 "general_operand" "g"))
2131   (use (match_operand:SI 2 "register_operand" "Z"))
2132   (use (match_operand 3 "" ""))
2133   (clobber (reg:SI REG_RETS))]
2134  "! SIBLING_CALL_P (insn)"
2135  "call (%0);"
2136  [(set_attr "type" "call")
2137   (set_attr "length" "2")])
2138
2139(define_insn "*sibcall_insn_fdpic"
2140  [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y"))
2141	 (match_operand 1 "general_operand" "g"))
2142   (use (match_operand:SI 2 "register_operand" "Z"))
2143   (use (match_operand 3 "" ""))
2144   (return)]
2145  "SIBLING_CALL_P (insn)"
2146  "jump (%0);"
2147  [(set_attr "type" "br")
2148   (set_attr "length" "2")])
2149
2150(define_insn "*call_value_insn_fdpic"
2151  [(set (match_operand 0 "register_operand" "=d")
2152        (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y"))
2153	      (match_operand 2 "general_operand" "g")))
2154   (use (match_operand:SI 3 "register_operand" "Z"))
2155   (use (match_operand 4 "" ""))
2156   (clobber (reg:SI REG_RETS))]
2157  "! SIBLING_CALL_P (insn)"
2158  "call (%1);"
2159  [(set_attr "type" "call")
2160   (set_attr "length" "2")])
2161
2162(define_insn "*sibcall_value_insn_fdpic"
2163  [(set (match_operand 0 "register_operand" "=d")
2164         (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y"))
2165	       (match_operand 2 "general_operand" "g")))
2166   (use (match_operand:SI 3 "register_operand" "Z"))
2167   (use (match_operand 4 "" ""))
2168   (return)]
2169  "SIBLING_CALL_P (insn)"
2170  "jump (%1);"
2171  [(set_attr "type" "br")
2172   (set_attr "length" "2")])
2173
2174(define_insn "*call_symbol"
2175  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
2176	 (match_operand 1 "general_operand" "g"))
2177   (use (match_operand 2 "" ""))
2178   (clobber (reg:SI REG_RETS))]
2179  "! SIBLING_CALL_P (insn)
2180   && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
2181   && GET_CODE (operands[0]) == SYMBOL_REF
2182   && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
2183  "call %0;"
2184  [(set_attr "type" "call")
2185   (set_attr "length" "4")])
2186
2187(define_insn "*sibcall_symbol"
2188  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
2189	 (match_operand 1 "general_operand" "g"))
2190   (use (match_operand 2 "" ""))
2191   (return)]
2192  "SIBLING_CALL_P (insn)
2193   && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
2194   && GET_CODE (operands[0]) == SYMBOL_REF
2195   && !bfin_longcall_p (operands[0], INTVAL (operands[2]))"
2196  "jump.l %0;"
2197  [(set_attr "type" "br")
2198   (set_attr "length" "4")])
2199
2200(define_insn "*call_value_symbol"
2201  [(set (match_operand 0 "register_operand" "=d")
2202        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
2203	      (match_operand 2 "general_operand" "g")))
2204   (use (match_operand 3 "" ""))
2205   (clobber (reg:SI REG_RETS))]
2206  "! SIBLING_CALL_P (insn)
2207   && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
2208   && GET_CODE (operands[1]) == SYMBOL_REF
2209   && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
2210  "call %1;"
2211  [(set_attr "type" "call")
2212   (set_attr "length" "4")])
2213
2214(define_insn "*sibcall_value_symbol"
2215  [(set (match_operand 0 "register_operand" "=d")
2216         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
2217	       (match_operand 2 "general_operand" "g")))
2218   (use (match_operand 3 "" ""))
2219   (return)]
2220  "SIBLING_CALL_P (insn)
2221   && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
2222   && GET_CODE (operands[1]) == SYMBOL_REF
2223   && !bfin_longcall_p (operands[1], INTVAL (operands[3]))"
2224  "jump.l %1;"
2225  [(set_attr "type" "br")
2226   (set_attr "length" "4")])
2227
2228(define_insn "*call_insn"
2229  [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a"))
2230	 (match_operand 1 "general_operand" "g"))
2231   (use (match_operand 2 "" ""))
2232   (clobber (reg:SI REG_RETS))]
2233  "! SIBLING_CALL_P (insn)"
2234  "call (%0);"
2235  [(set_attr "type" "call")
2236   (set_attr "length" "2")])
2237
2238(define_insn "*sibcall_insn"
2239  [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "z"))
2240	 (match_operand 1 "general_operand" "g"))
2241   (use (match_operand 2 "" ""))
2242   (return)]
2243  "SIBLING_CALL_P (insn)"
2244  "jump (%0);"
2245  [(set_attr "type" "br")
2246   (set_attr "length" "2")])
2247
2248(define_insn "*call_value_insn"
2249  [(set (match_operand 0 "register_operand" "=d")
2250        (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a"))
2251	      (match_operand 2 "general_operand" "g")))
2252   (use (match_operand 3 "" ""))
2253   (clobber (reg:SI REG_RETS))]
2254  "! SIBLING_CALL_P (insn)"
2255  "call (%1);"
2256  [(set_attr "type" "call")
2257   (set_attr "length" "2")])
2258
2259(define_insn "*sibcall_value_insn"
2260  [(set (match_operand 0 "register_operand" "=d")
2261         (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "z"))
2262	       (match_operand 2 "general_operand" "g")))
2263   (use (match_operand 3 "" ""))
2264   (return)]
2265  "SIBLING_CALL_P (insn)"
2266  "jump (%1);"
2267  [(set_attr "type" "br")
2268   (set_attr "length" "2")])
2269
2270;; Block move patterns
2271
2272;; We cheat.  This copies one more word than operand 2 indicates.
2273
2274(define_insn "rep_movsi"
2275  [(set (match_operand:SI 0 "register_operand" "=&a")
2276        (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
2277			  (ashift:SI (match_operand:SI 2 "register_operand" "a")
2278				     (const_int 2)))
2279		 (const_int 4)))
2280   (set (match_operand:SI 1 "register_operand" "=&b")
2281        (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
2282			  (ashift:SI (match_dup 2) (const_int 2)))
2283		 (const_int 4)))
2284   (set (mem:BLK (match_dup 3))
2285	(mem:BLK (match_dup 4)))
2286   (use (match_dup 2))
2287   (clobber (match_scratch:HI 5 "=&d"))
2288   (clobber (reg:SI REG_LT1))
2289   (clobber (reg:SI REG_LC1))
2290   (clobber (reg:SI REG_LB1))]
2291  ""
2292  "%5 = [%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || [%3++] = %5 || %5 = [%4++]; [%3++] = %5;"
2293  [(set_attr "type" "misc")
2294   (set_attr "length" "16")
2295   (set_attr "seq_insns" "multi")])
2296
2297(define_insn "rep_movhi"
2298  [(set (match_operand:SI 0 "register_operand" "=&a")
2299        (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0")
2300			  (ashift:SI (match_operand:SI 2 "register_operand" "a")
2301				     (const_int 1)))
2302		 (const_int 2)))
2303   (set (match_operand:SI 1 "register_operand" "=&b")
2304        (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1")
2305			  (ashift:SI (match_dup 2) (const_int 1)))
2306		 (const_int 2)))
2307   (set (mem:BLK (match_dup 3))
2308	(mem:BLK (match_dup 4)))
2309   (use (match_dup 2))
2310   (clobber (match_scratch:HI 5 "=&d"))
2311   (clobber (reg:SI REG_LT1))
2312   (clobber (reg:SI REG_LC1))
2313   (clobber (reg:SI REG_LB1))]
2314  ""
2315  "%h5 = W[%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || W [%3++] = %5 || %h5 = W [%4++]; W [%3++] = %5;"
2316  [(set_attr "type" "misc")
2317   (set_attr "length" "16")
2318   (set_attr "seq_insns" "multi")])
2319
2320(define_expand "cpymemsi"
2321  [(match_operand:BLK 0 "general_operand" "")
2322   (match_operand:BLK 1 "general_operand" "")
2323   (match_operand:SI 2 "const_int_operand" "")
2324   (match_operand:SI 3 "const_int_operand" "")]
2325  ""
2326{
2327  if (bfin_expand_cpymem (operands[0], operands[1], operands[2], operands[3]))
2328    DONE;
2329  FAIL;
2330})
2331
2332;; Conditional branch patterns
2333;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
2334
2335(define_insn "compare_eq"
2336  [(set (match_operand:BI 0 "register_operand" "=C,C")
2337        (eq:BI (match_operand:SI 1 "register_operand" "d,a")
2338               (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
2339  ""
2340  "cc =%1==%2;"
2341  [(set_attr "type" "compare")])
2342
2343(define_insn "compare_ne"
2344  [(set (match_operand:BI 0 "register_operand" "=C,C")
2345        (ne:BI (match_operand:SI 1 "register_operand" "d,a")
2346               (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
2347  "0"
2348  "cc =%1!=%2;"
2349  [(set_attr "type" "compare")])
2350
2351(define_insn "compare_lt"
2352  [(set (match_operand:BI 0 "register_operand" "=C,C")
2353        (lt:BI (match_operand:SI 1 "register_operand" "d,a")
2354               (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
2355  ""
2356  "cc =%1<%2;"
2357  [(set_attr "type" "compare")])
2358
2359(define_insn "compare_le"
2360  [(set (match_operand:BI 0 "register_operand" "=C,C")
2361        (le:BI (match_operand:SI 1 "register_operand" "d,a")
2362               (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))]
2363  ""
2364  "cc =%1<=%2;"
2365  [(set_attr "type" "compare")])
2366
2367(define_insn "compare_leu"
2368  [(set (match_operand:BI 0 "register_operand" "=C,C")
2369        (leu:BI (match_operand:SI 1 "register_operand" "d,a")
2370                (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
2371  ""
2372  "cc =%1<=%2 (iu);"
2373  [(set_attr "type" "compare")])
2374
2375(define_insn "compare_ltu"
2376  [(set (match_operand:BI 0 "register_operand" "=C,C")
2377        (ltu:BI (match_operand:SI 1 "register_operand" "d,a")
2378                (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))]
2379  ""
2380  "cc =%1<%2 (iu);"
2381  [(set_attr "type" "compare")])
2382
2383;; Same as above, but and CC with the overflow bit generated by the first
2384;; multiplication.
2385(define_insn "flag_mul_macv2hi_parts_acconly_andcc0"
2386  [(set (match_operand:PDI 0 "register_operand" "=B,e,e")
2387	(unspec:PDI [(vec_select:HI
2388		      (match_operand:V2HI 2 "register_operand" "d,d,d")
2389		      (parallel [(match_operand 4 "const01_operand" "P0P1,P0P1,P0P1")]))
2390		     (vec_select:HI
2391		      (match_operand:V2HI 3 "register_operand" "d,d,d")
2392		      (parallel [(match_operand 6 "const01_operand" "P0P1,P0P1,P0P1")]))
2393		     (match_operand 10 "const_int_operand" "PB,PA,PA")]
2394		    UNSPEC_MUL_WITH_FLAG))
2395   (set (match_operand:PDI 1 "register_operand" "=B,e,e")
2396	(unspec:PDI [(vec_select:HI
2397		      (match_dup 2)
2398		      (parallel [(match_operand 5 "const01_operand" "P0P1,P0P1,P0P1")]))
2399		     (vec_select:HI
2400		      (match_dup 3)
2401		      (parallel [(match_operand 7 "const01_operand" "P0P1,P0P1,P0P1")]))
2402		     (match_operand:PDI 8 "register_operand" "1,1,1")
2403		     (match_operand 9 "const01_operand" "P0P1,P0P1,P0P1")
2404		     (match_operand 11 "const_int_operand" "PA,PB,PA")]
2405		    UNSPEC_MAC_WITH_FLAG))
2406   (set (reg:BI REG_CC)
2407	(and:BI (reg:BI REG_CC)
2408		(unspec:BI [(vec_select:HI (match_dup 2) (parallel [(match_dup 4)]))
2409			    (vec_select:HI (match_dup 3) (parallel [(match_dup 6)]))
2410			    (match_dup 10)]
2411			   UNSPEC_MUL_WITH_FLAG)))]
2412  "MACFLAGS_MATCH_P (INTVAL (operands[10]), INTVAL (operands[11]))"
2413{
2414  rtx xops[6];
2415  const char *templates[] = {
2416    "%0 = %h2 * %h3, %1 %b4 %h2 * %h3 %M5;\n\tCC &= %v0;",
2417    "%0 = %d2 * %h3, %1 %b4 %h2 * %h3 %M5;\n\tCC &= %v0;",
2418    "%0 = %h2 * %h3, %1 %b4 %d2 * %h3 %M5;\n\tCC &= %v0;",
2419    "%0 = %d2 * %h3, %1 %b4 %d2 * %h3 %M5;\n\tCC &= %v0;",
2420    "%0 = %h2 * %d3, %1 %b4 %h2 * %h3 %M5;\n\tCC &= %v0;",
2421    "%0 = %d2 * %d3, %1 %b4 %h2 * %h3 %M5;\n\tCC &= %v0;",
2422    "%0 = %h2 * %d3, %1 %b4 %d2 * %h3 %M5;\n\tCC &= %v0;",
2423    "%0 = %d2 * %d3, %1 %b4 %d2 * %h3 %M5;\n\tCC &= %v0;",
2424    "%0 = %h2 * %h3, %1 %b4 %h2 * %d3 %M5;\n\tCC &= %v0;",
2425    "%0 = %d2 * %h3, %1 %b4 %h2 * %d3 %M5;\n\tCC &= %v0;",
2426    "%0 = %h2 * %h3, %1 %b4 %d2 * %d3 %M5;\n\tCC &= %v0;",
2427    "%0 = %d2 * %h3, %1 %b4 %d2 * %d3 %M5;\n\tCC &= %v0;",
2428    "%0 = %h2 * %d3, %1 %b4 %h2 * %d3 %M5;\n\tCC &= %v0;",
2429    "%0 = %d2 * %d3, %1 %b4 %h2 * %d3 %M5;\n\tCC &= %v0;",
2430    "%0 = %h2 * %d3, %1 %b4 %d2 * %d3 %M5;\n\tCC &= %v0;",
2431    "%0 = %d2 * %d3, %1 %b4 %d2 * %d3 %M5;\n\tCC &= %v0;" };
2432  int alt = (INTVAL (operands[4]) + (INTVAL (operands[5]) << 1)
2433	     + (INTVAL (operands[6]) << 2)  + (INTVAL (operands[7]) << 3));
2434  xops[0] = operands[0];
2435  xops[1] = operands[1];
2436  xops[2] = operands[2];
2437  xops[3] = operands[3];
2438  xops[4] = operands[9];
2439  xops[5] = which_alternative == 0 ? operands[10] : operands[11];
2440  output_asm_insn (templates[alt], xops);
2441  return "";
2442}
2443  [(set_attr "type" "misc")
2444   (set_attr "length" "6")
2445   (set_attr "seq_insns" "multi")])
2446
2447(define_expand "cbranchsi4"
2448  [(set (pc)
2449        (if_then_else (match_operator 0 "ordered_comparison_operator"
2450                       [(match_operand:SI 1 "register_operand" "")
2451                        (match_operand:SI 2 "reg_or_const_int_operand" "")])
2452                   (label_ref (match_operand 3 "" ""))
2453                   (pc)))]
2454  ""
2455{
2456  rtx bi_compare = bfin_gen_compare (operands[0], SImode);
2457  emit_jump_insn (gen_cbranchbi4 (bi_compare, bfin_cc_rtx, CONST0_RTX (BImode),
2458				  operands[3]));
2459  DONE;
2460})
2461
2462(define_insn "cbranchbi4"
2463  [(set (pc)
2464	(if_then_else
2465	 (match_operator 0 "bfin_bimode_comparison_operator"
2466			 [(match_operand:BI 1 "register_operand" "C")
2467			  (match_operand:BI 2 "immediate_operand" "P0")])
2468	 (label_ref (match_operand 3 "" ""))
2469	 (pc)))]
2470  ""
2471{
2472  asm_conditional_branch (insn, operands, 0, 0);
2473  return "";
2474}
2475  [(set_attr "type" "brcc")])
2476
2477;; Special cbranch patterns to deal with the speculative load problem - see
2478;; bfin_reorg for details.
2479
2480(define_insn "cbranch_predicted_taken"
2481  [(set (pc)
2482	(if_then_else
2483	 (match_operator 0 "bfin_bimode_comparison_operator"
2484			 [(match_operand:BI 1 "register_operand" "C")
2485			  (match_operand:BI 2 "immediate_operand" "P0")])
2486	 (label_ref (match_operand 3 "" ""))
2487	 (pc)))
2488   (unspec [(const_int 0)] UNSPEC_CBRANCH_TAKEN)]
2489  ""
2490{
2491  asm_conditional_branch (insn, operands, 0, 1);
2492  return "";
2493}
2494  [(set_attr "type" "brcc")])
2495
2496(define_insn "cbranch_with_nops"
2497  [(set (pc)
2498	(if_then_else
2499	 (match_operator 0 "bfin_bimode_comparison_operator"
2500			 [(match_operand:BI 1 "register_operand" "C")
2501			  (match_operand:BI 2 "immediate_operand" "P0")])
2502	 (label_ref (match_operand 3 "" ""))
2503	 (pc)))
2504   (unspec [(match_operand 4 "immediate_operand" "")] UNSPEC_CBRANCH_NOPS)]
2505  "reload_completed"
2506{
2507  asm_conditional_branch (insn, operands, INTVAL (operands[4]), 0);
2508  return "";
2509}
2510  [(set_attr "type" "brcc")
2511   (set_attr "length" "8")])
2512
2513;; setcc insns.
2514
2515(define_expand "cstorebi4"
2516  [(set (match_dup 4)
2517        (match_operator:BI 1 "bfin_bimode_comparison_operator"
2518                       [(match_operand:BI 2 "register_operand" "")
2519                        (match_operand:BI 3 "reg_or_const_int_operand" "")]))
2520   (set (match_operand:SI 0 "register_operand" "")
2521       (ne:SI (match_dup 4) (const_int 0)))]
2522  ""
2523{
2524  /* It could be expanded as a movbisi instruction, but the portable
2525     alternative produces better code.  */
2526  if (GET_CODE (operands[1]) == NE)
2527    FAIL;
2528
2529  operands[4] = bfin_cc_rtx;
2530})
2531
2532(define_expand "cstoresi4"
2533  [(set (match_operand:SI 0 "register_operand")
2534        (match_operator:SI 1 "ordered_comparison_operator"
2535                       [(match_operand:SI 2 "register_operand" "")
2536                        (match_operand:SI 3 "reg_or_const_int_operand" "")]))]
2537  ""
2538{
2539  rtx bi_compare, test;
2540
2541  if (!bfin_direct_comparison_operator (operands[1], SImode))
2542    {
2543      if (!register_operand (operands[3], SImode)
2544	  || GET_CODE (operands[1]) == NE)
2545	FAIL;
2546      test = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
2547			     SImode, operands[3], operands[2]);
2548    }
2549  else
2550    test = operands[1];
2551
2552  bi_compare = bfin_gen_compare (test, SImode);
2553  gcc_assert (GET_CODE (bi_compare) == NE);
2554  emit_insn (gen_movbisi (operands[0], bfin_cc_rtx));
2555  DONE;
2556})
2557
2558(define_insn "nop"
2559  [(const_int 0)]
2560  ""
2561  "nop;")
2562
2563;; A nop which stays there when emitted.
2564(define_insn "forced_nop"
2565  [(unspec [(const_int 0)] UNSPEC_NOP)]
2566  ""
2567  "nop;")
2568
2569(define_insn "mnop"
2570  [(unspec [(const_int 0)] UNSPEC_32BIT)]
2571  ""
2572  "mnop%!"
2573  [(set_attr "type" "dsp32")])
2574
2575;;;;;;;;;;;;;;;;;;;;   CC2dreg   ;;;;;;;;;;;;;;;;;;;;;;;;;
2576(define_insn "movsibi"
2577  [(set (match_operand:BI 0 "register_operand" "=C")
2578	(ne:BI (match_operand:SI 1 "register_operand" "d")
2579	       (const_int 0)))]
2580  ""
2581  "CC = %1;"
2582  [(set_attr "length" "2")])
2583
2584(define_insn_and_split "movbisi"
2585  [(set (match_operand:SI 0 "register_operand" "=d")
2586	(ne:SI (match_operand:BI 1 "register_operand" "C")
2587	       (const_int 0)))]
2588  ""
2589  "#"
2590  ""
2591  [(set (match_operand:SI 0 "register_operand" "")
2592	(zero_extend:SI (match_operand:BI 1 "register_operand" "")))]
2593  "")
2594
2595(define_insn "notbi"
2596  [(set (match_operand:BI 0 "register_operand" "=C")
2597	(eq:BI (match_operand:BI 1 "register_operand" " 0")
2598	       (const_int 0)))]
2599  ""
2600  "%0 = ! %0;"    /*  NOT CC;"  */
2601  [(set_attr "type" "compare")])
2602
2603;; Vector and DSP insns
2604
2605(define_insn ""
2606  [(set (match_operand:SI 0 "register_operand" "=d")
2607	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2608			   (const_int 24))
2609		(lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2610			     (const_int 8))))]
2611  ""
2612  "%0 = ALIGN8(%1, %2)%!"
2613  [(set_attr "type" "dsp32")])
2614
2615(define_insn ""
2616  [(set (match_operand:SI 0 "register_operand" "=d")
2617	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2618			   (const_int 16))
2619		(lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2620			     (const_int 16))))]
2621  ""
2622  "%0 = ALIGN16(%1, %2)%!"
2623  [(set_attr "type" "dsp32")])
2624
2625(define_insn ""
2626  [(set (match_operand:SI 0 "register_operand" "=d")
2627	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
2628			   (const_int 8))
2629		(lshiftrt:SI (match_operand:SI 2 "register_operand" "d")
2630			     (const_int 24))))]
2631  ""
2632  "%0 = ALIGN24(%1, %2)%!"
2633  [(set_attr "type" "dsp32")])
2634
2635;; Prologue and epilogue.
2636
2637(define_expand "prologue"
2638  [(const_int 1)]
2639  ""
2640  "bfin_expand_prologue (); DONE;")
2641
2642(define_expand "epilogue"
2643  [(const_int 1)]
2644  ""
2645  "bfin_expand_epilogue (1, 0, 0); DONE;")
2646
2647(define_expand "sibcall_epilogue"
2648  [(const_int 1)]
2649  ""
2650  "bfin_expand_epilogue (0, 0, 1); DONE;")
2651
2652(define_expand "eh_return"
2653  [(use (match_operand:SI 0 "register_operand" ""))]
2654  ""
2655{
2656  emit_insn (gen_eh_store_handler (EH_RETURN_HANDLER_RTX, operands[0]));
2657  emit_jump_insn (gen_eh_return_internal ());
2658  emit_barrier ();
2659  DONE;
2660})
2661
2662(define_insn "eh_store_handler"
2663  [(unspec_volatile [(match_operand:SI 1 "register_operand" "da")]
2664		    UNSPEC_VOLATILE_STORE_EH_HANDLER)
2665   (clobber (match_operand:SI 0 "memory_operand" "=m"))]
2666  ""
2667  "%0 = %1%!"
2668  [(set_attr "type" "mcst")])
2669
2670(define_insn_and_split "eh_return_internal"
2671  [(eh_return)]
2672  ""
2673  "#"
2674  "epilogue_completed"
2675  [(const_int 1)]
2676  "bfin_expand_epilogue (1, 1, 0); DONE;")
2677
2678(define_insn "link"
2679  [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS))
2680   (set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:SI REG_FP))
2681   (set (reg:SI REG_FP)
2682	(plus:SI (reg:SI REG_SP) (const_int -8)))
2683   (set (reg:SI REG_SP)
2684	(plus:SI (reg:SI REG_SP) (match_operand:SI 0 "immediate_operand" "i")))]
2685  ""
2686  "LINK %Z0;"
2687  [(set_attr "length" "4")])
2688
2689(define_insn "unlink"
2690  [(set (reg:SI REG_FP) (mem:SI (reg:SI REG_FP)))
2691   (set (reg:SI REG_RETS) (mem:SI (plus:SI (reg:SI REG_FP) (const_int 4))))
2692   (set (reg:SI REG_SP) (plus:SI (reg:SI REG_FP) (const_int 8)))]
2693  ""
2694  "UNLINK;"
2695  [(set_attr "length" "4")])
2696
2697;; This pattern is slightly clumsy.  The stack adjust must be the final SET in
2698;; the pattern, otherwise dwarf2out becomes very confused about which reg goes
2699;; where on the stack, since it goes through all elements of the parallel in
2700;; sequence.
2701(define_insn "push_multiple"
2702  [(match_parallel 0 "push_multiple_operation"
2703    [(unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_PUSH_MULTIPLE)])]
2704  ""
2705{
2706  output_push_multiple (insn, operands);
2707  return "";
2708})
2709
2710(define_insn "pop_multiple"
2711  [(match_parallel 0 "pop_multiple_operation"
2712    [(set (reg:SI REG_SP)
2713	  (plus:SI (reg:SI REG_SP) (match_operand:SI 1 "immediate_operand" "i")))])]
2714  ""
2715{
2716  output_pop_multiple (insn, operands);
2717  return "";
2718})
2719
2720(define_insn "return_internal"
2721  [(return)
2722   (use (match_operand 0 "register_operand" ""))]
2723  "reload_completed"
2724{
2725  switch (REGNO (operands[0]))
2726    {
2727    case REG_RETX:
2728      return "rtx;";
2729    case REG_RETN:
2730      return "rtn;";
2731    case REG_RETI:
2732      return "rti;";
2733    case REG_RETS:
2734      return "rts;";
2735    }
2736  gcc_unreachable ();
2737})
2738
2739;; When used at a location where CC contains 1, causes a speculative load
2740;; that is later cancelled.  This is used for certain workarounds in
2741;; interrupt handler prologues.
2742(define_insn "dummy_load"
2743  [(unspec_volatile [(match_operand 0 "register_operand" "a")
2744		     (match_operand 1 "register_operand" "C")]
2745		    UNSPEC_VOLATILE_DUMMY)]
2746  ""
2747  "if cc jump 4;\n\tr7 = [%0];"
2748 [(set_attr "type" "misc")
2749  (set_attr "length" "4")
2750  (set_attr "seq_insns" "multi")])
2751
2752;; A placeholder insn inserted before the final scheduling pass.  It is used
2753;; to improve scheduling of loads when workarounds for speculative loads are
2754;; needed, by not placing them in the first few cycles after a conditional
2755;; branch.
2756(define_insn "stall"
2757  [(unspec_volatile [(match_operand 0 "const_int_operand" "P1P3")]
2758		    UNSPEC_VOLATILE_STALL)]
2759  ""
2760  ""
2761  [(set_attr "type" "stall")])
2762
2763(define_insn "csync"
2764  [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
2765  ""
2766  "csync;"
2767  [(set_attr "type" "sync")])
2768
2769(define_insn "ssync"
2770  [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_SSYNC)]
2771  ""
2772  "ssync;"
2773  [(set_attr "type" "sync")])
2774
2775(define_insn "trap"
2776  [(trap_if (const_int 1) (const_int 3))]
2777  ""
2778  "excpt 3;"
2779  [(set_attr "type" "misc")
2780   (set_attr "length" "2")])
2781
2782(define_insn "trapifcc"
2783  [(trap_if (reg:BI REG_CC) (const_int 3))]
2784  ""
2785  "if !cc jump 4 (bp); excpt 3;"
2786  [(set_attr "type" "misc")
2787   (set_attr "length" "4")
2788   (set_attr "seq_insns" "multi")])
2789
2790;;; Vector instructions
2791
2792;; First, all sorts of move variants
2793
2794(define_insn "movhiv2hi_low"
2795  [(set (match_operand:V2HI 0 "register_operand" "=d")
2796	(vec_concat:V2HI
2797	 (match_operand:HI 2 "register_operand" "d")
2798	 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2799			(parallel [(const_int 1)]))))]
2800  ""
2801  "%h0 = %h2 << 0%!"
2802  [(set_attr "type" "dsp32shiftimm")])
2803
2804(define_insn "movhiv2hi_high"
2805  [(set (match_operand:V2HI 0 "register_operand" "=d")
2806	(vec_concat:V2HI
2807	 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2808			(parallel [(const_int 0)]))
2809	 (match_operand:HI 2 "register_operand" "d")))]
2810  ""
2811  "%d0 = %h2 << 0%!"
2812  [(set_attr "type" "dsp32shiftimm")])
2813
2814;; No earlyclobber on alternative two since our sequence ought to be safe.
2815;; The order of operands is intentional to match the VDSP builtin (high word
2816;; is passed first).
2817(define_insn_and_split "composev2hi"
2818  [(set (match_operand:V2HI 0 "register_operand" "=d,d")
2819	(vec_concat:V2HI (match_operand:HI 2 "register_operand" "0,d")
2820			 (match_operand:HI 1 "register_operand" "d,d")))]
2821  ""
2822  "@
2823   %d0 = %h1 << 0%!
2824   #"
2825  "reload_completed"
2826  [(set (match_dup 0)
2827	(vec_concat:V2HI
2828	 (vec_select:HI (match_dup 0) (parallel [(const_int 0)]))
2829	 (match_dup 1)))
2830   (set (match_dup 0)
2831	(vec_concat:V2HI
2832	 (match_dup 2)
2833	 (vec_select:HI (match_dup 0) (parallel [(const_int 1)]))))]
2834  ""
2835  [(set_attr "type" "dsp32shiftimm")])
2836
2837; Like composev2hi, but operating on elements of V2HI vectors.
2838; Useful on its own, and as a combiner bridge for the multiply and
2839; mac patterns.
2840(define_insn "packv2hi"
2841  [(set (match_operand:V2HI 0 "register_operand" "=d,d,d,d,d,d,d,d")
2842	(vec_concat:V2HI (vec_select:HI
2843			  (match_operand:V2HI 1 "register_operand" "0,0,d,d,d,d,d,d")
2844			  (parallel [(match_operand 3 "const01_operand" "P0,P0,P0,P1,P0,P1,P0,P1")]))
2845			 (vec_select:HI
2846			  (match_operand:V2HI 2 "register_operand" "d,d,0,0,d,d,d,d")
2847			  (parallel [(match_operand 4 "const01_operand" "P0,P1,P1,P1,P0,P0,P1,P1")]))))]
2848  ""
2849  "@
2850   %d0 = %h2 << 0%!
2851   %d0 = %d2 << 0%!
2852   %h0 = %h1 << 0%!
2853   %h0 = %d1 << 0%!
2854   %0 = PACK (%h2,%h1)%!
2855   %0 = PACK (%h2,%d1)%!
2856   %0 = PACK (%d2,%h1)%!
2857   %0 = PACK (%d2,%d1)%!"
2858  [(set_attr "type" "dsp32shiftimm,dsp32shiftimm,dsp32shiftimm,dsp32shiftimm,dsp32,dsp32,dsp32,dsp32")])
2859
2860(define_insn "movv2hi_hi"
2861  [(set (match_operand:HI 0 "register_operand" "=d,d,d")
2862	(vec_select:HI (match_operand:V2HI 1 "register_operand" "0,d,d")
2863		       (parallel [(match_operand 2 "const01_operand" "P0,P0,P1")])))]
2864  ""
2865  "@
2866   /* optimized out */
2867   %h0 = %h1 << 0%!
2868   %h0 = %d1 << 0%!"
2869  [(set_attr "type" "dsp32shiftimm")])
2870
2871(define_expand "movv2hi_hi_low"
2872  [(set (match_operand:HI 0 "register_operand" "")
2873	(vec_select:HI (match_operand:V2HI 1 "register_operand" "")
2874		       (parallel [(const_int 0)])))]
2875  ""
2876  "")
2877
2878(define_expand "movv2hi_hi_high"
2879  [(set (match_operand:HI 0 "register_operand" "")
2880	(vec_select:HI (match_operand:V2HI 1 "register_operand" "")
2881		       (parallel [(const_int 1)])))]
2882  ""
2883  "")
2884
2885;; Unusual arithmetic operations on 16-bit registers.
2886
2887(define_code_iterator sp_or_sm [ss_plus ss_minus])
2888(define_code_attr spm_string [(ss_plus "+") (ss_minus "-")])
2889(define_code_attr spm_name [(ss_plus "add") (ss_minus "sub")])
2890
2891(define_insn "ss<spm_name>hi3"
2892  [(set (match_operand:HI 0 "register_operand" "=d")
2893	(sp_or_sm:HI (match_operand:HI 1 "register_operand" "d")
2894		    (match_operand:HI 2 "register_operand" "d")))]
2895  ""
2896  "%h0 = %h1 <spm_string>  %h2 (S)%!"
2897  [(set_attr "type" "dsp32")])
2898
2899(define_insn "ss<spm_name>hi3_parts"
2900  [(set (match_operand:HI 0 "register_operand" "=d")
2901	(sp_or_sm:HI (vec_select:HI
2902		      (match_operand:V2HI 1 "register_operand" "d")
2903		      (parallel [(match_operand 3 "const01_operand" "P0P1")]))
2904		     (vec_select:HI
2905		      (match_operand:V2HI 2 "register_operand" "d")
2906		      (parallel [(match_operand 4 "const01_operand" "P0P1")]))))]
2907   ""
2908{
2909  const char *templates[] = {
2910    "%h0 = %h1 <spm_string> %h2 (S)%!",
2911    "%h0 = %d1 <spm_string> %h2 (S)%!",
2912    "%h0 = %h1 <spm_string> %d2 (S)%!",
2913    "%h0 = %d1 <spm_string> %d2 (S)%!" };
2914  int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
2915  return templates[alt];
2916}
2917  [(set_attr "type" "dsp32")])
2918
2919(define_insn "ss<spm_name>hi3_low_parts"
2920  [(set (match_operand:V2HI 0 "register_operand" "=d")
2921	(vec_concat:V2HI
2922	 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2923			(parallel [(const_int 0)]))
2924	 (sp_or_sm:HI (vec_select:HI
2925		       (match_operand:V2HI 2 "register_operand" "d")
2926		       (parallel [(match_operand 4 "const01_operand" "P0P1")]))
2927		      (vec_select:HI
2928		       (match_operand:V2HI 3 "register_operand" "d")
2929		       (parallel [(match_operand 5 "const01_operand" "P0P1")])))))]
2930   ""
2931{
2932  const char *templates[] = {
2933    "%h0 = %h2 <spm_string> %h3 (S)%!",
2934    "%h0 = %d2 <spm_string> %h3 (S)%!",
2935    "%h0 = %h2 <spm_string> %d3 (S)%!",
2936    "%h0 = %d2 <spm_string> %d3 (S)%!" };
2937  int alt = INTVAL (operands[4]) + (INTVAL (operands[5]) << 1);
2938  return templates[alt];
2939}
2940  [(set_attr "type" "dsp32")])
2941
2942(define_insn "ss<spm_name>hi3_high_parts"
2943  [(set (match_operand:V2HI 0 "register_operand" "=d")
2944	(vec_concat:V2HI
2945	 (sp_or_sm:HI (vec_select:HI
2946		       (match_operand:V2HI 2 "register_operand" "d")
2947		       (parallel [(match_operand 4 "const01_operand" "P0P1")]))
2948		      (vec_select:HI
2949		       (match_operand:V2HI 3 "register_operand" "d")
2950		       (parallel [(match_operand 5 "const01_operand" "P0P1")])))
2951	 (vec_select:HI (match_operand:V2HI 1 "register_operand" "0")
2952			(parallel [(const_int 1)]))))]
2953   ""
2954{
2955  const char *templates[] = {
2956    "%d0 = %h2 <spm_string> %h3 (S)%!",
2957    "%d0 = %d2 <spm_string> %h3 (S)%!",
2958    "%d0 = %h2 <spm_string> %d3 (S)%!",
2959    "%d0 = %d2 <spm_string> %d3 (S)%!" };
2960  int alt = INTVAL (operands[4]) + (INTVAL (operands[5]) << 1);
2961  return templates[alt];
2962}
2963  [(set_attr "type" "dsp32")])
2964
2965;; V2HI vector insns
2966
2967(define_insn "addv2hi3"
2968  [(set (match_operand:V2HI 0 "register_operand" "=d")
2969	(plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2970		   (match_operand:V2HI 2 "register_operand" "d")))]
2971  ""
2972  "%0 = %1 +|+ %2%!"
2973  [(set_attr "type" "dsp32")])
2974
2975(define_insn "ssaddv2hi3"
2976  [(set (match_operand:V2HI 0 "register_operand" "=d")
2977	(ss_plus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2978		      (match_operand:V2HI 2 "register_operand" "d")))]
2979  ""
2980  "%0 = %1 +|+ %2 (S)%!"
2981  [(set_attr "type" "dsp32")])
2982
2983(define_insn "subv2hi3"
2984  [(set (match_operand:V2HI 0 "register_operand" "=d")
2985	(minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2986		   (match_operand:V2HI 2 "register_operand" "d")))]
2987  ""
2988  "%0 = %1 -|- %2%!"
2989  [(set_attr "type" "dsp32")])
2990
2991(define_insn "sssubv2hi3"
2992  [(set (match_operand:V2HI 0 "register_operand" "=d")
2993	(ss_minus:V2HI (match_operand:V2HI 1 "register_operand" "d")
2994		       (match_operand:V2HI 2 "register_operand" "d")))]
2995  ""
2996  "%0 = %1 -|- %2 (S)%!"
2997  [(set_attr "type" "dsp32")])
2998
2999(define_insn "addsubv2hi3"
3000  [(set (match_operand:V2HI 0 "register_operand" "=d")
3001	(vec_concat:V2HI
3002	 (plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3003				 (parallel [(const_int 0)]))
3004		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3005				 (parallel [(const_int 0)])))
3006	 (minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
3007		   (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3008  ""
3009  "%0 = %1 +|- %2%!"
3010  [(set_attr "type" "dsp32")])
3011
3012(define_insn "subaddv2hi3"
3013  [(set (match_operand:V2HI 0 "register_operand" "=d")
3014	(vec_concat:V2HI
3015	 (minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3016				  (parallel [(const_int 0)]))
3017		   (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3018				  (parallel [(const_int 0)])))
3019	 (plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
3020		  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3021  ""
3022  "%0 = %1 -|+ %2%!"
3023  [(set_attr "type" "dsp32")])
3024
3025(define_insn "ssaddsubv2hi3"
3026  [(set (match_operand:V2HI 0 "register_operand" "=d")
3027	(vec_concat:V2HI
3028	 (ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3029				    (parallel [(const_int 0)]))
3030		     (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3031				    (parallel [(const_int 0)])))
3032	 (ss_minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
3033		      (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3034  ""
3035  "%0 = %1 +|- %2 (S)%!"
3036  [(set_attr "type" "dsp32")])
3037
3038(define_insn "sssubaddv2hi3"
3039  [(set (match_operand:V2HI 0 "register_operand" "=d")
3040	(vec_concat:V2HI
3041	 (ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3042				     (parallel [(const_int 0)]))
3043		      (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3044				     (parallel [(const_int 0)])))
3045	 (ss_plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))
3046		     (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3047  ""
3048  "%0 = %1 -|+ %2 (S)%!"
3049  [(set_attr "type" "dsp32")])
3050
3051(define_insn "sublohiv2hi3"
3052  [(set (match_operand:HI 0 "register_operand" "=d")
3053	(minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3054				 (parallel [(const_int 1)]))
3055		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3056				 (parallel [(const_int 0)]))))]
3057  ""
3058  "%h0 = %d1 - %h2%!"
3059  [(set_attr "type" "dsp32")])
3060
3061(define_insn "subhilov2hi3"
3062  [(set (match_operand:HI 0 "register_operand" "=d")
3063	(minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3064				 (parallel [(const_int 0)]))
3065		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3066				 (parallel [(const_int 1)]))))]
3067  ""
3068  "%h0 = %h1 - %d2%!"
3069  [(set_attr "type" "dsp32")])
3070
3071(define_insn "sssublohiv2hi3"
3072  [(set (match_operand:HI 0 "register_operand" "=d")
3073	(ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3074				    (parallel [(const_int 1)]))
3075		     (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3076				    (parallel [(const_int 0)]))))]
3077  ""
3078  "%h0 = %d1 - %h2 (S)%!"
3079  [(set_attr "type" "dsp32")])
3080
3081(define_insn "sssubhilov2hi3"
3082  [(set (match_operand:HI 0 "register_operand" "=d")
3083	(ss_minus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3084				    (parallel [(const_int 0)]))
3085		     (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3086				    (parallel [(const_int 1)]))))]
3087  ""
3088  "%h0 = %h1 - %d2 (S)%!"
3089  [(set_attr "type" "dsp32")])
3090
3091(define_insn "addlohiv2hi3"
3092  [(set (match_operand:HI 0 "register_operand" "=d")
3093	(plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3094				(parallel [(const_int 1)]))
3095		 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3096				(parallel [(const_int 0)]))))]
3097  ""
3098  "%h0 = %d1 + %h2%!"
3099  [(set_attr "type" "dsp32")])
3100
3101(define_insn "addhilov2hi3"
3102  [(set (match_operand:HI 0 "register_operand" "=d")
3103	(plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3104				(parallel [(const_int 0)]))
3105		 (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3106				(parallel [(const_int 1)]))))]
3107  ""
3108  "%h0 = %h1 + %d2%!"
3109  [(set_attr "type" "dsp32")])
3110
3111(define_insn "ssaddlohiv2hi3"
3112  [(set (match_operand:HI 0 "register_operand" "=d")
3113	(ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3114				   (parallel [(const_int 1)]))
3115		    (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3116				   (parallel [(const_int 0)]))))]
3117  ""
3118  "%h0 = %d1 + %h2 (S)%!"
3119  [(set_attr "type" "dsp32")])
3120
3121(define_insn "ssaddhilov2hi3"
3122  [(set (match_operand:HI 0 "register_operand" "=d")
3123	(ss_plus:HI (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3124				   (parallel [(const_int 0)]))
3125		    (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3126				   (parallel [(const_int 1)]))))]
3127  ""
3128  "%h0 = %h1 + %d2 (S)%!"
3129  [(set_attr "type" "dsp32")])
3130
3131(define_insn "sminv2hi3"
3132  [(set (match_operand:V2HI 0 "register_operand" "=d")
3133	(smin:V2HI (match_operand:V2HI 1 "register_operand" "d")
3134		   (match_operand:V2HI 2 "register_operand" "d")))]
3135  ""
3136  "%0 = MIN (%1, %2) (V)%!"
3137  [(set_attr "type" "dsp32")])
3138
3139(define_insn "smaxv2hi3"
3140  [(set (match_operand:V2HI 0 "register_operand" "=d")
3141	(smax:V2HI (match_operand:V2HI 1 "register_operand" "d")
3142		   (match_operand:V2HI 2 "register_operand" "d")))]
3143  ""
3144  "%0 = MAX (%1, %2) (V)%!"
3145  [(set_attr "type" "dsp32")])
3146
3147;; Multiplications.
3148
3149;; The Blackfin allows a lot of different options, and we need many patterns to
3150;; cover most of the hardware's abilities.
3151;; There are a few simple patterns using MULT rtx codes, but most of them use
3152;; an unspec with a const_int operand that determines which flag to use in the
3153;; instruction.
3154;; There are variants for single and parallel multiplications.
3155;; There are variants which just use 16-bit lowparts as inputs, and variants
3156;; which allow the user to choose just which halves to use as input values.
3157;; There are variants which set D registers, variants which set accumulators,
3158;; variants which set both, some of them optionally using the accumulators as
3159;; inputs for multiply-accumulate operations.
3160
3161(define_insn "flag_mulhi"
3162  [(set (match_operand:HI 0 "register_operand" "=d")
3163	(unspec:HI [(match_operand:HI 1 "register_operand" "d")
3164		    (match_operand:HI 2 "register_operand" "d")
3165		    (match_operand 3 "const_int_operand" "n")]
3166		   UNSPEC_MUL_WITH_FLAG))]
3167  ""
3168  "%h0 = %h1 * %h2 %M3%!"
3169  [(set_attr "type" "dsp32")])
3170
3171(define_insn "flag_mulhi_parts"
3172  [(set (match_operand:HI 0 "register_operand" "=d")
3173	(unspec:HI [(vec_select:HI
3174		     (match_operand:V2HI 1 "register_operand" "d")
3175		     (parallel [(match_operand 3 "const01_operand" "P0P1")]))
3176		    (vec_select:HI
3177		     (match_operand:V2HI 2 "register_operand" "d")
3178		     (parallel [(match_operand 4 "const01_operand" "P0P1")]))
3179		    (match_operand 5 "const_int_operand" "n")]
3180		   UNSPEC_MUL_WITH_FLAG))]
3181  ""
3182{
3183  const char *templates[] = {
3184    "%h0 = %h1 * %h2 %M5%!",
3185    "%h0 = %d1 * %h2 %M5%!",
3186    "%h0 = %h1 * %d2 %M5%!",
3187    "%h0 = %d1 * %d2 %M5%!" };
3188  int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
3189  return templates[alt];
3190}
3191  [(set_attr "type" "dsp32")])
3192
3193(define_insn "flag_mulhisi"
3194  [(set (match_operand:SI 0 "register_operand" "=d")
3195	(unspec:SI [(match_operand:HI 1 "register_operand" "d")
3196		    (match_operand:HI 2 "register_operand" "d")
3197		    (match_operand 3 "const_int_operand" "n")]
3198		   UNSPEC_MUL_WITH_FLAG))]
3199  ""
3200  "%0 = %h1 * %h2 %M3%!"
3201  [(set_attr "type" "dsp32")])
3202
3203(define_insn "flag_mulhisi_parts"
3204  [(set (match_operand:SI 0 "register_operand" "=d")
3205	(unspec:SI [(vec_select:HI
3206		     (match_operand:V2HI 1 "register_operand" "d")
3207		     (parallel [(match_operand 3 "const01_operand" "P0P1")]))
3208		    (vec_select:HI
3209		     (match_operand:V2HI 2 "register_operand" "d")
3210		     (parallel [(match_operand 4 "const01_operand" "P0P1")]))
3211		    (match_operand 5 "const_int_operand" "n")]
3212		   UNSPEC_MUL_WITH_FLAG))]
3213  ""
3214{
3215  const char *templates[] = {
3216    "%0 = %h1 * %h2 %M5%!",
3217    "%0 = %d1 * %h2 %M5%!",
3218    "%0 = %h1 * %d2 %M5%!",
3219    "%0 = %d1 * %d2 %M5%!" };
3220  int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
3221  return templates[alt];
3222}
3223  [(set_attr "type" "dsp32")])
3224
3225;; Three alternatives here to cover all possible allocations:
3226;; 0. mac flag is usable only for accumulator 1 - use A1 and odd DREG
3227;; 1. mac flag is usable for accumulator 0 - use A0 and even DREG
3228;; 2. mac flag is usable in any accumulator - use A1 and odd DREG
3229;; Other patterns which don't have a DREG destination can collapse cases
3230;; 1 and 2 into one.
3231(define_insn "flag_machi"
3232  [(set (match_operand:HI 0 "register_operand" "=W,D,W")
3233	(unspec:HI [(match_operand:HI 2 "register_operand" "d,d,d")
3234		    (match_operand:HI 3 "register_operand" "d,d,d")
3235		    (match_operand 4 "register_operand" "1,1,1")
3236		    (match_operand 5 "const01_operand" "P0P1,P0P1,P0P1")
3237		    (match_operand 6 "const_int_operand" "PB,PA,PA")]
3238		   UNSPEC_MAC_WITH_FLAG))
3239   (set (match_operand:PDI 1 "register_operand" "=B,A,B")
3240	(unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)
3241		     (match_dup 4) (match_dup 5)]
3242		    UNSPEC_MAC_WITH_FLAG))]
3243  ""
3244  "%h0 = (%1 %b5 %h2 * %h3) %M6%!"
3245  [(set_attr "type" "dsp32")])
3246
3247(define_insn "flag_machi_acconly"
3248  [(set (match_operand:PDI 0 "register_operand" "=B,e")
3249	(unspec:PDI [(match_operand:HI 1 "register_operand" "d,d")
3250		     (match_operand:HI 2 "register_operand" "d,d")
3251		     (match_operand 3 "register_operand" "0,0")
3252		     (match_operand 4 "const01_operand" "P0P1,P0P1")
3253		     (match_operand 5 "const_int_operand" "PB,PA")]
3254		    UNSPEC_MAC_WITH_FLAG))]
3255  ""
3256  "%0 %b4 %h1 * %h2 %M5%!"
3257  [(set_attr "type" "dsp32")])
3258
3259(define_insn "flag_machi_parts_acconly"
3260  [(set (match_operand:PDI 0 "register_operand" "=B,e")
3261	(unspec:PDI [(vec_select:HI
3262		      (match_operand:V2HI 1 "register_operand" "d,d")
3263		      (parallel [(match_operand 3 "const01_operand" "P0P1,P0P1")]))
3264		     (vec_select:HI
3265		      (match_operand:V2HI 2 "register_operand" "d,d")
3266		      (parallel [(match_operand 4 "const01_operand" "P0P1,P0P1")]))
3267		     (match_operand:PDI 5 "register_operand" "0,0")
3268		     (match_operand 6 "const01_operand" "P0P1,P0P1")
3269		     (match_operand 7 "const_int_operand" "PB,PA")]
3270		    UNSPEC_MAC_WITH_FLAG))]
3271  ""
3272{
3273  const char *templates[] = {
3274    "%0 %b6 %h1 * %h2 %M7%!",
3275    "%0 %b6 %d1 * %h2 %M7%!",
3276    "%0 %b6 %h1 * %d2 %M7%!",
3277    "%0 %b6 %d1 * %d2 %M7%!"
3278  };
3279  int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
3280  return templates[alt];
3281}
3282  [(set_attr "type" "dsp32")])
3283
3284(define_insn "flag_macinithi"
3285  [(set (match_operand:HI 0 "register_operand" "=W,D,W")
3286	(unspec:HI [(match_operand:HI 1 "register_operand" "d,d,d")
3287		    (match_operand:HI 2 "register_operand" "d,d,d")
3288		    (match_operand 3 "const_int_operand" "PB,PA,PA")]
3289		   UNSPEC_MAC_WITH_FLAG))
3290   (set (match_operand:PDI 4 "register_operand" "=B,A,B")
3291	(unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)]
3292		    UNSPEC_MAC_WITH_FLAG))]
3293  ""
3294  "%h0 = (%4 = %h1 * %h2) %M3%!"
3295  [(set_attr "type" "dsp32")])
3296
3297(define_insn "flag_macinit1hi"
3298  [(set (match_operand:PDI 0 "register_operand" "=B,e")
3299	(unspec:PDI [(match_operand:HI 1 "register_operand" "d,d")
3300		     (match_operand:HI 2 "register_operand" "d,d")
3301		     (match_operand 3 "const_int_operand" "PB,PA")]
3302		    UNSPEC_MAC_WITH_FLAG))]
3303  ""
3304  "%0 = %h1 * %h2 %M3%!"
3305  [(set_attr "type" "dsp32")])
3306
3307(define_insn "mulv2hi3"
3308  [(set (match_operand:V2HI 0 "register_operand" "=d")
3309	(mult:V2HI (match_operand:V2HI 1 "register_operand" "d")
3310		   (match_operand:V2HI 2 "register_operand" "d")))]
3311  ""
3312  "%h0 = %h1 * %h2, %d0 = %d1 * %d2 (IS)%!"
3313  [(set_attr "type" "dsp32")])
3314
3315(define_insn "flag_mulv2hi"
3316  [(set (match_operand:V2HI 0 "register_operand" "=d")
3317	(unspec:V2HI [(match_operand:V2HI 1 "register_operand" "d")
3318		      (match_operand:V2HI 2 "register_operand" "d")
3319		      (match_operand 3 "const_int_operand" "n")]
3320		     UNSPEC_MUL_WITH_FLAG))]
3321  ""
3322  "%h0 = %h1 * %h2, %d0 = %d1 * %d2 %M3%!"
3323  [(set_attr "type" "dsp32")])
3324
3325(define_insn "flag_mulv2hi_parts"
3326  [(set (match_operand:V2HI 0 "register_operand" "=d")
3327	(unspec:V2HI [(vec_concat:V2HI
3328		       (vec_select:HI
3329			(match_operand:V2HI 1 "register_operand" "d")
3330			(parallel [(match_operand 3 "const01_operand" "P0P1")]))
3331		       (vec_select:HI
3332			(match_dup 1)
3333			(parallel [(match_operand 4 "const01_operand" "P0P1")])))
3334		      (vec_concat:V2HI
3335		       (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3336			(parallel [(match_operand 5 "const01_operand" "P0P1")]))
3337		       (vec_select:HI (match_dup 2)
3338			(parallel [(match_operand 6 "const01_operand" "P0P1")])))
3339		      (match_operand 7 "const_int_operand" "n")]
3340		     UNSPEC_MUL_WITH_FLAG))]
3341  ""
3342{
3343  const char *templates[] = {
3344    "%h0 = %h1 * %h2, %d0 = %h1 * %h2 %M7%!",
3345    "%h0 = %d1 * %h2, %d0 = %h1 * %h2 %M7%!",
3346    "%h0 = %h1 * %h2, %d0 = %d1 * %h2 %M7%!",
3347    "%h0 = %d1 * %h2, %d0 = %d1 * %h2 %M7%!",
3348    "%h0 = %h1 * %d2, %d0 = %h1 * %h2 %M7%!",
3349    "%h0 = %d1 * %d2, %d0 = %h1 * %h2 %M7%!",
3350    "%h0 = %h1 * %d2, %d0 = %d1 * %h2 %M7%!",
3351    "%h0 = %d1 * %d2, %d0 = %d1 * %h2 %M7%!",
3352    "%h0 = %h1 * %h2, %d0 = %h1 * %d2 %M7%!",
3353    "%h0 = %d1 * %h2, %d0 = %h1 * %d2 %M7%!",
3354    "%h0 = %h1 * %h2, %d0 = %d1 * %d2 %M7%!",
3355    "%h0 = %d1 * %h2, %d0 = %d1 * %d2 %M7%!",
3356    "%h0 = %h1 * %d2, %d0 = %h1 * %d2 %M7%!",
3357    "%h0 = %d1 * %d2, %d0 = %h1 * %d2 %M7%!",
3358    "%h0 = %h1 * %d2, %d0 = %d1 * %d2 %M7%!",
3359    "%h0 = %d1 * %d2, %d0 = %d1 * %d2 %M7%!" };
3360  int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3361	     + (INTVAL (operands[5]) << 2)  + (INTVAL (operands[6]) << 3));
3362  return templates[alt];
3363}
3364  [(set_attr "type" "dsp32")])
3365
3366;; A slightly complicated pattern.
3367;; Operand 0 is the halfword output; operand 11 is the accumulator output
3368;; Halfword inputs are operands 1 and 2; operands 3, 4, 5 and 6 specify which
3369;; parts of these 2x16 bit registers to use.
3370;; Operand 7 is the accumulator input.
3371;; Operands 8/9 specify whether low/high parts are mac (0) or msu (1)
3372;; Operand 10 is the macflag to be used.
3373(define_insn "flag_macv2hi_parts"
3374  [(set (match_operand:V2HI 0 "register_operand" "=d")
3375	(unspec:V2HI [(vec_concat:V2HI
3376		       (vec_select:HI
3377			(match_operand:V2HI 1 "register_operand" "d")
3378			(parallel [(match_operand 3 "const01_operand" "P0P1")]))
3379		       (vec_select:HI
3380			(match_dup 1)
3381			(parallel [(match_operand 4 "const01_operand" "P0P1")])))
3382		      (vec_concat:V2HI
3383		       (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3384			(parallel [(match_operand 5 "const01_operand" "P0P1")]))
3385		       (vec_select:HI (match_dup 2)
3386			(parallel [(match_operand 6 "const01_operand" "P0P1")])))
3387		      (match_operand:V2PDI 7 "register_operand" "e")
3388		      (match_operand 8 "const01_operand" "P0P1")
3389		      (match_operand 9 "const01_operand" "P0P1")
3390		      (match_operand 10 "const_int_operand" "n")]
3391		     UNSPEC_MAC_WITH_FLAG))
3392   (set (match_operand:V2PDI 11 "register_operand" "=e")
3393	(unspec:V2PDI [(vec_concat:V2HI
3394			(vec_select:HI (match_dup 1) (parallel [(match_dup 3)]))
3395			(vec_select:HI (match_dup 1) (parallel [(match_dup 4)])))
3396		       (vec_concat:V2HI
3397			(vec_select:HI (match_dup 2) (parallel [(match_dup 5)]))
3398			(vec_select:HI (match_dup 2) (parallel [(match_dup 5)])))
3399		       (match_dup 7) (match_dup 8) (match_dup 9) (match_dup 10)]
3400		      UNSPEC_MAC_WITH_FLAG))]
3401  ""
3402{
3403  const char *templates[] = {
3404    "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3405    "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3406    "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3407    "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3408    "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3409    "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %h1 * %h2) %M10%!",
3410    "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3411    "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %d1 * %h2) %M10%!",
3412    "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3413    "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3414    "%h0 = (A0 %b8 %h1 * %h2), %d0 = (A1 %b9 %d1 * %d2) %M10%!",
3415    "%h0 = (A0 %b8 %d1 * %h2), %d0 = (A1 %b9 %d1 * %d2) %M10%!",
3416    "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3417    "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %h1 * %d2) %M10%!",
3418    "%h0 = (A0 %b8 %h1 * %d2), %d0 = (A1 %b9 %d1 * %d2) %M10%!",
3419    "%h0 = (A0 %b8 %d1 * %d2), %d0 = (A1 %b9 %d1 * %d2) %M10%!" };
3420  int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3421	     + (INTVAL (operands[5]) << 2)  + (INTVAL (operands[6]) << 3));
3422  return templates[alt];
3423}
3424  [(set_attr "type" "dsp32")])
3425
3426(define_insn "flag_macv2hi_parts_acconly"
3427  [(set (match_operand:V2PDI 0 "register_operand" "=e")
3428	(unspec:V2PDI [(vec_concat:V2HI
3429			(vec_select:HI
3430			 (match_operand:V2HI 1 "register_operand" "d")
3431			 (parallel [(match_operand 3 "const01_operand" "P0P1")]))
3432			(vec_select:HI
3433			 (match_dup 1)
3434			 (parallel [(match_operand 4 "const01_operand" "P0P1")])))
3435		       (vec_concat:V2HI
3436			(vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3437				       (parallel [(match_operand 5 "const01_operand" "P0P1")]))
3438			(vec_select:HI (match_dup 2)
3439				       (parallel [(match_operand 6 "const01_operand" "P0P1")])))
3440		       (match_operand:V2PDI 7 "register_operand" "e")
3441		       (match_operand 8 "const01_operand" "P0P1")
3442		       (match_operand 9 "const01_operand" "P0P1")
3443		       (match_operand 10 "const_int_operand" "n")]
3444		      UNSPEC_MAC_WITH_FLAG))]
3445  ""
3446{
3447  const char *templates[] = {
3448    "A0 %b8 %h1 * %h2, A1 %b9 %h1 * %h2 %M10%!",
3449    "A0 %b8 %d1 * %h2, A1 %b9 %h1 * %h2 %M10%!",
3450    "A0 %b8 %h1 * %h2, A1 %b9 %d1 * %h2 %M10%!",
3451    "A0 %b8 %d1 * %h2, A1 %b9 %d1 * %h2 %M10%!",
3452    "A0 %b8 %h1 * %d2, A1 %b9 %h1 * %h2 %M10%!",
3453    "A0 %b8 %d1 * %d2, A1 %b9 %h1 * %h2 %M10%!",
3454    "A0 %b8 %h1 * %d2, A1 %b9 %d1 * %h2 %M10%!",
3455    "A0 %b8 %d1 * %d2, A1 %b9 %d1 * %h2 %M10%!",
3456    "A0 %b8 %h1 * %h2, A1 %b9 %h1 * %d2 %M10%!",
3457    "A0 %b8 %d1 * %h2, A1 %b9 %h1 * %d2 %M10%!",
3458    "A0 %b8 %h1 * %h2, A1 %b9 %d1 * %d2 %M10%!",
3459    "A0 %b8 %d1 * %h2, A1 %b9 %d1 * %d2 %M10%!",
3460    "A0 %b8 %h1 * %d2, A1 %b9 %h1 * %d2 %M10%!",
3461    "A0 %b8 %d1 * %d2, A1 %b9 %h1 * %d2 %M10%!",
3462    "A0 %b8 %h1 * %d2, A1 %b9 %d1 * %d2 %M10%!",
3463    "A0 %b8 %d1 * %d2, A1 %b9 %d1 * %d2 %M10%!" };
3464  int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3465	     + (INTVAL (operands[5]) << 2)  + (INTVAL (operands[6]) << 3));
3466  return templates[alt];
3467}
3468  [(set_attr "type" "dsp32")])
3469
3470;; Same as above, but initializing the accumulators and therefore a couple fewer
3471;; necessary operands.
3472(define_insn "flag_macinitv2hi_parts"
3473  [(set (match_operand:V2HI 0 "register_operand" "=d")
3474	(unspec:V2HI [(vec_concat:V2HI
3475		       (vec_select:HI
3476			(match_operand:V2HI 1 "register_operand" "d")
3477			(parallel [(match_operand 3 "const01_operand" "P0P1")]))
3478		       (vec_select:HI
3479			(match_dup 1)
3480			(parallel [(match_operand 4 "const01_operand" "P0P1")])))
3481		      (vec_concat:V2HI
3482		       (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3483			(parallel [(match_operand 5 "const01_operand" "P0P1")]))
3484		       (vec_select:HI (match_dup 2)
3485			(parallel [(match_operand 6 "const01_operand" "P0P1")])))
3486		      (match_operand 7 "const_int_operand" "n")]
3487		     UNSPEC_MAC_WITH_FLAG))
3488   (set (match_operand:V2PDI 8 "register_operand" "=e")
3489	(unspec:V2PDI [(vec_concat:V2HI
3490			(vec_select:HI (match_dup 1) (parallel [(match_dup 3)]))
3491			(vec_select:HI (match_dup 1) (parallel [(match_dup 4)])))
3492		       (vec_concat:V2HI
3493			(vec_select:HI (match_dup 2) (parallel [(match_dup 5)]))
3494			(vec_select:HI (match_dup 2) (parallel [(match_dup 5)])))
3495		       (match_dup 7)]
3496		      UNSPEC_MAC_WITH_FLAG))]
3497  ""
3498{
3499  const char *templates[] = {
3500    "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %h1 * %h2) %M7%!",
3501    "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %h1 * %h2) %M7%!",
3502    "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %d1 * %h2) %M7%!",
3503    "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %d1 * %h2) %M7%!",
3504    "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %h1 * %h2) %M7%!",
3505    "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %h1 * %h2) %M7%!",
3506    "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %d1 * %h2) %M7%!",
3507    "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %d1 * %h2) %M7%!",
3508    "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %h1 * %d2) %M7%!",
3509    "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %h1 * %d2) %M7%!",
3510    "%h0 = (A0 = %h1 * %h2), %d0 = (A1 = %d1 * %d2) %M7%!",
3511    "%h0 = (A0 = %d1 * %h2), %d0 = (A1 = %d1 * %d2) %M7%!",
3512    "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %h1 * %d2) %M7%!",
3513    "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %h1 * %d2) %M7%!",
3514    "%h0 = (A0 = %h1 * %d2), %d0 = (A1 = %d1 * %d2) %M7%!",
3515    "%h0 = (A0 = %d1 * %d2), %d0 = (A1 = %d1 * %d2) %M7%!" };
3516  int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3517	     + (INTVAL (operands[5]) << 2)  + (INTVAL (operands[6]) << 3));
3518  return templates[alt];
3519}
3520  [(set_attr "type" "dsp32")])
3521
3522(define_insn "flag_macinit1v2hi_parts"
3523  [(set (match_operand:V2PDI 0 "register_operand" "=e")
3524	(unspec:V2PDI [(vec_concat:V2HI
3525		       (vec_select:HI
3526			(match_operand:V2HI 1 "register_operand" "d")
3527			(parallel [(match_operand 3 "const01_operand" "P0P1")]))
3528		       (vec_select:HI
3529			(match_dup 1)
3530			(parallel [(match_operand 4 "const01_operand" "P0P1")])))
3531		      (vec_concat:V2HI
3532		       (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3533			(parallel [(match_operand 5 "const01_operand" "P0P1")]))
3534		       (vec_select:HI (match_dup 2)
3535			(parallel [(match_operand 6 "const01_operand" "P0P1")])))
3536		      (match_operand 7 "const_int_operand" "n")]
3537		     UNSPEC_MAC_WITH_FLAG))]
3538  ""
3539{
3540  const char *templates[] = {
3541    "A0 = %h1 * %h2, A1 = %h1 * %h2 %M7%!",
3542    "A0 = %d1 * %h2, A1 = %h1 * %h2 %M7%!",
3543    "A0 = %h1 * %h2, A1 = %d1 * %h2 %M7%!",
3544    "A0 = %d1 * %h2, A1 = %d1 * %h2 %M7%!",
3545    "A0 = %h1 * %d2, A1 = %h1 * %h2 %M7%!",
3546    "A0 = %d1 * %d2, A1 = %h1 * %h2 %M7%!",
3547    "A0 = %h1 * %d2, A1 = %d1 * %h2 %M7%!",
3548    "A0 = %d1 * %d2, A1 = %d1 * %h2 %M7%!",
3549    "A0 = %h1 * %h2, A1 = %h1 * %d2 %M7%!",
3550    "A0 = %d1 * %h2, A1 = %h1 * %d2 %M7%!",
3551    "A0 = %h1 * %h2, A1 = %d1 * %d2 %M7%!",
3552    "A0 = %d1 * %h2, A1 = %d1 * %d2 %M7%!",
3553    "A0 = %h1 * %d2, A1 = %h1 * %d2 %M7%!",
3554    "A0 = %d1 * %d2, A1 = %h1 * %d2 %M7%!",
3555    "A0 = %h1 * %d2, A1 = %d1 * %d2 %M7%!",
3556    "A0 = %d1 * %d2, A1 = %d1 * %d2 %M7%!" };
3557  int alt = (INTVAL (operands[3]) + (INTVAL (operands[4]) << 1)
3558	     + (INTVAL (operands[5]) << 2)  + (INTVAL (operands[6]) << 3));
3559  return templates[alt];
3560}
3561  [(set_attr "type" "dsp32")])
3562
3563;; A mixture of multiply and multiply-accumulate for when we only want to
3564;; initialize one part.
3565(define_insn "flag_mul_macv2hi_parts_acconly"
3566  [(set (match_operand:PDI 0 "register_operand" "=B,e,e")
3567	(unspec:PDI [(vec_select:HI
3568		      (match_operand:V2HI 2 "register_operand" "d,d,d")
3569		      (parallel [(match_operand 4 "const01_operand" "P0P1,P0P1,P0P1")]))
3570		     (vec_select:HI
3571		      (match_operand:V2HI 3 "register_operand" "d,d,d")
3572		      (parallel [(match_operand 6 "const01_operand" "P0P1,P0P1,P0P1")]))
3573		     (match_operand 10 "const_int_operand" "PB,PA,PA")]
3574		    UNSPEC_MUL_WITH_FLAG))
3575   (set (match_operand:PDI 1 "register_operand" "=B,e,e")
3576	(unspec:PDI [(vec_select:HI
3577		      (match_dup 2)
3578		      (parallel [(match_operand 5 "const01_operand" "P0P1,P0P1,P0P1")]))
3579		     (vec_select:HI
3580		      (match_dup 3)
3581		      (parallel [(match_operand 7 "const01_operand" "P0P1,P0P1,P0P1")]))
3582		     (match_operand:PDI 8 "register_operand" "1,1,1")
3583		     (match_operand 9 "const01_operand" "P0P1,P0P1,P0P1")
3584		     (match_operand 11 "const_int_operand" "PA,PB,PA")]
3585		    UNSPEC_MAC_WITH_FLAG))]
3586  "MACFLAGS_MATCH_P (INTVAL (operands[10]), INTVAL (operands[11]))"
3587{
3588  rtx xops[6];
3589  const char *templates[] = {
3590    "%0 = %h2 * %h3, %1 %b4 %h2 * %h3 %M5%!",
3591    "%0 = %d2 * %h3, %1 %b4 %h2 * %h3 %M5%!",
3592    "%0 = %h2 * %h3, %1 %b4 %d2 * %h3 %M5%!",
3593    "%0 = %d2 * %h3, %1 %b4 %d2 * %h3 %M5%!",
3594    "%0 = %h2 * %d3, %1 %b4 %h2 * %h3 %M5%!",
3595    "%0 = %d2 * %d3, %1 %b4 %h2 * %h3 %M5%!",
3596    "%0 = %h2 * %d3, %1 %b4 %d2 * %h3 %M5%!",
3597    "%0 = %d2 * %d3, %1 %b4 %d2 * %h3 %M5%!",
3598    "%0 = %h2 * %h3, %1 %b4 %h2 * %d3 %M5%!",
3599    "%0 = %d2 * %h3, %1 %b4 %h2 * %d3 %M5%!",
3600    "%0 = %h2 * %h3, %1 %b4 %d2 * %d3 %M5%!",
3601    "%0 = %d2 * %h3, %1 %b4 %d2 * %d3 %M5%!",
3602    "%0 = %h2 * %d3, %1 %b4 %h2 * %d3 %M5%!",
3603    "%0 = %d2 * %d3, %1 %b4 %h2 * %d3 %M5%!",
3604    "%0 = %h2 * %d3, %1 %b4 %d2 * %d3 %M5%!",
3605    "%0 = %d2 * %d3, %1 %b4 %d2 * %d3 %M5%!" };
3606  int alt = (INTVAL (operands[4]) + (INTVAL (operands[5]) << 1)
3607	     + (INTVAL (operands[6]) << 2)  + (INTVAL (operands[7]) << 3));
3608  xops[0] = operands[0];
3609  xops[1] = operands[1];
3610  xops[2] = operands[2];
3611  xops[3] = operands[3];
3612  xops[4] = operands[9];
3613  xops[5] = which_alternative == 0 ? operands[10] : operands[11];
3614  output_asm_insn (templates[alt], xops);
3615  return "";
3616}
3617  [(set_attr "type" "dsp32")])
3618
3619
3620(define_code_iterator s_or_u [sign_extend zero_extend])
3621(define_code_attr su_optab [(sign_extend "mul")
3622			    (zero_extend "umul")])
3623(define_code_attr su_modifier [(sign_extend "IS")
3624			       (zero_extend "FU")])
3625
3626(define_insn "<su_optab>hisi_ll"
3627  [(set (match_operand:SI 0 "register_operand" "=d")
3628	(mult:SI (s_or_u:SI
3629		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3630				 (parallel [(const_int 0)])))
3631		 (s_or_u:SI
3632		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3633				 (parallel [(const_int 0)])))))]
3634  ""
3635  "%0 = %h1 * %h2 (<su_modifier>)%!"
3636  [(set_attr "type" "dsp32")])
3637
3638(define_insn "<su_optab>hisi_lh"
3639  [(set (match_operand:SI 0 "register_operand" "=d")
3640	(mult:SI (s_or_u:SI
3641		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3642				 (parallel [(const_int 0)])))
3643		 (s_or_u:SI
3644		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3645				 (parallel [(const_int 1)])))))]
3646  ""
3647  "%0 = %h1 * %d2 (<su_modifier>)%!"
3648  [(set_attr "type" "dsp32")])
3649
3650(define_insn "<su_optab>hisi_hl"
3651  [(set (match_operand:SI 0 "register_operand" "=d")
3652	(mult:SI (s_or_u:SI
3653		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3654				 (parallel [(const_int 1)])))
3655		 (s_or_u:SI
3656		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3657				 (parallel [(const_int 0)])))))]
3658  ""
3659  "%0 = %d1 * %h2 (<su_modifier>)%!"
3660  [(set_attr "type" "dsp32")])
3661
3662(define_insn "<su_optab>hisi_hh"
3663  [(set (match_operand:SI 0 "register_operand" "=d")
3664	(mult:SI (s_or_u:SI
3665		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3666				 (parallel [(const_int 1)])))
3667		 (s_or_u:SI
3668		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3669				 (parallel [(const_int 1)])))))]
3670  ""
3671  "%0 = %d1 * %d2 (<su_modifier>)%!"
3672  [(set_attr "type" "dsp32")])
3673
3674;; Additional variants for signed * unsigned multiply.
3675
3676(define_insn "usmulhisi_ull"
3677  [(set (match_operand:SI 0 "register_operand" "=W")
3678	(mult:SI (zero_extend:SI
3679		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3680				 (parallel [(const_int 0)])))
3681		 (sign_extend:SI
3682		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3683				 (parallel [(const_int 0)])))))]
3684  ""
3685  "%0 = %h2 * %h1 (IS,M)%!"
3686  [(set_attr "type" "dsp32")])
3687
3688(define_insn "usmulhisi_ulh"
3689  [(set (match_operand:SI 0 "register_operand" "=W")
3690	(mult:SI (zero_extend:SI
3691		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3692				 (parallel [(const_int 0)])))
3693		 (sign_extend:SI
3694		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3695				 (parallel [(const_int 1)])))))]
3696  ""
3697  "%0 = %d2 * %h1 (IS,M)%!"
3698  [(set_attr "type" "dsp32")])
3699
3700(define_insn "usmulhisi_uhl"
3701  [(set (match_operand:SI 0 "register_operand" "=W")
3702	(mult:SI (zero_extend:SI
3703		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d")
3704				 (parallel [(const_int 1)])))
3705		 (sign_extend:SI
3706		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3707				 (parallel [(const_int 0)])))))]
3708  ""
3709  "%0 = %h2 * %d1 (IS,M)%!"
3710  [(set_attr "type" "dsp32")])
3711
3712(define_insn "usmulhisi_uhh"
3713  [(set (match_operand:SI 0 "register_operand" "=W")
3714	(mult:SI (zero_extend:SI
3715		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "%d")
3716				 (parallel [(const_int 1)])))
3717		 (sign_extend:SI
3718		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d")
3719				 (parallel [(const_int 1)])))))]
3720  ""
3721  "%0 = %d2 * %d1 (IS,M)%!"
3722  [(set_attr "type" "dsp32")])
3723
3724;; Parallel versions of these operations.  First, normal signed or unsigned
3725;; multiplies.
3726
3727(define_insn "<su_optab>hisi_ll_lh"
3728  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3729	(mult:SI (s_or_u:SI
3730		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3731				 (parallel [(const_int 0)])))
3732		 (s_or_u:SI
3733		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3734				 (parallel [(const_int 0)])))))
3735   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3736	(mult:SI (s_or_u:SI
3737		  (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3738		 (s_or_u:SI
3739		  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3740  ""
3741  "%0 = %h1 * %h2, %3 = %h1 * %d2 (<su_modifier>)%!"
3742  [(set_attr "type" "dsp32")])
3743
3744(define_insn "<su_optab>hisi_ll_hl"
3745  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3746	(mult:SI (s_or_u:SI
3747		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3748				 (parallel [(const_int 0)])))
3749		 (s_or_u:SI
3750		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3751				 (parallel [(const_int 0)])))))
3752   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3753	(mult:SI (s_or_u:SI
3754		  (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3755		 (s_or_u:SI
3756		  (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3757  ""
3758  "%0 = %h1 * %h2, %3 = %d1 * %h2 (<su_modifier>)%!"
3759  [(set_attr "type" "dsp32")])
3760
3761(define_insn "<su_optab>hisi_ll_hh"
3762  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3763	(mult:SI (s_or_u:SI
3764		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3765				 (parallel [(const_int 0)])))
3766		 (s_or_u:SI
3767		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3768				 (parallel [(const_int 0)])))))
3769   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3770	(mult:SI (s_or_u:SI
3771		  (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3772		 (s_or_u:SI
3773		  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3774  ""
3775  "%0 = %h1 * %h2, %3 = %d1 * %d2 (<su_modifier>)%!"
3776  [(set_attr "type" "dsp32")])
3777
3778(define_insn "<su_optab>hisi_lh_hl"
3779  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3780	(mult:SI (s_or_u:SI
3781		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3782				 (parallel [(const_int 0)])))
3783		 (s_or_u:SI
3784		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3785				 (parallel [(const_int 1)])))))
3786   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3787	(mult:SI (s_or_u:SI
3788		  (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3789		 (s_or_u:SI
3790		  (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3791  ""
3792  "%0 = %h1 * %d2, %3 = %d1 * %h2 (<su_modifier>)%!"
3793  [(set_attr "type" "dsp32")])
3794
3795(define_insn "<su_optab>hisi_lh_hh"
3796  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3797	(mult:SI (s_or_u:SI
3798		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3799				 (parallel [(const_int 0)])))
3800		 (s_or_u:SI
3801		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3802				 (parallel [(const_int 1)])))))
3803   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3804	(mult:SI (s_or_u:SI
3805		  (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3806		 (s_or_u:SI
3807		  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3808  ""
3809  "%0 = %h1 * %d2, %3 = %d1 * %d2 (<su_modifier>)%!"
3810  [(set_attr "type" "dsp32")])
3811
3812(define_insn "<su_optab>hisi_hl_hh"
3813  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3814	(mult:SI (s_or_u:SI
3815		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3816				 (parallel [(const_int 1)])))
3817		 (s_or_u:SI
3818		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3819				 (parallel [(const_int 0)])))))
3820   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3821	(mult:SI (s_or_u:SI
3822		  (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3823		 (s_or_u:SI
3824		  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3825  ""
3826  "%0 = %d1 * %h2, %3 = %d1 * %d2 (<su_modifier>)%!"
3827  [(set_attr "type" "dsp32")])
3828
3829;; Special signed * unsigned variants.
3830
3831(define_insn "usmulhisi_ll_lul"
3832  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3833	(mult:SI (sign_extend:SI
3834		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3835				 (parallel [(const_int 0)])))
3836		 (sign_extend:SI
3837		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3838				 (parallel [(const_int 0)])))))
3839   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3840	(mult:SI (sign_extend:SI
3841		  (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3842		 (zero_extend:SI
3843		  (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3844  ""
3845  "%0 = %h1 * %h2, %3 = %h1 * %h2 (IS,M)%!"
3846  [(set_attr "type" "dsp32")])
3847
3848(define_insn "usmulhisi_ll_luh"
3849  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3850	(mult:SI (sign_extend:SI
3851		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3852				 (parallel [(const_int 0)])))
3853		 (sign_extend:SI
3854		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3855				 (parallel [(const_int 0)])))))
3856   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3857	(mult:SI (sign_extend:SI
3858		  (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3859		 (zero_extend:SI
3860		  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3861  ""
3862  "%0 = %h1 * %h2, %3 = %h1 * %d2 (IS,M)%!"
3863  [(set_attr "type" "dsp32")])
3864
3865(define_insn "usmulhisi_ll_hul"
3866  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3867	(mult:SI (sign_extend:SI
3868		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3869				 (parallel [(const_int 0)])))
3870		 (sign_extend:SI
3871		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3872				 (parallel [(const_int 0)])))))
3873   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3874	(mult:SI (sign_extend:SI
3875		  (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3876		 (zero_extend:SI
3877		  (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3878  ""
3879  "%0 = %h1 * %h2, %3 = %d1 * %h2 (IS,M)%!"
3880  [(set_attr "type" "dsp32")])
3881
3882(define_insn "usmulhisi_ll_huh"
3883  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3884	(mult:SI (sign_extend:SI
3885		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3886				 (parallel [(const_int 0)])))
3887		 (sign_extend:SI
3888		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3889				 (parallel [(const_int 0)])))))
3890   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3891	(mult:SI (sign_extend:SI
3892		  (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3893		 (zero_extend:SI
3894		  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3895  ""
3896  "%0 = %h1 * %h2, %3 = %d1 * %d2 (IS,M)%!"
3897  [(set_attr "type" "dsp32")])
3898
3899(define_insn "usmulhisi_lh_lul"
3900  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3901	(mult:SI (sign_extend:SI
3902		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3903				 (parallel [(const_int 0)])))
3904		 (sign_extend:SI
3905		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3906				 (parallel [(const_int 1)])))))
3907   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3908	(mult:SI (sign_extend:SI
3909		  (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3910		 (zero_extend:SI
3911		  (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3912  ""
3913  "%0 = %h1 * %d2, %3 = %h1 * %h2 (IS,M)%!"
3914  [(set_attr "type" "dsp32")])
3915
3916(define_insn "usmulhisi_lh_luh"
3917  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3918	(mult:SI (sign_extend:SI
3919		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3920				 (parallel [(const_int 0)])))
3921		 (sign_extend:SI
3922		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3923				 (parallel [(const_int 1)])))))
3924   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3925	(mult:SI (sign_extend:SI
3926		  (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3927		 (zero_extend:SI
3928		  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3929  ""
3930  "%0 = %h1 * %d2, %3 = %h1 * %d2 (IS,M)%!"
3931  [(set_attr "type" "dsp32")])
3932
3933(define_insn "usmulhisi_lh_hul"
3934  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3935	(mult:SI (sign_extend:SI
3936		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3937				 (parallel [(const_int 0)])))
3938		 (sign_extend:SI
3939		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3940				 (parallel [(const_int 1)])))))
3941   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3942	(mult:SI (sign_extend:SI
3943		  (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3944		 (zero_extend:SI
3945		  (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3946  ""
3947  "%0 = %h1 * %d2, %3 = %d1 * %h2 (IS,M)%!"
3948  [(set_attr "type" "dsp32")])
3949
3950(define_insn "usmulhisi_lh_huh"
3951  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3952	(mult:SI (sign_extend:SI
3953		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3954				 (parallel [(const_int 0)])))
3955		 (sign_extend:SI
3956		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3957				 (parallel [(const_int 1)])))))
3958   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3959	(mult:SI (sign_extend:SI
3960		  (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3961		 (zero_extend:SI
3962		  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3963  ""
3964  "%0 = %h1 * %d2, %3 = %d1 * %d2 (IS,M)%!"
3965  [(set_attr "type" "dsp32")])
3966
3967(define_insn "usmulhisi_hl_lul"
3968  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3969	(mult:SI (sign_extend:SI
3970		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3971				 (parallel [(const_int 1)])))
3972		 (sign_extend:SI
3973		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3974				 (parallel [(const_int 0)])))))
3975   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3976	(mult:SI (sign_extend:SI
3977		  (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3978		 (zero_extend:SI
3979		  (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
3980  ""
3981  "%0 = %d1 * %h2, %3 = %h1 * %h2 (IS,M)%!"
3982  [(set_attr "type" "dsp32")])
3983
3984(define_insn "usmulhisi_hl_luh"
3985  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
3986	(mult:SI (sign_extend:SI
3987		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
3988				 (parallel [(const_int 1)])))
3989		 (sign_extend:SI
3990		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
3991				 (parallel [(const_int 0)])))))
3992   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
3993	(mult:SI (sign_extend:SI
3994		  (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
3995		 (zero_extend:SI
3996		  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
3997  ""
3998  "%0 = %d1 * %h2, %3 = %h1 * %d2 (IS,M)%!"
3999  [(set_attr "type" "dsp32")])
4000
4001(define_insn "usmulhisi_hl_hul"
4002  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4003	(mult:SI (sign_extend:SI
4004		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4005				 (parallel [(const_int 1)])))
4006		 (sign_extend:SI
4007		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4008				 (parallel [(const_int 0)])))))
4009   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4010	(mult:SI (sign_extend:SI
4011		  (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4012		 (zero_extend:SI
4013		  (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
4014  ""
4015  "%0 = %d1 * %h2, %3 = %d1 * %h2 (IS,M)%!"
4016  [(set_attr "type" "dsp32")])
4017
4018(define_insn "usmulhisi_hl_huh"
4019  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4020	(mult:SI (sign_extend:SI
4021		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4022				 (parallel [(const_int 1)])))
4023		 (sign_extend:SI
4024		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4025				 (parallel [(const_int 0)])))))
4026   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4027	(mult:SI (sign_extend:SI
4028		  (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4029		 (zero_extend:SI
4030		  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
4031  ""
4032  "%0 = %d1 * %h2, %3 = %d1 * %d2 (IS,M)%!"
4033  [(set_attr "type" "dsp32")])
4034
4035(define_insn "usmulhisi_hh_lul"
4036  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4037	(mult:SI (sign_extend:SI
4038		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4039				 (parallel [(const_int 1)])))
4040		 (sign_extend:SI
4041		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4042				 (parallel [(const_int 1)])))))
4043   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4044	(mult:SI (sign_extend:SI
4045		  (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
4046		 (zero_extend:SI
4047		  (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
4048  ""
4049  "%0 = %d1 * %d2, %3 = %h1 * %h2 (IS,M)%!"
4050  [(set_attr "type" "dsp32")])
4051
4052(define_insn "usmulhisi_hh_luh"
4053  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4054	(mult:SI (sign_extend:SI
4055		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4056				 (parallel [(const_int 1)])))
4057		 (sign_extend:SI
4058		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4059				 (parallel [(const_int 1)])))))
4060   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4061	(mult:SI (sign_extend:SI
4062		  (vec_select:HI (match_dup 1) (parallel [(const_int 0)])))
4063		 (zero_extend:SI
4064		  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
4065  ""
4066  "%0 = %d1 * %d2, %3 = %h1 * %d2 (IS,M)%!"
4067  [(set_attr "type" "dsp32")])
4068
4069(define_insn "usmulhisi_hh_hul"
4070  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4071	(mult:SI (sign_extend:SI
4072		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4073				 (parallel [(const_int 1)])))
4074		 (sign_extend:SI
4075		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4076				 (parallel [(const_int 1)])))))
4077   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4078	(mult:SI (sign_extend:SI
4079		  (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4080		 (zero_extend:SI
4081		  (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))))]
4082  ""
4083  "%0 = %d1 * %d2, %3 = %d1 * %h2 (IS,M)%!"
4084  [(set_attr "type" "dsp32")])
4085
4086(define_insn "usmulhisi_hh_huh"
4087  [(set (match_operand:SI 0 "register_operand" "=q0,q2,q4,q6")
4088	(mult:SI (sign_extend:SI
4089		  (vec_select:HI (match_operand:V2HI 1 "register_operand" "d,d,d,d")
4090				 (parallel [(const_int 1)])))
4091		 (sign_extend:SI
4092		  (vec_select:HI (match_operand:V2HI 2 "register_operand" "d,d,d,d")
4093				 (parallel [(const_int 1)])))))
4094   (set (match_operand:SI 3 "register_operand" "=q1,q3,q5,q7")
4095	(mult:SI (sign_extend:SI
4096		  (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4097		 (zero_extend:SI
4098		  (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))]
4099  ""
4100  "%0 = %d1 * %d2, %3 = %d1 * %d2 (IS,M)%!"
4101  [(set_attr "type" "dsp32")])
4102
4103;; Vector neg/abs.
4104
4105(define_insn "ssnegv2hi2"
4106  [(set (match_operand:V2HI 0 "register_operand" "=d")
4107	(ss_neg:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
4108  ""
4109  "%0 = - %1 (V)%!"
4110  [(set_attr "type" "dsp32")])
4111
4112(define_insn "ssabsv2hi2"
4113  [(set (match_operand:V2HI 0 "register_operand" "=d")
4114	(ss_abs:V2HI (match_operand:V2HI 1 "register_operand" "d")))]
4115  ""
4116  "%0 = ABS %1 (V)%!"
4117  [(set_attr "type" "dsp32")])
4118
4119;; Shifts.
4120
4121(define_insn "ssashiftv2hi3"
4122  [(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
4123	(if_then_else:V2HI
4124	 (lt (match_operand:HI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
4125	 (ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" "d,d,d")
4126			(match_dup 2))
4127	 (ss_ashift:V2HI (match_dup 1) (match_dup 2))))]
4128  ""
4129  "@
4130   %0 = ASHIFT %1 BY %h2 (V, S)%!
4131   %0 = %1 << %2 (V,S)%!
4132   %0 = %1 >>> %N2 (V,S)%!"
4133  [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
4134
4135(define_insn "ssashifthi3"
4136  [(set (match_operand:HI 0 "register_operand" "=d,d,d")
4137	(if_then_else:HI
4138	 (lt (match_operand:HI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
4139	 (ashiftrt:HI (match_operand:HI 1 "register_operand" "d,d,d")
4140		      (match_dup 2))
4141	 (ss_ashift:HI (match_dup 1) (match_dup 2))))]
4142  ""
4143  "@
4144   %0 = ASHIFT %1 BY %h2 (V, S)%!
4145   %0 = %1 << %2 (V,S)%!
4146   %0 = %1 >>> %N2 (V,S)%!"
4147  [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
4148
4149(define_insn "ssashiftsi3"
4150  [(set (match_operand:SI 0 "register_operand" "=d,d,d")
4151	(if_then_else:SI
4152	 (lt (match_operand:HI 2 "reg_or_const_int_operand" "d,Ku5,Ks5") (const_int 0))
4153	 (ashiftrt:SI (match_operand:HI 1 "register_operand" "d,d,d")
4154		      (match_dup 2))
4155	 (ss_ashift:SI (match_dup 1) (match_dup 2))))]
4156  ""
4157  "@
4158   %0 = ASHIFT %1 BY %h2 (S)%!
4159   %0 = %1 << %2 (S)%!
4160   %0 = %1 >>> %N2 (S)%!"
4161  [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
4162
4163(define_insn "lshiftv2hi3"
4164  [(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
4165	(if_then_else:V2HI
4166	 (lt (match_operand:HI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
4167	 (lshiftrt:V2HI (match_operand:V2HI 1 "register_operand" "d,d,d")
4168			(match_dup 2))
4169	 (ashift:V2HI (match_dup 1) (match_dup 2))))]
4170  ""
4171  "@
4172   %0 = LSHIFT %1 BY %h2 (V)%!
4173   %0 = %1 << %2 (V)%!
4174   %0 = %1 >> %N2 (V)%!"
4175  [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
4176
4177(define_insn "lshifthi3"
4178  [(set (match_operand:HI 0 "register_operand" "=d,d,d")
4179	(if_then_else:HI
4180	 (lt (match_operand:HI 2 "vec_shift_operand" "d,Ku4,Ks4") (const_int 0))
4181	 (lshiftrt:HI (match_operand:HI 1 "register_operand" "d,d,d")
4182		      (match_dup 2))
4183	 (ashift:HI (match_dup 1) (match_dup 2))))]
4184  ""
4185  "@
4186   %0 = LSHIFT %1 BY %h2 (V)%!
4187   %0 = %1 << %2 (V)%!
4188   %0 = %1 >> %N2 (V)%!"
4189  [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
4190
4191;; Load without alignment exception (masking off low bits)
4192
4193(define_insn "loadbytes"
4194  [(set (match_operand:SI 0 "register_operand" "=d")
4195	(mem:SI (and:SI (match_operand:SI 1 "register_operand" "b")
4196			(const_int -4))))]
4197  ""
4198  "DISALGNEXCPT || %0 = [%1];"
4199  [(set_attr "type" "mcld")
4200   (set_attr "length" "8")])
4201
4202(include "sync.md")
4203