Rebase.
[official-gcc.git] / gcc / config / msp430 / msp430.md
blobed4eea652f9c63ed2f4b8367719e684943335d7a
1 ;;  Machine Description for TI MSP43* processors
2 ;;  Copyright (C) 2013-2014 Free Software Foundation, Inc.
3 ;;  Contributed by Red Hat.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
22 (define_constants
23   [
24    (PC_REGNO 0)
25    (SP_REGNO 1)
26    (CARRY 2)
27   ])
29 (define_c_enum "unspec"
30   [
31    UNS_PROLOGUE_START_MARKER
32    UNS_PROLOGUE_END_MARKER
33    UNS_EPILOGUE_START_MARKER
34    UNS_EPILOGUE_HELPER
36    UNS_PUSHM
37    UNS_POPM
39    UNS_GROW_AND_SWAP
40    UNS_SWAP_AND_SHRINK
41    
42    UNS_DINT
43    UNS_EINT
44    UNS_PUSH_INTR
45    UNS_POP_INTR
46    UNS_BIC_SR
47    UNS_BIS_SR
49    UNS_REFSYM_NEED_EXIT
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 (include "predicates.md")
62 (include "constraints.md")
64 (define_mode_iterator QHI [QI HI PSI])
66 ;; There are two basic "family" tests we do here:
68 ;; msp430x - true if 430X instructions are available.
69 ;; TARGET_LARGE - true if pointers are 20-bits
71 ;; Note that there are three supported cases, since the base 430
72 ;; doesn't have 20-bit pointers:
74 ;; 1. MSP430 cpu, small model
75 ;; 2. MSP430X cpu, small model.
76 ;; 3. MSP430X cpu, large model.
78 ;;------------------------------------------------------------
79 ;; Moves
81 ;; Push/Pop must be before the generic move patterns
83 (define_insn "push"
84   [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO)))
85         (match_operand:HI 0 "register_operand" "r"))]
86   ""
87   "PUSH\t%0"
88   )
90 (define_insn "pusha"
91   [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO)))
92         (match_operand:PSI 0 "register_operand" "r"))]
93   "TARGET_LARGE"
94   "PUSHX.A\t%0"
95   )
97 (define_insn "pushm"
98   [(unspec_volatile [(match_operand 0 "register_operand" "r")
99                      (match_operand 1 "immediate_operand" "n")] UNS_PUSHM)]
100   ""
101   "PUSHM%b0\t%1, %0"
102   )
104 (define_insn "pop"
105   [(set (match_operand:HI 0 "register_operand" "=r")
106         (mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
107   ""
108   "POP\t%0"
109   )
111 (define_insn "popa"
112   [(set (match_operand:PSI 0 "register_operand" "=r")
113         (mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))]
114   "TARGET_LARGE"
115   "POPX.A\t%0"
116   )
118 ;; This is nasty.  Operand0 is bogus.  It is only there so that we can get a
119 ;; mode for the %b0 to work.  We should use operand1 for this, but that does
120 ;; not have a mode.
121 ;; 
122 ;; Operand1 is actually a register, but we cannot accept (REG...) because the
123 ;; cprop_hardreg pass can and will renumber registers even inside
124 ;; unspec_volatiles.  So we take an integer register number parameter and
125 ;; fudge it to be a register name when we generate the assembler.
127 ;; The pushm pattern does not have this problem because of all of the
128 ;; frame info cruft attached to it, so cprop_hardreg leaves it alone.
129 (define_insn "popm"
130   [(unspec_volatile [(match_operand 0 "register_operand" "r")
131                      (match_operand 1 "immediate_operand" "i")
132                      (match_operand 2 "immediate_operand" "i")] UNS_POPM)]
133   ""
134   "POPM%b0\t%2, r%J1"
135   )
137 ;; The next two patterns are here to support a "feature" of how GCC implements
138 ;; varargs.  When a function uses varargs and the *second* to last named
139 ;; argument is split between argument registers and the stack, gcc expects the
140 ;; callee to allocate space on the stack that can contain the register-based
141 ;; part of the argument.  This space *has* to be just before the remaining
142 ;; arguments (ie the ones that are fully on the stack).
144 ;; The problem is that the MSP430 CALL instruction pushes the return address
145 ;; onto the stack in the exact place where the callee wants to allocate
146 ;; this extra space.  So we need a sequence of instructions that can allocate
147 ;; the extra space and then move the return address down the stack, so that
148 ;; the extra space is now adjacent to the remaining arguments.
150 ;; This could be constructed through regular insns, but they might be split up
151 ;; by a misguided optimization, so an unspec volatile is used instead.
153 (define_insn "grow_and_swap"
154   [(unspec_volatile [(const_int 0)] UNS_GROW_AND_SWAP)]
155   ""
156   "*
157     if (TARGET_LARGE)
158       return \"SUBA\t#2, r1 { MOVX.A\t2(r1), 0(r1)\";
159     return \"SUB\t#2, r1 { MOV.W\t2(r1), 0(r1)\";
160   "
163 (define_insn "swap_and_shrink"
164   [(unspec_volatile [(const_int 0)] UNS_SWAP_AND_SHRINK)]
165   ""
166   "* return TARGET_LARGE
167            ? \"MOVX.A\t0(r1), 2(r1) { ADDA\t#2, SP\"
168            : \"MOV.W\t0(r1), 2(r1) { ADD\t#2, SP\";
169   ")
171 ; I set LOAD_EXTEND_OP and WORD_REGISTER_OPERATIONS, but gcc puts in a
172 ; zero_extend anyway.  Catch it here.
173 (define_insn "movqihi"
174   [(set (match_operand:HI                 0 "register_operand" "=r,r")
175         (zero_extend:HI (match_operand:QI 1 "memory_operand" "Ys,m")))]
176   ""
177   "@
178    MOV.B\t%1, %0
179    MOV%X1.B\t%1, %0"
182 (define_insn "movqi"
183   [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm")
184         (match_operand:QI 1 "msp_general_operand" "riYs,rmi"))]
185   ""
186   "@
187   MOV.B\t%1, %0
188   MOV%X0.B\t%1, %0"
191 (define_insn "movhi"
192   [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm")
193         (match_operand:HI 1 "msp_general_operand" "riYs,rmi"))]
194   ""
195   "@
196   MOV.W\t%1, %0
197   MOV%X0.W\t%1, %0"
200 (define_expand "movsi"
201   [(set (match_operand:SI 0 "nonimmediate_operand")
202         (match_operand:SI 1 "general_operand"))]
203   ""
204   ""
205   )
206   
207 (define_insn_and_split "movsi_x"
208   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
209         (match_operand:SI 1 "general_operand" "rmi"))]
210   ""
211   "#"
212   "reload_completed"
213   [(set (match_operand:HI 2 "nonimmediate_operand")
214         (match_operand:HI 4 "general_operand"))
215    (set (match_operand:HI 3 "nonimmediate_operand")
216         (match_operand:HI 5 "general_operand"))]
217   "msp430_split_movsi (operands);"
220 ;; Some MOVX.A cases can be done with MOVA, this is only a few of them.
221 (define_insn "movpsi"
222   [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,Ya,rm")
223         (match_operand:PSI 1 "msp_general_operand" "riYa,r,rmi"))]
224   ""
225   "@
226   MOV%Q0\t%1, %0
227   MOV%Q0\t%1, %0
228   MOV%X0.%Q0\t%1, %0")
230 ; This pattern is identical to the truncsipsi2 pattern except
231 ; that it uses a SUBREG instead of a TRUNC.  It is needed in
232 ; order to prevent reload from converting (set:SI (SUBREG:PSI (SI)))
233 ; into (SET:PSI (PSI)).
235 ; Note: using POPM.A #1 is two bytes smaller than using POPX.A....
237 (define_insn "movsipsi2"
238   [(set (match_operand:PSI            0 "register_operand" "=r")
239         (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
240   "TARGET_LARGE"
241   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0"
244 ;;------------------------------------------------------------
245 ;; Math
247 (define_insn "addpsi3"
248   [(set (match_operand:PSI           0 "msp_nonimmediate_operand" "=r,rm")
249         (plus:PSI (match_operand:PSI 1 "msp_nonimmediate_operand" "%0,0")
250                   (match_operand:PSI 2 "msp_general_operand"      "rLs,rmi")))]
251   ""
252   "@
253   ADDA\t%2, %0
254   ADDX.A\t%2, %0"
257 (define_insn "addqi3"
258   [(set (match_operand:QI          0 "msp_nonimmediate_operand" "=rYs,rm")
259         (plus:QI (match_operand:QI 1 "msp_nonimmediate_operand" "%0,0")
260                  (match_operand:QI 2 "msp_general_operand"      "riYs,rmi")))]
261   ""
262   "@
263    ADD.B\t%2, %0
264    ADD%X0.B\t%2, %0"
267 (define_insn "addhi3"
268   [(set (match_operand:HI           0 "msp_nonimmediate_operand" "=rYs,rm")
269         (plus:HI (match_operand:HI  1 "msp_nonimmediate_operand" "%0,0")
270                   (match_operand:HI 2 "msp_general_operand"      "riYs,rmi")))]
271   ""
272   "@
273    ADD.W\t%2, %0
274    ADD%X0.W\t%2, %0"
277 ; This pattern is needed in order to avoid reload problems.
278 ; It takes an SI pair of registers, adds a value to them, and
279 ; then converts them into a single PSI register.
281 (define_insn "addsipsi3"
282   [(set (subreg:SI (match_operand:PSI 0 "register_operand" "=&r") 0)
283         (plus:SI (match_operand:SI    1 "register_operand" "0")
284                  (match_operand       2 "general_operand" "rmi")))]
285   ""
286   "ADD.W\t%L2, %L0 { ADDC.W\t%H2, %H0 { PUSH.W\t%H0 { PUSH.W\t%L0 { POPM.A\t#1, %0"
289 (define_insn "addsi3"
290   [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,rm")
291         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
292                  (match_operand:SI 2 "general_operand" "r,mi")))]
293   ""
294   "@
295    ADD\t%L2, %L0 { ADDC\t%H2, %H0
296    ADD%X0\t%L2, %L0 { ADDC%X0\t%H2, %H0"
299 ; Version of addhi that exposes the carry operations, for SImode adds.
301 ; NOTE - we are playing a dangerous game with GCC here.  We have these two
302 ; add patterns and the splitter that follows because our tests have shown
303 ; that this results in a significant reduction in code size - because GCC is
304 ; able to discard any unused part of the addition.  We have to annotate the
305 ; patterns with the set and use of the carry flag because otherwise GCC will
306 ; discard parts of the addition when they are actually needed.  But we have
307 ; not annotated all the other patterns that set the CARRY flag as doing so
308 ; results in an overall increase in code size[1].  Instead we just *hope*
309 ; that GCC will not move a carry-setting instruction in between the first
310 ; and second adds.
312 ; So far our experiments have shown that GCC is likely to move MOV and CMP
313 ; instructions in between the two adds, but not other instructions.  MOV is
314 ; safe, CMP is not.  So we have annotated the CMP patterns and left the
315 ; subtract, shift and other add patterns alone.  At the moment this is
316 ; working, but with future changes to the generic parts of GCC that might
317 ; change.
319 ; [1] It is not clear exactly why the code size increases.  The cause appears
320 ; to be that reload is more prevelent to spilling a variable onto the stack
321 ; but why it does this is unknown.  Possibly the additional CLOBBERs necessary
322 ; to correctly annotate the other patterns makes reload think that there is
323 ; increased register pressure.  Or possibly reload does not handle ADD patterns
324 ; that are not single_set() very well.
326 (define_insn "addhi3_cy"
327   [(set (match_operand:HI          0 "msp_nonimmediate_operand" "=r,rm")
328         (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
329                  (match_operand:HI 2 "msp_nonimmediate_operand" "r,rm")))
330    (set (reg:BI CARRY)
331         (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
332                                            (zero_extend:SI (match_dup 2)))
333                                   (const_int 16))))
334    ]
335   ""
336   "@
337    ADD\t%2, %1 ; cy
338    ADD%X0\t%2, %1 ; cy"
339   )
341 (define_insn "addhi3_cy_i"
342   [(set (match_operand:HI          0 "nonimmediate_operand" "=r,rm")
343         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
344                  (match_operand:HI 2 "immediate_operand"     "i,i")))
345    (set (reg:BI CARRY)
346         (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
347                                            (match_operand 3 "immediate_operand" "i,i"))
348                                   (const_int 16))))
349    ]
350   ""
351   "@
352    ADD\t%2, %1 ; cy
353    ADD%X0\t%2, %1 ; cy"
354   )
356 ; Version of addhi that adds the carry, for SImode adds.
357 (define_insn "addchi4_cy"
358   [(set (match_operand:HI                   0 "msp_nonimmediate_operand" "=r,rm")
359         (plus:HI (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
360                           (match_operand:HI 2 "msp_general_operand"      "ri,rmi"))
361                  (zero_extend:HI (reg:BI CARRY))))
362    ]
363   ""
364   "@
365    ADDC\t%2, %1
366    ADDC%X0\t%2, %1"
367   )
369 ; Split an SImode add into two HImode adds, keeping track of the carry
370 ; so that gcc knows when it can and can't optimize away the two
371 ; halves.
372 (define_split
373   [(set (match_operand:SI          0 "msp430_nonsubreg_operand")
374         (plus:SI (match_operand:SI 1 "msp430_nonsubreg_operand")
375                  (match_operand:SI 2 "msp430_nonsubreg_or_imm_operand")))
376    ]
377   ""
378   [(parallel [(set (match_operand:HI 3 "nonimmediate_operand" "=&rm")
379                    (plus:HI (match_dup 4)
380                             (match_dup 5)))
381               (set (reg:BI CARRY)
382                    (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 4))
383                                                       (match_dup 9))
384                                              (const_int 16))))
385               ])
386    (set (match_operand:HI 6 "nonimmediate_operand" "=&rm")
387         (plus:HI (plus:HI (match_dup 7)
388                           (match_dup 8))
389                  (zero_extend:HI (reg:BI CARRY))))
390    ]
391   "
392    operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
393    operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
394    operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
395    operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
396    operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
397    operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
398    if (GET_CODE (operands[5]) == CONST_INT)
399      {
400        operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
401      }
402    else
403      {
404        operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
405      }
406    "
407   )
410 ;; Alternatives 2 and 3 are to handle cases generated by reload.
411 (define_insn "subpsi3"
412   [(set (match_operand:PSI            0 "nonimmediate_operand" "=r,   rm, &?r, ?&r")
413         (minus:PSI (match_operand:PSI 1 "general_operand"       "0,   0,   !r,  !i")
414                    (match_operand:PSI 2 "general_operand"       "rLs, rmi, rmi,  r")))]
415   ""
416   "@
417   SUBA\t%2, %0
418   SUBX.A\t%2, %0
419   MOVX.A\t%1, %0 { SUBX.A\t%2, %0
420   MOVX.A\t%1, %0 { SUBA\t%2, %0"
423 ;; Alternatives 2 and 3 are to handle cases generated by reload.
424 (define_insn "subqi3"
425   [(set (match_operand:QI           0 "nonimmediate_operand" "=rYs,  rm,  &?r, ?&r")
426         (minus:QI (match_operand:QI 1 "general_operand"       "0,    0,    !r,  !i")
427                   (match_operand:QI 2 "general_operand"      " riYs, rmi, rmi,   r")))]
428   ""
429   "@
430   SUB.B\t%2, %0
431   SUB%X0.B\t%2, %0
432   MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0
433   MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0"
436 ;; Alternatives 2 and 3 are to handle cases generated by reload.
437 (define_insn "subhi3"
438   [(set (match_operand:HI           0 "nonimmediate_operand" "=rYs,  rm,  &?r, ?&r")
439         (minus:HI (match_operand:HI 1 "general_operand"       "0,    0,    !r,  !i")
440                   (match_operand:HI 2 "general_operand"      " riYs, rmi, rmi,   r")))]
441   ""
442   "@
443   SUB.W\t%2, %0
444   SUB%X0.W\t%2, %0
445   MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0
446   MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0"
449 (define_insn "subsi3"
450   [(set (match_operand:SI           0 "nonimmediate_operand" "=&rm")
451         (minus:SI (match_operand:SI 1 "nonimmediate_operand"   "0")
452                   (match_operand:SI 2 "general_operand"        "rmi")))]
453   ""
454   "SUB%X0\t%L2, %L0 { SUBC%X0\t%H2, %H0"
457 (define_insn "*bic<mode>_cg"
458   [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m")
459         (and:QHI (match_operand:QHI 1 "msp_general_operand" "0,0")
460                  (match_operand 2 "msp430_inv_constgen_operator" "n,n")))]
461   ""
462   "@
463    BIC%x0%b0\t#%I2, %0
464    BIC%X0%b0\t#%I2, %0"
467 (define_insn "bic<mode>3"
468   [(set (match_operand:QHI                   0 "msp_nonimmediate_operand" "=rYs,rm")
469         (and:QHI (not:QHI (match_operand:QHI 1 "msp_general_operand"       "rYs,rmn"))
470                  (match_operand:QHI          2 "msp_nonimmediate_operand"  "0,0")))]
471   ""
472   "@
473    BIC%x0%b0\t%1, %0
474    BIC%X0%b0\t%1, %0"
477 (define_insn "and<mode>3"
478   [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
479         (and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
480                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
481   ""
482   "@
483    AND%x0%b0\t%2, %0
484    AND%X0%b0\t%2, %0"
487 (define_insn "ior<mode>3"
488   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,rm")
489         (ior:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
490                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
491   ""
492   "@
493    BIS%x0%b0\t%2, %0
494    BIS%X0%b0\t%2, %0"
497 (define_insn "xor<mode>3"
498   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,rm")
499         (xor:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
500                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
501   ""
502   "@
503    XOR%x0%b0\t%2, %0
504    XOR%X0%b0\t%2, %0"
507 ;; Macro : XOR #~0, %0
508 (define_insn "one_cmpl<mode>2"
509   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,m")
510         (not:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "0,0")))]
511   ""
512   "@
513    INV%x0%b0\t%0
514    INV%X0%b0\t%0"
517 (define_insn "extendqihi2"
518   [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,m")
519         (sign_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
520   ""
521   "@
522    SXT%X0\t%0
523    SXT%X0\t%0"
526 (define_insn "zero_extendqihi2"
527   [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,m")
528         (zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
529   ""
530   "@
531    AND\t#0xff, %0
532    AND%X0\t#0xff, %0"
535 ;; Eliminate extraneous zero-extends mysteriously created by gcc.
536 (define_peephole2
537   [(set (match_operand:HI 0 "register_operand")
538         (zero_extend:HI (match_operand:QI 1 "general_operand")))
539    (set (match_operand:HI 2 "register_operand")
540         (zero_extend:HI (match_operand:QI 3 "register_operand")))]
541   "REGNO (operands[0]) == REGNO (operands[2]) && REGNO (operands[2]) == REGNO (operands[3])"
542   [(set (match_dup 0)
543         (zero_extend:HI (match_dup 1)))]
545    
546 (define_insn "zero_extendhipsi2"
547   [(set (match_operand:PSI                 0 "msp_nonimmediate_operand" "=r,m")
548         (zero_extend:PSI (match_operand:HI 1 "msp_nonimmediate_operand" "rm,r")))]
549   ""
550   "MOVX\t%1, %0"
553 (define_insn "truncpsihi2"
554   [(set (match_operand:HI               0 "msp_nonimmediate_operand" "=rm")
555         (truncate:HI (match_operand:PSI 1 "register_operand"      "r")))]
556   ""
557   "MOVX\t%1, %0"
560 (define_insn "extendhisi2"
561   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
562         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
563   ""
564   { return msp430x_extendhisi (operands); }
567 (define_insn "extendhipsi2"
568   [(set (match_operand:PSI 0 "nonimmediate_operand" "=r")
569         (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))]
570   "TARGET_LARGE"
571   "RLAM #4, %0 { RRAM #4, %0"
574 ;; Look for cases where integer/pointer conversions are suboptimal due
575 ;; to missing patterns, despite us not having opcodes for these
576 ;; patterns.  Doing these manually allows for alternate optimization
577 ;; paths.
578 (define_insn "zero_extendhisi2"
579   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
580         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
581   "TARGET_LARGE"
582   "MOV.W\t#0,%H0"
585 (define_insn "zero_extendhisipsi2"
586   [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r")
587         (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))]
588   "TARGET_LARGE"
589   "@
590    AND.W\t#-1,%0
591    MOV.W\t%1,%0"
594 (define_insn "extend_and_shift1_hipsi2"
595   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
596         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
597                    (const_int 1)))]
598   "TARGET_LARGE"
599   "RLAM #4, %0 { RRAM #3, %0"
602 (define_insn "extend_and_shift2_hipsi2"
603   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
604         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
605                    (const_int 2)))]
606   "TARGET_LARGE"
607   "RLAM #4, %0 { RRAM #2, %0"
610 ; Nasty - we are sign-extending a 20-bit PSI value in one register into
611 ; two adjacent 16-bit registers to make an SI value.  There is no MSP430X
612 ; instruction that will do this, so we push the 20-bit value onto the stack
613 ; and then pop it off as two 16-bit values.
615 ; FIXME: The MSP430X documentation does not specify if zero-extension or
616 ; sign-extension happens when the 20-bit value is pushed onto the stack.
617 ; It is probably zero-extension, but if not this pattern will not work
618 ; when the PSI value is negative..
620 ; Note: using PUSHM.A #1 is two bytes smaller than using PUSHX.A....
622 ; Note: We use a + constraint on operand 0 as otherwise GCC gets confused
623 ; about extending a single PSI mode register into a pair of SImode registers
624 ; with the same starting register.  It thinks that the upper register of
625 ; the pair is unused and so it can clobber it.  Try compiling 20050826-2.c
626 ; at -O2 to see this.
628 (define_insn "zero_extendpsisi2"
629   [(set (match_operand:SI                  0 "register_operand" "+r")
630         (zero_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
631   ""
632   "*
633     if (REGNO (operands[1]) == SP_REGNO)
634       /* If the source register is the stack pointer, the value
635          stored in the stack slot will be the value *after* the
636          stack pointer has been decremented.  So allow for that
637          here.  */
638       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\";
639     else
640       return \"PUSHM.A\t#1, %1 { POPX.W\t%L0 { POPX.W\t%H0 ; move pointer in %1 into reg-pair %L0:%H0\";
641   "
644 ;; We also need to be able to sign-extend pointer types (eg ptrdiff_t).
645 ;; Since (we assume) pushing a 20-bit value onto the stack zero-extends
646 ;; it, we use a different method here.
648 (define_insn "extendpsisi2"
649   [(set (match_operand:SI                  0 "register_operand" "=r")
650         (sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
651   "TARGET_LARGE"
652   "*
653     /* The intention here is that we copy the bottom 16-bits of
654        %1 into %L0 (zeroing the top four bits).  Then we copy the
655        entire 20-bits of %1 into %H0 and then arithmetically shift
656        it right by 16 bits, to get the top four bits of the pointer
657        sign-extended in %H0.  */
658     if (REGNO (operands[0]) == REGNO (operands[1]))
659       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\";
660     else
661       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\";
662   "
665 ; See the movsipsi2 pattern above for another way that GCC performs this
666 ; conversion.
667 (define_insn "truncsipsi2"
668   [(set (match_operand:PSI              0 "register_operand" "=r")
669         (truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
670   ""
671   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A\t#1, %L0"
674 ;;------------------------------------------------------------
675 ;; Shift Functions
677 ;; Note:  We do not use the RPT ... SHIFT instruction sequence
678 ;; when the repeat count is in a register, because even though RPT
679 ;; accepts counts in registers, it does not work if the count is
680 ;; zero, and the actual count in the register has to be one less
681 ;; than the required number of iterations.  We could encode a
682 ;; seqeunce like this:
684 ;;   bit #0xf, Rn
685 ;;   bz  1f
686 ;;   dec Rn
687 ;;   rpt Rn
688 ;;   <shift> Rm
689 ;;   inc Rn
690 ;; 1:
692 ;; But is longer than calling a helper function, and we are mostly
693 ;; concerned with code size.  FIXME: Maybe enable a sequence like
694 ;; this at -O3 and above ?
696 ;; Note - we ignore shift counts of less than one or more than 15.
697 ;; This is permitted by the ISO C99 standard as such shifts result
698 ;; in "undefined" behaviour.  [6.5.7 (3)]
700 ;; signed A << C
702 (define_expand "ashlhi3"
703   [(set (match_operand:HI            0 "nonimmediate_operand")
704         (ashift:HI (match_operand:HI 1 "general_operand")
705                    (match_operand:HI 2 "general_operand")))]
706   ""
707   {
708     if (msp430x
709         && REG_P (operands[0])
710         && REG_P (operands[1])
711         && CONST_INT_P (operands[2]))
712       emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2]));
713     else                 
714       msp430_expand_helper (operands, \"__mspabi_slli\", true);
715     DONE;
716   }
719 (define_insn "slli_1"
720   [(set (match_operand:HI            0 "nonimmediate_operand" "=rm")
721         (ashift:HI (match_operand:HI 1 "general_operand"       "0")
722                    (const_int 1)))]
723   ""
724   "RLA.W\t%0" ;; Note - this is a macro for ADD
727 (define_insn "430x_shift_left"
728   [(set (match_operand:HI            0 "register_operand" "=r")
729         (ashift:HI (match_operand:HI 1 "register_operand"  "0")
730                    (match_operand    2 "immediate_operand" "n")))]
731   "msp430x"
732   "*
733   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
734     return \"rpt\t%2 { rlax.w\t%0\";
735   return \"# nop left shift\";
736   "
739 (define_insn "slll_1"
740   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
741         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
742                    (const_int 1)))]
743   ""
744   "RLA.W\t%L0 { RLC.W\t%H0"
747 (define_insn "slll_2"
748   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
749         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
750                    (const_int 2)))]
751   ""
752   "RLA.W\t%L0 { RLC.W\t%H0 { RLA.W\t%L0 { RLC.W\t%H0"
755 (define_expand "ashlsi3"
756   [(set (match_operand:SI            0 "nonimmediate_operand")
757         (ashift:SI (match_operand:SI 1 "general_operand")
758                    (match_operand:SI 2 "general_operand")))]
759   ""
760   "msp430_expand_helper (operands, \"__mspabi_slll\", true);
761    DONE;"
764 ;;----------
766 ;; signed A >> C
768 (define_expand "ashrhi3"
769   [(set (match_operand:HI              0 "nonimmediate_operand")
770         (ashiftrt:HI (match_operand:HI 1 "general_operand")
771                      (match_operand:HI 2 "general_operand")))]
772   ""
773   {
774     if (msp430x
775         && REG_P (operands[0])
776         && REG_P (operands[1])
777         && CONST_INT_P (operands[2]))
778       emit_insn (gen_430x_arithmetic_shift_right (operands[0], operands[1], operands[2]));
779     else                 
780        msp430_expand_helper (operands, \"__mspabi_srai\", true);
781    DONE;
782    }
785 (define_insn "srai_1"
786   [(set (match_operand:HI              0 "msp_nonimmediate_operand" "=rm")
787         (ashiftrt:HI (match_operand:HI 1 "msp_general_operand"      "0")
788                      (const_int 1)))]
789   ""
790   "RRA.W\t%0"
793 (define_insn "430x_arithmetic_shift_right"
794   [(set (match_operand:HI              0 "register_operand" "=r")
795         (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0")
796                      (match_operand    2 "immediate_operand" "n")))]
797   "msp430x"
798   "*
799   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
800     return \"rpt\t%2 { rrax.w\t%0\";
801   return \"# nop arith right shift\";
802   "
805 (define_insn "srap_1"
806   [(set (match_operand:PSI              0 "register_operand" "=r")
807         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
808                       (const_int 1)))]
809   "msp430x"
810   "RRAM.A #1,%0"
813 (define_insn "srap_2"
814   [(set (match_operand:PSI              0 "register_operand" "=r")
815         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
816                       (const_int 2)))]
817   "msp430x"
818   "RRAM.A #2,%0"
821 (define_insn "sral_1"
822   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
823         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
824                      (const_int 1)))]
825   ""
826   "RRA.W\t%H0 { RRC.W\t%L0"
829 (define_insn "sral_2"
830   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
831         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
832                      (const_int 2)))]
833   ""
834   "RRA.W\t%H0 { RRC.W\t%L0 { RRA.W\t%H0 { RRC.W\t%L0"
837 (define_expand "ashrsi3"
838   [(set (match_operand:SI              0 "nonimmediate_operand")
839         (ashiftrt:SI (match_operand:SI 1 "general_operand")
840                      (match_operand:SI 2 "general_operand")))]
841   ""
842   "msp430_expand_helper (operands, \"__mspabi_sral\", true);
843    DONE;"
846 ;;----------
848 ;; unsigned A >> C
850 (define_expand "lshrhi3"
851   [(set (match_operand:HI              0 "nonimmediate_operand")
852         (lshiftrt:HI (match_operand:HI 1 "general_operand")
853                      (match_operand:HI 2 "general_operand")))]
854   ""
855   {
856     if (msp430x
857         && REG_P (operands[0])
858         && REG_P (operands[1])
859         && CONST_INT_P (operands[2]))
860       emit_insn (gen_430x_logical_shift_right (operands[0], operands[1], operands[2]));
861     else                 
862       msp430_expand_helper (operands, \"__mspabi_srli\", true);
863     DONE;
864   }
867 (define_insn "srli_1"
868   [(set (match_operand:HI              0 "nonimmediate_operand" "=rm")
869         (lshiftrt:HI (match_operand:HI 1 "general_operand"       "0")
870                      (const_int 1)))]
871   ""
872   "CLRC { RRC.W\t%0"
875 (define_insn "430x_logical_shift_right"
876   [(set (match_operand:HI              0 "register_operand" "=r")
877         (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0")
878                      (match_operand    2 "immediate_operand" "n")))]
879   "msp430x"
880   {
881     return msp430x_logical_shift_right (operands[2]);
882   }
885 (define_insn "srlp_1"
886   [(set (match_operand:PSI              0 "register_operand" "=r")
887         (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
888                       (const_int 1)))]
889   ""
890   "RRUM.A #1,%0"
893 (define_insn "srll_1"
894   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
895         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
896                      (const_int 1)))]
897   ""
898   "CLRC { RRC.W\t%H0 { RRC.W\t%L0"
901 (define_insn "srll_2x"
902   [(set (match_operand:SI              0 "nonimmediate_operand" "=r")
903         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
904                      (const_int 2)))]
905   "msp430x"
906   "RRUX.W\t%H0 { RRC.W\t%L0 { RRUX.W\t%H0 { RRC.W\t%L0"
909 (define_expand "lshrsi3"
910   [(set (match_operand:SI              0 "nonimmediate_operand")
911         (lshiftrt:SI (match_operand:SI 1 "general_operand")
912                      (match_operand:SI 2 "general_operand")))]
913   ""
914   "msp430_expand_helper (operands, \"__mspabi_srll\", true);
915    DONE;"
918 ;;------------------------------------------------------------
919 ;; Function Entry/Exit
921 (define_expand "prologue"
922   [(const_int 0)]
923   ""
924   "msp430_expand_prologue (); DONE;"
925   )
927 (define_expand "epilogue"
928   [(const_int 0)]
929   ""
930   "msp430_expand_epilogue (0); DONE;"
931   )
934 (define_insn "epilogue_helper"
935   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)]
936   ""
937   "BR%Q0\t#__mspabi_func_epilog_%J0"
938   )
941 (define_insn "prologue_start_marker"
942   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)]
943   ""
944   "; start of prologue"
945   )
947 (define_insn "prologue_end_marker"
948   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)]
949   ""
950   "; end of prologue"
951   )
953 (define_insn "epilogue_start_marker"
954   [(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)]
955   ""
956   "; start of epilogue"
957   )
959 ;; This makes the linker add a call to exit() after the call to main()
960 ;; in crt0
961 (define_insn "msp430_refsym_need_exit"
962   [(unspec_volatile [(const_int 0)] UNS_REFSYM_NEED_EXIT)]
963   ""
964   ".refsym\t__crt0_call_exit"
965   )
967 ;;------------------------------------------------------------
968 ;; Jumps
970 (define_expand "call"
971   [(call:HI (match_operand 0 "")
972             (match_operand 1 ""))]
973   ""
974   ""
977 (define_insn "call_internal"
978   [(call (mem:HI (match_operand 0 "general_operand" "rYci"))
979          (match_operand 1 ""))]
980   ""
981   "CALL%Q0\t%0"
984 (define_expand "call_value"
985   [(set (match_operand          0 "register_operand")
986         (call:HI (match_operand 1 "general_operand")
987                  (match_operand 2 "")))]
988   ""
989   ""
992 (define_insn "call_value_internal"
993   [(set (match_operand               0 "register_operand" "=r")
994         (call (mem:HI (match_operand 1 "general_operand" "rYci"))
995               (match_operand 2 "")))]
996   ""
997   "CALL%Q0\t%1"
1000 (define_insn "msp_return"
1001   [(return)]
1002   ""
1003   { return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); }
1006 ;; This pattern is NOT, as expected, a return pattern.  It's called
1007 ;; before reload and must only store its operands, and emit a
1008 ;; placeholder where the epilog needs to be.  AFTER reload, the
1009 ;; placeholder should get expanded into a regular-type epilogue that
1010 ;; also does the EH return.
1011 (define_expand "eh_return"
1012   [(match_operand:HI 0 "")]
1013   ""
1014   "msp430_expand_eh_return (operands[0]);
1015    emit_jump_insn (gen_msp430_eh_epilogue ());
1016    emit_barrier ();
1017    DONE;"
1020 ;; This is the actual EH epilogue.  We emit it in the pattern above,
1021 ;; before reload, and convert it to a real epilogue after reload.
1022 (define_insn_and_split "msp430_eh_epilogue"
1023   [(eh_return)]
1024   ""
1025   "#"
1026   "reload_completed"
1027   [(const_int 0)]
1028   "msp430_expand_epilogue (1); DONE;"
1029   )
1031 (define_insn "jump"
1032   [(set (pc)
1033         (label_ref (match_operand 0 "" "")))]
1034   ""
1035   "BR%Q0\t#%l0"
1038 ;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
1039 ;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c).
1040 (define_insn "indirect_jump"
1041   [(set (pc)
1042         (match_operand 0 "nonimmediate_operand" "rYl"))]
1043   ""
1044   "BR%Q0\t%0"
1047 ;;------------------------------------------------------------
1048 ;; Various Conditionals
1050 (define_expand "cbranch<mode>4"
1051   [(parallel [(set (pc) (if_then_else
1052                          (match_operator 0 ""
1053                                          [(match_operand:QHI 1 "nonimmediate_operand")
1054                                           (match_operand:QHI 2 "general_operand")])
1055                          (label_ref (match_operand 3 "" ""))
1056                          (pc)))
1057               (clobber (reg:BI CARRY))]
1058   )]
1059   ""
1060   "msp430_fixup_compare_operands (<MODE>mode, operands);"
1061   )
1063 (define_insn "cbranchpsi4_real"
1064   [(set (pc) (if_then_else
1065               (match_operator                     0 "msp430_cmp_operator"
1066                               [(match_operand:PSI 1 "nonimmediate_operand" "r,rYs,rm")
1067                                (match_operand:PSI 2 "general_operand"      "rLs,rYsi,rmi")])
1068               (label_ref (match_operand           3 "" ""))
1069               (pc)))
1070    (clobber (reg:BI CARRY))
1071    ]
1072   ""
1073   "@
1074   CMP%Q0\t%2, %1 { J%0\t%l3
1075   CMPX.A\t%2, %1 { J%0\t%l3
1076   CMPX.A\t%2, %1 { J%0\t%l3"
1077   )
1079 (define_insn "cbranchqi4_real"
1080   [(set (pc) (if_then_else
1081               (match_operator                    0 "msp430_cmp_operator"
1082                               [(match_operand:QI 1 "nonimmediate_operand" "rYs,rm")
1083                                (match_operand:QI 2 "general_operand"      "rYsi,rmi")])
1084               (label_ref (match_operand          3 "" ""))
1085               (pc)))
1086    (clobber (reg:BI CARRY))
1087    ]
1088   ""
1089   "@
1090    CMP.B\t%2, %1 { J%0\t%l3
1091    CMP%X0.B\t%2, %1 { J%0\t%l3"
1092   )
1094 (define_insn "cbranchhi4_real"
1095   [(set (pc) (if_then_else
1096               (match_operator                    0 "msp430_cmp_operator"
1097                               [(match_operand:HI 1 "nonimmediate_operand" "rYs,rm")
1098                                (match_operand:HI 2 "general_operand"      "rYsi,rmi")])
1099               (label_ref (match_operand          3 "" ""))
1100               (pc)))
1101    (clobber (reg:BI CARRY))
1102    ]
1103   ""
1104   "@
1105    CMP.W\t%2, %1 { J%0\t%l3
1106    CMP%X0.W\t%2, %1 { J%0\t%l3"
1107   )
1109 (define_insn "cbranchpsi4_reversed"
1110   [(set (pc) (if_then_else
1111               (match_operator                     0 "msp430_reversible_cmp_operator"
1112                               [(match_operand:PSI 1 "general_operand" "rLs,rYsi,rmi")
1113                                (match_operand:PSI 2 "general_operand" "r,rYs,rm")])
1114               (label_ref (match_operand           3 "" ""))
1115               (pc)))
1116    (clobber (reg:BI CARRY))
1117    ]
1118   ""
1119   "@
1120   CMP%Q0\t%1, %2 { J%R0\t%l3
1121   CMPX.A\t%1, %2 { J%R0\t%l3
1122   CMPX.A\t%1, %2 { J%R0\t%l3"
1123   )
1125 (define_insn "cbranchqi4_reversed"
1126   [(set (pc) (if_then_else
1127               (match_operator                    0 "msp430_reversible_cmp_operator"
1128                               [(match_operand:QI 1 "general_operand" "rYsi,rmi")
1129                                (match_operand:QI 2 "general_operand" "rYs,rm")])
1130               (label_ref (match_operand          3 "" ""))
1131               (pc)))
1132    (clobber (reg:BI CARRY))
1133    ]
1134   ""
1135   "@
1136    CMP.B\t%1, %2 { J%R0\t%l3
1137    CMP%X0.B\t%1, %2 { J%R0\t%l3"
1138   )
1140 (define_insn "cbranchhi4_reversed"
1141   [(set (pc) (if_then_else
1142               (match_operator                    0 "msp430_reversible_cmp_operator"
1143                               [(match_operand:HI 1 "general_operand" "rYsi,rmi")
1144                                (match_operand:HI 2 "general_operand" "rYs,rm")])
1145               (label_ref (match_operand          3 "" ""))
1146               (pc)))
1147    (clobber (reg:BI CARRY))
1148    ]
1149   ""
1150   "@
1151    CMP.W\t%1, %2 { J%R0\t%l3
1152    CMP%X0.W\t%1, %2 { J%R0\t%l3"
1153   )
1155 (define_insn "*bitbranch<mode>4"
1156   [(set (pc) (if_then_else
1157               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1158                            (match_operand:QHI 1 "msp_general_operand" "rYsi,rmi"))
1159                   (const_int 0))
1160               (label_ref (match_operand 2 "" ""))
1161               (pc)))
1162    (clobber (reg:BI CARRY))
1163    ]
1164   ""
1165   "@
1166    BIT%x0%b0\t%1, %0 { JNE\t%l2
1167    BIT%X0%b0\t%1, %0 { JNE\t%l2"
1168   )
1170 (define_insn "*bitbranch<mode>4"
1171   [(set (pc) (if_then_else
1172               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1173                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1174                   (const_int 0))
1175               (label_ref (match_operand 2 "" ""))
1176               (pc)))
1177    (clobber (reg:BI CARRY))
1178    ]
1179   ""
1180   "BIT%x0%X0%b0\t%1, %0 { JEQ\t%l2"
1181   )
1183 (define_insn "*bitbranch<mode>4"
1184   [(set (pc) (if_then_else
1185               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1186                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1187                   (const_int 0))
1188               (pc)
1189               (label_ref (match_operand 2 "" ""))))
1190    (clobber (reg:BI CARRY))
1191    ]
1192   ""
1193   "BIT%X0%b0\t%1, %0 { JNE\t%l2"
1194   )
1196 (define_insn "*bitbranch<mode>4"
1197   [(set (pc) (if_then_else
1198               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1199                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1200                   (const_int 0))
1201               (pc)
1202               (label_ref (match_operand 2 "" ""))))
1203    (clobber (reg:BI CARRY))
1204    ]
1205   ""
1206   "BIT%X0%b0\t%1, %0 { JEQ\t%l2"
1207   )
1209 ;;------------------------------------------------------------
1210 ;; zero-extract versions of the above
1212 (define_insn "*bitbranch<mode>4_z"
1213   [(set (pc) (if_then_else
1214               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1215                                     (const_int 1)
1216                                     (match_operand 1 "msp430_bitpos" "i,i"))
1217                   (const_int 0))
1218               (label_ref (match_operand 2 "" ""))
1219               (pc)))
1220    (clobber (reg:BI CARRY))
1221    ]
1222   ""
1223   "@
1224    BIT%x0%b0\t%p1, %0 { JNE\t%l2
1225    BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1226   )
1228 (define_insn "*bitbranch<mode>4_z"
1229   [(set (pc) (if_then_else
1230               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1231                                    (const_int 1)
1232                                    (match_operand 1 "msp430_bitpos" "i"))
1233                   (const_int 0))
1234               (label_ref (match_operand 2 "" ""))
1235               (pc)))
1236    (clobber (reg:BI CARRY))
1237    ]
1238   ""
1239   "BIT%x0%X0%b0\t%p1, %0 { JEQ\t%l2"
1240   )
1242 (define_insn "*bitbranch<mode>4_z"
1243   [(set (pc) (if_then_else
1244               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1245                                    (const_int 1)
1246                                    (match_operand 1 "msp430_bitpos" "i"))
1247                   (const_int 0))
1248               (pc)
1249               (label_ref (match_operand 2 "" ""))))
1250    (clobber (reg:BI CARRY))
1251    ]
1252   ""
1253   "BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1254   )
1256 (define_insn "*bitbranch<mode>4_z"
1257   [(set (pc) (if_then_else
1258               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1259                                    (const_int 1)
1260                                    (match_operand 1 "msp430_bitpos" "i"))
1261                   (const_int 0))
1262               (pc)
1263               (label_ref (match_operand 2 "" ""))))
1264    (clobber (reg:BI CARRY))
1265    ]
1266   ""
1267   "BIT%X0%b0\t%p1, %0 { JEQ\t%l2"
1268   )
1270 ;;------------------------------------------------------------
1271 ;; Misc
1273 (define_insn "nop"
1274   [(const_int 0)]
1275   "1"
1276   "NOP"
1279 (define_insn "disable_interrupts"
1280   [(unspec_volatile [(const_int 0)] UNS_DINT)]
1281   ""
1282   "DINT \; NOP"
1283   )
1285 (define_insn "enable_interrupts"
1286   [(unspec_volatile [(const_int 0)] UNS_EINT)]
1287   ""
1288   "EINT"
1289   )
1291 (define_insn "push_intr_state"
1292   [(unspec_volatile [(const_int 0)] UNS_PUSH_INTR)]
1293   ""
1294   "PUSH\tSR"
1295   )
1297 (define_insn "pop_intr_state"
1298   [(unspec_volatile [(const_int 0)] UNS_POP_INTR)]
1299   ""
1300   "POP\tSR"
1301   )
1303 ;; Clear bits in the copy of the status register that is currently
1304 ;; saved on the stack at the top of the interrupt handler.
1305 (define_insn "bic_SR"
1306   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIC_SR)]
1307   ""
1308   "BIC.W\t%0, %O0(SP)"
1309   )
1311 ;; Set bits in the copy of the status register that is currently
1312 ;; saved on the stack at the top of the interrupt handler.
1313 (define_insn "bis_SR"
1314   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIS_SR)]
1315   ""
1316   "BIS.W\t%0, %O0(SP)"
1317   )
1319 ;; For some reason GCC is generating (set (reg) (and (neg (reg)) (int)))
1320 ;; very late on in the compilation and not splitting it into separate
1321 ;; instructions, so we provide a pattern to support it here.
1322 (define_insn "andneghi3"
1323   [(set (match_operand:HI                 0 "register_operand" "=r")
1324         (and:HI (neg:HI (match_operand:HI 1 "register_operand"  "r"))
1325                 (match_operand            2 "immediate_operand" "n")))]
1326   ""
1327   "*
1328     if (REGNO (operands[0]) != REGNO (operands[1]))
1329       return \"MOV.W\t%1, %0 { INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0\";
1330     else
1331       return \"INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0\";
1332   "
1333   )
1335 (define_insn "delay_cycles_start"
1336   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
1337                     UNS_DELAY_START)]
1338   ""
1339   "; Begin %J0 cycle delay"
1340   )
1342 (define_insn "delay_cycles_end"
1343   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
1344                     UNS_DELAY_END)]
1345   ""
1346   "; End %J0 cycle delay"
1347   )
1349 (define_insn "delay_cycles_32"
1350   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1351                      (match_operand 1 "immediate_operand" "i")
1352                      ] UNS_DELAY_32)]
1353   ""
1354   "PUSH r13
1355         PUSH    r14
1356         MOV.W   %A0, r13
1357         MOV.W   %B0, r14
1358 1:      SUB.W   #1, r13
1359         SUBC.W  #0, r14
1360         JNE     1b
1361         TST.W   r13
1362         JNE     1b
1363         POP     r14
1364         POP     r13"
1365   )
1367 (define_insn "delay_cycles_32x"
1368   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1369                      (match_operand 1 "immediate_operand" "i")
1370                      ] UNS_DELAY_32X)]
1371   ""
1372   "PUSHM.A      #2,r13
1373         MOV.W   %A0, r13
1374         MOV.W   %B0, r14
1375 1:      SUB.W   #1, r13
1376         SUBC.W  #0, r14
1377         JNE     1b
1378         TST.W   r13
1379         JNE     1b
1380         POPM.A  #2,r13"
1381   )
1383 (define_insn "delay_cycles_16"
1384   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1385                      (match_operand 1 "immediate_operand" "i")
1386                      ] UNS_DELAY_16)]
1387   ""
1388   "PUSH r13
1389         MOV.W   %0, r13
1390 1:      SUB.W   #1, r13
1391         JNE     1b
1392         POP     r13"
1393   )
1395 (define_insn "delay_cycles_16x"
1396   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1397                      (match_operand 1 "immediate_operand" "i")
1398                      ] UNS_DELAY_16X)]
1399   ""
1400   "PUSHM.A      #1,r13
1401         MOV.W   %0, r13
1402 1:      SUB.W   #1, r13
1403         JNE     1b
1404         POPM.A  #1,r13"
1405   )
1407 (define_insn "delay_cycles_2"
1408   [(unspec_volatile [(const_int 0) ] UNS_DELAY_2)]
1409   ""
1410   "JMP  .+2"
1411   )
1413 (define_insn "delay_cycles_1"
1414   [(unspec_volatile [(const_int 0) ] UNS_DELAY_1)]
1415   ""
1416   "NOP"
1417   )
1419 (define_insn "mulhisi3"
1420   [(set (match_operand:SI                          0 "register_operand" "=r")
1421         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1422                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1423   "optimize > 2 && msp430_hwmult_type != NONE"
1424   "*
1425     if (msp430_use_f5_series_hwmult ())
1426       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\";
1427     else
1428       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\";
1429   "
1432 (define_insn "umulhisi3"
1433   [(set (match_operand:SI                          0 "register_operand" "=r")
1434         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1435                  (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1436   "optimize > 2 && msp430_hwmult_type != NONE"
1437   "*
1438     if (msp430_use_f5_series_hwmult ())
1439       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\";
1440     else
1441       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\";
1442   "
1445 (define_insn "mulsidi3"
1446   [(set (match_operand:DI                          0 "register_operand" "=r")
1447         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1448                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1449   "optimize > 2 && msp430_hwmult_type != NONE"
1450   "*
1451     if (msp430_use_f5_series_hwmult ())
1452       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\";
1453     else
1454       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\";
1455   "
1458 (define_insn "umulsidi3"
1459   [(set (match_operand:DI                          0 "register_operand" "=r")
1460         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1461                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1462   "optimize > 2 && msp430_hwmult_type != NONE"
1463   "*
1464     if (msp430_use_f5_series_hwmult ())
1465       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\";
1466     else
1467       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\";
1468   "