PR target/66156
[official-gcc.git] / gcc / config / msp430 / msp430.md
blob64fdc459b784ab839dea5d24853a6859cc761244
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,r")
592         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")))]
593   "msp430x"
594   "@
595   MOV.W\t#0,%H0
596   MOV.W\t%1,%L0 { MOV.W\t#0,%H0"
599 (define_insn "zero_extendhisipsi2"
600   [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r")
601         (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))]
602   "msp430x"
603   "@
604    AND.W\t#-1,%0
605    MOV.W\t%1,%0"
608 (define_insn "extend_and_shift1_hipsi2"
609   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
610         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
611                    (const_int 1)))]
612   "msp430x"
613   "RLAM.A #4, %0 { RRAM.A #3, %0"
616 (define_insn "extend_and_shift2_hipsi2"
617   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
618         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
619                    (const_int 2)))]
620   "msp430x"
621   "RLAM.A #4, %0 { RRAM.A #2, %0"
624 ; Nasty - we are sign-extending a 20-bit PSI value in one register into
625 ; two adjacent 16-bit registers to make an SI value.  There is no MSP430X
626 ; instruction that will do this, so we push the 20-bit value onto the stack
627 ; and then pop it off as two 16-bit values.
629 ; FIXME: The MSP430X documentation does not specify if zero-extension or
630 ; sign-extension happens when the 20-bit value is pushed onto the stack.
631 ; It is probably zero-extension, but if not this pattern will not work
632 ; when the PSI value is negative..
634 ; Note: using PUSHM.A #1 is two bytes smaller than using PUSHX.A....
636 ; Note: We use a + constraint on operand 0 as otherwise GCC gets confused
637 ; about extending a single PSI mode register into a pair of SImode registers
638 ; with the same starting register.  It thinks that the upper register of
639 ; the pair is unused and so it can clobber it.  Try compiling 20050826-2.c
640 ; at -O2 to see this.
642 (define_insn "zero_extendpsisi2"
643   [(set (match_operand:SI                  0 "register_operand" "+r")
644         (zero_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
645   ""
646   "*
647     if (REGNO (operands[1]) == SP_REGNO)
648       /* If the source register is the stack pointer, the value
649          stored in the stack slot will be the value *after* the
650          stack pointer has been decremented.  So allow for that
651          here.  */
652       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\";
653     else
654       return \"PUSHM.A\t#1, %1 { POPX.W\t%L0 { POPX.W\t%H0 ; move pointer in %1 into reg-pair %L0:%H0\";
655   "
658 ;; We also need to be able to sign-extend pointer types (eg ptrdiff_t).
659 ;; Since (we assume) pushing a 20-bit value onto the stack zero-extends
660 ;; it, we use a different method here.
662 (define_insn "extendpsisi2"
663   [(set (match_operand:SI                  0 "register_operand" "=r")
664         (sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
665   "msp430x"
666   "*
667     /* The intention here is that we copy the bottom 16-bits of
668        %1 into %L0 (zeroing the top four bits).  Then we copy the
669        entire 20-bits of %1 into %H0 and then arithmetically shift
670        it right by 16 bits, to get the top four bits of the pointer
671        sign-extended in %H0.  */
672     if (REGNO (operands[0]) == REGNO (operands[1]))
673       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\";
674     else
675       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\";
676   "
679 ; See the movsipsi2 pattern above for another way that GCC performs this
680 ; conversion.
681 (define_insn "truncsipsi2"
682   [(set (match_operand:PSI              0 "register_operand" "=r")
683         (truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
684   ""
685   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A\t#1, %L0"
688 ;;------------------------------------------------------------
689 ;; Shift Functions
691 ;; Note:  We do not use the RPT ... SHIFT instruction sequence
692 ;; when the repeat count is in a register, because even though RPT
693 ;; accepts counts in registers, it does not work if the count is
694 ;; zero, and the actual count in the register has to be one less
695 ;; than the required number of iterations.  We could encode a
696 ;; seqeunce like this:
698 ;;   bit #0xf, Rn
699 ;;   bz  1f
700 ;;   dec Rn
701 ;;   rpt Rn
702 ;;   <shift> Rm
703 ;;   inc Rn
704 ;; 1:
706 ;; But is longer than calling a helper function, and we are mostly
707 ;; concerned with code size.  FIXME: Maybe enable a sequence like
708 ;; this at -O3 and above ?
710 ;; Note - we ignore shift counts of less than one or more than 15.
711 ;; This is permitted by the ISO C99 standard as such shifts result
712 ;; in "undefined" behaviour.  [6.5.7 (3)]
714 ;; signed A << C
716 (define_expand "ashlhi3"
717   [(set (match_operand:HI            0 "nonimmediate_operand")
718         (ashift:HI (match_operand:HI 1 "general_operand")
719                    (match_operand:HI 2 "general_operand")))]
720   ""
721   {
722     if (msp430x
723         && REG_P (operands[0])
724         && REG_P (operands[1])
725         && CONST_INT_P (operands[2]))
726       emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2]));
727     else                 
728       msp430_expand_helper (operands, \"__mspabi_slli\", true);
729     DONE;
730   }
733 (define_insn "slli_1"
734   [(set (match_operand:HI            0 "nonimmediate_operand" "=rm")
735         (ashift:HI (match_operand:HI 1 "general_operand"       "0")
736                    (const_int 1)))]
737   ""
738   "RLA.W\t%0" ;; Note - this is a macro for ADD
741 (define_insn "430x_shift_left"
742   [(set (match_operand:HI            0 "register_operand" "=r")
743         (ashift:HI (match_operand:HI 1 "register_operand"  "0")
744                    (match_operand    2 "immediate_operand" "n")))]
745   "msp430x"
746   "*
747   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
748     return \"rpt\t%2 { rlax.w\t%0\";
749   return \"# nop left shift\";
750   "
753 (define_insn "slll_1"
754   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
755         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
756                    (const_int 1)))]
757   ""
758   "RLA.W\t%L0 { RLC.W\t%H0"
761 (define_insn "slll_2"
762   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
763         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
764                    (const_int 2)))]
765   ""
766   "RLA.W\t%L0 { RLC.W\t%H0 { RLA.W\t%L0 { RLC.W\t%H0"
769 (define_expand "ashlsi3"
770   [(set (match_operand:SI            0 "nonimmediate_operand")
771         (ashift:SI (match_operand:SI 1 "general_operand")
772                    (match_operand:SI 2 "general_operand")))]
773   ""
774   "msp430_expand_helper (operands, \"__mspabi_slll\", true);
775    DONE;"
778 ;;----------
780 ;; signed A >> C
782 (define_expand "ashrhi3"
783   [(set (match_operand:HI              0 "nonimmediate_operand")
784         (ashiftrt:HI (match_operand:HI 1 "general_operand")
785                      (match_operand:HI 2 "general_operand")))]
786   ""
787   {
788     if (msp430x
789         && REG_P (operands[0])
790         && REG_P (operands[1])
791         && CONST_INT_P (operands[2]))
792       emit_insn (gen_430x_arithmetic_shift_right (operands[0], operands[1], operands[2]));
793     else                 
794        msp430_expand_helper (operands, \"__mspabi_srai\", true);
795    DONE;
796    }
799 (define_insn "srai_1"
800   [(set (match_operand:HI              0 "msp_nonimmediate_operand" "=rm")
801         (ashiftrt:HI (match_operand:HI 1 "msp_general_operand"      "0")
802                      (const_int 1)))]
803   ""
804   "RRA.W\t%0"
807 (define_insn "430x_arithmetic_shift_right"
808   [(set (match_operand:HI              0 "register_operand" "=r")
809         (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0")
810                      (match_operand    2 "immediate_operand" "n")))]
811   "msp430x"
812   "*
813   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
814     return \"rpt\t%2 { rrax.w\t%0\";
815   return \"# nop arith right shift\";
816   "
819 (define_insn "srap_1"
820   [(set (match_operand:PSI              0 "register_operand" "=r")
821         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
822                       (const_int 1)))]
823   "msp430x"
824   "RRAM.A #1,%0"
827 (define_insn "srap_2"
828   [(set (match_operand:PSI              0 "register_operand" "=r")
829         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
830                       (const_int 2)))]
831   "msp430x"
832   "RRAM.A #2,%0"
835 (define_insn "sral_1"
836   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
837         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
838                      (const_int 1)))]
839   ""
840   "RRA.W\t%H0 { RRC.W\t%L0"
843 (define_insn "sral_2"
844   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
845         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
846                      (const_int 2)))]
847   ""
848   "RRA.W\t%H0 { RRC.W\t%L0 { RRA.W\t%H0 { RRC.W\t%L0"
851 (define_expand "ashrsi3"
852   [(set (match_operand:SI              0 "nonimmediate_operand")
853         (ashiftrt:SI (match_operand:SI 1 "general_operand")
854                      (match_operand:SI 2 "general_operand")))]
855   ""
856   "msp430_expand_helper (operands, \"__mspabi_sral\", true);
857    DONE;"
860 ;;----------
862 ;; unsigned A >> C
864 (define_expand "lshrhi3"
865   [(set (match_operand:HI              0 "nonimmediate_operand")
866         (lshiftrt:HI (match_operand:HI 1 "general_operand")
867                      (match_operand:HI 2 "general_operand")))]
868   ""
869   {
870     if (msp430x
871         && REG_P (operands[0])
872         && REG_P (operands[1])
873         && CONST_INT_P (operands[2]))
874       emit_insn (gen_430x_logical_shift_right (operands[0], operands[1], operands[2]));
875     else                 
876       msp430_expand_helper (operands, \"__mspabi_srli\", true);
877     DONE;
878   }
881 (define_insn "srli_1"
882   [(set (match_operand:HI              0 "nonimmediate_operand" "=rm")
883         (lshiftrt:HI (match_operand:HI 1 "general_operand"       "0")
884                      (const_int 1)))]
885   ""
886   "CLRC { RRC.W\t%0"
889 (define_insn "430x_logical_shift_right"
890   [(set (match_operand:HI              0 "register_operand" "=r")
891         (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0")
892                      (match_operand    2 "immediate_operand" "n")))]
893   "msp430x"
894   {
895     return msp430x_logical_shift_right (operands[2]);
896   }
899 (define_insn "srlp_1"
900   [(set (match_operand:PSI              0 "register_operand" "=r")
901         (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
902                       (const_int 1)))]
903   ""
904   "RRUM.A #1,%0"
907 (define_insn "srll_1"
908   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
909         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
910                      (const_int 1)))]
911   ""
912   "CLRC { RRC.W\t%H0 { RRC.W\t%L0"
915 (define_insn "srll_2x"
916   [(set (match_operand:SI              0 "nonimmediate_operand" "=r")
917         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
918                      (const_int 2)))]
919   "msp430x"
920   "RRUX.W\t%H0 { RRC.W\t%L0 { RRUX.W\t%H0 { RRC.W\t%L0"
923 (define_expand "lshrsi3"
924   [(set (match_operand:SI              0 "nonimmediate_operand")
925         (lshiftrt:SI (match_operand:SI 1 "general_operand")
926                      (match_operand:SI 2 "general_operand")))]
927   ""
928   "msp430_expand_helper (operands, \"__mspabi_srll\", true);
929    DONE;"
932 ;;------------------------------------------------------------
933 ;; Function Entry/Exit
935 (define_expand "prologue"
936   [(const_int 0)]
937   ""
938   "msp430_expand_prologue (); DONE;"
939   )
941 (define_expand "epilogue"
942   [(const_int 0)]
943   ""
944   "msp430_expand_epilogue (0); DONE;"
945   )
947 (define_insn "epilogue_helper"
948   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)]
949   ""
950   "BR%Q0\t#__mspabi_func_epilog_%J0"
951   )
953 (define_insn "prologue_start_marker"
954   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)]
955   ""
956   "; start of prologue"
957   )
959 (define_insn "prologue_end_marker"
960   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)]
961   ""
962   "; end of prologue"
963   )
965 (define_insn "epilogue_start_marker"
966   [(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)]
967   ""
968   "; start of epilogue"
969   )
971 ;; This makes the linker add a call to exit() after the call to main()
972 ;; in crt0
973 (define_insn "msp430_refsym_need_exit"
974   [(unspec_volatile [(const_int 0)] UNS_REFSYM_NEED_EXIT)]
975   ""
976   ".refsym\t__crt0_call_exit"
977   )
979 ;;------------------------------------------------------------
980 ;; Jumps
982 (define_expand "call"
983   [(call:HI (match_operand 0 "")
984             (match_operand 1 ""))]
985   ""
986   ""
989 (define_insn "call_internal"
990   [(call (mem:HI (match_operand 0 "general_operand" "rYci"))
991          (match_operand 1 ""))]
992   ""
993   "CALL%Q0\t%0"
996 (define_expand "call_value"
997   [(set (match_operand          0 "register_operand")
998         (call:HI (match_operand 1 "general_operand")
999                  (match_operand 2 "")))]
1000   ""
1001   ""
1004 (define_insn "call_value_internal"
1005   [(set (match_operand               0 "register_operand" "=r")
1006         (call (mem:HI (match_operand 1 "general_operand" "rYci"))
1007               (match_operand 2 "")))]
1008   ""
1009   "CALL%Q0\t%1"
1012 (define_insn "msp_return"
1013   [(return)]
1014   ""
1015   { return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); }
1018 ;; This pattern is NOT, as expected, a return pattern.  It's called
1019 ;; before reload and must only store its operands, and emit a
1020 ;; placeholder where the epilog needs to be.  AFTER reload, the
1021 ;; placeholder should get expanded into a regular-type epilogue that
1022 ;; also does the EH return.
1023 (define_expand "eh_return"
1024   [(match_operand:HI 0 "")]
1025   ""
1026   "msp430_expand_eh_return (operands[0]);
1027    emit_jump_insn (gen_msp430_eh_epilogue ());
1028    emit_barrier ();
1029    DONE;"
1032 ;; This is the actual EH epilogue.  We emit it in the pattern above,
1033 ;; before reload, and convert it to a real epilogue after reload.
1034 (define_insn_and_split "msp430_eh_epilogue"
1035   [(eh_return)]
1036   ""
1037   "#"
1038   "reload_completed"
1039   [(const_int 0)]
1040   "msp430_expand_epilogue (1); DONE;"
1041   )
1043 (define_insn "jump"
1044   [(set (pc)
1045         (label_ref (match_operand 0 "" "")))]
1046   ""
1047   "BR%Q0\t#%l0"
1050 ;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
1051 ;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c).
1052 (define_insn "indirect_jump"
1053   [(set (pc)
1054         (match_operand 0 "nonimmediate_operand" "rYl"))]
1055   ""
1056   "BR%Q0\t%0"
1059 ;;------------------------------------------------------------
1060 ;; Various Conditionals
1062 (define_expand "cbranch<mode>4"
1063   [(parallel [(set (pc) (if_then_else
1064                          (match_operator 0 ""
1065                                          [(match_operand:QHI 1 "nonimmediate_operand")
1066                                           (match_operand:QHI 2 "general_operand")])
1067                          (label_ref (match_operand 3 "" ""))
1068                          (pc)))
1069               (clobber (reg:BI CARRY))]
1070   )]
1071   ""
1072   "msp430_fixup_compare_operands (<MODE>mode, operands);"
1073   )
1075 (define_insn "cbranchpsi4_real"
1076   [(set (pc) (if_then_else
1077               (match_operator                     0 "msp430_cmp_operator"
1078                               [(match_operand:PSI 1 "nonimmediate_operand" "r,rYs,rm")
1079                                (match_operand:PSI 2 "general_operand"      "rLs,rYsi,rmi")])
1080               (label_ref (match_operand           3 "" ""))
1081               (pc)))
1082    (clobber (reg:BI CARRY))
1083    ]
1084   ""
1085   "@
1086   CMP%Q0\t%2, %1 { J%0\t%l3
1087   CMPX.A\t%2, %1 { J%0\t%l3
1088   CMPX.A\t%2, %1 { J%0\t%l3"
1089   )
1091 (define_insn "cbranchqi4_real"
1092   [(set (pc) (if_then_else
1093               (match_operator                    0 "msp430_cmp_operator"
1094                               [(match_operand:QI 1 "nonimmediate_operand" "rYs,rm")
1095                                (match_operand:QI 2 "general_operand"      "rYsi,rmi")])
1096               (label_ref (match_operand          3 "" ""))
1097               (pc)))
1098    (clobber (reg:BI CARRY))
1099    ]
1100   ""
1101   "@
1102    CMP.B\t%2, %1 { J%0\t%l3
1103    CMP%X0.B\t%2, %1 { J%0\t%l3"
1104   )
1106 (define_insn "cbranchhi4_real"
1107   [(set (pc) (if_then_else
1108               (match_operator                    0 "msp430_cmp_operator"
1109                               [(match_operand:HI 1 "nonimmediate_operand" "rYs,rm")
1110                                (match_operand:HI 2 "general_operand"      "rYsi,rmi")])
1111               (label_ref (match_operand          3 "" ""))
1112               (pc)))
1113    (clobber (reg:BI CARRY))
1114    ]
1115   ""
1116   "*
1117     /* This is nasty.  If we are splitting code between low and high memory
1118        then we do not want the linker to increase the size of sections by
1119        relaxing out of range jump instructions.  (Since relaxation occurs
1120        after section placement).  So we have to generate pessimal branches
1121        here.  But we only want to do this when really necessary.
1123        FIXME: Do we need code in the other cbranch patterns ?  */
1124     if (msp430_do_not_relax_short_jumps () && get_attr_length (insn) > 6)
1125       {
1126         return which_alternative == 0 ?
1127             \"CMP.W\t%2, %1 { J%r0 1f { BRA #%l3 { 1:\" :
1128          \"CMP%X0.W\t%2, %1 { J%r0 1f { BRA #%l3 { 1:\";
1129       }
1131     return which_alternative == 0 ?
1132          \"CMP.W\t%2, %1 { J%0\t%l3\" :
1133       \"CMP%X0.W\t%2, %1 { J%0\t%l3\";
1134   "
1135   [(set (attr "length")
1136         (if_then_else
1137           (and (ge (minus (match_dup 3) (pc)) (const_int -510))
1138                (le (minus (match_dup 3) (pc)) (const_int 510)))
1139           (const_int 6)
1140           (const_int 10))
1141         )]
1142   )
1144 (define_insn "cbranchpsi4_reversed"
1145   [(set (pc) (if_then_else
1146               (match_operator                     0 "msp430_reversible_cmp_operator"
1147                               [(match_operand:PSI 1 "general_operand" "rLs,rYsi,rmi")
1148                                (match_operand:PSI 2 "general_operand" "r,rYs,rm")])
1149               (label_ref (match_operand           3 "" ""))
1150               (pc)))
1151    (clobber (reg:BI CARRY))
1152    ]
1153   ""
1154   "@
1155   CMP%Q0\t%1, %2 { J%R0\t%l3
1156   CMPX.A\t%1, %2 { J%R0\t%l3
1157   CMPX.A\t%1, %2 { J%R0\t%l3"
1158   )
1160 (define_insn "cbranchqi4_reversed"
1161   [(set (pc) (if_then_else
1162               (match_operator                    0 "msp430_reversible_cmp_operator"
1163                               [(match_operand:QI 1 "general_operand" "rYsi,rmi")
1164                                (match_operand:QI 2 "general_operand" "rYs,rm")])
1165               (label_ref (match_operand          3 "" ""))
1166               (pc)))
1167    (clobber (reg:BI CARRY))
1168    ]
1169   ""
1170   "@
1171    CMP.B\t%1, %2 { J%R0\t%l3
1172    CMP%X0.B\t%1, %2 { J%R0\t%l3"
1173   )
1175 (define_insn "cbranchhi4_reversed"
1176   [(set (pc) (if_then_else
1177               (match_operator                    0 "msp430_reversible_cmp_operator"
1178                               [(match_operand:HI 1 "general_operand" "rYsi,rmi")
1179                                (match_operand:HI 2 "general_operand" "rYs,rm")])
1180               (label_ref (match_operand          3 "" ""))
1181               (pc)))
1182    (clobber (reg:BI CARRY))
1183    ]
1184   ""
1185   "@
1186    CMP.W\t%1, %2 { J%R0\t%l3
1187    CMP%X0.W\t%1, %2 { J%R0\t%l3"
1188   )
1190 (define_insn "*bitbranch<mode>4"
1191   [(set (pc) (if_then_else
1192               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1193                            (match_operand:QHI 1 "msp_general_operand" "rYsi,rmi"))
1194                   (const_int 0))
1195               (label_ref (match_operand 2 "" ""))
1196               (pc)))
1197    (clobber (reg:BI CARRY))
1198    ]
1199   ""
1200   "@
1201    BIT%x0%b0\t%1, %0 { JNE\t%l2
1202    BIT%X0%b0\t%1, %0 { JNE\t%l2"
1203   )
1205 (define_insn "*bitbranch<mode>4"
1206   [(set (pc) (if_then_else
1207               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1208                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1209                   (const_int 0))
1210               (label_ref (match_operand 2 "" ""))
1211               (pc)))
1212    (clobber (reg:BI CARRY))
1213    ]
1214   ""
1215   "BIT%x0%b0\t%1, %0 { JEQ\t%l2"
1216   )
1218 (define_insn "*bitbranch<mode>4"
1219   [(set (pc) (if_then_else
1220               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1221                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1222                   (const_int 0))
1223               (pc)
1224               (label_ref (match_operand 2 "" ""))))
1225    (clobber (reg:BI CARRY))
1226    ]
1227   ""
1228   "BIT%X0%b0\t%1, %0 { JNE\t%l2"
1229   )
1231 (define_insn "*bitbranch<mode>4"
1232   [(set (pc) (if_then_else
1233               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1234                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1235                   (const_int 0))
1236               (pc)
1237               (label_ref (match_operand 2 "" ""))))
1238    (clobber (reg:BI CARRY))
1239    ]
1240   ""
1241   "BIT%X0%b0\t%1, %0 { JEQ\t%l2"
1242   )
1244 ;;------------------------------------------------------------
1245 ;; zero-extract versions of the above
1247 (define_insn "*bitbranch<mode>4_z"
1248   [(set (pc) (if_then_else
1249               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1250                                     (const_int 1)
1251                                     (match_operand 1 "msp430_bitpos" "i,i"))
1252                   (const_int 0))
1253               (label_ref (match_operand 2 "" ""))
1254               (pc)))
1255    (clobber (reg:BI CARRY))
1256    ]
1257   ""
1258   "@
1259    BIT%x0%b0\t%p1, %0 { JNE\t%l2
1260    BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1261   )
1263 (define_insn "*bitbranch<mode>4_z"
1264   [(set (pc) (if_then_else
1265               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1266                                    (const_int 1)
1267                                    (match_operand 1 "msp430_bitpos" "i"))
1268                   (const_int 0))
1269               (label_ref (match_operand 2 "" ""))
1270               (pc)))
1271    (clobber (reg:BI CARRY))
1272    ]
1273   ""
1274   "BIT%x0%X0%b0\t%p1, %0 { JEQ\t%l2"
1275   )
1277 (define_insn "*bitbranch<mode>4_z"
1278   [(set (pc) (if_then_else
1279               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1280                                    (const_int 1)
1281                                    (match_operand 1 "msp430_bitpos" "i"))
1282                   (const_int 0))
1283               (pc)
1284               (label_ref (match_operand 2 "" ""))))
1285    (clobber (reg:BI CARRY))
1286    ]
1287   ""
1288   "BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1289   )
1291 (define_insn "*bitbranch<mode>4_z"
1292   [(set (pc) (if_then_else
1293               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1294                                    (const_int 1)
1295                                    (match_operand 1 "msp430_bitpos" "i"))
1296                   (const_int 0))
1297               (pc)
1298               (label_ref (match_operand 2 "" ""))))
1299    (clobber (reg:BI CARRY))
1300    ]
1301   ""
1302   "BIT%X0%b0\t%p1, %0 { JEQ\t%l2"
1303   )
1305 ;;------------------------------------------------------------
1306 ;; Misc
1308 (define_insn "nop"
1309   [(const_int 0)]
1310   "1"
1311   "NOP"
1314 (define_insn "disable_interrupts"
1315   [(unspec_volatile [(const_int 0)] UNS_DINT)]
1316   ""
1317   "DINT \; NOP"
1318   )
1320 (define_insn "enable_interrupts"
1321   [(unspec_volatile [(const_int 0)] UNS_EINT)]
1322   ""
1323   "EINT"
1324   )
1326 (define_insn "push_intr_state"
1327   [(unspec_volatile [(const_int 0)] UNS_PUSH_INTR)]
1328   ""
1329   "PUSH\tSR"
1330   )
1332 (define_insn "pop_intr_state"
1333   [(unspec_volatile [(const_int 0)] UNS_POP_INTR)]
1334   ""
1335   "POP\tSR"
1336   )
1338 ;; Clear bits in the copy of the status register that is currently
1339 ;; saved on the stack at the top of the interrupt handler.
1340 (define_insn "bic_SR"
1341   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIC_SR)]
1342   ""
1343   "BIC.W\t%0, %O0(SP)"
1344   )
1346 ;; Set bits in the copy of the status register that is currently
1347 ;; saved on the stack at the top of the interrupt handler.
1348 (define_insn "bis_SR"
1349   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIS_SR)]
1350   ""
1351   "BIS.W\t%0, %O0(SP)"
1352   )
1354 ;; For some reason GCC is generating (set (reg) (and (neg (reg)) (int)))
1355 ;; very late on in the compilation and not splitting it into separate
1356 ;; instructions, so we provide a pattern to support it here.
1357 (define_insn "andneghi3"
1358   [(set (match_operand:HI                 0 "register_operand" "=r")
1359         (and:HI (neg:HI (match_operand:HI 1 "register_operand"  "r"))
1360                 (match_operand            2 "immediate_operand" "n")))]
1361   ""
1362   "*
1363     if (REGNO (operands[0]) != REGNO (operands[1]))
1364       return \"MOV.W\t%1, %0 { INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0\";
1365     else
1366       return \"INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0\";
1367   "
1368   )
1370 (define_insn "delay_cycles_start"
1371   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
1372                     UNS_DELAY_START)]
1373   ""
1374   "; Begin %J0 cycle delay"
1375   )
1377 (define_insn "delay_cycles_end"
1378   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
1379                     UNS_DELAY_END)]
1380   ""
1381   "; End %J0 cycle delay"
1382   )
1384 (define_insn "delay_cycles_32"
1385   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1386                      (match_operand 1 "immediate_operand" "i")
1387                      ] UNS_DELAY_32)]
1388   ""
1389   "PUSH r13
1390         PUSH    r14
1391         MOV.W   %A0, r13
1392         MOV.W   %B0, r14
1393 1:      SUB.W   #1, r13
1394         SUBC.W  #0, r14
1395         JNE     1b
1396         TST.W   r13
1397         JNE     1b
1398         POP     r14
1399         POP     r13"
1400   )
1402 (define_insn "delay_cycles_32x"
1403   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1404                      (match_operand 1 "immediate_operand" "i")
1405                      ] UNS_DELAY_32X)]
1406   ""
1407   "PUSHM.A      #2,r13
1408         MOV.W   %A0, r13
1409         MOV.W   %B0, r14
1410 1:      SUB.W   #1, r13
1411         SUBC.W  #0, r14
1412         JNE     1b
1413         TST.W   r13
1414         JNE     1b
1415         POPM.A  #2,r13"
1416   )
1418 (define_insn "delay_cycles_16"
1419   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1420                      (match_operand 1 "immediate_operand" "i")
1421                      ] UNS_DELAY_16)]
1422   ""
1423   "PUSH r13
1424         MOV.W   %0, r13
1425 1:      SUB.W   #1, r13
1426         JNE     1b
1427         POP     r13"
1428   )
1430 (define_insn "delay_cycles_16x"
1431   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1432                      (match_operand 1 "immediate_operand" "i")
1433                      ] UNS_DELAY_16X)]
1434   ""
1435   "PUSHM.A      #1,r13
1436         MOV.W   %0, r13
1437 1:      SUB.W   #1, r13
1438         JNE     1b
1439         POPM.A  #1,r13"
1440   )
1442 (define_insn "delay_cycles_2"
1443   [(unspec_volatile [(const_int 0) ] UNS_DELAY_2)]
1444   ""
1445   "JMP  .+2"
1446   )
1448 (define_insn "delay_cycles_1"
1449   [(unspec_volatile [(const_int 0) ] UNS_DELAY_1)]
1450   ""
1451   "NOP"
1452   )
1454 (define_insn "mulhisi3"
1455   [(set (match_operand:SI                          0 "register_operand" "=r")
1456         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1457                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1458   "optimize > 2 && msp430_hwmult_type != NONE"
1459   "*
1460     if (msp430_use_f5_series_hwmult ())
1461       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\";
1462     else
1463       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\";
1464   "
1467 (define_insn "umulhisi3"
1468   [(set (match_operand:SI                          0 "register_operand" "=r")
1469         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1470                  (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1471   "optimize > 2 && msp430_hwmult_type != NONE"
1472   "*
1473     if (msp430_use_f5_series_hwmult ())
1474       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\";
1475     else
1476       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\";
1477   "
1480 (define_insn "mulsidi3"
1481   [(set (match_operand:DI                          0 "register_operand" "=r")
1482         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1483                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1484   "optimize > 2 && msp430_hwmult_type != NONE"
1485   "*
1486     if (msp430_use_f5_series_hwmult ())
1487       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\";
1488     else
1489       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\";
1490   "
1493 (define_insn "umulsidi3"
1494   [(set (match_operand:DI                          0 "register_operand" "=r")
1495         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1496                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1497   "optimize > 2 && msp430_hwmult_type != NONE"
1498   "*
1499     if (msp430_use_f5_series_hwmult ())
1500       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\";
1501     else
1502       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\";
1503   "