PR target/59685
[official-gcc.git] / gcc / config / msp430 / msp430.md
blobee01cd1943c3a34be83c6dd1df076e8c0d4a9b74
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
48   ])
49   
50 (include "predicates.md")
51 (include "constraints.md")
53 (define_mode_iterator QHI [QI HI PSI])
55 ;; There are two basic "family" tests we do here:
57 ;; msp430x - true if 430X instructions are available.
58 ;; TARGET_LARGE - true if pointers are 20-bits
60 ;; Note that there are three supported cases, since the base 430
61 ;; doesn't have 20-bit pointers:
63 ;; 1. MSP430 cpu, small model
64 ;; 2. MSP430X cpu, small model.
65 ;; 3. MSP430X cpu, large model.
67 ;;------------------------------------------------------------
68 ;; Moves
70 ;; Push/Pop must be before the generic move patterns
72 (define_insn "push"
73   [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO)))
74         (match_operand:HI 0 "register_operand" "r"))]
75   ""
76   "PUSH\t%0"
77   )
79 (define_insn "pusha"
80   [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO)))
81         (match_operand:PSI 0 "register_operand" "r"))]
82   "TARGET_LARGE"
83   "PUSHX.A\t%0"
84   )
86 (define_insn "pushm"
87   [(unspec_volatile [(match_operand 0 "register_operand" "r")
88                      (match_operand 1 "immediate_operand" "n")] UNS_PUSHM)]
89   ""
90   "PUSHM%b0\t%1, %0"
91   )
93 (define_insn "pop"
94   [(set (match_operand:HI 0 "register_operand" "=r")
95         (mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
96   ""
97   "POP\t%0"
98   )
100 (define_insn "popa"
101   [(set (match_operand:PSI 0 "register_operand" "=r")
102         (mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))]
103   "TARGET_LARGE"
104   "POPX.A\t%0"
105   )
107 ;; This is nasty.  Operand0 is bogus.  It is only there so that we can get a
108 ;; mode for the %b0 to work.  We should use operand1 for this, but that does
109 ;; not have a mode.
110 ;; 
111 ;; Operand1 is actually a register, but we cannot accept (REG...) because the
112 ;; cprop_hardreg pass can and will renumber registers even inside
113 ;; unspec_volatiles.  So we take an integer register number parameter and
114 ;; fudge it to be a register name when we generate the assembler.
116 ;; The pushm pattern does not have this problem because of all of the
117 ;; frame info cruft attached to it, so cprop_hardreg leaves it alone.
118 (define_insn "popm"
119   [(unspec_volatile [(match_operand 0 "register_operand" "r")
120                      (match_operand 1 "immediate_operand" "i")
121                      (match_operand 2 "immediate_operand" "i")] UNS_POPM)]
122   ""
123   "POPM%b0\t%2, r%J1"
124   )
126 ;; The next two patterns are here to support a "feature" of how GCC implements
127 ;; varargs.  When a function uses varargs and the *second* to last named
128 ;; argument is split between argument registers and the stack, gcc expects the
129 ;; callee to allocate space on the stack that can contain the register-based
130 ;; part of the argument.  This space *has* to be just before the remaining
131 ;; arguments (ie the ones that are fully on the stack).
133 ;; The problem is that the MSP430 CALL instruction pushes the return address
134 ;; onto the stack in the exact place where the callee wants to allocate
135 ;; this extra space.  So we need a sequence of instructions that can allocate
136 ;; the extra space and then move the return address down the stack, so that
137 ;; the extra space is now adjacent to the remaining arguments.
139 ;; This could be constructed through regular insns, but they might be split up
140 ;; by a misguided optimization, so an unspec volatile is used instead.
142 (define_insn "grow_and_swap"
143   [(unspec_volatile [(const_int 0)] UNS_GROW_AND_SWAP)]
144   ""
145   { if (TARGET_LARGE)
146       return "SUBA\t#2, r1 \n MOVX.A\t2(r1), 0(r1)";
147     return "SUB\t#2, r1 \n MOV.W\t2(r1), 0(r1)";
148     }
149   )
151 (define_insn "swap_and_shrink"
152   [(unspec_volatile [(const_int 0)] UNS_SWAP_AND_SHRINK)]
153   ""
154   { return TARGET_LARGE
155            ? "MOVX.A\t0(r1), 2(r1) \n ADDA\t#2, SP"
156            : "MOV.W\t0(r1), 2(r1) \n ADD\t#2, SP";
157   })
159 ; I set LOAD_EXTEND_OP and WORD_REGISTER_OPERATIONS, but gcc puts in a
160 ; zero_extend anyway.  Catch it here.
161 (define_insn "movqihi"
162   [(set (match_operand:HI                 0 "register_operand" "=r,r")
163         (zero_extend:HI (match_operand:QI 1 "memory_operand" "Ys,m")))]
164   ""
165   "@
166    MOV.B\t%1, %0
167    MOV%X1.B\t%1, %0"
170 (define_insn "movqi"
171   [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm")
172         (match_operand:QI 1 "msp_general_operand" "riYs,rmi"))]
173   ""
174   "@
175   MOV.B\t%1, %0
176   MOV%X0.B\t%1, %0"
179 (define_insn "movhi"
180   [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm")
181         (match_operand:HI 1 "msp_general_operand" "riYs,rmi"))]
182   ""
183   "@
184   MOV.W\t%1, %0
185   MOV%X0.W\t%1, %0"
188 (define_expand "movsi"
189   [(set (match_operand:SI 0 "nonimmediate_operand")
190         (match_operand:SI 1 "general_operand"))]
191   ""
192   ""
193   )
194   
195 (define_insn_and_split "movsi_x"
196   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
197         (match_operand:SI 1 "general_operand" "rmi"))]
198   ""
199   "#"
200   "reload_completed"
201   [(set (match_operand:HI 2 "nonimmediate_operand")
202         (match_operand:HI 4 "general_operand"))
203    (set (match_operand:HI 3 "nonimmediate_operand")
204         (match_operand:HI 5 "general_operand"))]
205   "msp430_split_movsi (operands);"
208 ;; Some MOVX.A cases can be done with MOVA, this is only a few of them.
209 (define_insn "movpsi"
210   [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,Ya,rm")
211         (match_operand:PSI 1 "msp_general_operand" "riYa,r,rmi"))]
212   ""
213   "@
214   MOV%Q0\t%1, %0
215   MOV%Q0\t%1, %0
216   MOV%X0.%Q0\t%1, %0")
218 ; This pattern is identical to the truncsipsi2 pattern except
219 ; that it uses a SUBREG instead of a TRUNC.  It is needed in
220 ; order to prevent reload from converting (set:SI (SUBREG:PSI (SI)))
221 ; into (SET:PSI (PSI)).
223 ; Note: using POPM.A #1 is two bytes smaller than using POPX.A....
225 (define_insn "movsipsi2"
226   [(set (match_operand:PSI            0 "register_operand" "=r")
227         (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
228   "TARGET_LARGE"
229   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0"
232 ;;------------------------------------------------------------
233 ;; Math
235 (define_insn "addpsi3"
236   [(set (match_operand:PSI           0 "msp_nonimmediate_operand" "=r,rm")
237         (plus:PSI (match_operand:PSI 1 "msp_nonimmediate_operand" "%0,0")
238                   (match_operand:PSI 2 "msp_general_operand"      "rLs,rmi")))]
239   ""
240   "@
241   ADDA\t%2, %0
242   ADDX.A\t%2, %0"
245 (define_insn "addqi3"
246   [(set (match_operand:QI          0 "msp_nonimmediate_operand" "=rYs,rm")
247         (plus:QI (match_operand:QI 1 "msp_nonimmediate_operand" "%0,0")
248                  (match_operand:QI 2 "msp_general_operand"      "riYs,rmi")))]
249   ""
250   "@
251    ADD.B\t%2, %0
252    ADD%X0.B\t%2, %0"
255 (define_insn "addhi3"
256   [(set (match_operand:HI           0 "msp_nonimmediate_operand" "=rYs,rm")
257         (plus:HI (match_operand:HI  1 "msp_nonimmediate_operand" "%0,0")
258                   (match_operand:HI 2 "msp_general_operand"      "riYs,rmi")))]
259   ""
260   "@
261    ADD.W\t%2, %0
262    ADD%X0.W\t%2, %0"
265 ; This pattern is needed in order to avoid reload problems.
266 ; It takes an SI pair of registers, adds a value to them, and
267 ; then converts them into a single PSI register.
269 (define_insn "addsipsi3"
270   [(set (subreg:SI (match_operand:PSI 0 "register_operand" "=&r") 0)
271         (plus:SI (match_operand:SI    1 "register_operand" "0")
272                  (match_operand       2 "general_operand" "rmi")))]
273   ""
274   "ADD.W\t%L2, %L0 { ADDC.W\t%H2, %H0 { PUSH.W\t%H0 { PUSH.W\t%L0 { POPM.A\t#1, %0"
277 (define_insn "addsi3"
278   [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,rm")
279         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
280                  (match_operand:SI 2 "general_operand" "r,mi")))]
281   ""
282   "@
283    ADD\t%L2, %L0 { ADDC\t%H2, %H0
284    ADD%X0\t%L2, %L0 { ADDC%X0\t%H2, %H0"
287 ; Version of addhi that exposes the carry operations, for SImode adds.
289 ; NOTE - we are playing a dangerous game with GCC here.  We have these two
290 ; add patterns and the splitter that follows because our tests have shown
291 ; that this results in a significant reduction in code size - because GCC is
292 ; able to discard any unused part of the addition.  We have to annotate the
293 ; patterns with the set and use of the carry flag because otherwise GCC will
294 ; discard parts of the addition when they are actually needed.  But we have
295 ; not annotated all the other patterns that set the CARRY flag as doing so
296 ; results in an overall increase in code size[1].  Instead we just *hope*
297 ; that GCC will not move a carry-setting instruction in between the first
298 ; and second adds.
300 ; So far our experiments have shown that GCC is likely to move MOV and CMP
301 ; instructions in between the two adds, but not other instructions.  MOV is
302 ; safe, CMP is not.  So we have annotated the CMP patterns and left the
303 ; subtract, shift and other add patterns alone.  At the moment this is
304 ; working, but with future changes to the generic parts of GCC that might
305 ; change.
307 ; [1] It is not clear exactly why the code size increases.  The cause appears
308 ; to be that reload is more prevelent to spilling a variable onto the stack
309 ; but why it does this is unknown.  Possibly the additional CLOBBERs necessary
310 ; to correctly annotate the other patterns makes reload think that there is
311 ; increased register pressure.  Or possibly reload does not handle ADD patterns
312 ; that are not single_set() very well.
314 (define_insn "addhi3_cy"
315   [(set (match_operand:HI          0 "msp_nonimmediate_operand" "=r,rm")
316         (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
317                  (match_operand:HI 2 "msp_nonimmediate_operand" "r,rm")))
318    (set (reg:BI CARRY)
319         (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
320                                            (zero_extend:SI (match_dup 2)))
321                                   (const_int 16))))
322    ]
323   ""
324   "@
325    ADD\t%2, %1 ; cy
326    ADD%X0\t%2, %1 ; cy"
327   )
329 (define_insn "addhi3_cy_i"
330   [(set (match_operand:HI          0 "nonimmediate_operand" "=r,rm")
331         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
332                  (match_operand:HI 2 "immediate_operand"     "i,i")))
333    (set (reg:BI CARRY)
334         (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
335                                            (match_operand 3 "immediate_operand" "i,i"))
336                                   (const_int 16))))
337    ]
338   ""
339   "@
340    ADD\t%2, %1 ; cy
341    ADD%X0\t%2, %1 ; cy"
342   )
344 ; Version of addhi that adds the carry, for SImode adds.
345 (define_insn "addchi4_cy"
346   [(set (match_operand:HI                   0 "msp_nonimmediate_operand" "=r,rm")
347         (plus:HI (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
348                           (match_operand:HI 2 "msp_general_operand"      "ri,rmi"))
349                  (zero_extend:HI (reg:BI CARRY))))
350    ]
351   ""
352   "@
353    ADDC\t%2, %1
354    ADDC%X0\t%2, %1"
355   )
357 ; Split an SImode add into two HImode adds, keeping track of the carry
358 ; so that gcc knows when it can and can't optimize away the two
359 ; halves.
360 (define_split
361   [(set (match_operand:SI          0 "msp430_nonsubreg_operand")
362         (plus:SI (match_operand:SI 1 "nonimmediate_operand")
363                  (match_operand:SI 2 "general_operand")))
364    ]
365   ""
366   [(parallel [(set (match_operand:HI 3 "nonimmediate_operand" "=&rm")
367                    (plus:HI (match_dup 4)
368                             (match_dup 5)))
369               (set (reg:BI CARRY)
370                    (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 4))
371                                                       (match_dup 9))
372                                              (const_int 16))))
373               ])
374    (set (match_operand:HI 6 "nonimmediate_operand" "=&rm")
375         (plus:HI (plus:HI (match_dup 7)
376                           (match_dup 8))
377                  (zero_extend:HI (reg:BI CARRY))))
378    ]
379   "
380    operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
381    operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
382    operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
383    operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
384    operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
385    operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
386    if (GET_CODE (operands[5]) == CONST_INT)
387      {
388        operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
389      }
390    else
391      {
392        operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
393      }
394    "
395   )
398 ;; Alternatives 2 and 3 are to handle cases generated by reload.
399 (define_insn "subpsi3"
400   [(set (match_operand:PSI            0 "nonimmediate_operand" "=r,   rm, &?r, ?&r")
401         (minus:PSI (match_operand:PSI 1 "general_operand"       "0,   0,   !r,  !i")
402                    (match_operand:PSI 2 "general_operand"       "rLs, rmi, rmi,  r")))]
403   ""
404   "@
405   SUBA\t%2, %0
406   SUBX.A\t%2, %0
407   MOVX.A\t%1, %0 { SUBX.A\t%2, %0
408   MOVX.A\t%1, %0 { SUBA\t%2, %0"
411 ;; Alternatives 2 and 3 are to handle cases generated by reload.
412 (define_insn "subqi3"
413   [(set (match_operand:QI           0 "nonimmediate_operand" "=rYs,  rm,  &?r, ?&r")
414         (minus:QI (match_operand:QI 1 "general_operand"       "0,    0,    !r,  !i")
415                   (match_operand:QI 2 "general_operand"      " riYs, rmi, rmi,   r")))]
416   ""
417   "@
418   SUB.B\t%2, %0
419   SUB%X0.B\t%2, %0
420   MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0
421   MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0"
424 ;; Alternatives 2 and 3 are to handle cases generated by reload.
425 (define_insn "subhi3"
426   [(set (match_operand:HI           0 "nonimmediate_operand" "=rYs,  rm,  &?r, ?&r")
427         (minus:HI (match_operand:HI 1 "general_operand"       "0,    0,    !r,  !i")
428                   (match_operand:HI 2 "general_operand"      " riYs, rmi, rmi,   r")))]
429   ""
430   "@
431   SUB.W\t%2, %0
432   SUB%X0.W\t%2, %0
433   MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0
434   MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0"
437 (define_insn "subsi3"
438   [(set (match_operand:SI           0 "nonimmediate_operand" "=&rm")
439         (minus:SI (match_operand:SI 1 "nonimmediate_operand"   "0")
440                   (match_operand:SI 2 "general_operand"        "rmi")))]
441   ""
442   "SUB%X0\t%L2, %L0 { SUBC%X0\t%H2, %H0"
445 (define_insn "*bic<mode>_cg"
446   [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m")
447         (and:QHI (match_operand:QHI 1 "msp_general_operand" "0,0")
448                  (match_operand 2 "msp430_inv_constgen_operator" "n,n")))]
449   ""
450   "@
451    BIC%x0%b0\t#%I2, %0
452    BIC%X0%b0\t#%I2, %0"
455 (define_insn "bic<mode>3"
456   [(set (match_operand:QHI                   0 "msp_nonimmediate_operand" "=rYs,rm")
457         (and:QHI (not:QHI (match_operand:QHI 1 "msp_general_operand"       "rYs,rmn"))
458                  (match_operand:QHI          2 "msp_nonimmediate_operand"  "0,0")))]
459   ""
460   "@
461    BIC%x0%b0\t%1, %0
462    BIC%X0%b0\t%1, %0"
465 (define_insn "and<mode>3"
466   [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
467         (and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
468                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
469   ""
470   "@
471    AND%x0%b0\t%2, %0
472    AND%X0%b0\t%2, %0"
475 (define_insn "ior<mode>3"
476   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,rm")
477         (ior:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
478                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
479   ""
480   "@
481    BIS%x0%b0\t%2, %0
482    BIS%X0%b0\t%2, %0"
485 (define_insn "xor<mode>3"
486   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,rm")
487         (xor:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
488                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
489   ""
490   "@
491    XOR%x0%b0\t%2, %0
492    XOR%X0%b0\t%2, %0"
495 ;; Macro : XOR #~0, %0
496 (define_insn "one_cmpl<mode>2"
497   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,m")
498         (not:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "0,0")))]
499   ""
500   "@
501    INV%x0%b0\t%0
502    INV%X0%b0\t%0"
505 (define_insn "extendqihi2"
506   [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,m")
507         (sign_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
508   ""
509   "@
510    SXT%X0\t%0
511    SXT%X0\t%0"
514 (define_insn "zero_extendqihi2"
515   [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,m")
516         (zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
517   ""
518   "@
519    AND\t#0xff, %0
520    AND%X0\t#0xff, %0"
523 ;; Eliminate extraneous zero-extends mysteriously created by gcc.
524 (define_peephole2
525   [(set (match_operand:HI 0 "register_operand")
526         (zero_extend:HI (match_operand:QI 1 "general_operand")))
527    (set (match_operand:HI 2 "register_operand")
528         (zero_extend:HI (match_operand:QI 3 "register_operand")))]
529   "REGNO (operands[0]) == REGNO (operands[2]) && REGNO (operands[2]) == REGNO (operands[3])"
530   [(set (match_dup 0)
531         (zero_extend:HI (match_dup 1)))]
533    
534 (define_insn "zero_extendhipsi2"
535   [(set (match_operand:PSI                 0 "msp_nonimmediate_operand" "=r,m")
536         (zero_extend:PSI (match_operand:HI 1 "msp_nonimmediate_operand" "rm,r")))]
537   ""
538   "MOVX\t%1, %0"
541 (define_insn "truncpsihi2"
542   [(set (match_operand:HI               0 "msp_nonimmediate_operand" "=rm")
543         (truncate:HI (match_operand:PSI 1 "register_operand"      "r")))]
544   ""
545   "MOVX\t%1, %0"
548 (define_insn "extendhisi2"
549   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
550         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
551   ""
552   { return msp430x_extendhisi (operands); }
555 (define_insn "extendhipsi2"
556   [(set (match_operand:PSI 0 "nonimmediate_operand" "=r")
557         (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))]
558   "TARGET_LARGE"
559   "RLAM #4, %0 { RRAM #4, %0"
562 ;; Look for cases where integer/pointer conversions are suboptimal due
563 ;; to missing patterns, despite us not having opcodes for these
564 ;; patterns.  Doing these manually allows for alternate optimization
565 ;; paths.
566 (define_insn "zero_extendhisi2"
567   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
568         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
569   "TARGET_LARGE"
570   "MOV.W\t#0,%H0"
573 (define_insn "zero_extendhisipsi2"
574   [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r")
575         (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))]
576   "TARGET_LARGE"
577   "@
578    AND.W\t#-1,%0
579    MOV.W\t%1,%0"
582 (define_insn "extend_and_shift1_hipsi2"
583   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
584         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
585                    (const_int 1)))]
586   "TARGET_LARGE"
587   "RLAM #4, %0 { RRAM #3, %0"
590 (define_insn "extend_and_shift2_hipsi2"
591   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
592         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
593                    (const_int 2)))]
594   "TARGET_LARGE"
595   "RLAM #4, %0 { RRAM #2, %0"
598 ; Nasty - we are sign-extending a 20-bit PSI value in one register into
599 ; two adjacent 16-bit registers to make an SI value.  There is no MSP430X
600 ; instruction that will do this, so we push the 20-bit value onto the stack
601 ; and then pop it off as two 16-bit values.
603 ; FIXME: The MSP430X documentation does not specify if zero-extension or
604 ; sign-extension happens when the 20-bit value is pushed onto the stack.
605 ; It is probably zero-extension, but if not this pattern will not work
606 ; when the PSI value is negative..
608 ; Note: using PUSHM.A #1 is two bytes smaller than using PUSHX.A....
610 (define_insn "zero_extendpsisi2"
611   [(set (match_operand:SI                  0 "register_operand" "=r")
612         (zero_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
613   ""
614   "*
615     if (REGNO (operands[1]) == SP_REGNO)
616       /* If the source register is the stack pointer, the value
617          stored in the stack slot will be the value *after* the
618          stack pointer has been decremented.  So allow for that
619          here.  */
620       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\";
621     else
622       return \"PUSHM.A\t#1, %1 { POPX.W\t%L0 { POPX.W\t%H0 ; move pointer in %1 into reg-pair %L0:%H0\";
623   "
626 ;; We also need to be able to sign-extend pointer types (eg ptrdiff_t).
627 ;; Since (we assume) pushing a 20-bit value onto the stack zero-extends
628 ;; it, we use a different method here.
630 (define_insn "extendpsisi2"
631   [(set (match_operand:SI                  0 "register_operand" "=r")
632         (sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
633   "TARGET_LARGE"
634   "*
635     /* The intention here is that we copy the bottom 16-bits of
636        %1 into %L0 (zeroing the top four bits).  Then we copy the
637        entire 20-bits of %1 into %H0 and then arithmetically shift
638        it right by 16 bits, to get the top four bits of the pointer
639        sign-extended in %H0.  */
640     if (REGNO (operands[0]) == REGNO (operands[1]))
641       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\";
642     else
643       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\";
644   "
647 ; See the movsipsi2 pattern above for another way that GCC performs this
648 ; conversion.
649 (define_insn "truncsipsi2"
650   [(set (match_operand:PSI              0 "register_operand" "=r")
651         (truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
652   ""
653   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A\t#1, %L0"
656 ;;------------------------------------------------------------
657 ;; Shift Functions
659 ;; Note:  We do not use the RPT ... SHIFT instruction sequence
660 ;; when the repeat count is in a register, because even though RPT
661 ;; accepts counts in registers, it does not work if the count is
662 ;; zero, and the actual count in the register has to be one less
663 ;; than the required number of iterations.  We could encode a
664 ;; seqeunce like this:
666 ;;   bit #0xf, Rn
667 ;;   bz  1f
668 ;;   dec Rn
669 ;;   rpt Rn
670 ;;   <shift> Rm
671 ;;   inc Rn
672 ;; 1:
674 ;; But is longer than calling a helper function, and we are mostly
675 ;; concerned with code size.  FIXME: Maybe enable a sequence like
676 ;; this at -O3 and above ?
678 ;; Note - we ignore shift counts of less than one or more than 15.
679 ;; This is permitted by the ISO C99 standard as such shifts result
680 ;; in "undefined" behaviour.  [6.5.7 (3)]
682 ;; signed A << C
684 (define_expand "ashlhi3"
685   [(set (match_operand:HI            0 "nonimmediate_operand")
686         (ashift:HI (match_operand:HI 1 "general_operand")
687                    (match_operand:HI 2 "general_operand")))]
688   ""
689   {
690     if (msp430x
691         && REG_P (operands[0])
692         && REG_P (operands[1])
693         && CONST_INT_P (operands[2]))
694       emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2]));
695     else                 
696       msp430_expand_helper (operands, \"__mspabi_slli\", true);
697     DONE;
698   }
701 (define_insn "slli_1"
702   [(set (match_operand:HI            0 "nonimmediate_operand" "=rm")
703         (ashift:HI (match_operand:HI 1 "general_operand"       "0")
704                    (const_int 1)))]
705   ""
706   "RLA.W\t%0" ;; Note - this is a macro for ADD
709 (define_insn "430x_shift_left"
710   [(set (match_operand:HI            0 "register_operand" "=r")
711         (ashift:HI (match_operand:HI 1 "register_operand"  "0")
712                    (match_operand    2 "immediate_operand" "n")))]
713   "msp430x"
714   "*
715   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
716     return \"rpt\t%2 { rlax.w\t%0\";
717   return \"# nop left shift\";
718   "
721 (define_insn "slll_1"
722   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
723         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
724                    (const_int 1)))]
725   ""
726   "RLA.W\t%L0 { RLC.W\t%H0"
729 (define_insn "slll_2"
730   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
731         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
732                    (const_int 2)))]
733   ""
734   "RLA.W\t%L0 { RLC.W\t%H0 { RLA.W\t%L0 { RLC.W\t%H0"
737 (define_expand "ashlsi3"
738   [(set (match_operand:SI            0 "nonimmediate_operand")
739         (ashift:SI (match_operand:SI 1 "general_operand")
740                    (match_operand:SI 2 "general_operand")))]
741   ""
742   "msp430_expand_helper (operands, \"__mspabi_slll\", true);
743    DONE;"
746 ;;----------
748 ;; signed A >> C
750 (define_expand "ashrhi3"
751   [(set (match_operand:HI              0 "nonimmediate_operand")
752         (ashiftrt:HI (match_operand:HI 1 "general_operand")
753                      (match_operand:HI 2 "general_operand")))]
754   ""
755   {
756     if (msp430x
757         && REG_P (operands[0])
758         && REG_P (operands[1])
759         && CONST_INT_P (operands[2]))
760       emit_insn (gen_430x_arithmetic_shift_right (operands[0], operands[1], operands[2]));
761     else                 
762        msp430_expand_helper (operands, \"__mspabi_srai\", true);
763    DONE;
764    }
767 (define_insn "srai_1"
768   [(set (match_operand:HI              0 "msp_nonimmediate_operand" "=rm")
769         (ashiftrt:HI (match_operand:HI 1 "msp_general_operand"      "0")
770                      (const_int 1)))]
771   ""
772   "RRA.W\t%0"
775 (define_insn "430x_arithmetic_shift_right"
776   [(set (match_operand:HI              0 "register_operand" "=r")
777         (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0")
778                      (match_operand    2 "immediate_operand" "n")))]
779   "msp430x"
780   "*
781   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
782     return \"rpt\t%2 { rrax.w\t%0\";
783   return \"# nop arith right shift\";
784   "
787 (define_insn "srap_1"
788   [(set (match_operand:PSI              0 "register_operand" "=r")
789         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
790                       (const_int 1)))]
791   "msp430x"
792   "RRAM.A #1,%0"
795 (define_insn "srap_2"
796   [(set (match_operand:PSI              0 "register_operand" "=r")
797         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
798                       (const_int 2)))]
799   "msp430x"
800   "RRAM.A #2,%0"
803 (define_insn "sral_1"
804   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
805         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
806                      (const_int 1)))]
807   ""
808   "RRA.W\t%H0 { RRC.W\t%L0"
811 (define_insn "sral_2"
812   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
813         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
814                      (const_int 2)))]
815   ""
816   "RRA.W\t%H0 { RRC.W\t%L0 { RRA.W\t%H0 { RRC.W\t%L0"
819 (define_expand "ashrsi3"
820   [(set (match_operand:SI              0 "nonimmediate_operand")
821         (ashiftrt:SI (match_operand:SI 1 "general_operand")
822                      (match_operand:SI 2 "general_operand")))]
823   ""
824   "msp430_expand_helper (operands, \"__mspabi_sral\", true);
825    DONE;"
828 ;;----------
830 ;; unsigned A >> C
832 (define_expand "lshrhi3"
833   [(set (match_operand:HI              0 "nonimmediate_operand")
834         (lshiftrt:HI (match_operand:HI 1 "general_operand")
835                      (match_operand:HI 2 "general_operand")))]
836   ""
837   {
838     if (msp430x
839         && REG_P (operands[0])
840         && REG_P (operands[1])
841         && CONST_INT_P (operands[2]))
842       emit_insn (gen_430x_logical_shift_right (operands[0], operands[1], operands[2]));
843     else                 
844       msp430_expand_helper (operands, \"__mspabi_srli\", true);
845     DONE;
846   }
849 (define_insn "srli_1"
850   [(set (match_operand:HI              0 "nonimmediate_operand" "=rm")
851         (lshiftrt:HI (match_operand:HI 1 "general_operand"       "0")
852                      (const_int 1)))]
853   ""
854   "CLRC { RRC.W\t%0"
857 (define_insn "430x_logical_shift_right"
858   [(set (match_operand:HI              0 "register_operand" "=r")
859         (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0")
860                      (match_operand    2 "immediate_operand" "n")))]
861   "msp430x"
862   {
863     return msp430x_logical_shift_right (operands[2]);
864   }
867 (define_insn "srlp_1"
868   [(set (match_operand:PSI              0 "register_operand" "=r")
869         (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
870                       (const_int 1)))]
871   ""
872   "RRUM.A #1,%0"
875 (define_insn "srll_1"
876   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
877         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
878                      (const_int 1)))]
879   ""
880   "CLRC { RRC.W\t%H0 { RRC.W\t%L0"
883 (define_insn "srll_2x"
884   [(set (match_operand:SI              0 "nonimmediate_operand" "=r")
885         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
886                      (const_int 2)))]
887   "msp430x"
888   "RRUX.W\t%H0 { RRC.W\t%L0 { RRUX.W\t%H0 { RRC.W\t%L0"
891 (define_expand "lshrsi3"
892   [(set (match_operand:SI              0 "nonimmediate_operand")
893         (lshiftrt:SI (match_operand:SI 1 "general_operand")
894                      (match_operand:SI 2 "general_operand")))]
895   ""
896   "msp430_expand_helper (operands, \"__mspabi_srll\", true);
897    DONE;"
900 ;;------------------------------------------------------------
901 ;; Function Entry/Exit
903 (define_expand "prologue"
904   [(const_int 0)]
905   ""
906   "msp430_expand_prologue (); DONE;"
907   )
909 (define_expand "epilogue"
910   [(const_int 0)]
911   ""
912   "msp430_expand_epilogue (0); DONE;"
913   )
916 (define_insn "epilogue_helper"
917   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)]
918   ""
919   "BR%Q0\t#__mspabi_func_epilog_%J0"
920   )
923 (define_insn "prologue_start_marker"
924   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)]
925   ""
926   "; start of prologue"
927   )
929 (define_insn "prologue_end_marker"
930   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)]
931   ""
932   "; end of prologue"
933   )
935 (define_insn "epilogue_start_marker"
936   [(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)]
937   ""
938   "; start of epilogue"
939   )
941 ;;------------------------------------------------------------
942 ;; Jumps
944 (define_expand "call"
945   [(call:HI (match_operand 0 "")
946             (match_operand 1 ""))]
947   ""
948   ""
951 (define_insn "call_internal"
952   [(call (mem:HI (match_operand 0 "general_operand" "rYci"))
953          (match_operand 1 ""))]
954   ""
955   "CALL%Q0\t%0"
958 (define_expand "call_value"
959   [(set (match_operand          0 "register_operand")
960         (call:HI (match_operand 1 "general_operand")
961                  (match_operand 2 "")))]
962   ""
963   ""
966 (define_insn "call_value_internal"
967   [(set (match_operand               0 "register_operand" "=r")
968         (call (mem:HI (match_operand 1 "general_operand" "rYci"))
969               (match_operand 2 "")))]
970   ""
971   "CALL%Q0\t%1"
974 (define_insn "msp_return"
975   [(return)]
976   ""
977   { return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); }
980 ;; This pattern is NOT, as expected, a return pattern.  It's called
981 ;; before reload and must only store its operands, and emit a
982 ;; placeholder where the epilog needs to be.  AFTER reload, the
983 ;; placeholder should get expanded into a regular-type epilogue that
984 ;; also does the EH return.
985 (define_expand "eh_return"
986   [(match_operand:HI 0 "")]
987   ""
988   "msp430_expand_eh_return (operands[0]);
989    emit_jump_insn (gen_msp430_eh_epilogue ());
990    emit_barrier ();
991    DONE;"
994 ;; This is the actual EH epilogue.  We emit it in the pattern above,
995 ;; before reload, and convert it to a real epilogue after reload.
996 (define_insn_and_split "msp430_eh_epilogue"
997   [(eh_return)]
998   ""
999   "#"
1000   "reload_completed"
1001   [(const_int 0)]
1002   "msp430_expand_epilogue (1); DONE;"
1003   )
1005 (define_insn "jump"
1006   [(set (pc)
1007         (label_ref (match_operand 0 "" "")))]
1008   ""
1009   "BR%Q0\t#%l0"
1012 ;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
1013 ;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c).
1014 (define_insn "indirect_jump"
1015   [(set (pc)
1016         (match_operand 0 "nonimmediate_operand" "rYl"))]
1017   ""
1018   "BR%Q0\t%0"
1021 ;;------------------------------------------------------------
1022 ;; Various Conditionals
1024 (define_expand "cbranch<mode>4"
1025   [(parallel [(set (pc) (if_then_else
1026                          (match_operator 0 ""
1027                                          [(match_operand:QHI 1 "nonimmediate_operand")
1028                                           (match_operand:QHI 2 "general_operand")])
1029                          (label_ref (match_operand 3 "" ""))
1030                          (pc)))
1031               (clobber (reg:BI CARRY))]
1032   )]
1033   ""
1034   "msp430_fixup_compare_operands (<MODE>mode, operands);"
1035   )
1037 (define_insn "cbranchpsi4_real"
1038   [(set (pc) (if_then_else
1039               (match_operator                     0 "msp430_cmp_operator"
1040                               [(match_operand:PSI 1 "nonimmediate_operand" "r,rYs,rm")
1041                                (match_operand:PSI 2 "general_operand"      "rLs,rYsi,rmi")])
1042               (label_ref (match_operand           3 "" ""))
1043               (pc)))
1044    (clobber (reg:BI CARRY))
1045    ]
1046   ""
1047   "@
1048   CMP%Q0\t%2, %1 { J%0\t%l3
1049   CMPX.A\t%2, %1 { J%0\t%l3
1050   CMPX.A\t%2, %1 { J%0\t%l3"
1051   )
1053 (define_insn "cbranchqi4_real"
1054   [(set (pc) (if_then_else
1055               (match_operator                    0 "msp430_cmp_operator"
1056                               [(match_operand:QI 1 "nonimmediate_operand" "rYs,rm")
1057                                (match_operand:QI 2 "general_operand"      "rYsi,rmi")])
1058               (label_ref (match_operand          3 "" ""))
1059               (pc)))
1060    (clobber (reg:BI CARRY))
1061    ]
1062   ""
1063   "@
1064    CMP.B\t%2, %1 { J%0\t%l3
1065    CMP%X0.B\t%2, %1 { J%0\t%l3"
1066   )
1068 (define_insn "cbranchhi4_real"
1069   [(set (pc) (if_then_else
1070               (match_operator                    0 "msp430_cmp_operator"
1071                               [(match_operand:HI 1 "nonimmediate_operand" "rYs,rm")
1072                                (match_operand:HI 2 "general_operand"      "rYsi,rmi")])
1073               (label_ref (match_operand          3 "" ""))
1074               (pc)))
1075    (clobber (reg:BI CARRY))
1076    ]
1077   ""
1078   "@
1079    CMP.W\t%2, %1 { J%0\t%l3
1080    CMP%X0.W\t%2, %1 { J%0\t%l3"
1081   )
1083 (define_insn "cbranchpsi4_reversed"
1084   [(set (pc) (if_then_else
1085               (match_operator                     0 "msp430_reversible_cmp_operator"
1086                               [(match_operand:PSI 1 "general_operand" "rLs,rYsi,rmi")
1087                                (match_operand:PSI 2 "general_operand" "r,rYs,rm")])
1088               (label_ref (match_operand           3 "" ""))
1089               (pc)))
1090    (clobber (reg:BI CARRY))
1091    ]
1092   ""
1093   "@
1094   CMP%Q0\t%1, %2 { J%R0\t%l3
1095   CMPX.A\t%1, %2 { J%R0\t%l3
1096   CMPX.A\t%1, %2 { J%R0\t%l3"
1097   )
1099 (define_insn "cbranchqi4_reversed"
1100   [(set (pc) (if_then_else
1101               (match_operator                    0 "msp430_reversible_cmp_operator"
1102                               [(match_operand:QI 1 "general_operand" "rYsi,rmi")
1103                                (match_operand:QI 2 "general_operand" "rYs,rm")])
1104               (label_ref (match_operand          3 "" ""))
1105               (pc)))
1106    (clobber (reg:BI CARRY))
1107    ]
1108   ""
1109   "@
1110    CMP.B\t%1, %2 { J%R0\t%l3
1111    CMP%X0.B\t%1, %2 { J%R0\t%l3"
1112   )
1114 (define_insn "cbranchhi4_reversed"
1115   [(set (pc) (if_then_else
1116               (match_operator                    0 "msp430_reversible_cmp_operator"
1117                               [(match_operand:HI 1 "general_operand" "rYsi,rmi")
1118                                (match_operand:HI 2 "general_operand" "rYs,rm")])
1119               (label_ref (match_operand          3 "" ""))
1120               (pc)))
1121    (clobber (reg:BI CARRY))
1122    ]
1123   ""
1124   "@
1125    CMP.W\t%1, %2 { J%R0\t%l3
1126    CMP%X0.W\t%1, %2 { J%R0\t%l3"
1127   )
1129 (define_insn "*bitbranch<mode>4"
1130   [(set (pc) (if_then_else
1131               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1132                            (match_operand:QHI 1 "msp_general_operand" "rYsi,rmi"))
1133                   (const_int 0))
1134               (label_ref (match_operand 2 "" ""))
1135               (pc)))
1136    (clobber (reg:BI CARRY))
1137    ]
1138   ""
1139   "@
1140    BIT%x0%b0\t%1, %0 { JNE\t%l2
1141    BIT%X0%b0\t%1, %0 { JNE\t%l2"
1142   )
1144 (define_insn "*bitbranch<mode>4"
1145   [(set (pc) (if_then_else
1146               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1147                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1148                   (const_int 0))
1149               (label_ref (match_operand 2 "" ""))
1150               (pc)))
1151    (clobber (reg:BI CARRY))
1152    ]
1153   ""
1154   "BIT%x0%X0%b0\t%1, %0 { JEQ\t%l2"
1155   )
1157 (define_insn "*bitbranch<mode>4"
1158   [(set (pc) (if_then_else
1159               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1160                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1161                   (const_int 0))
1162               (pc)
1163               (label_ref (match_operand 2 "" ""))))
1164    (clobber (reg:BI CARRY))
1165    ]
1166   ""
1167   "BIT%X0%b0\t%1, %0 { JNE\t%l2"
1168   )
1170 (define_insn "*bitbranch<mode>4"
1171   [(set (pc) (if_then_else
1172               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1173                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1174                   (const_int 0))
1175               (pc)
1176               (label_ref (match_operand 2 "" ""))))
1177    (clobber (reg:BI CARRY))
1178    ]
1179   ""
1180   "BIT%X0%b0\t%1, %0 { JEQ\t%l2"
1181   )
1183 ;;------------------------------------------------------------
1184 ;; zero-extract versions of the above
1186 (define_insn "*bitbranch<mode>4_z"
1187   [(set (pc) (if_then_else
1188               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1189                                     (const_int 1)
1190                                     (match_operand 1 "msp430_bitpos" "i,i"))
1191                   (const_int 0))
1192               (label_ref (match_operand 2 "" ""))
1193               (pc)))
1194    (clobber (reg:BI CARRY))
1195    ]
1196   ""
1197   "@
1198    BIT%x0%b0\t%p1, %0 { JNE\t%l2
1199    BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1200   )
1202 (define_insn "*bitbranch<mode>4_z"
1203   [(set (pc) (if_then_else
1204               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1205                                    (const_int 1)
1206                                    (match_operand 1 "msp430_bitpos" "i"))
1207                   (const_int 0))
1208               (label_ref (match_operand 2 "" ""))
1209               (pc)))
1210    (clobber (reg:BI CARRY))
1211    ]
1212   ""
1213   "BIT%x0%X0%b0\t%p1, %0 { JEQ\t%l2"
1214   )
1216 (define_insn "*bitbranch<mode>4_z"
1217   [(set (pc) (if_then_else
1218               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1219                                    (const_int 1)
1220                                    (match_operand 1 "msp430_bitpos" "i"))
1221                   (const_int 0))
1222               (pc)
1223               (label_ref (match_operand 2 "" ""))))
1224    (clobber (reg:BI CARRY))
1225    ]
1226   ""
1227   "BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1228   )
1230 (define_insn "*bitbranch<mode>4_z"
1231   [(set (pc) (if_then_else
1232               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1233                                    (const_int 1)
1234                                    (match_operand 1 "msp430_bitpos" "i"))
1235                   (const_int 0))
1236               (pc)
1237               (label_ref (match_operand 2 "" ""))))
1238    (clobber (reg:BI CARRY))
1239    ]
1240   ""
1241   "BIT%X0%b0\t%p1, %0 { JEQ\t%l2"
1242   )
1244 ;;------------------------------------------------------------
1245 ;; Misc
1247 (define_insn "nop"
1248   [(const_int 0)]
1249   "1"
1250   "NOP"
1253 (define_insn "disable_interrupts"
1254   [(unspec_volatile [(const_int 0)] UNS_DINT)]
1255   ""
1256   "DINT \; NOP"
1257   )
1259 (define_insn "enable_interrupts"
1260   [(unspec_volatile [(const_int 0)] UNS_EINT)]
1261   ""
1262   "EINT"
1263   )
1265 (define_insn "push_intr_state"
1266   [(unspec_volatile [(const_int 0)] UNS_PUSH_INTR)]
1267   ""
1268   "PUSH\tSR"
1269   )
1271 (define_insn "pop_intr_state"
1272   [(unspec_volatile [(const_int 0)] UNS_POP_INTR)]
1273   ""
1274   "POP\tSR"
1275   )
1277 ;; Clear bits in the copy of the status register that is currently
1278 ;; saved on the stack at the top of the interrupt handler.
1279 (define_insn "bic_SR"
1280   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIC_SR)]
1281   ""
1282   "BIC.W\t%0, %O0(SP)"
1283   )
1285 ;; Set bits in the copy of the status register that is currently
1286 ;; saved on the stack at the top of the interrupt handler.
1287 (define_insn "bis_SR"
1288   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIS_SR)]
1289   ""
1290   "BIS.W\t%0, %O0(SP)"
1291   )
1293 ;; For some reason GCC is generating (set (reg) (and (neg (reg)) (int)))
1294 ;; very late on in the compilation and not splitting it into separate
1295 ;; instructions, so we provide a pattern to support it here.
1296 (define_insn "andneghi3"
1297   [(set (match_operand:HI                 0 "register_operand" "=r")
1298         (and:HI (neg:HI (match_operand:HI 1 "register_operand"  "r"))
1299                 (match_operand            2 "immediate_operand" "n")))]
1300   ""
1301   "*
1302     if (REGNO (operands[0]) != REGNO (operands[1]))
1303       return \"MOV.W\t%1, %0 { SUB.W\t#0, %0 { AND.W\t%2, %0\";
1304     else
1305       return \"SUB.W\t#0, %0 { AND.W\t%2, %0\";
1306   "
1307   )