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