* config/msp430/msp430.h (LIB_SPEC): Add -lcrt
[official-gcc.git] / gcc / config / msp430 / msp430.md
blob0037d8b16f86f741f771b4057f54856f9424d5be
1 ;;  Machine Description for TI MSP43* processors
2 ;;  Copyright (C) 2013-2014 Free Software Foundation, Inc.
3 ;;  Contributed by Red Hat.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
22 (define_constants
23   [
24    (PC_REGNO 0)
25    (SP_REGNO 1)
26    (CARRY 2)
27   ])
29 (define_c_enum "unspec"
30   [
31    UNS_PROLOGUE_START_MARKER
32    UNS_PROLOGUE_END_MARKER
33    UNS_EPILOGUE_START_MARKER
34    UNS_EPILOGUE_HELPER
36    UNS_PUSHM
37    UNS_POPM
39    UNS_GROW_AND_SWAP
40    UNS_SWAP_AND_SHRINK
41    
42    UNS_DINT
43    UNS_EINT
44    UNS_PUSH_INTR
45    UNS_POP_INTR
46    UNS_BIC_SR
47    UNS_BIS_SR
49    UNS_REFSYM_NEED_EXIT
50   ])
51   
52 (include "predicates.md")
53 (include "constraints.md")
55 (define_mode_iterator QHI [QI HI PSI])
57 ;; There are two basic "family" tests we do here:
59 ;; msp430x - true if 430X instructions are available.
60 ;; TARGET_LARGE - true if pointers are 20-bits
62 ;; Note that there are three supported cases, since the base 430
63 ;; doesn't have 20-bit pointers:
65 ;; 1. MSP430 cpu, small model
66 ;; 2. MSP430X cpu, small model.
67 ;; 3. MSP430X cpu, large model.
69 ;;------------------------------------------------------------
70 ;; Moves
72 ;; Push/Pop must be before the generic move patterns
74 (define_insn "push"
75   [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO)))
76         (match_operand:HI 0 "register_operand" "r"))]
77   ""
78   "PUSH\t%0"
79   )
81 (define_insn "pusha"
82   [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO)))
83         (match_operand:PSI 0 "register_operand" "r"))]
84   "TARGET_LARGE"
85   "PUSHX.A\t%0"
86   )
88 (define_insn "pushm"
89   [(unspec_volatile [(match_operand 0 "register_operand" "r")
90                      (match_operand 1 "immediate_operand" "n")] UNS_PUSHM)]
91   ""
92   "PUSHM%b0\t%1, %0"
93   )
95 (define_insn "pop"
96   [(set (match_operand:HI 0 "register_operand" "=r")
97         (mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
98   ""
99   "POP\t%0"
100   )
102 (define_insn "popa"
103   [(set (match_operand:PSI 0 "register_operand" "=r")
104         (mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))]
105   "TARGET_LARGE"
106   "POPX.A\t%0"
107   )
109 ;; This is nasty.  Operand0 is bogus.  It is only there so that we can get a
110 ;; mode for the %b0 to work.  We should use operand1 for this, but that does
111 ;; not have a mode.
112 ;; 
113 ;; Operand1 is actually a register, but we cannot accept (REG...) because the
114 ;; cprop_hardreg pass can and will renumber registers even inside
115 ;; unspec_volatiles.  So we take an integer register number parameter and
116 ;; fudge it to be a register name when we generate the assembler.
118 ;; The pushm pattern does not have this problem because of all of the
119 ;; frame info cruft attached to it, so cprop_hardreg leaves it alone.
120 (define_insn "popm"
121   [(unspec_volatile [(match_operand 0 "register_operand" "r")
122                      (match_operand 1 "immediate_operand" "i")
123                      (match_operand 2 "immediate_operand" "i")] UNS_POPM)]
124   ""
125   "POPM%b0\t%2, r%J1"
126   )
128 ;; The next two patterns are here to support a "feature" of how GCC implements
129 ;; varargs.  When a function uses varargs and the *second* to last named
130 ;; argument is split between argument registers and the stack, gcc expects the
131 ;; callee to allocate space on the stack that can contain the register-based
132 ;; part of the argument.  This space *has* to be just before the remaining
133 ;; arguments (ie the ones that are fully on the stack).
135 ;; The problem is that the MSP430 CALL instruction pushes the return address
136 ;; onto the stack in the exact place where the callee wants to allocate
137 ;; this extra space.  So we need a sequence of instructions that can allocate
138 ;; the extra space and then move the return address down the stack, so that
139 ;; the extra space is now adjacent to the remaining arguments.
141 ;; This could be constructed through regular insns, but they might be split up
142 ;; by a misguided optimization, so an unspec volatile is used instead.
144 (define_insn "grow_and_swap"
145   [(unspec_volatile [(const_int 0)] UNS_GROW_AND_SWAP)]
146   ""
147   { if (TARGET_LARGE)
148       return "SUBA\t#2, r1 \n MOVX.A\t2(r1), 0(r1)";
149     return "SUB\t#2, r1 \n MOV.W\t2(r1), 0(r1)";
150     }
151   )
153 (define_insn "swap_and_shrink"
154   [(unspec_volatile [(const_int 0)] UNS_SWAP_AND_SHRINK)]
155   ""
156   { return TARGET_LARGE
157            ? "MOVX.A\t0(r1), 2(r1) \n ADDA\t#2, SP"
158            : "MOV.W\t0(r1), 2(r1) \n ADD\t#2, SP";
159   })
161 ; I set LOAD_EXTEND_OP and WORD_REGISTER_OPERATIONS, but gcc puts in a
162 ; zero_extend anyway.  Catch it here.
163 (define_insn "movqihi"
164   [(set (match_operand:HI                 0 "register_operand" "=r,r")
165         (zero_extend:HI (match_operand:QI 1 "memory_operand" "Ys,m")))]
166   ""
167   "@
168    MOV.B\t%1, %0
169    MOV%X1.B\t%1, %0"
172 (define_insn "movqi"
173   [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm")
174         (match_operand:QI 1 "msp_general_operand" "riYs,rmi"))]
175   ""
176   "@
177   MOV.B\t%1, %0
178   MOV%X0.B\t%1, %0"
181 (define_insn "movhi"
182   [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm")
183         (match_operand:HI 1 "msp_general_operand" "riYs,rmi"))]
184   ""
185   "@
186   MOV.W\t%1, %0
187   MOV%X0.W\t%1, %0"
190 (define_expand "movsi"
191   [(set (match_operand:SI 0 "nonimmediate_operand")
192         (match_operand:SI 1 "general_operand"))]
193   ""
194   ""
195   )
196   
197 (define_insn_and_split "movsi_x"
198   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
199         (match_operand:SI 1 "general_operand" "rmi"))]
200   ""
201   "#"
202   "reload_completed"
203   [(set (match_operand:HI 2 "nonimmediate_operand")
204         (match_operand:HI 4 "general_operand"))
205    (set (match_operand:HI 3 "nonimmediate_operand")
206         (match_operand:HI 5 "general_operand"))]
207   "msp430_split_movsi (operands);"
210 ;; Some MOVX.A cases can be done with MOVA, this is only a few of them.
211 (define_insn "movpsi"
212   [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,Ya,rm")
213         (match_operand:PSI 1 "msp_general_operand" "riYa,r,rmi"))]
214   ""
215   "@
216   MOV%Q0\t%1, %0
217   MOV%Q0\t%1, %0
218   MOV%X0.%Q0\t%1, %0")
220 ; This pattern is identical to the truncsipsi2 pattern except
221 ; that it uses a SUBREG instead of a TRUNC.  It is needed in
222 ; order to prevent reload from converting (set:SI (SUBREG:PSI (SI)))
223 ; into (SET:PSI (PSI)).
225 ; Note: using POPM.A #1 is two bytes smaller than using POPX.A....
227 (define_insn "movsipsi2"
228   [(set (match_operand:PSI            0 "register_operand" "=r")
229         (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
230   "TARGET_LARGE"
231   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0"
234 ;;------------------------------------------------------------
235 ;; Math
237 (define_insn "addpsi3"
238   [(set (match_operand:PSI           0 "msp_nonimmediate_operand" "=r,rm")
239         (plus:PSI (match_operand:PSI 1 "msp_nonimmediate_operand" "%0,0")
240                   (match_operand:PSI 2 "msp_general_operand"      "rLs,rmi")))]
241   ""
242   "@
243   ADDA\t%2, %0
244   ADDX.A\t%2, %0"
247 (define_insn "addqi3"
248   [(set (match_operand:QI          0 "msp_nonimmediate_operand" "=rYs,rm")
249         (plus:QI (match_operand:QI 1 "msp_nonimmediate_operand" "%0,0")
250                  (match_operand:QI 2 "msp_general_operand"      "riYs,rmi")))]
251   ""
252   "@
253    ADD.B\t%2, %0
254    ADD%X0.B\t%2, %0"
257 (define_insn "addhi3"
258   [(set (match_operand:HI           0 "msp_nonimmediate_operand" "=rYs,rm")
259         (plus:HI (match_operand:HI  1 "msp_nonimmediate_operand" "%0,0")
260                   (match_operand:HI 2 "msp_general_operand"      "riYs,rmi")))]
261   ""
262   "@
263    ADD.W\t%2, %0
264    ADD%X0.W\t%2, %0"
267 ; This pattern is needed in order to avoid reload problems.
268 ; It takes an SI pair of registers, adds a value to them, and
269 ; then converts them into a single PSI register.
271 (define_insn "addsipsi3"
272   [(set (subreg:SI (match_operand:PSI 0 "register_operand" "=&r") 0)
273         (plus:SI (match_operand:SI    1 "register_operand" "0")
274                  (match_operand       2 "general_operand" "rmi")))]
275   ""
276   "ADD.W\t%L2, %L0 { ADDC.W\t%H2, %H0 { PUSH.W\t%H0 { PUSH.W\t%L0 { POPM.A\t#1, %0"
279 (define_insn "addsi3"
280   [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,rm")
281         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
282                  (match_operand:SI 2 "general_operand" "r,mi")))]
283   ""
284   "@
285    ADD\t%L2, %L0 { ADDC\t%H2, %H0
286    ADD%X0\t%L2, %L0 { ADDC%X0\t%H2, %H0"
289 ; Version of addhi that exposes the carry operations, for SImode adds.
291 ; NOTE - we are playing a dangerous game with GCC here.  We have these two
292 ; add patterns and the splitter that follows because our tests have shown
293 ; that this results in a significant reduction in code size - because GCC is
294 ; able to discard any unused part of the addition.  We have to annotate the
295 ; patterns with the set and use of the carry flag because otherwise GCC will
296 ; discard parts of the addition when they are actually needed.  But we have
297 ; not annotated all the other patterns that set the CARRY flag as doing so
298 ; results in an overall increase in code size[1].  Instead we just *hope*
299 ; that GCC will not move a carry-setting instruction in between the first
300 ; and second adds.
302 ; So far our experiments have shown that GCC is likely to move MOV and CMP
303 ; instructions in between the two adds, but not other instructions.  MOV is
304 ; safe, CMP is not.  So we have annotated the CMP patterns and left the
305 ; subtract, shift and other add patterns alone.  At the moment this is
306 ; working, but with future changes to the generic parts of GCC that might
307 ; change.
309 ; [1] It is not clear exactly why the code size increases.  The cause appears
310 ; to be that reload is more prevelent to spilling a variable onto the stack
311 ; but why it does this is unknown.  Possibly the additional CLOBBERs necessary
312 ; to correctly annotate the other patterns makes reload think that there is
313 ; increased register pressure.  Or possibly reload does not handle ADD patterns
314 ; that are not single_set() very well.
316 (define_insn "addhi3_cy"
317   [(set (match_operand:HI          0 "msp_nonimmediate_operand" "=r,rm")
318         (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
319                  (match_operand:HI 2 "msp_nonimmediate_operand" "r,rm")))
320    (set (reg:BI CARRY)
321         (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
322                                            (zero_extend:SI (match_dup 2)))
323                                   (const_int 16))))
324    ]
325   ""
326   "@
327    ADD\t%2, %1 ; cy
328    ADD%X0\t%2, %1 ; cy"
329   )
331 (define_insn "addhi3_cy_i"
332   [(set (match_operand:HI          0 "nonimmediate_operand" "=r,rm")
333         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
334                  (match_operand:HI 2 "immediate_operand"     "i,i")))
335    (set (reg:BI CARRY)
336         (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
337                                            (match_operand 3 "immediate_operand" "i,i"))
338                                   (const_int 16))))
339    ]
340   ""
341   "@
342    ADD\t%2, %1 ; cy
343    ADD%X0\t%2, %1 ; cy"
344   )
346 ; Version of addhi that adds the carry, for SImode adds.
347 (define_insn "addchi4_cy"
348   [(set (match_operand:HI                   0 "msp_nonimmediate_operand" "=r,rm")
349         (plus:HI (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
350                           (match_operand:HI 2 "msp_general_operand"      "ri,rmi"))
351                  (zero_extend:HI (reg:BI CARRY))))
352    ]
353   ""
354   "@
355    ADDC\t%2, %1
356    ADDC%X0\t%2, %1"
357   )
359 ; Split an SImode add into two HImode adds, keeping track of the carry
360 ; so that gcc knows when it can and can't optimize away the two
361 ; halves.
362 (define_split
363   [(set (match_operand:SI          0 "msp430_nonsubreg_operand")
364         (plus:SI (match_operand:SI 1 "nonimmediate_operand")
365                  (match_operand:SI 2 "general_operand")))
366    ]
367   ""
368   [(parallel [(set (match_operand:HI 3 "nonimmediate_operand" "=&rm")
369                    (plus:HI (match_dup 4)
370                             (match_dup 5)))
371               (set (reg:BI CARRY)
372                    (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 4))
373                                                       (match_dup 9))
374                                              (const_int 16))))
375               ])
376    (set (match_operand:HI 6 "nonimmediate_operand" "=&rm")
377         (plus:HI (plus:HI (match_dup 7)
378                           (match_dup 8))
379                  (zero_extend:HI (reg:BI CARRY))))
380    ]
381   "
382    operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
383    operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
384    operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
385    operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
386    operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
387    operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
388    if (GET_CODE (operands[5]) == CONST_INT)
389      {
390        operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
391      }
392    else
393      {
394        operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
395      }
396    "
397   )
400 ;; Alternatives 2 and 3 are to handle cases generated by reload.
401 (define_insn "subpsi3"
402   [(set (match_operand:PSI            0 "nonimmediate_operand" "=r,   rm, &?r, ?&r")
403         (minus:PSI (match_operand:PSI 1 "general_operand"       "0,   0,   !r,  !i")
404                    (match_operand:PSI 2 "general_operand"       "rLs, rmi, rmi,  r")))]
405   ""
406   "@
407   SUBA\t%2, %0
408   SUBX.A\t%2, %0
409   MOVX.A\t%1, %0 { SUBX.A\t%2, %0
410   MOVX.A\t%1, %0 { SUBA\t%2, %0"
413 ;; Alternatives 2 and 3 are to handle cases generated by reload.
414 (define_insn "subqi3"
415   [(set (match_operand:QI           0 "nonimmediate_operand" "=rYs,  rm,  &?r, ?&r")
416         (minus:QI (match_operand:QI 1 "general_operand"       "0,    0,    !r,  !i")
417                   (match_operand:QI 2 "general_operand"      " riYs, rmi, rmi,   r")))]
418   ""
419   "@
420   SUB.B\t%2, %0
421   SUB%X0.B\t%2, %0
422   MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0
423   MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0"
426 ;; Alternatives 2 and 3 are to handle cases generated by reload.
427 (define_insn "subhi3"
428   [(set (match_operand:HI           0 "nonimmediate_operand" "=rYs,  rm,  &?r, ?&r")
429         (minus:HI (match_operand:HI 1 "general_operand"       "0,    0,    !r,  !i")
430                   (match_operand:HI 2 "general_operand"      " riYs, rmi, rmi,   r")))]
431   ""
432   "@
433   SUB.W\t%2, %0
434   SUB%X0.W\t%2, %0
435   MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0
436   MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0"
439 (define_insn "subsi3"
440   [(set (match_operand:SI           0 "nonimmediate_operand" "=&rm")
441         (minus:SI (match_operand:SI 1 "nonimmediate_operand"   "0")
442                   (match_operand:SI 2 "general_operand"        "rmi")))]
443   ""
444   "SUB%X0\t%L2, %L0 { SUBC%X0\t%H2, %H0"
447 (define_insn "*bic<mode>_cg"
448   [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m")
449         (and:QHI (match_operand:QHI 1 "msp_general_operand" "0,0")
450                  (match_operand 2 "msp430_inv_constgen_operator" "n,n")))]
451   ""
452   "@
453    BIC%x0%b0\t#%I2, %0
454    BIC%X0%b0\t#%I2, %0"
457 (define_insn "bic<mode>3"
458   [(set (match_operand:QHI                   0 "msp_nonimmediate_operand" "=rYs,rm")
459         (and:QHI (not:QHI (match_operand:QHI 1 "msp_general_operand"       "rYs,rmn"))
460                  (match_operand:QHI          2 "msp_nonimmediate_operand"  "0,0")))]
461   ""
462   "@
463    BIC%x0%b0\t%1, %0
464    BIC%X0%b0\t%1, %0"
467 (define_insn "and<mode>3"
468   [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
469         (and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
470                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
471   ""
472   "@
473    AND%x0%b0\t%2, %0
474    AND%X0%b0\t%2, %0"
477 (define_insn "ior<mode>3"
478   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,rm")
479         (ior:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
480                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
481   ""
482   "@
483    BIS%x0%b0\t%2, %0
484    BIS%X0%b0\t%2, %0"
487 (define_insn "xor<mode>3"
488   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,rm")
489         (xor:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
490                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
491   ""
492   "@
493    XOR%x0%b0\t%2, %0
494    XOR%X0%b0\t%2, %0"
497 ;; Macro : XOR #~0, %0
498 (define_insn "one_cmpl<mode>2"
499   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,m")
500         (not:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "0,0")))]
501   ""
502   "@
503    INV%x0%b0\t%0
504    INV%X0%b0\t%0"
507 (define_insn "extendqihi2"
508   [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,m")
509         (sign_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
510   ""
511   "@
512    SXT%X0\t%0
513    SXT%X0\t%0"
516 (define_insn "zero_extendqihi2"
517   [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,m")
518         (zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
519   ""
520   "@
521    AND\t#0xff, %0
522    AND%X0\t#0xff, %0"
525 ;; Eliminate extraneous zero-extends mysteriously created by gcc.
526 (define_peephole2
527   [(set (match_operand:HI 0 "register_operand")
528         (zero_extend:HI (match_operand:QI 1 "general_operand")))
529    (set (match_operand:HI 2 "register_operand")
530         (zero_extend:HI (match_operand:QI 3 "register_operand")))]
531   "REGNO (operands[0]) == REGNO (operands[2]) && REGNO (operands[2]) == REGNO (operands[3])"
532   [(set (match_dup 0)
533         (zero_extend:HI (match_dup 1)))]
535    
536 (define_insn "zero_extendhipsi2"
537   [(set (match_operand:PSI                 0 "msp_nonimmediate_operand" "=r,m")
538         (zero_extend:PSI (match_operand:HI 1 "msp_nonimmediate_operand" "rm,r")))]
539   ""
540   "MOVX\t%1, %0"
543 (define_insn "truncpsihi2"
544   [(set (match_operand:HI               0 "msp_nonimmediate_operand" "=rm")
545         (truncate:HI (match_operand:PSI 1 "register_operand"      "r")))]
546   ""
547   "MOVX\t%1, %0"
550 (define_insn "extendhisi2"
551   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
552         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
553   ""
554   { return msp430x_extendhisi (operands); }
557 (define_insn "extendhipsi2"
558   [(set (match_operand:PSI 0 "nonimmediate_operand" "=r")
559         (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))]
560   "TARGET_LARGE"
561   "RLAM #4, %0 { RRAM #4, %0"
564 ;; Look for cases where integer/pointer conversions are suboptimal due
565 ;; to missing patterns, despite us not having opcodes for these
566 ;; patterns.  Doing these manually allows for alternate optimization
567 ;; paths.
568 (define_insn "zero_extendhisi2"
569   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
570         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
571   "TARGET_LARGE"
572   "MOV.W\t#0,%H0"
575 (define_insn "zero_extendhisipsi2"
576   [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r")
577         (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))]
578   "TARGET_LARGE"
579   "@
580    AND.W\t#-1,%0
581    MOV.W\t%1,%0"
584 (define_insn "extend_and_shift1_hipsi2"
585   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
586         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
587                    (const_int 1)))]
588   "TARGET_LARGE"
589   "RLAM #4, %0 { RRAM #3, %0"
592 (define_insn "extend_and_shift2_hipsi2"
593   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
594         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
595                    (const_int 2)))]
596   "TARGET_LARGE"
597   "RLAM #4, %0 { RRAM #2, %0"
600 ; Nasty - we are sign-extending a 20-bit PSI value in one register into
601 ; two adjacent 16-bit registers to make an SI value.  There is no MSP430X
602 ; instruction that will do this, so we push the 20-bit value onto the stack
603 ; and then pop it off as two 16-bit values.
605 ; FIXME: The MSP430X documentation does not specify if zero-extension or
606 ; sign-extension happens when the 20-bit value is pushed onto the stack.
607 ; It is probably zero-extension, but if not this pattern will not work
608 ; when the PSI value is negative..
610 ; Note: using PUSHM.A #1 is two bytes smaller than using PUSHX.A....
612 (define_insn "zero_extendpsisi2"
613   [(set (match_operand:SI                  0 "register_operand" "=r")
614         (zero_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
615   ""
616   "*
617     if (REGNO (operands[1]) == SP_REGNO)
618       /* If the source register is the stack pointer, the value
619          stored in the stack slot will be the value *after* the
620          stack pointer has been decremented.  So allow for that
621          here.  */
622       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\";
623     else
624       return \"PUSHM.A\t#1, %1 { POPX.W\t%L0 { POPX.W\t%H0 ; move pointer in %1 into reg-pair %L0:%H0\";
625   "
628 ;; We also need to be able to sign-extend pointer types (eg ptrdiff_t).
629 ;; Since (we assume) pushing a 20-bit value onto the stack zero-extends
630 ;; it, we use a different method here.
632 (define_insn "extendpsisi2"
633   [(set (match_operand:SI                  0 "register_operand" "=r")
634         (sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
635   "TARGET_LARGE"
636   "*
637     /* The intention here is that we copy the bottom 16-bits of
638        %1 into %L0 (zeroing the top four bits).  Then we copy the
639        entire 20-bits of %1 into %H0 and then arithmetically shift
640        it right by 16 bits, to get the top four bits of the pointer
641        sign-extended in %H0.  */
642     if (REGNO (operands[0]) == REGNO (operands[1]))
643       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\";
644     else
645       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\";
646   "
649 ; See the movsipsi2 pattern above for another way that GCC performs this
650 ; conversion.
651 (define_insn "truncsipsi2"
652   [(set (match_operand:PSI              0 "register_operand" "=r")
653         (truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
654   ""
655   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A\t#1, %L0"
658 ;;------------------------------------------------------------
659 ;; Shift Functions
661 ;; Note:  We do not use the RPT ... SHIFT instruction sequence
662 ;; when the repeat count is in a register, because even though RPT
663 ;; accepts counts in registers, it does not work if the count is
664 ;; zero, and the actual count in the register has to be one less
665 ;; than the required number of iterations.  We could encode a
666 ;; seqeunce like this:
668 ;;   bit #0xf, Rn
669 ;;   bz  1f
670 ;;   dec Rn
671 ;;   rpt Rn
672 ;;   <shift> Rm
673 ;;   inc Rn
674 ;; 1:
676 ;; But is longer than calling a helper function, and we are mostly
677 ;; concerned with code size.  FIXME: Maybe enable a sequence like
678 ;; this at -O3 and above ?
680 ;; Note - we ignore shift counts of less than one or more than 15.
681 ;; This is permitted by the ISO C99 standard as such shifts result
682 ;; in "undefined" behaviour.  [6.5.7 (3)]
684 ;; signed A << C
686 (define_expand "ashlhi3"
687   [(set (match_operand:HI            0 "nonimmediate_operand")
688         (ashift:HI (match_operand:HI 1 "general_operand")
689                    (match_operand:HI 2 "general_operand")))]
690   ""
691   {
692     if (msp430x
693         && REG_P (operands[0])
694         && REG_P (operands[1])
695         && CONST_INT_P (operands[2]))
696       emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2]));
697     else                 
698       msp430_expand_helper (operands, \"__mspabi_slli\", true);
699     DONE;
700   }
703 (define_insn "slli_1"
704   [(set (match_operand:HI            0 "nonimmediate_operand" "=rm")
705         (ashift:HI (match_operand:HI 1 "general_operand"       "0")
706                    (const_int 1)))]
707   ""
708   "RLA.W\t%0" ;; Note - this is a macro for ADD
711 (define_insn "430x_shift_left"
712   [(set (match_operand:HI            0 "register_operand" "=r")
713         (ashift:HI (match_operand:HI 1 "register_operand"  "0")
714                    (match_operand    2 "immediate_operand" "n")))]
715   "msp430x"
716   "*
717   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
718     return \"rpt\t%2 { rlax.w\t%0\";
719   return \"# nop left shift\";
720   "
723 (define_insn "slll_1"
724   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
725         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
726                    (const_int 1)))]
727   ""
728   "RLA.W\t%L0 { RLC.W\t%H0"
731 (define_insn "slll_2"
732   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
733         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
734                    (const_int 2)))]
735   ""
736   "RLA.W\t%L0 { RLC.W\t%H0 { RLA.W\t%L0 { RLC.W\t%H0"
739 (define_expand "ashlsi3"
740   [(set (match_operand:SI            0 "nonimmediate_operand")
741         (ashift:SI (match_operand:SI 1 "general_operand")
742                    (match_operand:SI 2 "general_operand")))]
743   ""
744   "msp430_expand_helper (operands, \"__mspabi_slll\", true);
745    DONE;"
748 ;;----------
750 ;; signed A >> C
752 (define_expand "ashrhi3"
753   [(set (match_operand:HI              0 "nonimmediate_operand")
754         (ashiftrt:HI (match_operand:HI 1 "general_operand")
755                      (match_operand:HI 2 "general_operand")))]
756   ""
757   {
758     if (msp430x
759         && REG_P (operands[0])
760         && REG_P (operands[1])
761         && CONST_INT_P (operands[2]))
762       emit_insn (gen_430x_arithmetic_shift_right (operands[0], operands[1], operands[2]));
763     else                 
764        msp430_expand_helper (operands, \"__mspabi_srai\", true);
765    DONE;
766    }
769 (define_insn "srai_1"
770   [(set (match_operand:HI              0 "msp_nonimmediate_operand" "=rm")
771         (ashiftrt:HI (match_operand:HI 1 "msp_general_operand"      "0")
772                      (const_int 1)))]
773   ""
774   "RRA.W\t%0"
777 (define_insn "430x_arithmetic_shift_right"
778   [(set (match_operand:HI              0 "register_operand" "=r")
779         (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0")
780                      (match_operand    2 "immediate_operand" "n")))]
781   "msp430x"
782   "*
783   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
784     return \"rpt\t%2 { rrax.w\t%0\";
785   return \"# nop arith right shift\";
786   "
789 (define_insn "srap_1"
790   [(set (match_operand:PSI              0 "register_operand" "=r")
791         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
792                       (const_int 1)))]
793   "msp430x"
794   "RRAM.A #1,%0"
797 (define_insn "srap_2"
798   [(set (match_operand:PSI              0 "register_operand" "=r")
799         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
800                       (const_int 2)))]
801   "msp430x"
802   "RRAM.A #2,%0"
805 (define_insn "sral_1"
806   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
807         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
808                      (const_int 1)))]
809   ""
810   "RRA.W\t%H0 { RRC.W\t%L0"
813 (define_insn "sral_2"
814   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
815         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
816                      (const_int 2)))]
817   ""
818   "RRA.W\t%H0 { RRC.W\t%L0 { RRA.W\t%H0 { RRC.W\t%L0"
821 (define_expand "ashrsi3"
822   [(set (match_operand:SI              0 "nonimmediate_operand")
823         (ashiftrt:SI (match_operand:SI 1 "general_operand")
824                      (match_operand:SI 2 "general_operand")))]
825   ""
826   "msp430_expand_helper (operands, \"__mspabi_sral\", true);
827    DONE;"
830 ;;----------
832 ;; unsigned A >> C
834 (define_expand "lshrhi3"
835   [(set (match_operand:HI              0 "nonimmediate_operand")
836         (lshiftrt:HI (match_operand:HI 1 "general_operand")
837                      (match_operand:HI 2 "general_operand")))]
838   ""
839   {
840     if (msp430x
841         && REG_P (operands[0])
842         && REG_P (operands[1])
843         && CONST_INT_P (operands[2]))
844       emit_insn (gen_430x_logical_shift_right (operands[0], operands[1], operands[2]));
845     else                 
846       msp430_expand_helper (operands, \"__mspabi_srli\", true);
847     DONE;
848   }
851 (define_insn "srli_1"
852   [(set (match_operand:HI              0 "nonimmediate_operand" "=rm")
853         (lshiftrt:HI (match_operand:HI 1 "general_operand"       "0")
854                      (const_int 1)))]
855   ""
856   "CLRC { RRC.W\t%0"
859 (define_insn "430x_logical_shift_right"
860   [(set (match_operand:HI              0 "register_operand" "=r")
861         (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0")
862                      (match_operand    2 "immediate_operand" "n")))]
863   "msp430x"
864   {
865     return msp430x_logical_shift_right (operands[2]);
866   }
869 (define_insn "srlp_1"
870   [(set (match_operand:PSI              0 "register_operand" "=r")
871         (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
872                       (const_int 1)))]
873   ""
874   "RRUM.A #1,%0"
877 (define_insn "srll_1"
878   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
879         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
880                      (const_int 1)))]
881   ""
882   "CLRC { RRC.W\t%H0 { RRC.W\t%L0"
885 (define_insn "srll_2x"
886   [(set (match_operand:SI              0 "nonimmediate_operand" "=r")
887         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
888                      (const_int 2)))]
889   "msp430x"
890   "RRUX.W\t%H0 { RRC.W\t%L0 { RRUX.W\t%H0 { RRC.W\t%L0"
893 (define_expand "lshrsi3"
894   [(set (match_operand:SI              0 "nonimmediate_operand")
895         (lshiftrt:SI (match_operand:SI 1 "general_operand")
896                      (match_operand:SI 2 "general_operand")))]
897   ""
898   "msp430_expand_helper (operands, \"__mspabi_srll\", true);
899    DONE;"
902 ;;------------------------------------------------------------
903 ;; Function Entry/Exit
905 (define_expand "prologue"
906   [(const_int 0)]
907   ""
908   "msp430_expand_prologue (); DONE;"
909   )
911 (define_expand "epilogue"
912   [(const_int 0)]
913   ""
914   "msp430_expand_epilogue (0); DONE;"
915   )
918 (define_insn "epilogue_helper"
919   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)]
920   ""
921   "BR%Q0\t#__mspabi_func_epilog_%J0"
922   )
925 (define_insn "prologue_start_marker"
926   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)]
927   ""
928   "; start of prologue"
929   )
931 (define_insn "prologue_end_marker"
932   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)]
933   ""
934   "; end of prologue"
935   )
937 (define_insn "epilogue_start_marker"
938   [(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)]
939   ""
940   "; start of epilogue"
941   )
943 ;; This makes the linker add a call to exit() after the call to main()
944 ;; in crt0
945 (define_insn "msp430_refsym_need_exit"
946   [(unspec_volatile [(const_int 0)] UNS_REFSYM_NEED_EXIT)]
947   ""
948   ".refsym\t__crt0_call_exit"
949   )
951 ;;------------------------------------------------------------
952 ;; Jumps
954 (define_expand "call"
955   [(call:HI (match_operand 0 "")
956             (match_operand 1 ""))]
957   ""
958   ""
961 (define_insn "call_internal"
962   [(call (mem:HI (match_operand 0 "general_operand" "rYci"))
963          (match_operand 1 ""))]
964   ""
965   "CALL%Q0\t%0"
968 (define_expand "call_value"
969   [(set (match_operand          0 "register_operand")
970         (call:HI (match_operand 1 "general_operand")
971                  (match_operand 2 "")))]
972   ""
973   ""
976 (define_insn "call_value_internal"
977   [(set (match_operand               0 "register_operand" "=r")
978         (call (mem:HI (match_operand 1 "general_operand" "rYci"))
979               (match_operand 2 "")))]
980   ""
981   "CALL%Q0\t%1"
984 (define_insn "msp_return"
985   [(return)]
986   ""
987   { return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); }
990 ;; This pattern is NOT, as expected, a return pattern.  It's called
991 ;; before reload and must only store its operands, and emit a
992 ;; placeholder where the epilog needs to be.  AFTER reload, the
993 ;; placeholder should get expanded into a regular-type epilogue that
994 ;; also does the EH return.
995 (define_expand "eh_return"
996   [(match_operand:HI 0 "")]
997   ""
998   "msp430_expand_eh_return (operands[0]);
999    emit_jump_insn (gen_msp430_eh_epilogue ());
1000    emit_barrier ();
1001    DONE;"
1004 ;; This is the actual EH epilogue.  We emit it in the pattern above,
1005 ;; before reload, and convert it to a real epilogue after reload.
1006 (define_insn_and_split "msp430_eh_epilogue"
1007   [(eh_return)]
1008   ""
1009   "#"
1010   "reload_completed"
1011   [(const_int 0)]
1012   "msp430_expand_epilogue (1); DONE;"
1013   )
1015 (define_insn "jump"
1016   [(set (pc)
1017         (label_ref (match_operand 0 "" "")))]
1018   ""
1019   "BR%Q0\t#%l0"
1022 ;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
1023 ;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c).
1024 (define_insn "indirect_jump"
1025   [(set (pc)
1026         (match_operand 0 "nonimmediate_operand" "rYl"))]
1027   ""
1028   "BR%Q0\t%0"
1031 ;;------------------------------------------------------------
1032 ;; Various Conditionals
1034 (define_expand "cbranch<mode>4"
1035   [(parallel [(set (pc) (if_then_else
1036                          (match_operator 0 ""
1037                                          [(match_operand:QHI 1 "nonimmediate_operand")
1038                                           (match_operand:QHI 2 "general_operand")])
1039                          (label_ref (match_operand 3 "" ""))
1040                          (pc)))
1041               (clobber (reg:BI CARRY))]
1042   )]
1043   ""
1044   "msp430_fixup_compare_operands (<MODE>mode, operands);"
1045   )
1047 (define_insn "cbranchpsi4_real"
1048   [(set (pc) (if_then_else
1049               (match_operator                     0 "msp430_cmp_operator"
1050                               [(match_operand:PSI 1 "nonimmediate_operand" "r,rYs,rm")
1051                                (match_operand:PSI 2 "general_operand"      "rLs,rYsi,rmi")])
1052               (label_ref (match_operand           3 "" ""))
1053               (pc)))
1054    (clobber (reg:BI CARRY))
1055    ]
1056   ""
1057   "@
1058   CMP%Q0\t%2, %1 { J%0\t%l3
1059   CMPX.A\t%2, %1 { J%0\t%l3
1060   CMPX.A\t%2, %1 { J%0\t%l3"
1061   )
1063 (define_insn "cbranchqi4_real"
1064   [(set (pc) (if_then_else
1065               (match_operator                    0 "msp430_cmp_operator"
1066                               [(match_operand:QI 1 "nonimmediate_operand" "rYs,rm")
1067                                (match_operand:QI 2 "general_operand"      "rYsi,rmi")])
1068               (label_ref (match_operand          3 "" ""))
1069               (pc)))
1070    (clobber (reg:BI CARRY))
1071    ]
1072   ""
1073   "@
1074    CMP.B\t%2, %1 { J%0\t%l3
1075    CMP%X0.B\t%2, %1 { J%0\t%l3"
1076   )
1078 (define_insn "cbranchhi4_real"
1079   [(set (pc) (if_then_else
1080               (match_operator                    0 "msp430_cmp_operator"
1081                               [(match_operand:HI 1 "nonimmediate_operand" "rYs,rm")
1082                                (match_operand:HI 2 "general_operand"      "rYsi,rmi")])
1083               (label_ref (match_operand          3 "" ""))
1084               (pc)))
1085    (clobber (reg:BI CARRY))
1086    ]
1087   ""
1088   "@
1089    CMP.W\t%2, %1 { J%0\t%l3
1090    CMP%X0.W\t%2, %1 { J%0\t%l3"
1091   )
1093 (define_insn "cbranchpsi4_reversed"
1094   [(set (pc) (if_then_else
1095               (match_operator                     0 "msp430_reversible_cmp_operator"
1096                               [(match_operand:PSI 1 "general_operand" "rLs,rYsi,rmi")
1097                                (match_operand:PSI 2 "general_operand" "r,rYs,rm")])
1098               (label_ref (match_operand           3 "" ""))
1099               (pc)))
1100    (clobber (reg:BI CARRY))
1101    ]
1102   ""
1103   "@
1104   CMP%Q0\t%1, %2 { J%R0\t%l3
1105   CMPX.A\t%1, %2 { J%R0\t%l3
1106   CMPX.A\t%1, %2 { J%R0\t%l3"
1107   )
1109 (define_insn "cbranchqi4_reversed"
1110   [(set (pc) (if_then_else
1111               (match_operator                    0 "msp430_reversible_cmp_operator"
1112                               [(match_operand:QI 1 "general_operand" "rYsi,rmi")
1113                                (match_operand:QI 2 "general_operand" "rYs,rm")])
1114               (label_ref (match_operand          3 "" ""))
1115               (pc)))
1116    (clobber (reg:BI CARRY))
1117    ]
1118   ""
1119   "@
1120    CMP.B\t%1, %2 { J%R0\t%l3
1121    CMP%X0.B\t%1, %2 { J%R0\t%l3"
1122   )
1124 (define_insn "cbranchhi4_reversed"
1125   [(set (pc) (if_then_else
1126               (match_operator                    0 "msp430_reversible_cmp_operator"
1127                               [(match_operand:HI 1 "general_operand" "rYsi,rmi")
1128                                (match_operand:HI 2 "general_operand" "rYs,rm")])
1129               (label_ref (match_operand          3 "" ""))
1130               (pc)))
1131    (clobber (reg:BI CARRY))
1132    ]
1133   ""
1134   "@
1135    CMP.W\t%1, %2 { J%R0\t%l3
1136    CMP%X0.W\t%1, %2 { J%R0\t%l3"
1137   )
1139 (define_insn "*bitbranch<mode>4"
1140   [(set (pc) (if_then_else
1141               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1142                            (match_operand:QHI 1 "msp_general_operand" "rYsi,rmi"))
1143                   (const_int 0))
1144               (label_ref (match_operand 2 "" ""))
1145               (pc)))
1146    (clobber (reg:BI CARRY))
1147    ]
1148   ""
1149   "@
1150    BIT%x0%b0\t%1, %0 { JNE\t%l2
1151    BIT%X0%b0\t%1, %0 { JNE\t%l2"
1152   )
1154 (define_insn "*bitbranch<mode>4"
1155   [(set (pc) (if_then_else
1156               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1157                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1158                   (const_int 0))
1159               (label_ref (match_operand 2 "" ""))
1160               (pc)))
1161    (clobber (reg:BI CARRY))
1162    ]
1163   ""
1164   "BIT%x0%X0%b0\t%1, %0 { JEQ\t%l2"
1165   )
1167 (define_insn "*bitbranch<mode>4"
1168   [(set (pc) (if_then_else
1169               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1170                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1171                   (const_int 0))
1172               (pc)
1173               (label_ref (match_operand 2 "" ""))))
1174    (clobber (reg:BI CARRY))
1175    ]
1176   ""
1177   "BIT%X0%b0\t%1, %0 { JNE\t%l2"
1178   )
1180 (define_insn "*bitbranch<mode>4"
1181   [(set (pc) (if_then_else
1182               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1183                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1184                   (const_int 0))
1185               (pc)
1186               (label_ref (match_operand 2 "" ""))))
1187    (clobber (reg:BI CARRY))
1188    ]
1189   ""
1190   "BIT%X0%b0\t%1, %0 { JEQ\t%l2"
1191   )
1193 ;;------------------------------------------------------------
1194 ;; zero-extract versions of the above
1196 (define_insn "*bitbranch<mode>4_z"
1197   [(set (pc) (if_then_else
1198               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1199                                     (const_int 1)
1200                                     (match_operand 1 "msp430_bitpos" "i,i"))
1201                   (const_int 0))
1202               (label_ref (match_operand 2 "" ""))
1203               (pc)))
1204    (clobber (reg:BI CARRY))
1205    ]
1206   ""
1207   "@
1208    BIT%x0%b0\t%p1, %0 { JNE\t%l2
1209    BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1210   )
1212 (define_insn "*bitbranch<mode>4_z"
1213   [(set (pc) (if_then_else
1214               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1215                                    (const_int 1)
1216                                    (match_operand 1 "msp430_bitpos" "i"))
1217                   (const_int 0))
1218               (label_ref (match_operand 2 "" ""))
1219               (pc)))
1220    (clobber (reg:BI CARRY))
1221    ]
1222   ""
1223   "BIT%x0%X0%b0\t%p1, %0 { JEQ\t%l2"
1224   )
1226 (define_insn "*bitbranch<mode>4_z"
1227   [(set (pc) (if_then_else
1228               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1229                                    (const_int 1)
1230                                    (match_operand 1 "msp430_bitpos" "i"))
1231                   (const_int 0))
1232               (pc)
1233               (label_ref (match_operand 2 "" ""))))
1234    (clobber (reg:BI CARRY))
1235    ]
1236   ""
1237   "BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1238   )
1240 (define_insn "*bitbranch<mode>4_z"
1241   [(set (pc) (if_then_else
1242               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1243                                    (const_int 1)
1244                                    (match_operand 1 "msp430_bitpos" "i"))
1245                   (const_int 0))
1246               (pc)
1247               (label_ref (match_operand 2 "" ""))))
1248    (clobber (reg:BI CARRY))
1249    ]
1250   ""
1251   "BIT%X0%b0\t%p1, %0 { JEQ\t%l2"
1252   )
1254 ;;------------------------------------------------------------
1255 ;; Misc
1257 (define_insn "nop"
1258   [(const_int 0)]
1259   "1"
1260   "NOP"
1263 (define_insn "disable_interrupts"
1264   [(unspec_volatile [(const_int 0)] UNS_DINT)]
1265   ""
1266   "DINT \; NOP"
1267   )
1269 (define_insn "enable_interrupts"
1270   [(unspec_volatile [(const_int 0)] UNS_EINT)]
1271   ""
1272   "EINT"
1273   )
1275 (define_insn "push_intr_state"
1276   [(unspec_volatile [(const_int 0)] UNS_PUSH_INTR)]
1277   ""
1278   "PUSH\tSR"
1279   )
1281 (define_insn "pop_intr_state"
1282   [(unspec_volatile [(const_int 0)] UNS_POP_INTR)]
1283   ""
1284   "POP\tSR"
1285   )
1287 ;; Clear bits in the copy of the status register that is currently
1288 ;; saved on the stack at the top of the interrupt handler.
1289 (define_insn "bic_SR"
1290   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIC_SR)]
1291   ""
1292   "BIC.W\t%0, %O0(SP)"
1293   )
1295 ;; Set bits in the copy of the status register that is currently
1296 ;; saved on the stack at the top of the interrupt handler.
1297 (define_insn "bis_SR"
1298   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIS_SR)]
1299   ""
1300   "BIS.W\t%0, %O0(SP)"
1301   )
1303 ;; For some reason GCC is generating (set (reg) (and (neg (reg)) (int)))
1304 ;; very late on in the compilation and not splitting it into separate
1305 ;; instructions, so we provide a pattern to support it here.
1306 (define_insn "andneghi3"
1307   [(set (match_operand:HI                 0 "register_operand" "=r")
1308         (and:HI (neg:HI (match_operand:HI 1 "register_operand"  "r"))
1309                 (match_operand            2 "immediate_operand" "n")))]
1310   ""
1311   "*
1312     if (REGNO (operands[0]) != REGNO (operands[1]))
1313       return \"MOV.W\t%1, %0 { SUB.W\t#0, %0 { AND.W\t%2, %0\";
1314     else
1315       return \"SUB.W\t#0, %0 { AND.W\t%2, %0\";
1316   "
1317   )