Merged revisions 208012,208018-208019,208021,208023-208030,208033,208037,208040-20804...
[official-gcc.git] / main / gcc / config / msp430 / msp430.md
blobc0c97dae6bd046e22e50fe003dff825db962e22f
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   ])
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   "*
148     if (TARGET_LARGE)
149       return \"SUBA\t#2, r1 { MOVX.A\t2(r1), 0(r1)\";
150     return \"SUB\t#2, r1 { MOV.W\t2(r1), 0(r1)\";
151   "
154 (define_insn "swap_and_shrink"
155   [(unspec_volatile [(const_int 0)] UNS_SWAP_AND_SHRINK)]
156   ""
157   "* return TARGET_LARGE
158            ? \"MOVX.A\t0(r1), 2(r1) { ADDA\t#2, SP\"
159            : \"MOV.W\t0(r1), 2(r1) { ADD\t#2, SP\";
160   ")
162 ; I set LOAD_EXTEND_OP and WORD_REGISTER_OPERATIONS, but gcc puts in a
163 ; zero_extend anyway.  Catch it here.
164 (define_insn "movqihi"
165   [(set (match_operand:HI                 0 "register_operand" "=r,r")
166         (zero_extend:HI (match_operand:QI 1 "memory_operand" "Ys,m")))]
167   ""
168   "@
169    MOV.B\t%1, %0
170    MOV%X1.B\t%1, %0"
173 (define_insn "movqi"
174   [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm")
175         (match_operand:QI 1 "msp_general_operand" "riYs,rmi"))]
176   ""
177   "@
178   MOV.B\t%1, %0
179   MOV%X0.B\t%1, %0"
182 (define_insn "movhi"
183   [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm")
184         (match_operand:HI 1 "msp_general_operand" "riYs,rmi"))]
185   ""
186   "@
187   MOV.W\t%1, %0
188   MOV%X0.W\t%1, %0"
191 (define_expand "movsi"
192   [(set (match_operand:SI 0 "nonimmediate_operand")
193         (match_operand:SI 1 "general_operand"))]
194   ""
195   ""
196   )
197   
198 (define_insn_and_split "movsi_x"
199   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
200         (match_operand:SI 1 "general_operand" "rmi"))]
201   ""
202   "#"
203   "reload_completed"
204   [(set (match_operand:HI 2 "nonimmediate_operand")
205         (match_operand:HI 4 "general_operand"))
206    (set (match_operand:HI 3 "nonimmediate_operand")
207         (match_operand:HI 5 "general_operand"))]
208   "msp430_split_movsi (operands);"
211 ;; Some MOVX.A cases can be done with MOVA, this is only a few of them.
212 (define_insn "movpsi"
213   [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,Ya,rm")
214         (match_operand:PSI 1 "msp_general_operand" "riYa,r,rmi"))]
215   ""
216   "@
217   MOV%Q0\t%1, %0
218   MOV%Q0\t%1, %0
219   MOV%X0.%Q0\t%1, %0")
221 ; This pattern is identical to the truncsipsi2 pattern except
222 ; that it uses a SUBREG instead of a TRUNC.  It is needed in
223 ; order to prevent reload from converting (set:SI (SUBREG:PSI (SI)))
224 ; into (SET:PSI (PSI)).
226 ; Note: using POPM.A #1 is two bytes smaller than using POPX.A....
228 (define_insn "movsipsi2"
229   [(set (match_operand:PSI            0 "register_operand" "=r")
230         (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
231   "TARGET_LARGE"
232   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0"
235 ;;------------------------------------------------------------
236 ;; Math
238 (define_insn "addpsi3"
239   [(set (match_operand:PSI           0 "msp_nonimmediate_operand" "=r,rm")
240         (plus:PSI (match_operand:PSI 1 "msp_nonimmediate_operand" "%0,0")
241                   (match_operand:PSI 2 "msp_general_operand"      "rLs,rmi")))]
242   ""
243   "@
244   ADDA\t%2, %0
245   ADDX.A\t%2, %0"
248 (define_insn "addqi3"
249   [(set (match_operand:QI          0 "msp_nonimmediate_operand" "=rYs,rm")
250         (plus:QI (match_operand:QI 1 "msp_nonimmediate_operand" "%0,0")
251                  (match_operand:QI 2 "msp_general_operand"      "riYs,rmi")))]
252   ""
253   "@
254    ADD.B\t%2, %0
255    ADD%X0.B\t%2, %0"
258 (define_insn "addhi3"
259   [(set (match_operand:HI           0 "msp_nonimmediate_operand" "=rYs,rm")
260         (plus:HI (match_operand:HI  1 "msp_nonimmediate_operand" "%0,0")
261                   (match_operand:HI 2 "msp_general_operand"      "riYs,rmi")))]
262   ""
263   "@
264    ADD.W\t%2, %0
265    ADD%X0.W\t%2, %0"
268 ; This pattern is needed in order to avoid reload problems.
269 ; It takes an SI pair of registers, adds a value to them, and
270 ; then converts them into a single PSI register.
272 (define_insn "addsipsi3"
273   [(set (subreg:SI (match_operand:PSI 0 "register_operand" "=&r") 0)
274         (plus:SI (match_operand:SI    1 "register_operand" "0")
275                  (match_operand       2 "general_operand" "rmi")))]
276   ""
277   "ADD.W\t%L2, %L0 { ADDC.W\t%H2, %H0 { PUSH.W\t%H0 { PUSH.W\t%L0 { POPM.A\t#1, %0"
280 (define_insn "addsi3"
281   [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,rm")
282         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
283                  (match_operand:SI 2 "general_operand" "r,mi")))]
284   ""
285   "@
286    ADD\t%L2, %L0 { ADDC\t%H2, %H0
287    ADD%X0\t%L2, %L0 { ADDC%X0\t%H2, %H0"
290 ; Version of addhi that exposes the carry operations, for SImode adds.
292 ; NOTE - we are playing a dangerous game with GCC here.  We have these two
293 ; add patterns and the splitter that follows because our tests have shown
294 ; that this results in a significant reduction in code size - because GCC is
295 ; able to discard any unused part of the addition.  We have to annotate the
296 ; patterns with the set and use of the carry flag because otherwise GCC will
297 ; discard parts of the addition when they are actually needed.  But we have
298 ; not annotated all the other patterns that set the CARRY flag as doing so
299 ; results in an overall increase in code size[1].  Instead we just *hope*
300 ; that GCC will not move a carry-setting instruction in between the first
301 ; and second adds.
303 ; So far our experiments have shown that GCC is likely to move MOV and CMP
304 ; instructions in between the two adds, but not other instructions.  MOV is
305 ; safe, CMP is not.  So we have annotated the CMP patterns and left the
306 ; subtract, shift and other add patterns alone.  At the moment this is
307 ; working, but with future changes to the generic parts of GCC that might
308 ; change.
310 ; [1] It is not clear exactly why the code size increases.  The cause appears
311 ; to be that reload is more prevelent to spilling a variable onto the stack
312 ; but why it does this is unknown.  Possibly the additional CLOBBERs necessary
313 ; to correctly annotate the other patterns makes reload think that there is
314 ; increased register pressure.  Or possibly reload does not handle ADD patterns
315 ; that are not single_set() very well.
317 (define_insn "addhi3_cy"
318   [(set (match_operand:HI          0 "msp_nonimmediate_operand" "=r,rm")
319         (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
320                  (match_operand:HI 2 "msp_nonimmediate_operand" "r,rm")))
321    (set (reg:BI CARRY)
322         (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
323                                            (zero_extend:SI (match_dup 2)))
324                                   (const_int 16))))
325    ]
326   ""
327   "@
328    ADD\t%2, %1 ; cy
329    ADD%X0\t%2, %1 ; cy"
330   )
332 (define_insn "addhi3_cy_i"
333   [(set (match_operand:HI          0 "nonimmediate_operand" "=r,rm")
334         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
335                  (match_operand:HI 2 "immediate_operand"     "i,i")))
336    (set (reg:BI CARRY)
337         (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
338                                            (match_operand 3 "immediate_operand" "i,i"))
339                                   (const_int 16))))
340    ]
341   ""
342   "@
343    ADD\t%2, %1 ; cy
344    ADD%X0\t%2, %1 ; cy"
345   )
347 ; Version of addhi that adds the carry, for SImode adds.
348 (define_insn "addchi4_cy"
349   [(set (match_operand:HI                   0 "msp_nonimmediate_operand" "=r,rm")
350         (plus:HI (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
351                           (match_operand:HI 2 "msp_general_operand"      "ri,rmi"))
352                  (zero_extend:HI (reg:BI CARRY))))
353    ]
354   ""
355   "@
356    ADDC\t%2, %1
357    ADDC%X0\t%2, %1"
358   )
360 ; Split an SImode add into two HImode adds, keeping track of the carry
361 ; so that gcc knows when it can and can't optimize away the two
362 ; halves.
363 (define_split
364   [(set (match_operand:SI          0 "msp430_nonsubreg_operand")
365         (plus:SI (match_operand:SI 1 "nonimmediate_operand")
366                  (match_operand:SI 2 "general_operand")))
367    ]
368   ""
369   [(parallel [(set (match_operand:HI 3 "nonimmediate_operand" "=&rm")
370                    (plus:HI (match_dup 4)
371                             (match_dup 5)))
372               (set (reg:BI CARRY)
373                    (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 4))
374                                                       (match_dup 9))
375                                              (const_int 16))))
376               ])
377    (set (match_operand:HI 6 "nonimmediate_operand" "=&rm")
378         (plus:HI (plus:HI (match_dup 7)
379                           (match_dup 8))
380                  (zero_extend:HI (reg:BI CARRY))))
381    ]
382   "
383    operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
384    operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
385    operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
386    operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
387    operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
388    operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
389    if (GET_CODE (operands[5]) == CONST_INT)
390      {
391        operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
392      }
393    else
394      {
395        operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
396      }
397    "
398   )
401 ;; Alternatives 2 and 3 are to handle cases generated by reload.
402 (define_insn "subpsi3"
403   [(set (match_operand:PSI            0 "nonimmediate_operand" "=r,   rm, &?r, ?&r")
404         (minus:PSI (match_operand:PSI 1 "general_operand"       "0,   0,   !r,  !i")
405                    (match_operand:PSI 2 "general_operand"       "rLs, rmi, rmi,  r")))]
406   ""
407   "@
408   SUBA\t%2, %0
409   SUBX.A\t%2, %0
410   MOVX.A\t%1, %0 { SUBX.A\t%2, %0
411   MOVX.A\t%1, %0 { SUBA\t%2, %0"
414 ;; Alternatives 2 and 3 are to handle cases generated by reload.
415 (define_insn "subqi3"
416   [(set (match_operand:QI           0 "nonimmediate_operand" "=rYs,  rm,  &?r, ?&r")
417         (minus:QI (match_operand:QI 1 "general_operand"       "0,    0,    !r,  !i")
418                   (match_operand:QI 2 "general_operand"      " riYs, rmi, rmi,   r")))]
419   ""
420   "@
421   SUB.B\t%2, %0
422   SUB%X0.B\t%2, %0
423   MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0
424   MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0"
427 ;; Alternatives 2 and 3 are to handle cases generated by reload.
428 (define_insn "subhi3"
429   [(set (match_operand:HI           0 "nonimmediate_operand" "=rYs,  rm,  &?r, ?&r")
430         (minus:HI (match_operand:HI 1 "general_operand"       "0,    0,    !r,  !i")
431                   (match_operand:HI 2 "general_operand"      " riYs, rmi, rmi,   r")))]
432   ""
433   "@
434   SUB.W\t%2, %0
435   SUB%X0.W\t%2, %0
436   MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0
437   MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0"
440 (define_insn "subsi3"
441   [(set (match_operand:SI           0 "nonimmediate_operand" "=&rm")
442         (minus:SI (match_operand:SI 1 "nonimmediate_operand"   "0")
443                   (match_operand:SI 2 "general_operand"        "rmi")))]
444   ""
445   "SUB%X0\t%L2, %L0 { SUBC%X0\t%H2, %H0"
448 (define_insn "*bic<mode>_cg"
449   [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m")
450         (and:QHI (match_operand:QHI 1 "msp_general_operand" "0,0")
451                  (match_operand 2 "msp430_inv_constgen_operator" "n,n")))]
452   ""
453   "@
454    BIC%x0%b0\t#%I2, %0
455    BIC%X0%b0\t#%I2, %0"
458 (define_insn "bic<mode>3"
459   [(set (match_operand:QHI                   0 "msp_nonimmediate_operand" "=rYs,rm")
460         (and:QHI (not:QHI (match_operand:QHI 1 "msp_general_operand"       "rYs,rmn"))
461                  (match_operand:QHI          2 "msp_nonimmediate_operand"  "0,0")))]
462   ""
463   "@
464    BIC%x0%b0\t%1, %0
465    BIC%X0%b0\t%1, %0"
468 (define_insn "and<mode>3"
469   [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
470         (and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
471                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
472   ""
473   "@
474    AND%x0%b0\t%2, %0
475    AND%X0%b0\t%2, %0"
478 (define_insn "ior<mode>3"
479   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,rm")
480         (ior:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
481                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
482   ""
483   "@
484    BIS%x0%b0\t%2, %0
485    BIS%X0%b0\t%2, %0"
488 (define_insn "xor<mode>3"
489   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,rm")
490         (xor:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
491                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
492   ""
493   "@
494    XOR%x0%b0\t%2, %0
495    XOR%X0%b0\t%2, %0"
498 ;; Macro : XOR #~0, %0
499 (define_insn "one_cmpl<mode>2"
500   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,m")
501         (not:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "0,0")))]
502   ""
503   "@
504    INV%x0%b0\t%0
505    INV%X0%b0\t%0"
508 (define_insn "extendqihi2"
509   [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,m")
510         (sign_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
511   ""
512   "@
513    SXT%X0\t%0
514    SXT%X0\t%0"
517 (define_insn "zero_extendqihi2"
518   [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,m")
519         (zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
520   ""
521   "@
522    AND\t#0xff, %0
523    AND%X0\t#0xff, %0"
526 ;; Eliminate extraneous zero-extends mysteriously created by gcc.
527 (define_peephole2
528   [(set (match_operand:HI 0 "register_operand")
529         (zero_extend:HI (match_operand:QI 1 "general_operand")))
530    (set (match_operand:HI 2 "register_operand")
531         (zero_extend:HI (match_operand:QI 3 "register_operand")))]
532   "REGNO (operands[0]) == REGNO (operands[2]) && REGNO (operands[2]) == REGNO (operands[3])"
533   [(set (match_dup 0)
534         (zero_extend:HI (match_dup 1)))]
536    
537 (define_insn "zero_extendhipsi2"
538   [(set (match_operand:PSI                 0 "msp_nonimmediate_operand" "=r,m")
539         (zero_extend:PSI (match_operand:HI 1 "msp_nonimmediate_operand" "rm,r")))]
540   ""
541   "MOVX\t%1, %0"
544 (define_insn "truncpsihi2"
545   [(set (match_operand:HI               0 "msp_nonimmediate_operand" "=rm")
546         (truncate:HI (match_operand:PSI 1 "register_operand"      "r")))]
547   ""
548   "MOVX\t%1, %0"
551 (define_insn "extendhisi2"
552   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
553         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
554   ""
555   { return msp430x_extendhisi (operands); }
558 (define_insn "extendhipsi2"
559   [(set (match_operand:PSI 0 "nonimmediate_operand" "=r")
560         (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))]
561   "TARGET_LARGE"
562   "RLAM #4, %0 { RRAM #4, %0"
565 ;; Look for cases where integer/pointer conversions are suboptimal due
566 ;; to missing patterns, despite us not having opcodes for these
567 ;; patterns.  Doing these manually allows for alternate optimization
568 ;; paths.
569 (define_insn "zero_extendhisi2"
570   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
571         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
572   "TARGET_LARGE"
573   "MOV.W\t#0,%H0"
576 (define_insn "zero_extendhisipsi2"
577   [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r")
578         (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))]
579   "TARGET_LARGE"
580   "@
581    AND.W\t#-1,%0
582    MOV.W\t%1,%0"
585 (define_insn "extend_and_shift1_hipsi2"
586   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
587         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
588                    (const_int 1)))]
589   "TARGET_LARGE"
590   "RLAM #4, %0 { RRAM #3, %0"
593 (define_insn "extend_and_shift2_hipsi2"
594   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
595         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
596                    (const_int 2)))]
597   "TARGET_LARGE"
598   "RLAM #4, %0 { RRAM #2, %0"
601 ; Nasty - we are sign-extending a 20-bit PSI value in one register into
602 ; two adjacent 16-bit registers to make an SI value.  There is no MSP430X
603 ; instruction that will do this, so we push the 20-bit value onto the stack
604 ; and then pop it off as two 16-bit values.
606 ; FIXME: The MSP430X documentation does not specify if zero-extension or
607 ; sign-extension happens when the 20-bit value is pushed onto the stack.
608 ; It is probably zero-extension, but if not this pattern will not work
609 ; when the PSI value is negative..
611 ; Note: using PUSHM.A #1 is two bytes smaller than using PUSHX.A....
613 (define_insn "zero_extendpsisi2"
614   [(set (match_operand:SI                  0 "register_operand" "=r")
615         (zero_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
616   ""
617   "*
618     if (REGNO (operands[1]) == SP_REGNO)
619       /* If the source register is the stack pointer, the value
620          stored in the stack slot will be the value *after* the
621          stack pointer has been decremented.  So allow for that
622          here.  */
623       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\";
624     else
625       return \"PUSHM.A\t#1, %1 { POPX.W\t%L0 { POPX.W\t%H0 ; move pointer in %1 into reg-pair %L0:%H0\";
626   "
629 ;; We also need to be able to sign-extend pointer types (eg ptrdiff_t).
630 ;; Since (we assume) pushing a 20-bit value onto the stack zero-extends
631 ;; it, we use a different method here.
633 (define_insn "extendpsisi2"
634   [(set (match_operand:SI                  0 "register_operand" "=r")
635         (sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
636   "TARGET_LARGE"
637   "*
638     /* The intention here is that we copy the bottom 16-bits of
639        %1 into %L0 (zeroing the top four bits).  Then we copy the
640        entire 20-bits of %1 into %H0 and then arithmetically shift
641        it right by 16 bits, to get the top four bits of the pointer
642        sign-extended in %H0.  */
643     if (REGNO (operands[0]) == REGNO (operands[1]))
644       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\";
645     else
646       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\";
647   "
650 ; See the movsipsi2 pattern above for another way that GCC performs this
651 ; conversion.
652 (define_insn "truncsipsi2"
653   [(set (match_operand:PSI              0 "register_operand" "=r")
654         (truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
655   ""
656   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A\t#1, %L0"
659 ;;------------------------------------------------------------
660 ;; Shift Functions
662 ;; Note:  We do not use the RPT ... SHIFT instruction sequence
663 ;; when the repeat count is in a register, because even though RPT
664 ;; accepts counts in registers, it does not work if the count is
665 ;; zero, and the actual count in the register has to be one less
666 ;; than the required number of iterations.  We could encode a
667 ;; seqeunce like this:
669 ;;   bit #0xf, Rn
670 ;;   bz  1f
671 ;;   dec Rn
672 ;;   rpt Rn
673 ;;   <shift> Rm
674 ;;   inc Rn
675 ;; 1:
677 ;; But is longer than calling a helper function, and we are mostly
678 ;; concerned with code size.  FIXME: Maybe enable a sequence like
679 ;; this at -O3 and above ?
681 ;; Note - we ignore shift counts of less than one or more than 15.
682 ;; This is permitted by the ISO C99 standard as such shifts result
683 ;; in "undefined" behaviour.  [6.5.7 (3)]
685 ;; signed A << C
687 (define_expand "ashlhi3"
688   [(set (match_operand:HI            0 "nonimmediate_operand")
689         (ashift:HI (match_operand:HI 1 "general_operand")
690                    (match_operand:HI 2 "general_operand")))]
691   ""
692   {
693     if (msp430x
694         && REG_P (operands[0])
695         && REG_P (operands[1])
696         && CONST_INT_P (operands[2]))
697       emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2]));
698     else                 
699       msp430_expand_helper (operands, \"__mspabi_slli\", true);
700     DONE;
701   }
704 (define_insn "slli_1"
705   [(set (match_operand:HI            0 "nonimmediate_operand" "=rm")
706         (ashift:HI (match_operand:HI 1 "general_operand"       "0")
707                    (const_int 1)))]
708   ""
709   "RLA.W\t%0" ;; Note - this is a macro for ADD
712 (define_insn "430x_shift_left"
713   [(set (match_operand:HI            0 "register_operand" "=r")
714         (ashift:HI (match_operand:HI 1 "register_operand"  "0")
715                    (match_operand    2 "immediate_operand" "n")))]
716   "msp430x"
717   "*
718   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
719     return \"rpt\t%2 { rlax.w\t%0\";
720   return \"# nop left shift\";
721   "
724 (define_insn "slll_1"
725   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
726         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
727                    (const_int 1)))]
728   ""
729   "RLA.W\t%L0 { RLC.W\t%H0"
732 (define_insn "slll_2"
733   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
734         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
735                    (const_int 2)))]
736   ""
737   "RLA.W\t%L0 { RLC.W\t%H0 { RLA.W\t%L0 { RLC.W\t%H0"
740 (define_expand "ashlsi3"
741   [(set (match_operand:SI            0 "nonimmediate_operand")
742         (ashift:SI (match_operand:SI 1 "general_operand")
743                    (match_operand:SI 2 "general_operand")))]
744   ""
745   "msp430_expand_helper (operands, \"__mspabi_slll\", true);
746    DONE;"
749 ;;----------
751 ;; signed A >> C
753 (define_expand "ashrhi3"
754   [(set (match_operand:HI              0 "nonimmediate_operand")
755         (ashiftrt:HI (match_operand:HI 1 "general_operand")
756                      (match_operand:HI 2 "general_operand")))]
757   ""
758   {
759     if (msp430x
760         && REG_P (operands[0])
761         && REG_P (operands[1])
762         && CONST_INT_P (operands[2]))
763       emit_insn (gen_430x_arithmetic_shift_right (operands[0], operands[1], operands[2]));
764     else                 
765        msp430_expand_helper (operands, \"__mspabi_srai\", true);
766    DONE;
767    }
770 (define_insn "srai_1"
771   [(set (match_operand:HI              0 "msp_nonimmediate_operand" "=rm")
772         (ashiftrt:HI (match_operand:HI 1 "msp_general_operand"      "0")
773                      (const_int 1)))]
774   ""
775   "RRA.W\t%0"
778 (define_insn "430x_arithmetic_shift_right"
779   [(set (match_operand:HI              0 "register_operand" "=r")
780         (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0")
781                      (match_operand    2 "immediate_operand" "n")))]
782   "msp430x"
783   "*
784   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
785     return \"rpt\t%2 { rrax.w\t%0\";
786   return \"# nop arith right shift\";
787   "
790 (define_insn "srap_1"
791   [(set (match_operand:PSI              0 "register_operand" "=r")
792         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
793                       (const_int 1)))]
794   "msp430x"
795   "RRAM.A #1,%0"
798 (define_insn "srap_2"
799   [(set (match_operand:PSI              0 "register_operand" "=r")
800         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
801                       (const_int 2)))]
802   "msp430x"
803   "RRAM.A #2,%0"
806 (define_insn "sral_1"
807   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
808         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
809                      (const_int 1)))]
810   ""
811   "RRA.W\t%H0 { RRC.W\t%L0"
814 (define_insn "sral_2"
815   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
816         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
817                      (const_int 2)))]
818   ""
819   "RRA.W\t%H0 { RRC.W\t%L0 { RRA.W\t%H0 { RRC.W\t%L0"
822 (define_expand "ashrsi3"
823   [(set (match_operand:SI              0 "nonimmediate_operand")
824         (ashiftrt:SI (match_operand:SI 1 "general_operand")
825                      (match_operand:SI 2 "general_operand")))]
826   ""
827   "msp430_expand_helper (operands, \"__mspabi_sral\", true);
828    DONE;"
831 ;;----------
833 ;; unsigned A >> C
835 (define_expand "lshrhi3"
836   [(set (match_operand:HI              0 "nonimmediate_operand")
837         (lshiftrt:HI (match_operand:HI 1 "general_operand")
838                      (match_operand:HI 2 "general_operand")))]
839   ""
840   {
841     if (msp430x
842         && REG_P (operands[0])
843         && REG_P (operands[1])
844         && CONST_INT_P (operands[2]))
845       emit_insn (gen_430x_logical_shift_right (operands[0], operands[1], operands[2]));
846     else                 
847       msp430_expand_helper (operands, \"__mspabi_srli\", true);
848     DONE;
849   }
852 (define_insn "srli_1"
853   [(set (match_operand:HI              0 "nonimmediate_operand" "=rm")
854         (lshiftrt:HI (match_operand:HI 1 "general_operand"       "0")
855                      (const_int 1)))]
856   ""
857   "CLRC { RRC.W\t%0"
860 (define_insn "430x_logical_shift_right"
861   [(set (match_operand:HI              0 "register_operand" "=r")
862         (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0")
863                      (match_operand    2 "immediate_operand" "n")))]
864   "msp430x"
865   {
866     return msp430x_logical_shift_right (operands[2]);
867   }
870 (define_insn "srlp_1"
871   [(set (match_operand:PSI              0 "register_operand" "=r")
872         (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
873                       (const_int 1)))]
874   ""
875   "RRUM.A #1,%0"
878 (define_insn "srll_1"
879   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
880         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
881                      (const_int 1)))]
882   ""
883   "CLRC { RRC.W\t%H0 { RRC.W\t%L0"
886 (define_insn "srll_2x"
887   [(set (match_operand:SI              0 "nonimmediate_operand" "=r")
888         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
889                      (const_int 2)))]
890   "msp430x"
891   "RRUX.W\t%H0 { RRC.W\t%L0 { RRUX.W\t%H0 { RRC.W\t%L0"
894 (define_expand "lshrsi3"
895   [(set (match_operand:SI              0 "nonimmediate_operand")
896         (lshiftrt:SI (match_operand:SI 1 "general_operand")
897                      (match_operand:SI 2 "general_operand")))]
898   ""
899   "msp430_expand_helper (operands, \"__mspabi_srll\", true);
900    DONE;"
903 ;;------------------------------------------------------------
904 ;; Function Entry/Exit
906 (define_expand "prologue"
907   [(const_int 0)]
908   ""
909   "msp430_expand_prologue (); DONE;"
910   )
912 (define_expand "epilogue"
913   [(const_int 0)]
914   ""
915   "msp430_expand_epilogue (0); DONE;"
916   )
919 (define_insn "epilogue_helper"
920   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)]
921   ""
922   "BR%Q0\t#__mspabi_func_epilog_%J0"
923   )
926 (define_insn "prologue_start_marker"
927   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)]
928   ""
929   "; start of prologue"
930   )
932 (define_insn "prologue_end_marker"
933   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)]
934   ""
935   "; end of prologue"
936   )
938 (define_insn "epilogue_start_marker"
939   [(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)]
940   ""
941   "; start of epilogue"
942   )
944 ;; This makes the linker add a call to exit() after the call to main()
945 ;; in crt0
946 (define_insn "msp430_refsym_need_exit"
947   [(unspec_volatile [(const_int 0)] UNS_REFSYM_NEED_EXIT)]
948   ""
949   ".refsym\t__crt0_call_exit"
950   )
952 ;;------------------------------------------------------------
953 ;; Jumps
955 (define_expand "call"
956   [(call:HI (match_operand 0 "")
957             (match_operand 1 ""))]
958   ""
959   ""
962 (define_insn "call_internal"
963   [(call (mem:HI (match_operand 0 "general_operand" "rYci"))
964          (match_operand 1 ""))]
965   ""
966   "CALL%Q0\t%0"
969 (define_expand "call_value"
970   [(set (match_operand          0 "register_operand")
971         (call:HI (match_operand 1 "general_operand")
972                  (match_operand 2 "")))]
973   ""
974   ""
977 (define_insn "call_value_internal"
978   [(set (match_operand               0 "register_operand" "=r")
979         (call (mem:HI (match_operand 1 "general_operand" "rYci"))
980               (match_operand 2 "")))]
981   ""
982   "CALL%Q0\t%1"
985 (define_insn "msp_return"
986   [(return)]
987   ""
988   { return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); }
991 ;; This pattern is NOT, as expected, a return pattern.  It's called
992 ;; before reload and must only store its operands, and emit a
993 ;; placeholder where the epilog needs to be.  AFTER reload, the
994 ;; placeholder should get expanded into a regular-type epilogue that
995 ;; also does the EH return.
996 (define_expand "eh_return"
997   [(match_operand:HI 0 "")]
998   ""
999   "msp430_expand_eh_return (operands[0]);
1000    emit_jump_insn (gen_msp430_eh_epilogue ());
1001    emit_barrier ();
1002    DONE;"
1005 ;; This is the actual EH epilogue.  We emit it in the pattern above,
1006 ;; before reload, and convert it to a real epilogue after reload.
1007 (define_insn_and_split "msp430_eh_epilogue"
1008   [(eh_return)]
1009   ""
1010   "#"
1011   "reload_completed"
1012   [(const_int 0)]
1013   "msp430_expand_epilogue (1); DONE;"
1014   )
1016 (define_insn "jump"
1017   [(set (pc)
1018         (label_ref (match_operand 0 "" "")))]
1019   ""
1020   "BR%Q0\t#%l0"
1023 ;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
1024 ;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c).
1025 (define_insn "indirect_jump"
1026   [(set (pc)
1027         (match_operand 0 "nonimmediate_operand" "rYl"))]
1028   ""
1029   "BR%Q0\t%0"
1032 ;;------------------------------------------------------------
1033 ;; Various Conditionals
1035 (define_expand "cbranch<mode>4"
1036   [(parallel [(set (pc) (if_then_else
1037                          (match_operator 0 ""
1038                                          [(match_operand:QHI 1 "nonimmediate_operand")
1039                                           (match_operand:QHI 2 "general_operand")])
1040                          (label_ref (match_operand 3 "" ""))
1041                          (pc)))
1042               (clobber (reg:BI CARRY))]
1043   )]
1044   ""
1045   "msp430_fixup_compare_operands (<MODE>mode, operands);"
1046   )
1048 (define_insn "cbranchpsi4_real"
1049   [(set (pc) (if_then_else
1050               (match_operator                     0 "msp430_cmp_operator"
1051                               [(match_operand:PSI 1 "nonimmediate_operand" "r,rYs,rm")
1052                                (match_operand:PSI 2 "general_operand"      "rLs,rYsi,rmi")])
1053               (label_ref (match_operand           3 "" ""))
1054               (pc)))
1055    (clobber (reg:BI CARRY))
1056    ]
1057   ""
1058   "@
1059   CMP%Q0\t%2, %1 { J%0\t%l3
1060   CMPX.A\t%2, %1 { J%0\t%l3
1061   CMPX.A\t%2, %1 { J%0\t%l3"
1062   )
1064 (define_insn "cbranchqi4_real"
1065   [(set (pc) (if_then_else
1066               (match_operator                    0 "msp430_cmp_operator"
1067                               [(match_operand:QI 1 "nonimmediate_operand" "rYs,rm")
1068                                (match_operand:QI 2 "general_operand"      "rYsi,rmi")])
1069               (label_ref (match_operand          3 "" ""))
1070               (pc)))
1071    (clobber (reg:BI CARRY))
1072    ]
1073   ""
1074   "@
1075    CMP.B\t%2, %1 { J%0\t%l3
1076    CMP%X0.B\t%2, %1 { J%0\t%l3"
1077   )
1079 (define_insn "cbranchhi4_real"
1080   [(set (pc) (if_then_else
1081               (match_operator                    0 "msp430_cmp_operator"
1082                               [(match_operand:HI 1 "nonimmediate_operand" "rYs,rm")
1083                                (match_operand:HI 2 "general_operand"      "rYsi,rmi")])
1084               (label_ref (match_operand          3 "" ""))
1085               (pc)))
1086    (clobber (reg:BI CARRY))
1087    ]
1088   ""
1089   "@
1090    CMP.W\t%2, %1 { J%0\t%l3
1091    CMP%X0.W\t%2, %1 { J%0\t%l3"
1092   )
1094 (define_insn "cbranchpsi4_reversed"
1095   [(set (pc) (if_then_else
1096               (match_operator                     0 "msp430_reversible_cmp_operator"
1097                               [(match_operand:PSI 1 "general_operand" "rLs,rYsi,rmi")
1098                                (match_operand:PSI 2 "general_operand" "r,rYs,rm")])
1099               (label_ref (match_operand           3 "" ""))
1100               (pc)))
1101    (clobber (reg:BI CARRY))
1102    ]
1103   ""
1104   "@
1105   CMP%Q0\t%1, %2 { J%R0\t%l3
1106   CMPX.A\t%1, %2 { J%R0\t%l3
1107   CMPX.A\t%1, %2 { J%R0\t%l3"
1108   )
1110 (define_insn "cbranchqi4_reversed"
1111   [(set (pc) (if_then_else
1112               (match_operator                    0 "msp430_reversible_cmp_operator"
1113                               [(match_operand:QI 1 "general_operand" "rYsi,rmi")
1114                                (match_operand:QI 2 "general_operand" "rYs,rm")])
1115               (label_ref (match_operand          3 "" ""))
1116               (pc)))
1117    (clobber (reg:BI CARRY))
1118    ]
1119   ""
1120   "@
1121    CMP.B\t%1, %2 { J%R0\t%l3
1122    CMP%X0.B\t%1, %2 { J%R0\t%l3"
1123   )
1125 (define_insn "cbranchhi4_reversed"
1126   [(set (pc) (if_then_else
1127               (match_operator                    0 "msp430_reversible_cmp_operator"
1128                               [(match_operand:HI 1 "general_operand" "rYsi,rmi")
1129                                (match_operand:HI 2 "general_operand" "rYs,rm")])
1130               (label_ref (match_operand          3 "" ""))
1131               (pc)))
1132    (clobber (reg:BI CARRY))
1133    ]
1134   ""
1135   "@
1136    CMP.W\t%1, %2 { J%R0\t%l3
1137    CMP%X0.W\t%1, %2 { J%R0\t%l3"
1138   )
1140 (define_insn "*bitbranch<mode>4"
1141   [(set (pc) (if_then_else
1142               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1143                            (match_operand:QHI 1 "msp_general_operand" "rYsi,rmi"))
1144                   (const_int 0))
1145               (label_ref (match_operand 2 "" ""))
1146               (pc)))
1147    (clobber (reg:BI CARRY))
1148    ]
1149   ""
1150   "@
1151    BIT%x0%b0\t%1, %0 { JNE\t%l2
1152    BIT%X0%b0\t%1, %0 { JNE\t%l2"
1153   )
1155 (define_insn "*bitbranch<mode>4"
1156   [(set (pc) (if_then_else
1157               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1158                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1159                   (const_int 0))
1160               (label_ref (match_operand 2 "" ""))
1161               (pc)))
1162    (clobber (reg:BI CARRY))
1163    ]
1164   ""
1165   "BIT%x0%X0%b0\t%1, %0 { JEQ\t%l2"
1166   )
1168 (define_insn "*bitbranch<mode>4"
1169   [(set (pc) (if_then_else
1170               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1171                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1172                   (const_int 0))
1173               (pc)
1174               (label_ref (match_operand 2 "" ""))))
1175    (clobber (reg:BI CARRY))
1176    ]
1177   ""
1178   "BIT%X0%b0\t%1, %0 { JNE\t%l2"
1179   )
1181 (define_insn "*bitbranch<mode>4"
1182   [(set (pc) (if_then_else
1183               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1184                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1185                   (const_int 0))
1186               (pc)
1187               (label_ref (match_operand 2 "" ""))))
1188    (clobber (reg:BI CARRY))
1189    ]
1190   ""
1191   "BIT%X0%b0\t%1, %0 { JEQ\t%l2"
1192   )
1194 ;;------------------------------------------------------------
1195 ;; zero-extract versions of the above
1197 (define_insn "*bitbranch<mode>4_z"
1198   [(set (pc) (if_then_else
1199               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1200                                     (const_int 1)
1201                                     (match_operand 1 "msp430_bitpos" "i,i"))
1202                   (const_int 0))
1203               (label_ref (match_operand 2 "" ""))
1204               (pc)))
1205    (clobber (reg:BI CARRY))
1206    ]
1207   ""
1208   "@
1209    BIT%x0%b0\t%p1, %0 { JNE\t%l2
1210    BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1211   )
1213 (define_insn "*bitbranch<mode>4_z"
1214   [(set (pc) (if_then_else
1215               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1216                                    (const_int 1)
1217                                    (match_operand 1 "msp430_bitpos" "i"))
1218                   (const_int 0))
1219               (label_ref (match_operand 2 "" ""))
1220               (pc)))
1221    (clobber (reg:BI CARRY))
1222    ]
1223   ""
1224   "BIT%x0%X0%b0\t%p1, %0 { JEQ\t%l2"
1225   )
1227 (define_insn "*bitbranch<mode>4_z"
1228   [(set (pc) (if_then_else
1229               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1230                                    (const_int 1)
1231                                    (match_operand 1 "msp430_bitpos" "i"))
1232                   (const_int 0))
1233               (pc)
1234               (label_ref (match_operand 2 "" ""))))
1235    (clobber (reg:BI CARRY))
1236    ]
1237   ""
1238   "BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1239   )
1241 (define_insn "*bitbranch<mode>4_z"
1242   [(set (pc) (if_then_else
1243               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1244                                    (const_int 1)
1245                                    (match_operand 1 "msp430_bitpos" "i"))
1246                   (const_int 0))
1247               (pc)
1248               (label_ref (match_operand 2 "" ""))))
1249    (clobber (reg:BI CARRY))
1250    ]
1251   ""
1252   "BIT%X0%b0\t%p1, %0 { JEQ\t%l2"
1253   )
1255 ;;------------------------------------------------------------
1256 ;; Misc
1258 (define_insn "nop"
1259   [(const_int 0)]
1260   "1"
1261   "NOP"
1264 (define_insn "disable_interrupts"
1265   [(unspec_volatile [(const_int 0)] UNS_DINT)]
1266   ""
1267   "DINT \; NOP"
1268   )
1270 (define_insn "enable_interrupts"
1271   [(unspec_volatile [(const_int 0)] UNS_EINT)]
1272   ""
1273   "EINT"
1274   )
1276 (define_insn "push_intr_state"
1277   [(unspec_volatile [(const_int 0)] UNS_PUSH_INTR)]
1278   ""
1279   "PUSH\tSR"
1280   )
1282 (define_insn "pop_intr_state"
1283   [(unspec_volatile [(const_int 0)] UNS_POP_INTR)]
1284   ""
1285   "POP\tSR"
1286   )
1288 ;; Clear bits in the copy of the status register that is currently
1289 ;; saved on the stack at the top of the interrupt handler.
1290 (define_insn "bic_SR"
1291   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIC_SR)]
1292   ""
1293   "BIC.W\t%0, %O0(SP)"
1294   )
1296 ;; Set bits in the copy of the status register that is currently
1297 ;; saved on the stack at the top of the interrupt handler.
1298 (define_insn "bis_SR"
1299   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIS_SR)]
1300   ""
1301   "BIS.W\t%0, %O0(SP)"
1302   )
1304 ;; For some reason GCC is generating (set (reg) (and (neg (reg)) (int)))
1305 ;; very late on in the compilation and not splitting it into separate
1306 ;; instructions, so we provide a pattern to support it here.
1307 (define_insn "andneghi3"
1308   [(set (match_operand:HI                 0 "register_operand" "=r")
1309         (and:HI (neg:HI (match_operand:HI 1 "register_operand"  "r"))
1310                 (match_operand            2 "immediate_operand" "n")))]
1311   ""
1312   "*
1313     if (REGNO (operands[0]) != REGNO (operands[1]))
1314       return \"MOV.W\t%1, %0 { SUB.W\t#0, %0 { AND.W\t%2, %0\";
1315     else
1316       return \"SUB.W\t#0, %0 { AND.W\t%2, %0\";
1317   "
1318   )
1320 (define_insn "mulhisi3"
1321   [(set (match_operand:SI                          0 "register_operand" "=r")
1322         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1323                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1324   "optimize > 2 && msp430_hwmult_enabled ()"
1325   "*
1326     if (msp430_is_f5_mcu ())
1327       return \"MOV.W %1, &0x04C2 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0\";
1328     else
1329       return \"MOV.W %1, &0x0132 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0\";
1330   "
1333 (define_insn "umulhisi3"
1334   [(set (match_operand:SI                          0 "register_operand" "=r")
1335         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1336                  (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1337   "optimize > 2 && msp430_hwmult_enabled ()"
1338   "*
1339     if (msp430_is_f5_mcu ())
1340       return \"MOV.W %1, &0x04C0 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0\";
1341     else
1342       return \"MOV.W %1, &0x0130 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0\";
1343   "
1346 (define_insn "mulsidi3"
1347   [(set (match_operand:DI                          0 "register_operand" "=r")
1348         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1349                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1350   "optimize > 2 && msp430_hwmult_enabled ()"
1351   "*
1352     if (msp430_is_f5_mcu ())
1353       return \"MOV.W %L1, &0x04D4 { MOV.W %H1, &0x04D6 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0\";
1354     else
1355       return \"MOV.W %L1, &0x0144 { MOV.W %H1, &0x0146 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0\";
1356   "
1359 (define_insn "umulsidi3"
1360   [(set (match_operand:DI                          0 "register_operand" "=r")
1361         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1362                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1363   "optimize > 2 && msp430_hwmult_enabled ()"
1364   "*
1365     if (msp430_is_f5_mcu ())
1366       return \"MOV.W %L1, &0x04D0 { MOV.W %H1, &0x04D2 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0\";
1367     else
1368       return \"MOV.W %L1, &0x0140 { MOV.W %H1, &0x0141 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0\";
1369   "