* config/msp430/msp430-opts.h (enum msp430_regions): New.
[official-gcc.git] / gcc / config / msp430 / msp430.md
blob91742fc38b5ed2d4c0933d3d8d55a9ff63dccd78
1 ;;  Machine Description for TI MSP43* processors
2 ;;  Copyright (C) 2013-2015 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
51    UNS_DELAY_32
52    UNS_DELAY_32X
53    UNS_DELAY_16
54    UNS_DELAY_16X
55    UNS_DELAY_2
56    UNS_DELAY_1
57    UNS_DELAY_START
58    UNS_DELAY_END
59   ])
61 ;; This is an approximation.
62 (define_attr "length" "" (const_int 4))
64 (include "predicates.md")
65 (include "constraints.md")
67 (define_mode_iterator QHI [QI HI PSI])
69 ;; There are two basic "family" tests we do here:
71 ;; msp430x - true if 430X instructions are available.
72 ;; TARGET_LARGE - true if pointers are 20-bits
74 ;; Note that there are three supported cases, since the base 430
75 ;; doesn't have 20-bit pointers:
77 ;; 1. MSP430 cpu, small model
78 ;; 2. MSP430X cpu, small model.
79 ;; 3. MSP430X cpu, large model.
81 ;;------------------------------------------------------------
82 ;; Moves
84 ;; Push/Pop must be before the generic move patterns
86 (define_insn "push"
87   [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO)))
88         (match_operand:HI 0 "register_operand" "r"))]
89   ""
90   "PUSH\t%0"
91   )
93 (define_insn "pusha"
94   [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO)))
95         (match_operand:PSI 0 "register_operand" "r"))]
96   "TARGET_LARGE"
97   "PUSHX.A\t%0"
98   )
100 (define_insn "pushm"
101   [(unspec_volatile [(match_operand 0 "register_operand" "r")
102                      (match_operand 1 "immediate_operand" "n")] UNS_PUSHM)]
103   ""
104   "PUSHM%b0\t%1, %0"
105   )
107 (define_insn "pop"
108   [(set (match_operand:HI 0 "register_operand" "=r")
109         (mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
110   ""
111   "POP\t%0"
112   )
114 (define_insn "popa"
115   [(set (match_operand:PSI 0 "register_operand" "=r")
116         (mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))]
117   "TARGET_LARGE"
118   "POPX.A\t%0"
119   )
121 ;; This is nasty.  Operand0 is bogus.  It is only there so that we can get a
122 ;; mode for the %b0 to work.  We should use operand1 for this, but that does
123 ;; not have a mode.
124 ;; 
125 ;; Operand1 is actually a register, but we cannot accept (REG...) because the
126 ;; cprop_hardreg pass can and will renumber registers even inside
127 ;; unspec_volatiles.  So we take an integer register number parameter and
128 ;; fudge it to be a register name when we generate the assembler.
130 ;; The pushm pattern does not have this problem because of all of the
131 ;; frame info cruft attached to it, so cprop_hardreg leaves it alone.
132 (define_insn "popm"
133   [(unspec_volatile [(match_operand 0 "register_operand" "r")
134                      (match_operand 1 "immediate_operand" "i")
135                      (match_operand 2 "immediate_operand" "i")] UNS_POPM)]
136   ""
137   "POPM%b0\t%2, r%J1"
138   )
140 ;; The next two patterns are here to support a "feature" of how GCC implements
141 ;; varargs.  When a function uses varargs and the *second* to last named
142 ;; argument is split between argument registers and the stack, gcc expects the
143 ;; callee to allocate space on the stack that can contain the register-based
144 ;; part of the argument.  This space *has* to be just before the remaining
145 ;; arguments (ie the ones that are fully on the stack).
147 ;; The problem is that the MSP430 CALL instruction pushes the return address
148 ;; onto the stack in the exact place where the callee wants to allocate
149 ;; this extra space.  So we need a sequence of instructions that can allocate
150 ;; the extra space and then move the return address down the stack, so that
151 ;; the extra space is now adjacent to the remaining arguments.
153 ;; This could be constructed through regular insns, but they might be split up
154 ;; by a misguided optimization, so an unspec volatile is used instead.
156 (define_insn "grow_and_swap"
157   [(unspec_volatile [(const_int 0)] UNS_GROW_AND_SWAP)]
158   ""
159   "*
160     if (TARGET_LARGE)
161       return \"SUBA\t#2, r1 { MOVX.A\t2(r1), 0(r1)\";
162     return \"SUB\t#2, r1 { MOV.W\t2(r1), 0(r1)\";
163   "
166 (define_insn "swap_and_shrink"
167   [(unspec_volatile [(const_int 0)] UNS_SWAP_AND_SHRINK)]
168   ""
169   "* return TARGET_LARGE
170            ? \"MOVX.A\t0(r1), 2(r1) { ADDA\t#2, SP\"
171            : \"MOV.W\t0(r1), 2(r1) { ADD\t#2, SP\";
172   ")
174 ; I set LOAD_EXTEND_OP and WORD_REGISTER_OPERATIONS, but gcc puts in a
175 ; zero_extend anyway.  Catch it here.
176 (define_insn "movqihi"
177   [(set (match_operand:HI                 0 "register_operand" "=r,r")
178         (zero_extend:HI (match_operand:QI 1 "memory_operand" "Ys,m")))]
179   ""
180   "@
181    MOV.B\t%1, %0
182    MOV%X1.B\t%1, %0"
185 (define_insn "movqi_topbyte"
186   [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=r")
187         (subreg:QI (match_operand:PSI 1 "msp_general_operand" "r") 2))]
188   "msp430x"
189   "PUSHM.A\t#1,%1 { POPM.W\t#1,%0 { POPM.W\t#1,%0"
192 (define_insn "movqi"
193   [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm")
194         (match_operand:QI 1 "msp_general_operand" "riYs,rmi"))]
195   ""
196   "@
197   MOV.B\t%1, %0
198   MOV%X0.B\t%1, %0"
201 (define_insn "movhi"
202   [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm")
203         (match_operand:HI 1 "msp_general_operand" "riYs,rmi"))]
204   ""
205   "@
206   MOV.W\t%1, %0
207   MOV%X0.W\t%1, %0"
210 (define_expand "movsi"
211   [(set (match_operand:SI 0 "nonimmediate_operand")
212         (match_operand:SI 1 "general_operand"))]
213   ""
214   ""
215   )
217 (define_insn_and_split "movsi_x"
218   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
219         (match_operand:SI 1 "general_operand" "rmi"))]
220   ""
221   "#"
222   "reload_completed"
223   [(set (match_operand:HI 2 "nonimmediate_operand")
224         (match_operand:HI 4 "general_operand"))
225    (set (match_operand:HI 3 "nonimmediate_operand")
226         (match_operand:HI 5 "general_operand"))]
227   "msp430_split_movsi (operands);"
230 ;; Some MOVX.A cases can be done with MOVA, this is only a few of them.
231 (define_insn "movpsi"
232   [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,Ya,rm")
233         (match_operand:PSI 1 "msp_general_operand" "riYa,r,rmi"))]
234   ""
235   "@
236   MOVA\t%1, %0
237   MOVA\t%1, %0
238   MOVX.A\t%1, %0")
240 ; This pattern is identical to the truncsipsi2 pattern except
241 ; that it uses a SUBREG instead of a TRUNC.  It is needed in
242 ; order to prevent reload from converting (set:SI (SUBREG:PSI (SI)))
243 ; into (SET:PSI (PSI)).
245 ; Note: using POPM.A #1 is two bytes smaller than using POPX.A....
247 (define_insn "movsipsi2"
248   [(set (match_operand:PSI            0 "register_operand" "=r")
249         (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
250   "msp430x"
251   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0"
254 ;;------------------------------------------------------------
255 ;; Math
257 (define_insn "addpsi3"
258   [(set (match_operand:PSI           0 "msp_nonimmediate_operand" "=r,rm")
259         (plus:PSI (match_operand:PSI 1 "msp_nonimmediate_operand" "%0,0")
260                   (match_operand:PSI 2 "msp_general_operand"      "rLs,rmi")))]
261   ""
262   "@
263   ADDA\t%2, %0
264   ADDX.A\t%2, %0"
267 (define_insn "addqi3"
268   [(set (match_operand:QI          0 "msp_nonimmediate_operand" "=rYs,rm")
269         (plus:QI (match_operand:QI 1 "msp_nonimmediate_operand" "%0,0")
270                  (match_operand:QI 2 "msp_general_operand"      "riYs,rmi")))]
271   ""
272   "@
273    ADD.B\t%2, %0
274    ADD%X0.B\t%2, %0"
277 (define_insn "addhi3"
278   [(set (match_operand:HI           0 "msp_nonimmediate_operand" "=rYs,rm")
279         (plus:HI (match_operand:HI  1 "msp_nonimmediate_operand" "%0,0")
280                   (match_operand:HI 2 "msp_general_operand"      "riYs,rmi")))]
281   ""
282   "@
283    ADD.W\t%2, %0
284    ADD%X0.W\t%2, %0"
287 ; This pattern is needed in order to avoid reload problems.
288 ; It takes an SI pair of registers, adds a value to them, and
289 ; then converts them into a single PSI register.
291 (define_insn "addsipsi3"
292   [(set (subreg:SI (match_operand:PSI 0 "register_operand" "=&r") 0)
293         (plus:SI (match_operand:SI    1 "register_operand" "0")
294                  (match_operand       2 "general_operand" "rmi")))]
295   ""
296   "ADD.W\t%L2, %L0 { ADDC.W\t%H2, %H0 { PUSH.W\t%H0 { PUSH.W\t%L0 { POPM.A\t#1, %0"
299 (define_insn "addsi3"
300   [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,rm")
301         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
302                  (match_operand:SI 2 "general_operand" "r,mi")))]
303   ""
304   "@
305    ADD\t%L2, %L0 { ADDC\t%H2, %H0
306    ADD%X0\t%L2, %L0 { ADDC%X0\t%H2, %H0"
309 ; Version of addhi that exposes the carry operations, for SImode adds.
311 ; NOTE - we are playing a dangerous game with GCC here.  We have these two
312 ; add patterns and the splitter that follows because our tests have shown
313 ; that this results in a significant reduction in code size - because GCC is
314 ; able to discard any unused part of the addition.  We have to annotate the
315 ; patterns with the set and use of the carry flag because otherwise GCC will
316 ; discard parts of the addition when they are actually needed.  But we have
317 ; not annotated all the other patterns that set the CARRY flag as doing so
318 ; results in an overall increase in code size[1].  Instead we just *hope*
319 ; that GCC will not move a carry-setting instruction in between the first
320 ; and second adds.
322 ; So far our experiments have shown that GCC is likely to move MOV and CMP
323 ; instructions in between the two adds, but not other instructions.  MOV is
324 ; safe, CMP is not.  So we have annotated the CMP patterns and left the
325 ; subtract, shift and other add patterns alone.  At the moment this is
326 ; working, but with future changes to the generic parts of GCC that might
327 ; change.
329 ; [1] It is not clear exactly why the code size increases.  The cause appears
330 ; to be that reload is more prevelent to spilling a variable onto the stack
331 ; but why it does this is unknown.  Possibly the additional CLOBBERs necessary
332 ; to correctly annotate the other patterns makes reload think that there is
333 ; increased register pressure.  Or possibly reload does not handle ADD patterns
334 ; that are not single_set() very well.
336 (define_insn "addhi3_cy"
337   [(set (match_operand:HI          0 "msp_nonimmediate_operand" "=r,rm")
338         (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
339                  (match_operand:HI 2 "msp_nonimmediate_operand" "r,rm")))
340    (set (reg:BI CARRY)
341         (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
342                                            (zero_extend:SI (match_dup 2)))
343                                   (const_int 16))))
344    ]
345   ""
346   "@
347    ADD\t%2, %1 ; cy
348    ADD%X0\t%2, %1 ; cy"
349   )
351 (define_insn "addhi3_cy_i"
352   [(set (match_operand:HI          0 "nonimmediate_operand" "=r,rm")
353         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
354                  (match_operand:HI 2 "immediate_operand"     "i,i")))
355    (set (reg:BI CARRY)
356         (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
357                                            (match_operand 3 "immediate_operand" "i,i"))
358                                   (const_int 16))))
359    ]
360   ""
361   "@
362    ADD\t%2, %1 ; cy
363    ADD%X0\t%2, %1 ; cy"
364   )
366 ; Version of addhi that adds the carry, for SImode adds.
367 (define_insn "addchi4_cy"
368   [(set (match_operand:HI                   0 "msp_nonimmediate_operand" "=r,rm")
369         (plus:HI (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
370                           (match_operand:HI 2 "msp_general_operand"      "ri,rmi"))
371                  (zero_extend:HI (reg:BI CARRY))))
372    ]
373   ""
374   "@
375    ADDC\t%2, %1
376    ADDC%X0\t%2, %1"
377   )
379 ; Split an SImode add into two HImode adds, keeping track of the carry
380 ; so that gcc knows when it can and can't optimize away the two
381 ; halves.
382 (define_split
383   [(set (match_operand:SI          0 "msp430_nonsubreg_operand")
384         (plus:SI (match_operand:SI 1 "msp430_nonsubreg_operand")
385                  (match_operand:SI 2 "msp430_nonsubreg_or_imm_operand")))
386    ]
387   ""
388   [(parallel [(set (match_operand:HI 3 "nonimmediate_operand" "=&rm")
389                    (plus:HI (match_dup 4)
390                             (match_dup 5)))
391               (set (reg:BI CARRY)
392                    (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 4))
393                                                       (match_dup 9))
394                                              (const_int 16))))
395               ])
396    (set (match_operand:HI 6 "nonimmediate_operand" "=&rm")
397         (plus:HI (plus:HI (match_dup 7)
398                           (match_dup 8))
399                  (zero_extend:HI (reg:BI CARRY))))
400    ]
401   "
402    operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
403    operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
404    operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
405    operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
406    operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
407    operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
409    /* BZ 64160: Do not use this splitter when the dest partially overlaps the source.  */
410    if (reg_overlap_mentioned_p (operands[3], operands[7])
411        || reg_overlap_mentioned_p (operands[3], operands[8]))
412       FAIL;
414    if (GET_CODE (operands[5]) == CONST_INT)
415      operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
416    else
417      operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
418    "
419   )
422 ;; Alternatives 2 and 3 are to handle cases generated by reload.
423 (define_insn "subpsi3"
424   [(set (match_operand:PSI            0 "nonimmediate_operand" "=r,   rm, &?r, ?&r")
425         (minus:PSI (match_operand:PSI 1 "general_operand"       "0,   0,   !r,  !i")
426                    (match_operand:PSI 2 "general_operand"       "rLs, rmi, rmi,  r")))]
427   ""
428   "@
429   SUBA\t%2, %0
430   SUBX.A\t%2, %0
431   MOVX.A\t%1, %0 { SUBX.A\t%2, %0
432   MOVX.A\t%1, %0 { SUBA\t%2, %0"
435 ;; Alternatives 2 and 3 are to handle cases generated by reload.
436 (define_insn "subqi3"
437   [(set (match_operand:QI           0 "nonimmediate_operand" "=rYs,  rm,  &?r, ?&r")
438         (minus:QI (match_operand:QI 1 "general_operand"       "0,    0,    !r,  !i")
439                   (match_operand:QI 2 "general_operand"      " riYs, rmi, rmi,   r")))]
440   ""
441   "@
442   SUB.B\t%2, %0
443   SUB%X0.B\t%2, %0
444   MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0
445   MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0"
448 ;; Alternatives 2 and 3 are to handle cases generated by reload.
449 (define_insn "subhi3"
450   [(set (match_operand:HI           0 "nonimmediate_operand" "=rYs,  rm,  &?r, ?&r")
451         (minus:HI (match_operand:HI 1 "general_operand"       "0,    0,    !r,  !i")
452                   (match_operand:HI 2 "general_operand"      " riYs, rmi, rmi,   r")))]
453   ""
454   "@
455   SUB.W\t%2, %0
456   SUB%X0.W\t%2, %0
457   MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0
458   MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0"
461 (define_insn "subsi3"
462   [(set (match_operand:SI           0 "nonimmediate_operand" "=&rm")
463         (minus:SI (match_operand:SI 1 "nonimmediate_operand"   "0")
464                   (match_operand:SI 2 "general_operand"        "rmi")))]
465   ""
466   "SUB%X0\t%L2, %L0 { SUBC%X0\t%H2, %H0"
469 (define_insn "*bic<mode>_cg"
470   [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m")
471         (and:QHI (match_operand:QHI 1 "msp_general_operand" "0,0")
472                  (match_operand 2 "msp430_inv_constgen_operator" "n,n")))]
473   ""
474   "@
475    BIC%x0%b0\t#%I2, %0
476    BIC%X0%b0\t#%I2, %0"
479 (define_insn "bic<mode>3"
480   [(set (match_operand:QHI                   0 "msp_nonimmediate_operand" "=rYs,rm")
481         (and:QHI (not:QHI (match_operand:QHI 1 "msp_general_operand"       "rYs,rmn"))
482                  (match_operand:QHI          2 "msp_nonimmediate_operand"  "0,0")))]
483   ""
484   "@
485    BIC%x0%b0\t%1, %0
486    BIC%X0%b0\t%1, %0"
489 (define_insn "and<mode>3"
490   [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
491         (and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
492                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
493   ""
494   "@
495    AND%x0%b0\t%2, %0
496    AND%X0%b0\t%2, %0"
499 (define_insn "ior<mode>3"
500   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,rm")
501         (ior:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
502                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
503   ""
504   "@
505    BIS%x0%b0\t%2, %0
506    BIS%X0%b0\t%2, %0"
509 (define_insn "xor<mode>3"
510   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,rm")
511         (xor:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
512                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
513   ""
514   "@
515    XOR%x0%b0\t%2, %0
516    XOR%X0%b0\t%2, %0"
519 ;; Macro : XOR #~0, %0
520 (define_insn "one_cmpl<mode>2"
521   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,m")
522         (not:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "0,0")))]
523   ""
524   "@
525    INV%x0%b0\t%0
526    INV%X0%b0\t%0"
529 (define_insn "extendqihi2"
530   [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,m")
531         (sign_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
532   ""
533   "@
534    SXT%X0\t%0
535    SXT%X0\t%0"
538 (define_insn "zero_extendqihi2"
539   [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,m")
540         (zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
541   ""
542   "@
543    AND\t#0xff, %0
544    AND%X0\t#0xff, %0"
547 ;; Eliminate extraneous zero-extends mysteriously created by gcc.
548 (define_peephole2
549   [(set (match_operand:HI 0 "register_operand")
550         (zero_extend:HI (match_operand:QI 1 "general_operand")))
551    (set (match_operand:HI 2 "register_operand")
552         (zero_extend:HI (match_operand:QI 3 "register_operand")))]
553   "REGNO (operands[0]) == REGNO (operands[2]) && REGNO (operands[2]) == REGNO (operands[3])"
554   [(set (match_dup 0)
555         (zero_extend:HI (match_dup 1)))]
558 (define_insn "zero_extendhipsi2"
559   [(set (match_operand:PSI                 0 "msp_nonimmediate_operand" "=r,m")
560         (zero_extend:PSI (match_operand:HI 1 "msp_nonimmediate_operand" "rm,r")))]
561   ""
562   "MOVX\t%1, %0"
565 (define_insn "truncpsihi2"
566   [(set (match_operand:HI               0 "msp_nonimmediate_operand" "=rm")
567         (truncate:HI (match_operand:PSI 1 "register_operand"      "r")))]
568   ""
569   "MOVX\t%1, %0"
572 (define_insn "extendhisi2"
573   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
574         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
575   ""
576   { return msp430x_extendhisi (operands); }
579 (define_insn "extendhipsi2"
580   [(set (match_operand:PSI 0 "nonimmediate_operand" "=r")
581         (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))]
582   "msp430x"
583   "RLAM.A #4, %0 { RRAM.A #4, %0"
586 ;; Look for cases where integer/pointer conversions are suboptimal due
587 ;; to missing patterns, despite us not having opcodes for these
588 ;; patterns.  Doing these manually allows for alternate optimization
589 ;; paths.
590 (define_insn "zero_extendhisi2"
591   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
592         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
593   "msp430x"
594   "MOV.W\t#0,%H0"
597 (define_insn "zero_extendhisipsi2"
598   [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r")
599         (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))]
600   "msp430x"
601   "@
602    AND.W\t#-1,%0
603    MOV.W\t%1,%0"
606 (define_insn "extend_and_shift1_hipsi2"
607   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
608         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
609                    (const_int 1)))]
610   "msp430x"
611   "RLAM.A #4, %0 { RRAM.A #3, %0"
614 (define_insn "extend_and_shift2_hipsi2"
615   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
616         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
617                    (const_int 2)))]
618   "msp430x"
619   "RLAM.A #4, %0 { RRAM.A #2, %0"
622 ; Nasty - we are sign-extending a 20-bit PSI value in one register into
623 ; two adjacent 16-bit registers to make an SI value.  There is no MSP430X
624 ; instruction that will do this, so we push the 20-bit value onto the stack
625 ; and then pop it off as two 16-bit values.
627 ; FIXME: The MSP430X documentation does not specify if zero-extension or
628 ; sign-extension happens when the 20-bit value is pushed onto the stack.
629 ; It is probably zero-extension, but if not this pattern will not work
630 ; when the PSI value is negative..
632 ; Note: using PUSHM.A #1 is two bytes smaller than using PUSHX.A....
634 ; Note: We use a + constraint on operand 0 as otherwise GCC gets confused
635 ; about extending a single PSI mode register into a pair of SImode registers
636 ; with the same starting register.  It thinks that the upper register of
637 ; the pair is unused and so it can clobber it.  Try compiling 20050826-2.c
638 ; at -O2 to see this.
640 (define_insn "zero_extendpsisi2"
641   [(set (match_operand:SI                  0 "register_operand" "+r")
642         (zero_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
643   ""
644   "*
645     if (REGNO (operands[1]) == SP_REGNO)
646       /* If the source register is the stack pointer, the value
647          stored in the stack slot will be the value *after* the
648          stack pointer has been decremented.  So allow for that
649          here.  */
650       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\";
651     else
652       return \"PUSHM.A\t#1, %1 { POPX.W\t%L0 { POPX.W\t%H0 ; move pointer in %1 into reg-pair %L0:%H0\";
653   "
656 ;; We also need to be able to sign-extend pointer types (eg ptrdiff_t).
657 ;; Since (we assume) pushing a 20-bit value onto the stack zero-extends
658 ;; it, we use a different method here.
660 (define_insn "extendpsisi2"
661   [(set (match_operand:SI                  0 "register_operand" "=r")
662         (sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
663   "msp430x"
664   "*
665     /* The intention here is that we copy the bottom 16-bits of
666        %1 into %L0 (zeroing the top four bits).  Then we copy the
667        entire 20-bits of %1 into %H0 and then arithmetically shift
668        it right by 16 bits, to get the top four bits of the pointer
669        sign-extended in %H0.  */
670     if (REGNO (operands[0]) == REGNO (operands[1]))
671       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\";
672     else
673       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\";
674   "
677 ; See the movsipsi2 pattern above for another way that GCC performs this
678 ; conversion.
679 (define_insn "truncsipsi2"
680   [(set (match_operand:PSI              0 "register_operand" "=r")
681         (truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
682   ""
683   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A\t#1, %L0"
686 ;;------------------------------------------------------------
687 ;; Shift Functions
689 ;; Note:  We do not use the RPT ... SHIFT instruction sequence
690 ;; when the repeat count is in a register, because even though RPT
691 ;; accepts counts in registers, it does not work if the count is
692 ;; zero, and the actual count in the register has to be one less
693 ;; than the required number of iterations.  We could encode a
694 ;; seqeunce like this:
696 ;;   bit #0xf, Rn
697 ;;   bz  1f
698 ;;   dec Rn
699 ;;   rpt Rn
700 ;;   <shift> Rm
701 ;;   inc Rn
702 ;; 1:
704 ;; But is longer than calling a helper function, and we are mostly
705 ;; concerned with code size.  FIXME: Maybe enable a sequence like
706 ;; this at -O3 and above ?
708 ;; Note - we ignore shift counts of less than one or more than 15.
709 ;; This is permitted by the ISO C99 standard as such shifts result
710 ;; in "undefined" behaviour.  [6.5.7 (3)]
712 ;; signed A << C
714 (define_expand "ashlhi3"
715   [(set (match_operand:HI            0 "nonimmediate_operand")
716         (ashift:HI (match_operand:HI 1 "general_operand")
717                    (match_operand:HI 2 "general_operand")))]
718   ""
719   {
720     if (msp430x
721         && REG_P (operands[0])
722         && REG_P (operands[1])
723         && CONST_INT_P (operands[2]))
724       emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2]));
725     else                 
726       msp430_expand_helper (operands, \"__mspabi_slli\", true);
727     DONE;
728   }
731 (define_insn "slli_1"
732   [(set (match_operand:HI            0 "nonimmediate_operand" "=rm")
733         (ashift:HI (match_operand:HI 1 "general_operand"       "0")
734                    (const_int 1)))]
735   ""
736   "RLA.W\t%0" ;; Note - this is a macro for ADD
739 (define_insn "430x_shift_left"
740   [(set (match_operand:HI            0 "register_operand" "=r")
741         (ashift:HI (match_operand:HI 1 "register_operand"  "0")
742                    (match_operand    2 "immediate_operand" "n")))]
743   "msp430x"
744   "*
745   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
746     return \"rpt\t%2 { rlax.w\t%0\";
747   return \"# nop left shift\";
748   "
751 (define_insn "slll_1"
752   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
753         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
754                    (const_int 1)))]
755   ""
756   "RLA.W\t%L0 { RLC.W\t%H0"
759 (define_insn "slll_2"
760   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
761         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
762                    (const_int 2)))]
763   ""
764   "RLA.W\t%L0 { RLC.W\t%H0 { RLA.W\t%L0 { RLC.W\t%H0"
767 (define_expand "ashlsi3"
768   [(set (match_operand:SI            0 "nonimmediate_operand")
769         (ashift:SI (match_operand:SI 1 "general_operand")
770                    (match_operand:SI 2 "general_operand")))]
771   ""
772   "msp430_expand_helper (operands, \"__mspabi_slll\", true);
773    DONE;"
776 ;;----------
778 ;; signed A >> C
780 (define_expand "ashrhi3"
781   [(set (match_operand:HI              0 "nonimmediate_operand")
782         (ashiftrt:HI (match_operand:HI 1 "general_operand")
783                      (match_operand:HI 2 "general_operand")))]
784   ""
785   {
786     if (msp430x
787         && REG_P (operands[0])
788         && REG_P (operands[1])
789         && CONST_INT_P (operands[2]))
790       emit_insn (gen_430x_arithmetic_shift_right (operands[0], operands[1], operands[2]));
791     else                 
792        msp430_expand_helper (operands, \"__mspabi_srai\", true);
793    DONE;
794    }
797 (define_insn "srai_1"
798   [(set (match_operand:HI              0 "msp_nonimmediate_operand" "=rm")
799         (ashiftrt:HI (match_operand:HI 1 "msp_general_operand"      "0")
800                      (const_int 1)))]
801   ""
802   "RRA.W\t%0"
805 (define_insn "430x_arithmetic_shift_right"
806   [(set (match_operand:HI              0 "register_operand" "=r")
807         (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0")
808                      (match_operand    2 "immediate_operand" "n")))]
809   "msp430x"
810   "*
811   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
812     return \"rpt\t%2 { rrax.w\t%0\";
813   return \"# nop arith right shift\";
814   "
817 (define_insn "srap_1"
818   [(set (match_operand:PSI              0 "register_operand" "=r")
819         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
820                       (const_int 1)))]
821   "msp430x"
822   "RRAM.A #1,%0"
825 (define_insn "srap_2"
826   [(set (match_operand:PSI              0 "register_operand" "=r")
827         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
828                       (const_int 2)))]
829   "msp430x"
830   "RRAM.A #2,%0"
833 (define_insn "sral_1"
834   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
835         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
836                      (const_int 1)))]
837   ""
838   "RRA.W\t%H0 { RRC.W\t%L0"
841 (define_insn "sral_2"
842   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
843         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
844                      (const_int 2)))]
845   ""
846   "RRA.W\t%H0 { RRC.W\t%L0 { RRA.W\t%H0 { RRC.W\t%L0"
849 (define_expand "ashrsi3"
850   [(set (match_operand:SI              0 "nonimmediate_operand")
851         (ashiftrt:SI (match_operand:SI 1 "general_operand")
852                      (match_operand:SI 2 "general_operand")))]
853   ""
854   "msp430_expand_helper (operands, \"__mspabi_sral\", true);
855    DONE;"
858 ;;----------
860 ;; unsigned A >> C
862 (define_expand "lshrhi3"
863   [(set (match_operand:HI              0 "nonimmediate_operand")
864         (lshiftrt:HI (match_operand:HI 1 "general_operand")
865                      (match_operand:HI 2 "general_operand")))]
866   ""
867   {
868     if (msp430x
869         && REG_P (operands[0])
870         && REG_P (operands[1])
871         && CONST_INT_P (operands[2]))
872       emit_insn (gen_430x_logical_shift_right (operands[0], operands[1], operands[2]));
873     else                 
874       msp430_expand_helper (operands, \"__mspabi_srli\", true);
875     DONE;
876   }
879 (define_insn "srli_1"
880   [(set (match_operand:HI              0 "nonimmediate_operand" "=rm")
881         (lshiftrt:HI (match_operand:HI 1 "general_operand"       "0")
882                      (const_int 1)))]
883   ""
884   "CLRC { RRC.W\t%0"
887 (define_insn "430x_logical_shift_right"
888   [(set (match_operand:HI              0 "register_operand" "=r")
889         (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0")
890                      (match_operand    2 "immediate_operand" "n")))]
891   "msp430x"
892   {
893     return msp430x_logical_shift_right (operands[2]);
894   }
897 (define_insn "srlp_1"
898   [(set (match_operand:PSI              0 "register_operand" "=r")
899         (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
900                       (const_int 1)))]
901   ""
902   "RRUM.A #1,%0"
905 (define_insn "srll_1"
906   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
907         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
908                      (const_int 1)))]
909   ""
910   "CLRC { RRC.W\t%H0 { RRC.W\t%L0"
913 (define_insn "srll_2x"
914   [(set (match_operand:SI              0 "nonimmediate_operand" "=r")
915         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
916                      (const_int 2)))]
917   "msp430x"
918   "RRUX.W\t%H0 { RRC.W\t%L0 { RRUX.W\t%H0 { RRC.W\t%L0"
921 (define_expand "lshrsi3"
922   [(set (match_operand:SI              0 "nonimmediate_operand")
923         (lshiftrt:SI (match_operand:SI 1 "general_operand")
924                      (match_operand:SI 2 "general_operand")))]
925   ""
926   "msp430_expand_helper (operands, \"__mspabi_srll\", true);
927    DONE;"
930 ;;------------------------------------------------------------
931 ;; Function Entry/Exit
933 (define_expand "prologue"
934   [(const_int 0)]
935   ""
936   "msp430_expand_prologue (); DONE;"
937   )
939 (define_expand "epilogue"
940   [(const_int 0)]
941   ""
942   "msp430_expand_epilogue (0); DONE;"
943   )
945 (define_insn "epilogue_helper"
946   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)]
947   ""
948   "BR%Q0\t#__mspabi_func_epilog_%J0"
949   )
951 (define_insn "prologue_start_marker"
952   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)]
953   ""
954   "; start of prologue"
955   )
957 (define_insn "prologue_end_marker"
958   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)]
959   ""
960   "; end of prologue"
961   )
963 (define_insn "epilogue_start_marker"
964   [(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)]
965   ""
966   "; start of epilogue"
967   )
969 ;; This makes the linker add a call to exit() after the call to main()
970 ;; in crt0
971 (define_insn "msp430_refsym_need_exit"
972   [(unspec_volatile [(const_int 0)] UNS_REFSYM_NEED_EXIT)]
973   ""
974   ".refsym\t__crt0_call_exit"
975   )
977 ;;------------------------------------------------------------
978 ;; Jumps
980 (define_expand "call"
981   [(call:HI (match_operand 0 "")
982             (match_operand 1 ""))]
983   ""
984   ""
987 (define_insn "call_internal"
988   [(call (mem:HI (match_operand 0 "general_operand" "rYci"))
989          (match_operand 1 ""))]
990   ""
991   "CALL%Q0\t%0"
994 (define_expand "call_value"
995   [(set (match_operand          0 "register_operand")
996         (call:HI (match_operand 1 "general_operand")
997                  (match_operand 2 "")))]
998   ""
999   ""
1002 (define_insn "call_value_internal"
1003   [(set (match_operand               0 "register_operand" "=r")
1004         (call (mem:HI (match_operand 1 "general_operand" "rYci"))
1005               (match_operand 2 "")))]
1006   ""
1007   "CALL%Q0\t%1"
1010 (define_insn "msp_return"
1011   [(return)]
1012   ""
1013   { return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); }
1016 ;; This pattern is NOT, as expected, a return pattern.  It's called
1017 ;; before reload and must only store its operands, and emit a
1018 ;; placeholder where the epilog needs to be.  AFTER reload, the
1019 ;; placeholder should get expanded into a regular-type epilogue that
1020 ;; also does the EH return.
1021 (define_expand "eh_return"
1022   [(match_operand:HI 0 "")]
1023   ""
1024   "msp430_expand_eh_return (operands[0]);
1025    emit_jump_insn (gen_msp430_eh_epilogue ());
1026    emit_barrier ();
1027    DONE;"
1030 ;; This is the actual EH epilogue.  We emit it in the pattern above,
1031 ;; before reload, and convert it to a real epilogue after reload.
1032 (define_insn_and_split "msp430_eh_epilogue"
1033   [(eh_return)]
1034   ""
1035   "#"
1036   "reload_completed"
1037   [(const_int 0)]
1038   "msp430_expand_epilogue (1); DONE;"
1039   )
1041 (define_insn "jump"
1042   [(set (pc)
1043         (label_ref (match_operand 0 "" "")))]
1044   ""
1045   "BR%Q0\t#%l0"
1048 ;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
1049 ;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c).
1050 (define_insn "indirect_jump"
1051   [(set (pc)
1052         (match_operand 0 "nonimmediate_operand" "rYl"))]
1053   ""
1054   "BR%Q0\t%0"
1057 ;;------------------------------------------------------------
1058 ;; Various Conditionals
1060 (define_expand "cbranch<mode>4"
1061   [(parallel [(set (pc) (if_then_else
1062                          (match_operator 0 ""
1063                                          [(match_operand:QHI 1 "nonimmediate_operand")
1064                                           (match_operand:QHI 2 "general_operand")])
1065                          (label_ref (match_operand 3 "" ""))
1066                          (pc)))
1067               (clobber (reg:BI CARRY))]
1068   )]
1069   ""
1070   "msp430_fixup_compare_operands (<MODE>mode, operands);"
1071   )
1073 (define_insn "cbranchpsi4_real"
1074   [(set (pc) (if_then_else
1075               (match_operator                     0 "msp430_cmp_operator"
1076                               [(match_operand:PSI 1 "nonimmediate_operand" "r,rYs,rm")
1077                                (match_operand:PSI 2 "general_operand"      "rLs,rYsi,rmi")])
1078               (label_ref (match_operand           3 "" ""))
1079               (pc)))
1080    (clobber (reg:BI CARRY))
1081    ]
1082   ""
1083   "@
1084   CMP%Q0\t%2, %1 { J%0\t%l3
1085   CMPX.A\t%2, %1 { J%0\t%l3
1086   CMPX.A\t%2, %1 { J%0\t%l3"
1087   )
1089 (define_insn "cbranchqi4_real"
1090   [(set (pc) (if_then_else
1091               (match_operator                    0 "msp430_cmp_operator"
1092                               [(match_operand:QI 1 "nonimmediate_operand" "rYs,rm")
1093                                (match_operand:QI 2 "general_operand"      "rYsi,rmi")])
1094               (label_ref (match_operand          3 "" ""))
1095               (pc)))
1096    (clobber (reg:BI CARRY))
1097    ]
1098   ""
1099   "@
1100    CMP.B\t%2, %1 { J%0\t%l3
1101    CMP%X0.B\t%2, %1 { J%0\t%l3"
1102   )
1104 (define_insn "cbranchhi4_real"
1105   [(set (pc) (if_then_else
1106               (match_operator                    0 "msp430_cmp_operator"
1107                               [(match_operand:HI 1 "nonimmediate_operand" "rYs,rm")
1108                                (match_operand:HI 2 "general_operand"      "rYsi,rmi")])
1109               (label_ref (match_operand          3 "" ""))
1110               (pc)))
1111    (clobber (reg:BI CARRY))
1112    ]
1113   ""
1114   "*
1115     /* This is nasty.  If we are splitting code between low and high memory
1116        then we do not want the linker to increase the size of sections by
1117        relaxing out of range jump instructions.  (Since relaxation occurs
1118        after section placement).  So we have to generate pessimal branches
1119        here.  But we only want to do this when really necessary.
1121        FIXME: Do we need code in the other cbranch patterns ?  */
1122     if (msp430_do_not_relax_short_jumps () && get_attr_length (insn) > 6)
1123       {
1124         return which_alternative == 0 ?
1125             \"CMP.W\t%2, %1 { J%r0 1f { BRA #%l3 { 1:\" :
1126          \"CMP%X0.W\t%2, %1 { J%r0 1f { BRA #%l3 { 1:\";
1127       }
1129     return which_alternative == 0 ?
1130          \"CMP.W\t%2, %1 { J%0\t%l3\" :
1131       \"CMP%X0.W\t%2, %1 { J%0\t%l3\";
1132   "
1133   [(set (attr "length")
1134         (if_then_else
1135           (and (ge (minus (match_dup 3) (pc)) (const_int -510))
1136                (le (minus (match_dup 3) (pc)) (const_int 510)))
1137           (const_int 6)
1138           (const_int 10))
1139         )]
1140   )
1142 (define_insn "cbranchpsi4_reversed"
1143   [(set (pc) (if_then_else
1144               (match_operator                     0 "msp430_reversible_cmp_operator"
1145                               [(match_operand:PSI 1 "general_operand" "rLs,rYsi,rmi")
1146                                (match_operand:PSI 2 "general_operand" "r,rYs,rm")])
1147               (label_ref (match_operand           3 "" ""))
1148               (pc)))
1149    (clobber (reg:BI CARRY))
1150    ]
1151   ""
1152   "@
1153   CMP%Q0\t%1, %2 { J%R0\t%l3
1154   CMPX.A\t%1, %2 { J%R0\t%l3
1155   CMPX.A\t%1, %2 { J%R0\t%l3"
1156   )
1158 (define_insn "cbranchqi4_reversed"
1159   [(set (pc) (if_then_else
1160               (match_operator                    0 "msp430_reversible_cmp_operator"
1161                               [(match_operand:QI 1 "general_operand" "rYsi,rmi")
1162                                (match_operand:QI 2 "general_operand" "rYs,rm")])
1163               (label_ref (match_operand          3 "" ""))
1164               (pc)))
1165    (clobber (reg:BI CARRY))
1166    ]
1167   ""
1168   "@
1169    CMP.B\t%1, %2 { J%R0\t%l3
1170    CMP%X0.B\t%1, %2 { J%R0\t%l3"
1171   )
1173 (define_insn "cbranchhi4_reversed"
1174   [(set (pc) (if_then_else
1175               (match_operator                    0 "msp430_reversible_cmp_operator"
1176                               [(match_operand:HI 1 "general_operand" "rYsi,rmi")
1177                                (match_operand:HI 2 "general_operand" "rYs,rm")])
1178               (label_ref (match_operand          3 "" ""))
1179               (pc)))
1180    (clobber (reg:BI CARRY))
1181    ]
1182   ""
1183   "@
1184    CMP.W\t%1, %2 { J%R0\t%l3
1185    CMP%X0.W\t%1, %2 { J%R0\t%l3"
1186   )
1188 (define_insn "*bitbranch<mode>4"
1189   [(set (pc) (if_then_else
1190               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1191                            (match_operand:QHI 1 "msp_general_operand" "rYsi,rmi"))
1192                   (const_int 0))
1193               (label_ref (match_operand 2 "" ""))
1194               (pc)))
1195    (clobber (reg:BI CARRY))
1196    ]
1197   ""
1198   "@
1199    BIT%x0%b0\t%1, %0 { JNE\t%l2
1200    BIT%X0%b0\t%1, %0 { JNE\t%l2"
1201   )
1203 (define_insn "*bitbranch<mode>4"
1204   [(set (pc) (if_then_else
1205               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1206                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1207                   (const_int 0))
1208               (label_ref (match_operand 2 "" ""))
1209               (pc)))
1210    (clobber (reg:BI CARRY))
1211    ]
1212   ""
1213   "BIT%x0%b0\t%1, %0 { JEQ\t%l2"
1214   )
1216 (define_insn "*bitbranch<mode>4"
1217   [(set (pc) (if_then_else
1218               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1219                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1220                   (const_int 0))
1221               (pc)
1222               (label_ref (match_operand 2 "" ""))))
1223    (clobber (reg:BI CARRY))
1224    ]
1225   ""
1226   "BIT%X0%b0\t%1, %0 { JNE\t%l2"
1227   )
1229 (define_insn "*bitbranch<mode>4"
1230   [(set (pc) (if_then_else
1231               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1232                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1233                   (const_int 0))
1234               (pc)
1235               (label_ref (match_operand 2 "" ""))))
1236    (clobber (reg:BI CARRY))
1237    ]
1238   ""
1239   "BIT%X0%b0\t%1, %0 { JEQ\t%l2"
1240   )
1242 ;;------------------------------------------------------------
1243 ;; zero-extract versions of the above
1245 (define_insn "*bitbranch<mode>4_z"
1246   [(set (pc) (if_then_else
1247               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1248                                     (const_int 1)
1249                                     (match_operand 1 "msp430_bitpos" "i,i"))
1250                   (const_int 0))
1251               (label_ref (match_operand 2 "" ""))
1252               (pc)))
1253    (clobber (reg:BI CARRY))
1254    ]
1255   ""
1256   "@
1257    BIT%x0%b0\t%p1, %0 { JNE\t%l2
1258    BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1259   )
1261 (define_insn "*bitbranch<mode>4_z"
1262   [(set (pc) (if_then_else
1263               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1264                                    (const_int 1)
1265                                    (match_operand 1 "msp430_bitpos" "i"))
1266                   (const_int 0))
1267               (label_ref (match_operand 2 "" ""))
1268               (pc)))
1269    (clobber (reg:BI CARRY))
1270    ]
1271   ""
1272   "BIT%x0%X0%b0\t%p1, %0 { JEQ\t%l2"
1273   )
1275 (define_insn "*bitbranch<mode>4_z"
1276   [(set (pc) (if_then_else
1277               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1278                                    (const_int 1)
1279                                    (match_operand 1 "msp430_bitpos" "i"))
1280                   (const_int 0))
1281               (pc)
1282               (label_ref (match_operand 2 "" ""))))
1283    (clobber (reg:BI CARRY))
1284    ]
1285   ""
1286   "BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1287   )
1289 (define_insn "*bitbranch<mode>4_z"
1290   [(set (pc) (if_then_else
1291               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1292                                    (const_int 1)
1293                                    (match_operand 1 "msp430_bitpos" "i"))
1294                   (const_int 0))
1295               (pc)
1296               (label_ref (match_operand 2 "" ""))))
1297    (clobber (reg:BI CARRY))
1298    ]
1299   ""
1300   "BIT%X0%b0\t%p1, %0 { JEQ\t%l2"
1301   )
1303 ;;------------------------------------------------------------
1304 ;; Misc
1306 (define_insn "nop"
1307   [(const_int 0)]
1308   "1"
1309   "NOP"
1312 (define_insn "disable_interrupts"
1313   [(unspec_volatile [(const_int 0)] UNS_DINT)]
1314   ""
1315   "DINT \; NOP"
1316   )
1318 (define_insn "enable_interrupts"
1319   [(unspec_volatile [(const_int 0)] UNS_EINT)]
1320   ""
1321   "EINT"
1322   )
1324 (define_insn "push_intr_state"
1325   [(unspec_volatile [(const_int 0)] UNS_PUSH_INTR)]
1326   ""
1327   "PUSH\tSR"
1328   )
1330 (define_insn "pop_intr_state"
1331   [(unspec_volatile [(const_int 0)] UNS_POP_INTR)]
1332   ""
1333   "POP\tSR"
1334   )
1336 ;; Clear bits in the copy of the status register that is currently
1337 ;; saved on the stack at the top of the interrupt handler.
1338 (define_insn "bic_SR"
1339   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIC_SR)]
1340   ""
1341   "BIC.W\t%0, %O0(SP)"
1342   )
1344 ;; Set bits in the copy of the status register that is currently
1345 ;; saved on the stack at the top of the interrupt handler.
1346 (define_insn "bis_SR"
1347   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIS_SR)]
1348   ""
1349   "BIS.W\t%0, %O0(SP)"
1350   )
1352 ;; For some reason GCC is generating (set (reg) (and (neg (reg)) (int)))
1353 ;; very late on in the compilation and not splitting it into separate
1354 ;; instructions, so we provide a pattern to support it here.
1355 (define_insn "andneghi3"
1356   [(set (match_operand:HI                 0 "register_operand" "=r")
1357         (and:HI (neg:HI (match_operand:HI 1 "register_operand"  "r"))
1358                 (match_operand            2 "immediate_operand" "n")))]
1359   ""
1360   "*
1361     if (REGNO (operands[0]) != REGNO (operands[1]))
1362       return \"MOV.W\t%1, %0 { INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0\";
1363     else
1364       return \"INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0\";
1365   "
1366   )
1368 (define_insn "delay_cycles_start"
1369   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
1370                     UNS_DELAY_START)]
1371   ""
1372   "; Begin %J0 cycle delay"
1373   )
1375 (define_insn "delay_cycles_end"
1376   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
1377                     UNS_DELAY_END)]
1378   ""
1379   "; End %J0 cycle delay"
1380   )
1382 (define_insn "delay_cycles_32"
1383   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1384                      (match_operand 1 "immediate_operand" "i")
1385                      ] UNS_DELAY_32)]
1386   ""
1387   "PUSH r13
1388         PUSH    r14
1389         MOV.W   %A0, r13
1390         MOV.W   %B0, r14
1391 1:      SUB.W   #1, r13
1392         SUBC.W  #0, r14
1393         JNE     1b
1394         TST.W   r13
1395         JNE     1b
1396         POP     r14
1397         POP     r13"
1398   )
1400 (define_insn "delay_cycles_32x"
1401   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1402                      (match_operand 1 "immediate_operand" "i")
1403                      ] UNS_DELAY_32X)]
1404   ""
1405   "PUSHM.A      #2,r13
1406         MOV.W   %A0, r13
1407         MOV.W   %B0, r14
1408 1:      SUB.W   #1, r13
1409         SUBC.W  #0, r14
1410         JNE     1b
1411         TST.W   r13
1412         JNE     1b
1413         POPM.A  #2,r13"
1414   )
1416 (define_insn "delay_cycles_16"
1417   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1418                      (match_operand 1 "immediate_operand" "i")
1419                      ] UNS_DELAY_16)]
1420   ""
1421   "PUSH r13
1422         MOV.W   %0, r13
1423 1:      SUB.W   #1, r13
1424         JNE     1b
1425         POP     r13"
1426   )
1428 (define_insn "delay_cycles_16x"
1429   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1430                      (match_operand 1 "immediate_operand" "i")
1431                      ] UNS_DELAY_16X)]
1432   ""
1433   "PUSHM.A      #1,r13
1434         MOV.W   %0, r13
1435 1:      SUB.W   #1, r13
1436         JNE     1b
1437         POPM.A  #1,r13"
1438   )
1440 (define_insn "delay_cycles_2"
1441   [(unspec_volatile [(const_int 0) ] UNS_DELAY_2)]
1442   ""
1443   "JMP  .+2"
1444   )
1446 (define_insn "delay_cycles_1"
1447   [(unspec_volatile [(const_int 0) ] UNS_DELAY_1)]
1448   ""
1449   "NOP"
1450   )
1452 (define_insn "mulhisi3"
1453   [(set (match_operand:SI                          0 "register_operand" "=r")
1454         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1455                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1456   "optimize > 2 && msp430_hwmult_type != NONE"
1457   "*
1458     if (msp430_use_f5_series_hwmult ())
1459       return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x04C2 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\";
1460     else
1461       return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x0132 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\";
1462   "
1465 (define_insn "umulhisi3"
1466   [(set (match_operand:SI                          0 "register_operand" "=r")
1467         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1468                  (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1469   "optimize > 2 && msp430_hwmult_type != NONE"
1470   "*
1471     if (msp430_use_f5_series_hwmult ())
1472       return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x04C0 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\";
1473     else
1474       return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x0130 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\";
1475   "
1478 (define_insn "mulsidi3"
1479   [(set (match_operand:DI                          0 "register_operand" "=r")
1480         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1481                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1482   "optimize > 2 && msp430_hwmult_type != NONE"
1483   "*
1484     if (msp430_use_f5_series_hwmult ())
1485       return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x04D4 { MOV.W %H1, &0x04D6 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\";
1486     else
1487       return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x0144 { MOV.W %H1, &0x0146 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\";
1488   "
1491 (define_insn "umulsidi3"
1492   [(set (match_operand:DI                          0 "register_operand" "=r")
1493         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1494                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1495   "optimize > 2 && msp430_hwmult_type != NONE"
1496   "*
1497     if (msp430_use_f5_series_hwmult ())
1498       return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x04D0 { MOV.W %H1, &0x04D2 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\";
1499     else
1500       return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x0140 { MOV.W %H1, &0x0142 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\";
1501   "