Home | History | Annotate | Line # | Download | only in msp430
      1 ;;  Machine Description for TI MSP43* processors
      2 ;;  Copyright (C) 2013-2024 Free Software Foundation, Inc.
      3 ;;  Contributed by Red Hat.
      4 
      5 ;; This file is part of GCC.
      6 
      7 ;; GCC is free software; you can redistribute it and/or modify
      8 ;; it under the terms of the GNU General Public License as published by
      9 ;; the Free Software Foundation; either version 3, or (at your option)
     10 ;; any later version.
     11 
     12 ;; GCC is distributed in the hope that it will be useful,
     13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 ;; GNU General Public 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 
     22 
     23 (define_constants
     24   [
     25    (PC_REGNO 0)
     26    (SP_REGNO 1)
     27    (CARRY 2)
     28   ])
     29 
     30 (define_c_enum "unspec"
     31   [
     32    UNS_PROLOGUE_START_MARKER
     33    UNS_PROLOGUE_END_MARKER
     34    UNS_EPILOGUE_START_MARKER
     35    UNS_EPILOGUE_HELPER
     36 
     37    UNS_PUSHM
     38    UNS_POPM
     39 
     40    UNS_GROW_AND_SWAP
     41    UNS_SWAP_AND_SHRINK
     42    
     43    UNS_DINT
     44    UNS_EINT
     45    UNS_PUSH_INTR
     46    UNS_POP_INTR
     47    UNS_BIC_SR
     48    UNS_BIS_SR
     49 
     50    UNS_REFSYM_NEED_EXIT
     51 
     52    UNS_DELAY_32
     53    UNS_DELAY_32X
     54    UNS_DELAY_16
     55    UNS_DELAY_16X
     56    UNS_DELAY_2
     57    UNS_DELAY_1
     58    UNS_DELAY_START
     59    UNS_DELAY_END
     60   ])
     61 
     62 ;; Instruction length is calculated by examining the type and number of
     63 ;; operands.
     64 ;; Whether the insn uses the 430X extension word, or is a 430X address
     65 ;; instruction also has an effect.
     66 ;; "Cheap" source operands do not contribute to the overall length of the insn
     67 ;; and are register (Rn), indirect post-increment (@Rn+) and indirect register
     68 ;; (@Rn).
     69 ;; The lengths of instructions in bytes are:
     70 ;; Single-op 430: Cheap op == 2
     71 ;; (also CALLA)   Other op == 4
     72 ;; Double-op 430: Source is not cheap == 2
     73 ;;  (also MOVA,   Dest is register == 2
     74 ;;   CMPA, ADDA,  Dest is not a register == 4
     75 ;;   SUBA)	  (sum the source and dest cost)
     76 ;; Single-op 430X: For insn names ending in 'X' add 2 to single-op 430 cost.
     77 ;; Double-op 430X: Insn name ends in 'M' == 2
     78 ;;		   Others have the same cost as double-op 430 but add 2.
     79 ;;
     80 ;; The insn type describes whether it is a single or double operand MSP430
     81 ;; instruction (some single-operand GCC instructions are actually
     82 ;; double-operand on the target).
     83 ;; "triple" and "cmp" types use the costs of a double operand type but
     84 ;; instead assume that the src operand is in op2, and also cmp types assume the
     85 ;; dst operand is in op1.
     86 ;; This attribute also describes which operands are safe to examine
     87 ;; when calculating the length or extension.  GCC will segfault trying to
     88 ;; examine a non-existant operand of an insn.
     89 (define_attr "type" "none,single,double,triple,cmp" (const_string "none"))
     90 
     91 ;; The M extension is for instructions like RRAM - they always
     92 ;; only, and the operand must be a register.
     93 (define_attr "extension" "none,x,a,m"
     94  (cond [(eq_attr "type" "none")
     95 	(const_string "none")
     96 	(match_operand 0 "msp430_high_memory_operand" "")
     97 	(const_string "x")
     98 	(and (eq_attr "type" "double")
     99 	     (match_operand 1 "msp430_high_memory_operand" ""))
    100 	(const_string "x")
    101 	(and (ior (eq_attr "type" "triple") (eq_attr "type" "cmp"))
    102 	     (ior (match_operand 1 "msp430_high_memory_operand" "")
    103 		  (match_operand 2 "msp430_high_memory_operand" "")))
    104 	(const_string "x")]
    105 	(const_string "none")))
    106 
    107 ;; Multiply the default length by this constant value.
    108 (define_attr "length_multiplier" "" (const_int 1))
    109 
    110 ;; Add an additional amount to the total length of the insn.
    111 (define_attr "extra_length" "" (const_int 0))
    112 
    113 ;; FIXME for some reason if we move the addition of 2 for extension == x to
    114 ;; ADJUST_INSN_LENGTH, codesize gets much worse.
    115 (define_attr "length" ""
    116  (cond [(eq_attr "extension" "m")
    117 	(const_int 2)
    118 	(eq_attr "type" "single")
    119 	(plus (if_then_else (match_operand 0 "msp430_cheap_operand" "")
    120 			    (const_int 2)
    121 			    (const_int 4))
    122 	      (if_then_else (eq_attr "extension" "x")
    123 			    (const_int 2)
    124 			    (const_int 0)))
    125 	(eq_attr "type" "double")
    126 	(plus (plus (if_then_else (match_operand 0 "register_operand" "")
    127 				   (const_int 2)
    128 				   (const_int 4))
    129 		    (if_then_else (match_operand 1 "msp430_cheap_operand" "")
    130 				  (const_int 0)
    131 				  (const_int 2)))
    132 	      (if_then_else (eq_attr "extension" "x")
    133 			    (const_int 2)
    134 			    (const_int 0)))
    135 	(eq_attr "type" "triple")
    136 	(plus (plus (if_then_else (match_operand 0 "register_operand" "")
    137 				   (const_int 2)
    138 				   (const_int 4))
    139 		    (if_then_else (match_operand 2 "msp430_cheap_operand" "")
    140 				  (const_int 0)
    141 				  (const_int 2)))
    142 	      (if_then_else (eq_attr "extension" "x")
    143 			    (const_int 2)
    144 			    (const_int 0)))
    145 	(eq_attr "type" "cmp")
    146 	(plus (plus (if_then_else (match_operand 1 "register_operand" "")
    147 				   (const_int 2)
    148 				   (const_int 4))
    149 		    (if_then_else (match_operand 2 "msp430_cheap_operand" "")
    150 				  (const_int 0)
    151 				  (const_int 2)))
    152 	      (if_then_else (eq_attr "extension" "x")
    153 			    (const_int 2)
    154 			    (const_int 0)))]
    155   (const_int 2)))
    156 
    157 (include "predicates.md")
    158 (include "constraints.md")
    159 
    160 (define_mode_iterator QHI [QI HI PSI])
    161 (define_mode_iterator HPSI [HI PSI])
    162 (define_mode_iterator HDI [HI PSI SI DI])
    163 
    164 ;; Mapping of all shift operators
    165 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
    166 
    167 ;; Base name for define_insn
    168 (define_code_attr shift_insn
    169   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
    170 
    171 ;; There are two basic "family" tests we do here:
    172 ;;
    173 ;; msp430x - true if 430X instructions are available.
    174 ;; TARGET_LARGE - true if pointers are 20-bits
    175 ;;
    176 ;; Note that there are three supported cases, since the base 430
    177 ;; doesn't have 20-bit pointers:
    178 ;;
    179 ;; 1. MSP430 cpu, small model
    180 ;; 2. MSP430X cpu, small model.
    181 ;; 3. MSP430X cpu, large model.
    182 
    183 ;;------------------------------------------------------------
    184 ;; Moves
    185 
    186 ;; Push/Pop must be before the generic move patterns
    187 
    188 (define_insn "push"
    189   [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO)))
    190 	(match_operand:HI 0 "register_operand" "r"))]
    191   ""
    192   "PUSH\t%0"
    193   [(set_attr "type" "single")]
    194 )
    195 
    196 (define_insn "pusha"
    197   [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO)))
    198 	(match_operand:PSI 0 "register_operand" "r"))]
    199   "TARGET_LARGE"
    200   "PUSHX.A\t%0"
    201   [(set_attr "type" "single")
    202    (set_attr "extension" "x")]
    203 )
    204 
    205 (define_insn "pushm"
    206   [(unspec_volatile [(match_operand 0 "register_operand" "r")
    207 		     (match_operand 1 "immediate_operand" "n")] UNS_PUSHM)]
    208   ""
    209   "PUSHM%b0\t%1, %0"
    210   [(set_attr "type" "single")
    211    (set_attr "extension" "m")]
    212 )
    213 
    214 (define_insn "pop"
    215   [(set (match_operand:HI 0 "register_operand" "=r")
    216 	(mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
    217   ""
    218   "POP\t%0"
    219   [(set_attr "type" "single")]
    220 )
    221 
    222 (define_insn "popa"
    223   [(set (match_operand:PSI 0 "register_operand" "=r")
    224 	(mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))]
    225   "TARGET_LARGE"
    226   "POPX.A\t%0"
    227   [(set_attr "type" "single")
    228    (set_attr "extension" "x")]
    229 )
    230 
    231 ;; This is nasty.  Operand0 is bogus.  It is only there so that we can get a
    232 ;; mode for the %b0 to work.  We should use operand1 for this, but that does
    233 ;; not have a mode.
    234 ;; 
    235 ;; Operand1 is actually a register, but we cannot accept (REG...) because the
    236 ;; cprop_hardreg pass can and will renumber registers even inside
    237 ;; unspec_volatiles.  So we take an integer register number parameter and
    238 ;; fudge it to be a register name when we generate the assembler.
    239 ;;
    240 ;; The pushm pattern does not have this problem because of all of the
    241 ;; frame info cruft attached to it, so cprop_hardreg leaves it alone.
    242 (define_insn "popm"
    243   [(unspec_volatile [(match_operand 0 "register_operand" "r")
    244 		     (match_operand 1 "immediate_operand" "i")
    245 		     (match_operand 2 "immediate_operand" "i")] UNS_POPM)]
    246   ""
    247   "POPM%b0\t%2, r%J1"
    248   [(set_attr "type" "single")
    249    (set_attr "extension" "m")]
    250 )
    251 
    252 ;; The next two patterns are here to support a "feature" of how GCC implements
    253 ;; varargs.  When a function uses varargs and the *second* to last named
    254 ;; argument is split between argument registers and the stack, gcc expects the
    255 ;; callee to allocate space on the stack that can contain the register-based
    256 ;; part of the argument.  This space *has* to be just before the remaining
    257 ;; arguments (ie the ones that are fully on the stack).
    258 ;;
    259 ;; The problem is that the MSP430 CALL instruction pushes the return address
    260 ;; onto the stack in the exact place where the callee wants to allocate
    261 ;; this extra space.  So we need a sequence of instructions that can allocate
    262 ;; the extra space and then move the return address down the stack, so that
    263 ;; the extra space is now adjacent to the remaining arguments.
    264 ;;
    265 ;; This could be constructed through regular insns, but they might be split up
    266 ;; by a misguided optimization, so an unspec volatile is used instead.
    267 
    268 (define_insn "grow_and_swap"
    269   [(unspec_volatile [(const_int 0)] UNS_GROW_AND_SWAP)]
    270   ""
    271   "*
    272     if (TARGET_LARGE)
    273       return \"SUBA\t#2, r1 { MOVX.A\t2(r1), 0(r1)\";
    274     return \"SUB\t#2, r1 { MOV.W\t2(r1), 0(r1)\";
    275   "
    276   [(set (attr "length")
    277 	(if_then_else (match_test "TARGET_LARGE")
    278 		      (const_int 8)
    279 		      (const_int 6)))]
    280 )
    281 
    282 (define_insn "swap_and_shrink"
    283   [(unspec_volatile [(const_int 0)] UNS_SWAP_AND_SHRINK)]
    284   ""
    285   "* return TARGET_LARGE
    286 	   ? \"MOVX.A\t0(r1), 2(r1) { ADDA\t#2, SP\"
    287 	   : \"MOV.W\t0(r1), 2(r1) { ADD\t#2, SP\";
    288   "
    289   [(set (attr "length")
    290 	(if_then_else (match_test "TARGET_LARGE")
    291 		      (const_int 10)
    292 		      (const_int 8)))]
    293 )
    294 
    295 ; I set LOAD_EXTEND_OP and WORD_REGISTER_OPERATIONS, but gcc puts in a
    296 ; zero_extend anyway.  Catch it here.
    297 (define_insn "movqihi"
    298   [(set (match_operand:HI                 0 "register_operand" "=r,r")
    299 	(zero_extend:HI (match_operand:QI 1 "memory_operand" "Ys,m")))]
    300   ""
    301   "@
    302    MOV.B\t%1, %0
    303    MOV%X1.B\t%1, %0"
    304   [(set_attr "type" "double")]
    305 )
    306 
    307 (define_insn "movqi_topbyte"
    308   [(set (match_operand:QI 0 "msp430_general_dst_operand" "=r")
    309 	(subreg:QI (match_operand:PSI 1 "msp430_general_operand" "r") 2))]
    310   "msp430x"
    311   "PUSHM.A\t#1,%1 { POPM.W\t#1,%0 { POPM.W\t#1,%0"
    312   [(set_attr "length" "6")
    313    (set_attr "type" "double")]
    314 )
    315 
    316 (define_insn "movqi"
    317   [(set (match_operand:QI 0 "msp430_general_dst_operand" "=rYsYx,rm")
    318 	(match_operand:QI 1 "msp430_general_operand" "riYsYx,rmi"))]
    319   ""
    320   "@
    321   MOV.B\t%1, %0
    322   MOVX.B\t%1, %0"
    323   [(set_attr "type" "double")]
    324 )
    325 
    326 (define_insn "movhi"
    327   [(set (match_operand:HI 0 "msp430_general_dst_operand" "=r,rYsYx,rm")
    328 	(match_operand:HI 1 "msp430_general_operand" "N,riYsYx,rmi"))]
    329   ""
    330   "@
    331   MOV.B\t%1, %0
    332   MOV.W\t%1, %0
    333   MOVX.W\t%1, %0"
    334   [(set_attr "type" "double")]
    335 )
    336 
    337 (define_expand "movsi"
    338   [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand")
    339 	(match_operand:SI 1 "general_operand"))]
    340   ""
    341   ""
    342 )
    343 
    344 (define_insn_and_split "movsi_s"
    345   [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=rm")
    346 	(subreg:SI (match_operand:PSI 1 "msp430_symbol_operand" "i") 0))]
    347   ""
    348   ""
    349   "reload_completed"
    350   [(set (match_operand:HI 2 "msp430_general_dst_nonv_operand")
    351 	(match_operand:HI 4 "general_operand"))
    352    (set (match_operand:HI 3 "msp430_general_dst_nonv_operand")
    353 	(match_operand:HI 5 "general_operand"))]
    354   "msp430_split_movsi (operands);"
    355   [(set_attr "type" "double")]
    356 )
    357 
    358 (define_insn_and_split "movsi_x"
    359   [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=rm")
    360 	(match_operand:SI 1 "general_operand" "rmi"))]
    361   ""
    362   "#"
    363   "reload_completed"
    364   [(set (match_operand:HI 2 "msp430_general_dst_nonv_operand")
    365 	(match_operand:HI 4 "general_operand"))
    366    (set (match_operand:HI 3 "msp430_general_dst_nonv_operand")
    367 	(match_operand:HI 5 "general_operand"))]
    368   "msp430_split_movsi (operands);"
    369   [(set_attr "type" "double")]
    370 )
    371 
    372 ;; FIXME: Some MOVX.A cases can be done with MOVA, this is only a few of them.
    373 (define_insn "movpsi"
    374   [(set (match_operand:PSI 0 "msp430_general_dst_operand" "=r,r,r,Ya,rm")
    375 	(match_operand:PSI 1 "msp430_general_operand" "N,O,riYa,r,rmi"))]
    376   ""
    377   "@
    378   MOV.B\t%1, %0
    379   MOV.W\t%1, %0
    380   MOVA\t%1, %0
    381   MOVA\t%1, %0
    382   MOVX.A\t%1, %0"
    383   [(set_attr "extension" "none,none,a,a,x")
    384    (set_attr "type" "double")]
    385 )
    386 
    387 ; This pattern is identical to the truncsipsi2 pattern except
    388 ; that it uses a SUBREG instead of a TRUNC.  It is needed in
    389 ; order to prevent reload from converting (set:SI (SUBREG:PSI (SI)))
    390 ; into (SET:PSI (PSI)).
    391 ;
    392 ; Note: using POPM.A #1 is two bytes smaller than using POPX.A....
    393 
    394 (define_insn "movsipsi2"
    395   [(set (match_operand:PSI            0 "register_operand" "=r")
    396 	(subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
    397   "msp430x"
    398   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0"
    399   [(set_attr "length" "6")
    400    (set_attr "type" "double")]
    401 )
    402 
    403 ;; Produced when converting a pointer to an integer via a union, eg gcc.dg/pr47201.c.
    404 (define_insn "*movpsihi2_lo"
    405   [(set (match_operand:HI             0 "register_operand" "=r")
    406 	(subreg:HI (match_operand:PSI 1 "msp430_symbol_operand" "i") 0))]
    407   "msp430x"
    408   "MOVA\t%1, %0"
    409   [(set_attr "extension" "a")
    410    (set_attr "type" "double")]
    411 )
    412 
    413 ;;------------------------------------------------------------
    414 ;; Math
    415 
    416 (define_insn "addpsi3"
    417   [(set (match_operand:PSI	     0 "msp430_general_dst_operand" "=r,rm")
    418 	(plus:PSI (match_operand:PSI 1 "msp430_general_operand" "%0,0")
    419 		  (match_operand:PSI 2 "msp430_general_operand"      "rLs,rmi")))]
    420   ""
    421   "@
    422   ADDA\t%2, %0
    423   ADDX.A\t%2, %0"
    424   [(set_attr "extension" "a,x")
    425    (set_attr "type" "triple")]
    426 )
    427 
    428 (define_insn "addqi3"
    429   [(set (match_operand:QI	   0 "msp430_general_dst_operand" "=rYsYx,rm")
    430 	(plus:QI (match_operand:QI 1 "msp430_general_operand" "%0,0")
    431 		 (match_operand:QI 2 "msp430_general_operand"      "riYsYx,rmi")))]
    432   ""
    433   "@
    434    ADD.B\t%2, %0
    435    ADDX.B\t%2, %0"
    436   [(set_attr "type" "triple")]
    437 )
    438 
    439 (define_insn "addhi3"
    440   [(set (match_operand:HI	    0 "msp430_general_dst_operand" "=rYsYx,rm")
    441 	(plus:HI (match_operand:HI  1 "msp430_general_operand" "%0,0")
    442 		  (match_operand:HI 2 "msp430_general_operand"      "riYsYx,rmi")))]
    443   ""
    444   "@
    445    ADD.W\t%2, %0
    446    ADDX.W\t%2, %0"
    447   [(set_attr "type" "triple")]
    448 )
    449 
    450 ; This pattern is needed in order to avoid reload problems.
    451 ; It takes an SI pair of registers, adds a value to them, and
    452 ; then converts them into a single PSI register.
    453 
    454 (define_insn "addsipsi3"
    455   [(set (subreg:SI (match_operand:PSI 0 "register_operand" "=&r") 0)
    456 	(plus:SI (match_operand:SI    1 "register_operand" "0")
    457 		 (match_operand       2 "general_operand" "rmi")))]
    458   ""
    459   "ADD%X2.W\t%L2, %L0 { ADDC%X2.W\t%H2, %H0 { PUSH.W\t%H0 { PUSH.W\t%L0 { POPM.A\t#1, %0"
    460   [(set (attr "length")
    461 	(if_then_else (match_operand 2 "register_operand" "")
    462 		      (const_int 10)
    463 		      (if_then_else (match_operand 2 "msp430_high_memory_operand" "")
    464 				    (const_int 18)
    465 				    (const_int 14))))
    466    (set_attr "type" "triple")]
    467 )
    468 
    469 (define_insn "addsi3"
    470   [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=&rYsYx,rm")
    471 	(plus:SI (match_operand:SI 1 "general_operand" "%0,0")
    472 		 (match_operand:SI 2 "general_operand" "rYsYxi,mi")))]
    473   ""
    474   "@
    475    ADD\t%L2, %L0 { ADDC\t%H2, %H0
    476    ADDX\t%L2, %L0 { ADDCX\t%H2, %H0"
    477   [(set_attr "length_multiplier" "2")
    478    (set_attr "type" "triple")]
    479 )
    480 
    481 ; Version of addhi that exposes the carry operations, for SImode adds.
    482 ;
    483 ; NOTE - we are playing a dangerous game with GCC here.  We have these two
    484 ; add patterns and the splitter that follows because our tests have shown
    485 ; that this results in a significant reduction in code size - because GCC is
    486 ; able to discard any unused part of the addition.  We have to annotate the
    487 ; patterns with the set and use of the carry flag because otherwise GCC will
    488 ; discard parts of the addition when they are actually needed.  But we have
    489 ; not annotated all the other patterns that set the CARRY flag as doing so
    490 ; results in an overall increase in code size[1].  Instead we just *hope*
    491 ; that GCC will not move a carry-setting instruction in between the first
    492 ; and second adds.
    493 ;
    494 ; So far our experiments have shown that GCC is likely to move MOV and CMP
    495 ; instructions in between the two adds, but not other instructions.  MOV is
    496 ; safe, CMP is not.  So we have annotated the CMP patterns and left the
    497 ; subtract, shift and other add patterns alone.  At the moment this is
    498 ; working, but with future changes to the generic parts of GCC that might
    499 ; change.
    500 ;
    501 ; [1] It is not clear exactly why the code size increases.  The cause appears
    502 ; to be that reload is more prevelent to spilling a variable onto the stack
    503 ; but why it does this is unknown.  Possibly the additional CLOBBERs necessary
    504 ; to correctly annotate the other patterns makes reload think that there is
    505 ; increased register pressure.  Or possibly reload does not handle ADD patterns
    506 ; that are not single_set() very well.
    507 
    508 ; match_operand 3 is likely to be the same as op2 most of the time - except
    509 ; when op2 is a post_inc and we have stripped the post_inc from match_operand 3
    510 
    511 (define_insn "addhi3_cy"
    512   [(set (match_operand:HI	   0 "msp430_general_dst_operand" "=rYsYx,rm")
    513 	(plus:HI (match_operand:HI 1 "msp430_general_operand" "%0,0")
    514 		 (match_operand:HI 2 "msp430_nonimmediate_operand" "rYsYxi,rm")))
    515    (set (reg:BI CARRY)
    516 	(truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
    517 					   (zero_extend:SI (match_operand:HI 3 "msp430_nonimmediate_operand" "rYsYxi,rm")))
    518 				  (const_int 16))))
    519    ]
    520   ""
    521   "@
    522    ADD\t%2, %1 ; cy
    523    ADDX\t%2, %1 ; cy"
    524   [(set_attr "type" "triple")]
    525 )
    526 
    527 (define_insn "addhi3_cy_i"
    528   [(set (match_operand:HI	   0 "msp430_general_dst_nonv_operand" "=r,rm")
    529 	(plus:HI (match_operand:HI 1 "general_operand" "%0,0")
    530 		 (match_operand:HI 2 "immediate_operand"     "i,i")))
    531    (set (reg:BI CARRY)
    532 	(truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
    533 					   (match_operand 3 "immediate_operand" "i,i"))
    534 				  (const_int 16))))
    535    ]
    536   ""
    537   "@
    538    ADD\t%2, %1 ; cy
    539    ADD%X0\t%2, %1 ; cy"
    540   [(set_attr "type" "triple")]
    541 )
    542 
    543 ; Version of addhi that adds the carry, for SImode adds.
    544 (define_insn "addchi4_cy"
    545   [(set (match_operand:HI		    0 "msp430_general_dst_operand" "=rYsYx,rm")
    546 	(plus:HI (plus:HI (match_operand:HI 1 "msp430_general_operand" "%0,0")
    547 			  (match_operand:HI 2 "msp430_general_operand"      "riYsYx,rmi"))
    548 		 (zero_extend:HI (reg:BI CARRY))))
    549    ]
    550   ""
    551   "@
    552    ADDC\t%2, %1
    553    ADDCX\t%2, %1"
    554   [(set_attr "type" "triple")]
    555 )
    556 
    557 ; Split an SImode add into two HImode adds, keeping track of the carry
    558 ; so that gcc knows when it can and can't optimize away the two
    559 ; halves.
    560 ; We use the ugly predicate "msp430_nonsubregnonpostinc_or_imm_operand" to
    561 ; enforce the position of a post_inc into op2 if present
    562 (define_split
    563   [(set (match_operand:SI	   0 "msp430_nonsubreg_dst_operand")
    564 	(plus:SI (match_operand:SI 1 "msp430_nonsubregnonpostinc_or_imm_operand")
    565 		 (match_operand:SI 2 "msp430_nonsubreg_or_imm_operand")))
    566    ]
    567   ""
    568   [(parallel [(set (match_operand:HI 3 "msp430_general_dst_nonv_operand" "=&rm")
    569 		   (plus:HI (match_dup 4)
    570 			    (match_dup 5)))
    571 	      (set (reg:BI CARRY)
    572 		   (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 4))
    573 						      (match_dup 9))
    574 					     (const_int 16))))
    575 	      ])
    576    (set (match_operand:HI 6 "msp430_general_dst_nonv_operand" "=&rm")
    577 	(plus:HI (plus:HI (match_dup 7)
    578 			  (match_dup 8))
    579 		 (zero_extend:HI (reg:BI CARRY))))
    580    ]
    581   "
    582   if (msp430_split_addsi (operands))
    583     FAIL;
    584   "
    585 )
    586 
    587 
    588 ;; Alternatives 2 and 3 are to handle cases generated by reload.
    589 (define_insn "subpsi3"
    590   [(set (match_operand:PSI	      0 "msp430_general_dst_nonv_operand"	"=r,   rm, &?r, ?&r")
    591 	(minus:PSI (match_operand:PSI 1 "general_operand"			"0,   0,   !r,  !i")
    592 		   (match_operand:PSI 2 "general_operand"			"rLs, rmi, rmi,  r")))]
    593   ""
    594   "@
    595   SUBA\t%2, %0
    596   SUBX.A\t%2, %0
    597   MOVX.A\t%1, %0 { SUBX.A\t%2, %0
    598   MOVX.A\t%1, %0 { SUBA\t%2, %0"
    599   [(set_attr "type" "triple")
    600    (set_attr "extension" "a,x,x,x")
    601    (set_attr "length_multiplier" "1,1,2,2")]
    602 )
    603 
    604 ;; Alternatives 2 and 3 are to handle cases generated by reload.
    605 (define_insn "subqi3"
    606   [(set (match_operand:QI	    0 "msp430_general_dst_nonv_operand" "=rYsYx,  rm,  &?r, ?&r")
    607 	(minus:QI (match_operand:QI 1 "general_operand"       "0,    0,    !r,  !i")
    608 		  (match_operand:QI 2 "general_operand"      " riYsYx, rmi, rmi,   r")))]
    609   ""
    610   "@
    611   SUB.B\t%2, %0
    612   SUBX.B\t%2, %0
    613   MOV%X2.B\t%1, %0 { SUB%X2.B\t%2, %0
    614   MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0"
    615   [(set_attr "length_multiplier" "1,1,2,2")
    616    (set_attr "type" "triple")]
    617 )
    618 
    619 ;; Alternatives 2 and 3 are to handle cases generated by reload.
    620 (define_insn "subhi3"
    621   [(set (match_operand:HI	    0 "msp430_general_dst_nonv_operand" "=rYsYx,  rm,  &?r, ?&r")
    622 	(minus:HI (match_operand:HI 1 "general_operand"       "0,    0,    !r,  !i")
    623 		  (match_operand:HI 2 "general_operand"      " riYsYx, rmi, rmi,   r")))]
    624   ""
    625   "@
    626   SUB.W\t%2, %0
    627   SUBX.W\t%2, %0
    628   MOV%X2.W\t%1, %0 { SUB%X2.W\t%2, %0
    629   MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0"
    630   [(set_attr "length_multiplier" "1,1,2,2")
    631    (set_attr "type" "triple")]
    632 )
    633 
    634 (define_insn "subsi3"
    635   [(set (match_operand:SI	    0 "msp430_general_dst_nonv_operand" "=&rYsYx,m")
    636 	(minus:SI (match_operand:SI 1 "general_operand"   "0,0")
    637 		  (match_operand:SI 2 "general_operand"        "riYsYx,mi")))]
    638   ""
    639   "@
    640   SUB\t%L2, %L0 { SUBC\t%H2, %H0
    641   SUBX\t%L2, %L0 { SUBCX\t%H2, %H0"
    642   [(set_attr "length_multiplier" "2")
    643    (set_attr "type" "triple")]
    644 )
    645 
    646 (define_insn "*bic<mode>_cg"
    647   [(set (match_operand:QHI 0 "msp430_general_dst_operand" "=rYs,m")
    648 	(and:QHI (match_operand:QHI 1 "msp430_general_operand" "0,0")
    649 		 (match_operand 2 "msp430_inv_constgen_operator" "n,n")))]
    650   ""
    651   "@
    652    BIC%x0%b0\t#%I2, %0
    653    BIC%X0%b0\t#%I2, %0"
    654   [(set_attr "length" "2")	; Smaller length achieved by using constant generator
    655    (set_attr "type" "double")]
    656 )
    657 
    658 (define_insn "bic<mode>3"
    659   [(set (match_operand:QHI		     0 "msp430_general_dst_operand" "=rYsYx,rm")
    660 	(and:QHI (not:QHI (match_operand:QHI 1 "msp430_general_operand"       "rYsYx,rmn"))
    661 		 (match_operand:QHI	     2 "msp430_general_operand"  "0,0")))]
    662   ""
    663   "@
    664    BIC%x0%b0\t%1, %0
    665    BICX%b0\t%1, %0"
    666   [(set_attr "type" "double")]
    667 )
    668 
    669 (define_insn "and<mode>3"
    670   [(set (match_operand:QHI 0 "msp430_general_dst_operand" "=r,rYsYx,rm")
    671 	(and:QHI (match_operand:QHI 1 "msp430_general_operand" "%0,0,0")
    672 		 (match_operand:QHI 2 "msp430_general_operand" "N,riYsYx,rmi")))]
    673   ""
    674   "@
    675    AND%x0.B\t%2, %0
    676    AND%x0%b0\t%2, %0
    677    ANDX%b0\t%2, %0"
    678   [(set_attr "type" "triple")]
    679 )
    680 
    681 (define_insn "ior<mode>3"
    682   [(set (match_operand:QHI	    0 "msp430_general_dst_operand" "=rYsYx,rm")
    683 	(ior:QHI (match_operand:QHI 1 "msp430_general_operand" "%0,0")
    684 		 (match_operand:QHI 2 "msp430_general_operand" "riYsYx,rmi")))]
    685   ""
    686   "@
    687    BIS%x0%b0\t%2, %0
    688    BISX%b0\t%2, %0"
    689   [(set_attr "type" "triple")]
    690 )
    691 
    692 (define_insn "xor<mode>3"
    693   [(set (match_operand:QHI	    0 "msp430_general_dst_operand" "=rYsYx,rm")
    694 	(xor:QHI (match_operand:QHI 1 "msp430_general_operand" "%0,0")
    695 		 (match_operand:QHI 2 "msp430_general_operand" "riYsYx,rmi")))]
    696   ""
    697   "@
    698    XOR%x0%b0\t%2, %0
    699    XORX%b0\t%2, %0"
    700   [(set_attr "type" "triple")]
    701 )
    702 
    703 ;; Macro : XOR #~0, %0
    704 (define_insn "one_cmpl<mode>2"
    705   [(set (match_operand:QHI	    0 "msp430_general_dst_operand" "=rYs,m")
    706 	(not:QHI (match_operand:QHI 1 "msp430_general_operand" "0,0")))]
    707   ""
    708   "@
    709    INV%x0%b0\t%0
    710    INV%X0%b0\t%0"
    711   [(set_attr "type" "double")]
    712 )
    713 
    714 (define_insn "extendqihi2"
    715   [(set (match_operand:HI		  0 "msp430_general_dst_operand" "=rYs,m")
    716 	(sign_extend:HI (match_operand:QI 1 "msp430_general_operand" "0,0")))]
    717   ""
    718   "@
    719    SXT%X0\t%0
    720    SXT%X0\t%0"
    721   [(set_attr "type" "single")]
    722 )
    723 
    724 (define_insn "extendqipsi2"
    725   [(set (match_operand:PSI		   0 "msp430_general_dst_operand" "=r,m")
    726 	(sign_extend:PSI (match_operand:QI 1 "msp430_general_operand" "0,0")))]
    727   ""
    728   "@
    729   SXT\t%0
    730   SXTX.A\t%0"
    731   [(set_attr "type" "single")
    732    (set_attr "extension" "none,x")]
    733 )
    734 
    735 ;; ------------------------
    736 ;; ZERO EXTEND INSTRUCTIONS
    737 ;; Byte-writes to registers clear bits 19:8
    738 ;;   * Byte-writes to memory do not affect bits 15:8
    739 ;; Word-writes to registers clear bits 19:16
    740 ;; PSImode writes to memory clear bits 15:4 of the second memory word
    741 ;; We define all possible insns since that results in better code than if
    742 ;; they are inferred.
    743 ;; ------------------------
    744 
    745 (define_insn "zero_extendqihi2"
    746   [(set (match_operand:HI		  0 "msp430_general_dst_operand" "=rYs,r,r,m")
    747 	(zero_extend:HI (match_operand:QI 1 "msp430_general_operand" "0,rYs,m,0")))]
    748   ""
    749   "@
    750    AND\t#0xff, %0
    751    MOV.B\t%1, %0
    752    MOV%X1.B\t%1, %0
    753    AND%X0\t#0xff, %0"
    754   [(set_attr "type" "double")]
    755 )
    756 
    757 (define_insn "zero_extendqipsi2"
    758   [(set (match_operand:PSI		   0 "register_operand" "=r,r")
    759 	(zero_extend:PSI (match_operand:QI 1 "general_operand" "rYs,m")))]
    760   "msp430x"
    761   "@
    762    MOV.B\t%1, %0
    763    MOV%X1.B\t%1, %0"
    764   [(set_attr "type" "double")]
    765 )
    766 
    767 (define_insn "zero_extendqisi2"
    768   [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=r,r")
    769 	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,rm")))]
    770   ""
    771   "@
    772   CLR\t%H0
    773   MOV%X1.B\t%1,%L0 { CLR\t%H0"
    774   [(set_attr "extra_length" "2")
    775    (set_attr "length_multiplier" "1,2")
    776    (set_attr "type" "double")]
    777 )
    778 
    779 (define_insn "zero_extendhipsi2"
    780   [(set (match_operand:PSI		   0 "msp430_general_dst_operand" "=r,r,m")
    781 	(zero_extend:PSI (match_operand:HI 1 "msp430_general_operand"     "rYs,m,r")))]
    782   "msp430x"
    783   "@
    784   MOV.W\t%1, %0
    785   MOV%X1\t%1, %0
    786   MOVX.A\t%1, %0"
    787   [(set_attr "type" "double")]
    788 )
    789 
    790 (define_insn "zero_extendhisi2"
    791   [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=rm,r")
    792 	(zero_extend:SI (match_operand:HI 1 "general_operand" "0,r")))]
    793   ""
    794   "@
    795   MOV%X0.W\t#0,%H0
    796   MOV.W\t%1,%L0 { MOV.W\t#0,%H0"
    797   [(set_attr "length_multiplier" "1,2")
    798    (set_attr "type" "double")]
    799 )
    800 
    801 (define_insn "zero_extendhisipsi2"
    802   [(set (match_operand:PSI 0 "msp430_general_dst_nonv_operand" "=r,r")
    803 	(subreg:PSI (zero_extend:SI (match_operand:HI 1 "general_operand" "0,r")) 0))]
    804   "msp430x"
    805   "@
    806    AND.W\t#-1,%0
    807    MOV.W\t%1,%0"
    808   [(set_attr "length" "4,2")
    809    (set_attr "type" "double")]
    810 )
    811 
    812 ; Nasty - we are sign-extending a 20-bit PSI value in one register into
    813 ; two adjacent 16-bit registers to make an SI value.  There is no MSP430X
    814 ; instruction that will do this, so we push the 20-bit value onto the stack
    815 ; and then pop it off as two 16-bit values.
    816 ;
    817 ; FIXME: The MSP430X documentation does not specify if zero-extension or
    818 ; sign-extension happens when the 20-bit value is pushed onto the stack.
    819 ; It is probably zero-extension, but if not this pattern will not work
    820 ; when the PSI value is negative..
    821 ;
    822 ; Note: using PUSHM.A #1 is two bytes smaller than using PUSHX.A....
    823 ;
    824 ; Note: We use a + constraint on operand 0 as otherwise GCC gets confused
    825 ; about extending a single PSI mode register into a pair of SImode registers
    826 ; with the same starting register.  It thinks that the upper register of
    827 ; the pair is unused and so it can clobber it.  Try compiling 20050826-2.c
    828 ; at -O2 to see this.
    829 
    830 ; FIXME we can use MOVA for r->m if m is &abs20 or z16(rdst)
    831 (define_insn "zero_extendpsisi2"
    832   [(set (match_operand:SI		   0 "register_operand" "+r,m")
    833 	(zero_extend:SI (match_operand:PSI 1 "register_operand" "r,r")))]
    834   ""
    835   "@
    836   * if (REGNO (operands[1]) == SP_REGNO) \
    837       /* If the source register is the stack pointer, the value \
    838 	 stored in the stack slot will be the value *after* the \
    839 	 stack pointer has been decremented.  So allow for that \
    840 	 here.  */ \
    841       return \"PUSHM.A\t#1, %1 { ADDX.W\t#4, @r1 { POPX.W\t%L0 { POPX.W\t%H0 ; get stack pointer into %L0:%H0\"; \
    842     else \
    843       return \"PUSHM.A\t#1, %1 { POPX.W\t%L0 { POPX.W\t%H0 ; move pointer in %1 into reg-pair %L0:%H0\";
    844   MOVX.A %1, %0"
    845   [(set (attr "length")
    846     (cond [(match_test "REGNO (operands[1]) == SP_REGNO")
    847 	   (const_int 18)
    848 	   (eq_attr "alternative" "1")
    849 	   (const_int 6)]
    850 	   (const_int 10)))
    851    (set_attr "type" "double")]
    852 )
    853 
    854 ;; Below are unnamed insn patterns to catch pointer manipulation insns
    855 ;; generated by combine.
    856 ;; We get large code size bloat when a PSImode pointer is stored in
    857 ;; memory, so we try to avoid that where possible and keep point manipulation
    858 ;; between registers.
    859 ; FIXME many of these should be unnnecessary once combine deals with
    860 ; (sign_extend (zero_extend)) or (sign_extend (subreg)) BZ 91865.
    861 
    862 ;; This is just another way of writing movqipsi/zero_extendqipsi
    863 (define_insn ""
    864   [(set (match_operand:PSI 0 "register_operand" "=r")
    865 	(sign_extend:PSI (subreg:HI (match_operand:QI 1 "general_operand" "rm") 0)))]
    866   "msp430x"
    867   "MOV%X1.B\t%1, %0"
    868   [(set_attr "type" "double")]
    869 )
    870 
    871 (define_insn ""
    872   [(set (match_operand:PSI				   0 "register_operand" "=r,r")
    873 	(sign_extend:PSI (zero_extend:HI (match_operand:QI 1 "general_operand" "rYs,m"))))]
    874   "msp430x"
    875   "@
    876    MOV.B\t%1, %0
    877    MOV%X1.B\t%1, %0"
    878   [(set_attr "type" "double")]
    879 )
    880 
    881 ;; The next three insns emit identical assembly code.
    882 ;; They take a QImode and shift it in SImode.  Only shift counts <= 8
    883 ;; are handled since that is the simple case where the high 16-bits (i.e. the
    884 ;; high register) are always 0.
    885 (define_insn ""
    886   [(set (match_operand:SI			     0 "register_operand" "=r,r,r")
    887 	(ashift:SI (zero_extend:SI (match_operand:QI 1 "general_operand" "0,rm,rm"))
    888 		   (match_operand:HI		     2 "const_1_to_8_operand" "M,M,i")))]
    889   "msp430x"
    890   "@
    891   RLAM.W %2, %L0 { CLR %H0
    892   MOV%X1.B %1, %L0 { RLAM.W %2, %L0 { CLR %H0
    893   MOV%X1.B %1, %L0 { RPT %2 { RLAX.W %L0 { CLR %H0"
    894   [(set_attr "length" "4,*,*")
    895    (set_attr "extra_length" "0,4,6")
    896    (set_attr "type" "double")]
    897 )
    898 
    899 (define_insn ""
    900   [(set (match_operand:SI			     		0 "register_operand" "=r,r,r")
    901 	(ashift:SI (zero_extend:SI (subreg:HI (match_operand:QI 1 "general_operand" "0,rm,rm") 0))
    902 		   (match_operand:HI		     		2 "const_1_to_8_operand" "M,M,i")))]
    903   "msp430x"
    904   "@
    905   RLAM.W %2, %L0 { CLR %H0
    906   MOV%X1.B %1, %L0 { RLAM.W %2, %L0 { CLR %H0
    907   MOV%X1.B %1, %L0 { RPT %2 { RLAX.W %L0 { CLR %H0"
    908   [(set_attr "length" "4,*,*")
    909    (set_attr "extra_length" "0,4,6")
    910    (set_attr "type" "double")]
    911 )
    912 
    913 ;; Same as above but with a NOP sign_extend round the subreg
    914 (define_insn ""
    915   [(set (match_operand:SI			     				 0 "register_operand" "=r,r,r")
    916 	(ashift:SI (zero_extend:SI (sign_extend:PSI (subreg:HI (match_operand:QI 1 "general_operand" "0,rm,rm") 0)))
    917 		   (match_operand:HI		     				 2 "const_1_to_8_operand" "M,M,i")))]
    918   "msp430x"
    919   "@
    920   RLAM.W %2, %L0 { CLR %H0
    921   MOV%X1.B %1, %L0 { RLAM.W %2, %L0 { CLR %H0
    922   MOV%X1.B %1, %L0 { RPT %2 { RLAX.W %L0 { CLR %H0"
    923   [(set_attr "length" "4,*,*")
    924    (set_attr "extra_length" "0,4,6")
    925    (set_attr "type" "double")]
    926 )
    927 
    928 (define_insn ""
    929   [(set (match_operand:SI 0 "register_operand" "=r")
    930 	(zero_extend:SI (sign_extend:PSI (subreg:HI (match_operand:QI 1 "general_operand" "rm") 0))))]
    931   "msp430x"
    932   "MOV%X1.B %1, %L0 { CLR %H0"
    933   [(set_attr "extra_length" "4")
    934    (set_attr "type" "double")]
    935 )
    936 
    937 (define_insn ""
    938   [(set (match_operand:PSI					  0 "register_operand" "=r,r,r")
    939 	(ashift:PSI (sign_extend:PSI (subreg:HI (match_operand:QI 1 "general_operand" "0,rm,rm") 0))
    940 		    (match_operand:HI				  2 "const_1_to_19_operand" "M,M,i")))]
    941   "msp430x"
    942   "@
    943   RLAM.W %2, %0
    944   MOV%X1.B %1, %0 { RLAM.W %2, %0
    945   MOV%X1.B %1, %0 { RPT %2 { RLAX.A %0"
    946   [(set_attr "length" "2,*,*")
    947    (set_attr "extra_length" "0,2,4")
    948    (set_attr "type" "double")]
    949 )
    950 ;; END msp430 pointer manipulation combine insn patterns
    951 
    952 ;; Eliminate extraneous zero-extends mysteriously created by gcc.
    953 (define_peephole2
    954   [(set (match_operand:HI 0 "register_operand")
    955 	(zero_extend:HI (match_operand:QI 1 "general_operand")))
    956    (set (match_operand:HI 2 "register_operand")
    957 	(zero_extend:HI (match_operand:QI 3 "register_operand")))]
    958   "REGNO (operands[0]) == REGNO (operands[2]) && REGNO (operands[2]) == REGNO (operands[3])"
    959   [(set (match_dup 0)
    960 	(zero_extend:HI (match_dup 1)))]
    961 )
    962 
    963 (define_insn "truncpsihi2"
    964   [(set (match_operand:HI		0 "msp430_general_dst_operand" "=rm")
    965 	(truncate:HI (match_operand:PSI 1 "register_operand"      "r")))]
    966   ""
    967   "MOVX\t%1, %0"
    968   [(set_attr "extension" "m")
    969    (set_attr "type" "double")]
    970 )
    971 
    972 (define_insn "extendhisi2"
    973   [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=r")
    974 	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
    975   ""
    976   { msp430x_extendhisi (operands, 0); return ""; }
    977   [(set (attr "length")
    978 	(symbol_ref "msp430x_extendhisi (operands, 1)"))
    979    (set_attr "type" "double")]
    980 )
    981 
    982 (define_insn "extendhipsi2"
    983   [(set (match_operand:PSI 0 "msp430_general_dst_nonv_operand" "=r")
    984 	(subreg:PSI (sign_extend:SI (match_operand:HI 1 "general_operand" "0")) 0))]
    985   "msp430x"
    986   "RLAM.A #4, %0 { RRAM.A #4, %0"
    987   [(set_attr "length_multiplier" "2")
    988    (set_attr "extension" "m")
    989    (set_attr "type" "double")]
    990 )
    991 
    992 ;; Look for cases where integer/pointer conversions are suboptimal due
    993 ;; to missing patterns, despite us not having opcodes for these
    994 ;; patterns.  Doing these manually allows for alternate optimization
    995 ;; paths.
    996 
    997 (define_insn "extend_and_shift1_hipsi2"
    998   [(set (subreg:SI (match_operand:PSI 0 "msp430_general_dst_nonv_operand" "=r") 0)
    999 	(ashift:SI (sign_extend:SI (match_operand:HI 1 "general_operand" "0"))
   1000 		   (const_int 1)))]
   1001   "msp430x"
   1002   "RLAM.A #4, %0 { RRAM.A #3, %0"
   1003   [(set_attr "length_multiplier" "2")
   1004    (set_attr "extension" "m")
   1005    (set_attr "type" "double")]
   1006 )
   1007 
   1008 (define_insn "extend_and_shift2_hipsi2"
   1009   [(set (subreg:SI (match_operand:PSI 0 "msp430_general_dst_nonv_operand" "=r") 0)
   1010 	(ashift:SI (sign_extend:SI (match_operand:HI 1 "general_operand" "0"))
   1011 		   (const_int 2)))]
   1012   "msp430x"
   1013   "RLAM.A #4, %0 { RRAM.A #2, %0"
   1014   [(set_attr "length_multiplier" "2")
   1015    (set_attr "extension" "m")
   1016    (set_attr "type" "double")]
   1017 )
   1018 
   1019 ;; We also need to be able to sign-extend pointer types (eg ptrdiff_t).
   1020 ;; Since (we assume) pushing a 20-bit value onto the stack zero-extends
   1021 ;; it, we use a different method here.
   1022 
   1023 (define_insn "extendpsisi2"
   1024   [(set (match_operand:SI                  0 "register_operand" "=r")
   1025 	(sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
   1026   "msp430x"
   1027   "*
   1028     /* The intention here is that we copy the bottom 16-bits of
   1029        %1 into %L0 (zeroing the top four bits).  Then we copy the
   1030        entire 20-bits of %1 into %H0 and then arithmetically shift
   1031        it right by 16 bits, to get the top four bits of the pointer
   1032        sign-extended in %H0.  */
   1033     if (REGNO (operands[0]) == REGNO (operands[1]))
   1034       return \"MOVX.A\t%1, %H0 { MOV.W\t%1, %L0 { RPT\t#16 { RRAX.A\t%H0 ; sign extend pointer in %1 into %L0:%H0\";
   1035     else
   1036       return \"MOV.W\t%1, %L0 { MOVX.A\t%1, %H0 { RPT\t#16 { RRAX.A\t%H0 ; sign extend pointer in %1 into %L0:%H0\";
   1037   "
   1038   [(set_attr "length" "10")
   1039    (set_attr "type" "double")]
   1040 )
   1041 
   1042 ; See the movsipsi2 pattern above for another way that GCC performs this
   1043 ; conversion.
   1044 (define_insn "truncsipsi2"
   1045   [(set (match_operand:PSI              0 "register_operand" "=r")
   1046 	(truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
   1047   ""
   1048   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A\t#1, %L0"
   1049   [(set_attr "length" "6")
   1050    (set_attr "type" "single")]
   1051 )
   1052 
   1053 ;;------------------------------------------------------------
   1054 ;; Shift Functions
   1055 
   1056 ;; Note:  We do not use the RPT ... SHIFT instruction sequence
   1057 ;; when the repeat count is in a register, because even though RPT
   1058 ;; accepts counts in registers, it does not work if the count is
   1059 ;; zero, and the actual count in the register has to be one less
   1060 ;; than the required number of iterations.  We could encode a
   1061 ;; seqeunce like this:
   1062 ;;
   1063 ;;   bit #0xf, Rn
   1064 ;;   bz  1f
   1065 ;;   dec Rn
   1066 ;;   rpt Rn
   1067 ;;   <shift> Rm
   1068 ;;   inc Rn
   1069 ;; 1:
   1070 ;;
   1071 ;; But is longer than calling a helper function, and we are mostly
   1072 ;; concerned with code size.  FIXME: Maybe enable a sequence like
   1073 ;; this at -O3 and above ?
   1074 ;;
   1075 ;; Note - we ignore shift counts of less than one or more than 15.
   1076 ;; This is permitted by the ISO C99 standard as such shifts result
   1077 ;; in "undefined" behavior.  [6.5.7 (3)]
   1078 ;;
   1079 ;; We avoid emitting insns in msp430_expand_shift, since we would have to handle
   1080 ;; many extra cases such as op0 != op1, or, op0 or op1 in memory.  Instead we
   1081 ;; let reload coerce op0 and op1 into the same register.
   1082 
   1083 (define_expand "<shift_insn><mode>3"
   1084   [(set (match_operand:HDI		  0 "msp430_general_dst_nonv_operand")
   1085 	(any_shift:HDI (match_operand:HDI 1 "general_operand")
   1086 		       (match_operand:HDI 2 "general_operand")))]
   1087   ""
   1088   {
   1089     if (msp430_expand_shift (<CODE>, <MODE>mode, operands))
   1090       DONE;
   1091     /* Otherwise, fallthrough.  */
   1092   }
   1093 )
   1094 
   1095 ;; All 430 HImode constant shifts
   1096 (define_insn "<shift_insn>hi3_430"
   1097   [(set (match_operand:HI		0 "msp430_general_dst_nonv_operand" "=rm")
   1098 	(any_shift:HI (match_operand:HI 1 "general_operand"       "0")
   1099 		      (match_operand:HI 2 "const_int_operand"     "n")))]
   1100   "!msp430x"
   1101   "* msp430_output_asm_shift_insns (<CODE>, HImode, operands, false); return \"\";"
   1102   [(set (attr "length")
   1103 	(symbol_ref "msp430_output_asm_shift_insns (<CODE>, HImode, operands, true)"))
   1104    (set_attr "type" "single")]
   1105 )
   1106 
   1107 ;; All 430 and 430X SImode constant shifts
   1108 (define_insn "<shift_insn>si3_const"
   1109   [(set (match_operand:SI		0 "msp430_general_dst_nonv_operand" "=rm")
   1110 	(any_shift:SI (match_operand:SI 1 "general_operand"       "0")
   1111 		      (match_operand:SI 2 "const_int_operand"     "n")))]
   1112   ""
   1113   "* msp430_output_asm_shift_insns (<CODE>, SImode, operands, false); return \"\";"
   1114   [(set (attr "length")
   1115 	(symbol_ref "msp430_output_asm_shift_insns (<CODE>, SImode, operands, true)"))
   1116    (set_attr "type" "single")]
   1117 )
   1118 
   1119 (define_insn "ashl<mode>3_430x"
   1120   [(set (match_operand:HPSI		 0 "msp430_general_dst_nonv_operand" "=r,r,r,r")
   1121 	(ashift:HPSI (match_operand:HPSI 1 "general_operand" 		     "0 ,0,0,0")
   1122 		     (match_operand:HPSI 2 "const_int_operand" 		     "M ,P,K,i")))]
   1123   "msp430x"
   1124   "@
   1125   RLAM%b0\t%2, %0
   1126   RPT\t%2 { RLAX%b0\t%0
   1127   RPT\t#16 { RLAX%b0\t%0 { RPT\t%W2 { RLAX%b0\t%0
   1128   # undefined behavior left shift of %1 by %2"
   1129   [(set_attr "length" "2,4,8,0")
   1130    (set_attr "type" "single")]
   1131 )
   1132 
   1133 (define_insn "ashr<mode>3_430x"
   1134   [(set (match_operand:HPSI		   0 "msp430_general_dst_nonv_operand" "=r,r,r,r")
   1135 	(ashiftrt:HPSI (match_operand:HPSI 1 "general_operand"	  	     "0,0,0,0")
   1136 		       (match_operand:HPSI 2 "const_int_operand" 	     "M,P,K,i")))]
   1137   "msp430x"
   1138   "@
   1139   RRAM%b0\t%2, %0
   1140   RPT\t%2 { RRAX%b0\t%0
   1141   RPT\t#16 { RRAX%b0\t%0 { RPT\t%W2 { RRAX%b0\t%0
   1142   # undefined behavior arithmetic right shift of %1 by %2"
   1143   [(set_attr "length" "2,4,8,0")
   1144    (set_attr "type" "single")]
   1145 )
   1146 
   1147 (define_insn "lshr<mode>3_430x"
   1148   [(set (match_operand:HPSI		   0 "msp430_general_dst_nonv_operand" "=r,r,r,r")
   1149 	(lshiftrt:HPSI (match_operand:HPSI 1 "general_operand"	  	     "0,0,0,0")
   1150 		       (match_operand:HPSI 2 "const_int_operand" 	     "M,P,K,i")))]
   1151   "msp430x"
   1152   "@
   1153   RRUM%b0\t%2, %0
   1154   RPT\t%2 { RRUX%b0\t%0
   1155   RPT\t#16 { RRUX%b0\t%0 { RPT\t%W2 { RRUX%b0\t%0
   1156   # undefined behavior logical right shift of %1 by %2"
   1157   [(set_attr "length" "2,4,8,0")
   1158    (set_attr "type" "single")]
   1159 )
   1160 
   1161 ;;------------------------------------------------------------
   1162 ;; Function Entry/Exit
   1163 
   1164 (define_expand "prologue"
   1165   [(const_int 0)]
   1166   ""
   1167   "msp430_expand_prologue (); DONE;"
   1168 )
   1169 
   1170 (define_expand "epilogue"
   1171   [(const_int 0)]
   1172   ""
   1173   "msp430_expand_epilogue (0); DONE;"
   1174 )
   1175 
   1176 (define_insn "epilogue_helper"
   1177   [(set (pc)
   1178 	(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER))
   1179    (return)]
   1180   "!msp430x"
   1181   "BR%Q0\t#__mspabi_func_epilog_%J0"
   1182   [(set_attr "length" "2")]
   1183 )
   1184 
   1185 (define_insn "prologue_start_marker"
   1186   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)]
   1187   ""
   1188   "; start of prologue"
   1189   [(set_attr "length" "0")]
   1190 )
   1191 
   1192 (define_insn "prologue_end_marker"
   1193   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)]
   1194   ""
   1195   "; end of prologue"
   1196   [(set_attr "length" "0")]
   1197 )
   1198 
   1199 (define_insn "epilogue_start_marker"
   1200   [(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)]
   1201   ""
   1202   "; start of epilogue"
   1203   [(set_attr "length" "0")]
   1204 )
   1205 
   1206 ;; This makes the linker add a call to exit() after the call to main()
   1207 ;; in crt0
   1208 (define_insn "msp430_refsym_need_exit"
   1209   [(unspec_volatile [(const_int 0)] UNS_REFSYM_NEED_EXIT)]
   1210   ""
   1211   ".refsym\t__crt0_call_exit"
   1212   [(set_attr "length" "0")]
   1213 )
   1214 
   1215 ;;------------------------------------------------------------
   1216 ;; Jumps
   1217 
   1218 (define_expand "call"
   1219   [(call:HI (match_operand 0 "")
   1220 	    (match_operand 1 ""))]
   1221   ""
   1222   ""
   1223 )
   1224 
   1225 (define_insn "call_internal"
   1226   [(call (mem:HI (match_operand 0 "general_operand" "rYci"))
   1227 	 (match_operand 1 ""))]
   1228   ""
   1229   "CALL%Q0\t%0"
   1230   [(set_attr "extension" "none")
   1231    (set_attr "type" "single")]
   1232 )
   1233 
   1234 (define_expand "call_value"
   1235   [(set (match_operand          0 "register_operand")
   1236 	(call:HI (match_operand 1 "general_operand")
   1237 		 (match_operand 2 "")))]
   1238   ""
   1239   ""
   1240 )
   1241 
   1242 (define_insn "call_value_internal"
   1243   [(set (match_operand               0 "register_operand" "=r")
   1244 	(call (mem:HI (match_operand 1 "general_operand" "rYci"))
   1245 	      (match_operand 2 "")))]
   1246   ""
   1247   "CALL%Q0\t%1"
   1248   [(set_attr "extension" "none")
   1249    (set_attr "type" "single")]
   1250 )
   1251 
   1252 (define_insn "msp430_return"
   1253   [(return)]
   1254   ""
   1255   { return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); }
   1256   [(set_attr "length" "2")]
   1257 )
   1258 
   1259 ;; This pattern is NOT, as expected, a return pattern.  It's called
   1260 ;; before reload and must only store its operands, and emit a
   1261 ;; placeholder where the epilog needs to be.  AFTER reload, the
   1262 ;; placeholder should get expanded into a regular-type epilogue that
   1263 ;; also does the EH return.
   1264 (define_expand "eh_return"
   1265   [(match_operand:HI 0 "")]
   1266   ""
   1267   "msp430_expand_eh_return (operands[0]);
   1268    emit_jump_insn (gen_msp430_eh_epilogue ());
   1269    emit_barrier ();
   1270    DONE;"
   1271 )
   1272 
   1273 ;; This is the actual EH epilogue.  We emit it in the pattern above,
   1274 ;; before reload, and convert it to a real epilogue after reload.
   1275 (define_insn_and_split "msp430_eh_epilogue"
   1276   [(eh_return)]
   1277   ""
   1278   "#"
   1279   "reload_completed"
   1280   [(const_int 0)]
   1281   "msp430_expand_epilogue (1); DONE;"
   1282   [(set_attr "length" "40")]
   1283 )
   1284 
   1285 (define_insn "jump"
   1286   [(set (pc)
   1287 	(label_ref (match_operand 0 "" "")))]
   1288   ""
   1289   "BR%Q0\t#%l0"
   1290   [(set_attr "length" "4")]
   1291 )
   1292 
   1293 ;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
   1294 ;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c).
   1295 (define_insn "indirect_jump"
   1296   [(set (pc)
   1297 	(match_operand 0 "nonimmediate_operand" "rYl"))]
   1298   ""
   1299   "BR%Q0\t%0"
   1300   [(set (attr "length")
   1301 	(if_then_else (match_operand 0 "register_operand" "")
   1302 		      (const_int 2)
   1303 		      (const_int 4)))]
   1304 )
   1305 
   1306 ;;------------------------------------------------------------
   1307 ;; Various Conditionals
   1308 
   1309 (define_expand "cbranch<mode>4"
   1310   [(parallel [(set (pc) (if_then_else
   1311 			 (match_operator 0 ""
   1312 					 [(match_operand:QHI 1 "msp430_general_dst_nonv_operand")
   1313 					  (match_operand:QHI 2 "general_operand")])
   1314 			 (label_ref (match_operand 3 "" ""))
   1315 			 (pc)))
   1316 	      (clobber (reg:BI CARRY))]
   1317   )]
   1318   ""
   1319   "msp430_fixup_compare_operands (<MODE>mode, operands);"
   1320 )
   1321 
   1322 (define_insn "cbranchpsi4_real"
   1323   [(set (pc) (if_then_else
   1324 	      (match_operator                     0 "msp430_cmp_operator"
   1325 			      [(match_operand:PSI 1 "msp430_general_dst_nonv_operand" "r,rYs,rm")
   1326 			       (match_operand:PSI 2 "general_operand"      "rLs,rYsi,rmi")])
   1327 	      (label_ref (match_operand		  3 "" ""))
   1328 	      (pc)))
   1329    (clobber (reg:BI CARRY))
   1330    ]
   1331   ""
   1332   "@
   1333   CMP%Q0\t%2, %1 { J%0\t%l3
   1334   CMPX.A\t%2, %1 { J%0\t%l3
   1335   CMPX.A\t%2, %1 { J%0\t%l3"
   1336   [(set_attr "extra_length" "2")
   1337    (set_attr "type" "cmp")]
   1338 )
   1339 
   1340 (define_insn "cbranchqi4_real"
   1341   [(set (pc) (if_then_else
   1342 	      (match_operator                    0 "msp430_cmp_operator"
   1343 			      [(match_operand:QI 1 "msp430_general_dst_nonv_operand" "rYsYx,rm")
   1344 			       (match_operand:QI 2 "general_operand"      "rYsYxi,rmi")])
   1345               (label_ref (match_operand          3 "" ""))
   1346 	      (pc)))
   1347    (clobber (reg:BI CARRY))
   1348    ]
   1349   ""
   1350   "@
   1351    CMP.B\t%2, %1 { J%0\t%l3
   1352    CMPX.B\t%2, %1 { J%0\t%l3"
   1353   [(set_attr "extra_length" "2")
   1354    (set_attr "type" "cmp")]
   1355 )
   1356 
   1357 (define_insn "cbranchhi4_real"
   1358   [(set (pc) (if_then_else
   1359 	      (match_operator                    0 "msp430_cmp_operator"
   1360 			      [(match_operand:HI 1 "msp430_general_dst_nonv_operand" "rYsYx,rm")
   1361 			       (match_operand:HI 2 "general_operand"      "rYsYxi,rmi")])
   1362               (label_ref (match_operand          3 "" ""))
   1363 	      (pc)))
   1364    (clobber (reg:BI CARRY))
   1365    ]
   1366   ""
   1367   "@
   1368    CMP.W\t%2, %1 { J%0\t%l3
   1369    CMPX.W\t%2, %1 { J%0\t%l3"
   1370   [(set_attr "extra_length" "2")
   1371    (set_attr "type" "cmp")]
   1372 )
   1373 
   1374 (define_insn "cbranchpsi4_reversed"
   1375   [(set (pc) (if_then_else
   1376 	      (match_operator                     0 "msp430_reversible_cmp_operator"
   1377 			      [(match_operand:PSI 1 "general_operand" "rLs,rYsi,rmi")
   1378 			       (match_operand:PSI 2 "msp430_general_dst_nonv_operand" "r,rYs,rm")])
   1379               (label_ref (match_operand           3 "" ""))
   1380 	      (pc)))
   1381    (clobber (reg:BI CARRY))
   1382    ]
   1383   ""
   1384   "@
   1385   CMP%Q0\t%1, %2 { J%R0\t%l3
   1386   CMPX.A\t%1, %2 { J%R0\t%l3
   1387   CMPX.A\t%1, %2 { J%R0\t%l3"
   1388   [(set_attr "extra_length" "2")
   1389    (set_attr "type" "cmp")]
   1390 )
   1391 
   1392 (define_insn "cbranchqi4_reversed"
   1393   [(set (pc) (if_then_else
   1394 	      (match_operator                    0 "msp430_reversible_cmp_operator"
   1395 			      [(match_operand:QI 1 "general_operand" "rYsYxi,rmi")
   1396 			       (match_operand:QI 2 "msp430_general_dst_nonv_operand" "rYsYx,rm")])
   1397               (label_ref (match_operand          3 "" ""))
   1398 	      (pc)))
   1399    (clobber (reg:BI CARRY))
   1400    ]
   1401   ""
   1402   "@
   1403    CMP.B\t%1, %2 { J%R0\t%l3
   1404    CMPX.B\t%1, %2 { J%R0\t%l3"
   1405   [(set_attr "extra_length" "2")
   1406    (set_attr "type" "cmp")]
   1407 )
   1408 
   1409 (define_insn "cbranchhi4_reversed"
   1410   [(set (pc) (if_then_else
   1411 	      (match_operator                    0 "msp430_reversible_cmp_operator"
   1412 			      [(match_operand:HI 1 "general_operand" "rYsYxi,rmi")
   1413 			       (match_operand:HI 2 "msp430_general_dst_nonv_operand" "rYsYx,rm")])
   1414               (label_ref (match_operand          3 "" ""))
   1415 	      (pc)))
   1416    (clobber (reg:BI CARRY))
   1417    ]
   1418   ""
   1419   "@
   1420    CMP.W\t%1, %2 { J%R0\t%l3
   1421    CMPX.W\t%1, %2 { J%R0\t%l3"
   1422   [(set_attr "extra_length" "2")
   1423    (set_attr "type" "cmp")]
   1424 )
   1425 
   1426 (define_insn "*bitbranch<mode>4"
   1427   [(set (pc) (if_then_else
   1428 	      (ne (and:QHI (match_operand:QHI 0 "msp430_general_dst_operand" "rYsYx,rm")
   1429 			   (match_operand:QHI 1 "msp430_general_operand" "rYsYxi,rmi"))
   1430 		  (const_int 0))
   1431 	      (label_ref (match_operand 2 "" ""))
   1432 	      (pc)))
   1433    (clobber (reg:BI CARRY))
   1434    ]
   1435   ""
   1436   "@
   1437    BIT%x0%b0\t%1, %0 { JNE\t%l2
   1438    BITX%b0\t%1, %0 { JNE\t%l2"
   1439   [(set_attr "extra_length" "2")
   1440    (set_attr "type" "double")]
   1441 )
   1442 
   1443 (define_insn "*bitbranch<mode>4"
   1444   [(set (pc) (if_then_else
   1445 	      (eq (and:QHI (match_operand:QHI 0 "msp430_general_dst_operand" "rYsYx,rm")
   1446 			   (match_operand:QHI 1 "msp430_general_operand" "rYsYxi,rmi"))
   1447 		  (const_int 0))
   1448 	      (label_ref (match_operand 2 "" ""))
   1449 	      (pc)))
   1450    (clobber (reg:BI CARRY))
   1451    ]
   1452   ""
   1453   "@
   1454    BIT%x0%b0\t%1, %0 { JEQ\t%l2
   1455    BITX%b0\t%1, %0 { JEQ\t%l2"
   1456   [(set_attr "extra_length" "2")
   1457    (set_attr "type" "double")]
   1458 )
   1459 
   1460 (define_insn "*bitbranch<mode>4"
   1461   [(set (pc) (if_then_else
   1462 	      (eq (and:QHI (match_operand:QHI 0 "msp430_general_dst_operand" "rYsYx,rm")
   1463 			   (match_operand:QHI 1 "msp430_general_operand" "rYsYxi,rmi"))
   1464 		  (const_int 0))
   1465 	      (pc)
   1466 	      (label_ref (match_operand 2 "" ""))))
   1467    (clobber (reg:BI CARRY))
   1468    ]
   1469   ""
   1470   "@
   1471   BIT%x0%b0\t%1, %0 { JNE\t%l2
   1472   BITX%b0\t%1, %0 { JNE\t%l2"
   1473   [(set_attr "extra_length" "2")
   1474    (set_attr "type" "double")]
   1475 )
   1476 
   1477 (define_insn "*bitbranch<mode>4"
   1478   [(set (pc) (if_then_else
   1479 	      (ne (and:QHI (match_operand:QHI 0 "msp430_general_dst_operand" "rYsYx,rm")
   1480 			   (match_operand:QHI 1 "msp430_general_operand" "rYsYxi,rmi"))
   1481 		  (const_int 0))
   1482 	      (pc)
   1483 	      (label_ref (match_operand 2 "" ""))))
   1484    (clobber (reg:BI CARRY))
   1485    ]
   1486   ""
   1487   "@
   1488   BIT%x0%b0\t%1, %0 { JEQ\t%l2
   1489   BITX%b0\t%1, %0 { JEQ\t%l2"
   1490   [(set_attr "extra_length" "2")
   1491    (set_attr "type" "double")]
   1492 )
   1493 
   1494 ;;------------------------------------------------------------
   1495 ;; zero-extract versions of the above
   1496 
   1497 (define_insn "*bitbranch<mode>4_z"
   1498   [(set (pc) (if_then_else
   1499 	      (ne (zero_extract:HI (match_operand:QHI 0 "msp430_general_dst_operand" "rYs,rm")
   1500 				    (const_int 1)
   1501 				    (match_operand 1 "const_0_to_15_operand" "i,i"))
   1502 		  (const_int 0))
   1503 	      (label_ref (match_operand 2 "" ""))
   1504 	      (pc)))
   1505    (clobber (reg:BI CARRY))
   1506    ]
   1507   ""
   1508   "@
   1509    BIT%x0%b0\t%p1, %0 { JNE\t%l2
   1510    BIT%X0%b0\t%p1, %0 { JNE\t%l2"
   1511   [(set_attr "extra_length" "2")
   1512    (set_attr "type" "double")]
   1513 )
   1514 
   1515 (define_insn "*bitbranch<mode>4_z"
   1516   [(set (pc) (if_then_else
   1517 	      (eq (zero_extract:HI (match_operand:QHI 0 "msp430_general_dst_operand" "rm")
   1518 				   (const_int 1)
   1519 				   (match_operand 1 "const_0_to_15_operand" "i"))
   1520 		  (const_int 0))
   1521 	      (label_ref (match_operand 2 "" ""))
   1522 	      (pc)))
   1523    (clobber (reg:BI CARRY))
   1524    ]
   1525   ""
   1526   "BIT%X0%b0\t%p1, %0 { JEQ\t%l2"
   1527   [(set_attr "extra_length" "2")
   1528    (set_attr "type" "double")]
   1529 )
   1530 
   1531 (define_insn "*bitbranch<mode>4_z"
   1532   [(set (pc) (if_then_else
   1533 	      (eq (zero_extract:HI (match_operand:QHI 0 "msp430_general_dst_operand" "rm")
   1534 				   (const_int 1)
   1535 				   (match_operand 1 "const_0_to_15_operand" "i"))
   1536 		  (const_int 0))
   1537 	      (pc)
   1538 	      (label_ref (match_operand 2 "" ""))))
   1539    (clobber (reg:BI CARRY))
   1540    ]
   1541   ""
   1542   "BIT%X0%b0\t%p1, %0 { JNE\t%l2"
   1543   [(set_attr "extra_length" "2")
   1544    (set_attr "type" "double")]
   1545 )
   1546 
   1547 (define_insn "*bitbranch<mode>4_z"
   1548   [(set (pc) (if_then_else
   1549 	      (ne (zero_extract:HI (match_operand:QHI 0 "msp430_general_dst_operand" "rm")
   1550 				   (const_int 1)
   1551 				   (match_operand 1 "const_0_to_15_operand" "i"))
   1552 		  (const_int 0))
   1553 	      (pc)
   1554 	      (label_ref (match_operand 2 "" ""))))
   1555    (clobber (reg:BI CARRY))
   1556    ]
   1557   ""
   1558   "BIT%X0%b0\t%p1, %0 { JEQ\t%l2"
   1559   [(set_attr "extra_length" "2")
   1560    (set_attr "type" "double")]
   1561 )
   1562 
   1563 ;;------------------------------------------------------------
   1564 ;; Misc
   1565 
   1566 (define_insn "nop"
   1567   [(const_int 0)]
   1568   "1"
   1569   "NOP"
   1570   [(set_attr "length" "2")]
   1571 )
   1572 
   1573 (define_insn "disable_interrupts"
   1574   [(unspec_volatile [(const_int 0)] UNS_DINT)]
   1575   ""
   1576   "DINT \; NOP"
   1577   [(set_attr "length" "2")]
   1578 )
   1579 
   1580 (define_insn "enable_interrupts"
   1581   [(unspec_volatile [(const_int 0)] UNS_EINT)]
   1582   ""
   1583   "EINT"
   1584   [(set_attr "length" "2")]
   1585 )
   1586 
   1587 (define_insn "push_intr_state"
   1588   [(unspec_volatile [(const_int 0)] UNS_PUSH_INTR)]
   1589   ""
   1590   "PUSH\tSR"
   1591   [(set_attr "length" "2")]
   1592 )
   1593 
   1594 (define_insn "pop_intr_state"
   1595   [(unspec_volatile [(const_int 0)] UNS_POP_INTR)]
   1596   ""
   1597   "POP\tSR"
   1598   [(set_attr "length" "2")]
   1599 )
   1600 
   1601 ;; Clear bits in the copy of the status register that is currently
   1602 ;; saved on the stack at the top of the interrupt handler.
   1603 (define_insn "bic_SR"
   1604   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIC_SR)]
   1605   ""
   1606   "BIC.W\t%0, %O0(SP)"
   1607   [(set_attr "type" "single")
   1608    (set_attr "extra_length" "2")]
   1609 )
   1610 
   1611 ;; Set bits in the copy of the status register that is currently
   1612 ;; saved on the stack at the top of the interrupt handler.
   1613 (define_insn "bis_SR"
   1614   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIS_SR)]
   1615   ""
   1616   "BIS.W\t%0, %O0(SP)"
   1617   [(set_attr "type" "single")
   1618    (set_attr "extra_length" "2")]
   1619 )
   1620 
   1621 ;; For some reason GCC is generating (set (reg) (and (neg (reg)) (int)))
   1622 ;; very late on in the compilation and not splitting it into separate
   1623 ;; instructions, so we provide a pattern to support it here.
   1624 (define_insn "andneghi3"
   1625   [(set (match_operand:HI		  0 "register_operand" "=r,r")
   1626 	(and:HI (neg:HI (match_operand:HI 1 "general_operand"  "0,rm"))
   1627 		(match_operand		  2 "immediate_operand" "n,n")))]
   1628   ""
   1629   "@
   1630   INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0
   1631   MOV%X1.W\t%1, %0 { INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0"
   1632   [(set_attr "length" "12,14")
   1633    (set_attr "type" "double")]
   1634 )
   1635 
   1636 
   1637 (define_insn "delay_cycles_start"
   1638   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
   1639 		    UNS_DELAY_START)]
   1640   ""
   1641   "; Begin %J0 cycle delay"
   1642   [(set_attr "length" "0")]
   1643 )
   1644 
   1645 (define_insn "delay_cycles_end"
   1646   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
   1647 		    UNS_DELAY_END)]
   1648   ""
   1649   "; End %J0 cycle delay"
   1650   )
   1651 
   1652 (define_insn "delay_cycles_32"
   1653   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
   1654 		     (match_operand 1 "immediate_operand" "i")
   1655 		     ] UNS_DELAY_32)]
   1656   ""
   1657   "PUSH	r13
   1658 	PUSH	r14
   1659 	MOV.W	%A0, r13
   1660 	MOV.W	%B0, r14
   1661 1:	SUB.W	#1, r13
   1662 	SUBC.W	#0, r14
   1663 	JNE	1b
   1664 	TST.W	r13
   1665 	JNE	1b
   1666 	POP	r14
   1667 	POP	r13"
   1668   [(set_attr "length" "32")]
   1669 )
   1670 
   1671 (define_insn "delay_cycles_32x"
   1672   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
   1673 		     (match_operand 1 "immediate_operand" "i")
   1674 		     ] UNS_DELAY_32X)]
   1675   ""
   1676   "PUSHM.A	#2,r14
   1677 	MOV.W	%A0, r13
   1678 	MOV.W	%B0, r14
   1679 1:	SUB.W	#1, r13
   1680 	SUBC.W	#0, r14
   1681 	JNE	1b
   1682 	TST.W	r13
   1683 	JNE	1b
   1684 	POPM.A	#2,r14"
   1685   [(set_attr "length" "28")]
   1686 )
   1687 
   1688 (define_insn "delay_cycles_16"
   1689   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
   1690 		     (match_operand 1 "immediate_operand" "i")
   1691 		     ] UNS_DELAY_16)]
   1692   ""
   1693   "PUSH	r13
   1694 	MOV.W	%0, r13
   1695 1:	SUB.W	#1, r13
   1696 	JNE	1b
   1697 	POP	r13"
   1698   [(set_attr "length" "14")]
   1699 )
   1700 
   1701 (define_insn "delay_cycles_16x"
   1702   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
   1703 		     (match_operand 1 "immediate_operand" "i")
   1704 		     ] UNS_DELAY_16X)]
   1705   ""
   1706   "PUSHM.A	#1,r13
   1707 	MOV.W	%0, r13
   1708 1:	SUB.W	#1, r13
   1709 	JNE	1b
   1710 	POPM.A	#1,r13"
   1711   [(set_attr "length" "14")]
   1712 )
   1713 
   1714 (define_insn "delay_cycles_2"
   1715   [(unspec_volatile [(const_int 0) ] UNS_DELAY_2)]
   1716   ""
   1717   "JMP	.+2"
   1718   [(set_attr "length" "2")]
   1719 )
   1720 
   1721 (define_insn "delay_cycles_1"
   1722   [(unspec_volatile [(const_int 0) ] UNS_DELAY_1)]
   1723   ""
   1724   "NOP"
   1725   [(set_attr "length" "2")]
   1726 )
   1727 
   1728 (define_expand "mulhi3"
   1729   [(set (match_operand:HI			   0 "register_operand" "=r")
   1730 	(mult:HI (match_operand:HI 1 "register_operand" "%0")
   1731 		 (match_operand:HI 2 "register_operand" "r")))]
   1732   "msp430_has_hwmult ()"
   1733   {
   1734     msp430_expand_helper (operands, "__mspabi_mpyi", false);
   1735     DONE;
   1736   }
   1737 )
   1738 
   1739 (define_expand "mulsi3"
   1740   [(set (match_operand:SI			   0 "register_operand" "=r")
   1741 	(mult:SI (match_operand:SI 1 "register_operand" "%0")
   1742 		 (match_operand:SI 2 "register_operand" "r")))]
   1743   "msp430_has_hwmult ()"
   1744   {
   1745     msp430_expand_helper (operands, "__mspabi_mpyl", false);
   1746     DONE;
   1747   }
   1748 )
   1749 
   1750 ; libgcc helper functions for widening multiplication aren't currently
   1751 ; generated by gcc, so we can't catch them later and map them to the mspabi
   1752 ; functions.
   1753 ; We catch the patterns here and either generate a call to the helper function,
   1754 ; or emit the hardware multiply instruction sequence inline.
   1755 ;
   1756 ; If we don't have hardware multiply support, it will generally be slower and
   1757 ; result in larger code to call the mspabi library function to perform the
   1758 ; widening multiplication than just leaving GCC to widen the arguments itself.
   1759 
   1760 (define_expand "mulhisi3"
   1761   [(set (match_operand:SI			   0 "register_operand" "=r")
   1762 	(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
   1763 		 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
   1764   "msp430_has_hwmult ()"
   1765   {
   1766     /* Leave the other case for the inline insn.  */
   1767     if (!(optimize > 2 && msp430_has_hwmult ()))
   1768     {
   1769       msp430_expand_helper (operands, "__mspabi_mpysl", false);
   1770       DONE;
   1771     }
   1772   }
   1773 )
   1774 
   1775 (define_expand "umulhisi3"
   1776   [(set (match_operand:SI			   0 "register_operand" "=r")
   1777 	(mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
   1778 		 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
   1779   "msp430_has_hwmult ()"
   1780   {
   1781     /* Leave the other case for the inline insn.  */
   1782     if (!(optimize > 2 && msp430_has_hwmult ()))
   1783     {
   1784       msp430_expand_helper (operands, "__mspabi_mpyul", false);
   1785       DONE;
   1786     }
   1787   }
   1788 )
   1789 
   1790 (define_expand "mulsidi3"
   1791   [(set (match_operand:DI			   0 "register_operand" "=r")
   1792 	(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
   1793 		 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
   1794   "msp430_has_hwmult ()"
   1795   {
   1796     /* Leave the other case for the inline insn.  */
   1797     if (!(optimize > 2 && msp430_has_hwmult ()))
   1798     {
   1799       msp430_expand_helper (operands, "__mspabi_mpysll", false);
   1800       DONE;
   1801     }
   1802   }
   1803 )
   1804 
   1805 (define_expand "umulsidi3"
   1806   [(set (match_operand:DI			   0 "register_operand" "=r")
   1807 	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
   1808 		 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
   1809   "msp430_has_hwmult ()"
   1810   {
   1811     /* Leave the other case for the inline insn.  */
   1812     if (!(optimize > 2 && msp430_has_hwmult ()))
   1813     {
   1814       msp430_expand_helper (operands, "__mspabi_mpyull", false);
   1815       DONE;
   1816     }
   1817   }
   1818 )
   1819 
   1820 
   1821 (define_insn "*mulhisi3_inline"
   1822   [(set (match_operand:SI                          0 "register_operand" "=r")
   1823 	(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
   1824 		 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
   1825   "optimize > 2 && msp430_has_hwmult ()"
   1826   "*
   1827     if (msp430_use_f5_series_hwmult ())
   1828       return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x04C2 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\";
   1829     else
   1830       return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x0132 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\";
   1831   "
   1832   [(set_attr "length" "24")]
   1833 )
   1834 
   1835 (define_insn "*umulhisi3_inline"
   1836   [(set (match_operand:SI                          0 "register_operand" "=r")
   1837 	(mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
   1838 		 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
   1839   "optimize > 2 && msp430_has_hwmult ()"
   1840   "*
   1841     if (msp430_use_f5_series_hwmult ())
   1842       return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x04C0 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\";
   1843     else
   1844       return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x0130 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\";
   1845   "
   1846   [(set_attr "length" "24")]
   1847 )
   1848 
   1849 (define_insn "*mulsidi3_inline"
   1850   [(set (match_operand:DI                          0 "register_operand" "=r")
   1851 	(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
   1852 		 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
   1853   "optimize > 2 && msp430_has_hwmult ()"
   1854   "*
   1855     if (msp430_use_f5_series_hwmult ())
   1856       return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x04D4 { MOV.W %H1, &0x04D6 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\";
   1857     else
   1858       return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x0144 { MOV.W %H1, &0x0146 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\";
   1859   "
   1860   [(set_attr "length" "40")]
   1861 )
   1862 
   1863 (define_insn "*umulsidi3_inline"
   1864   [(set (match_operand:DI                          0 "register_operand" "=r")
   1865 	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
   1866 		 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
   1867   "optimize > 2 && msp430_has_hwmult ()"
   1868   "*
   1869     if (msp430_use_f5_series_hwmult ())
   1870       return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x04D0 { MOV.W %H1, &0x04D2 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\";
   1871     else
   1872       return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x0140 { MOV.W %H1, &0x0142 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\";
   1873   "
   1874   [(set_attr "length" "40")]
   1875 )
   1876