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