PR target/64160
[official-gcc.git] / gcc / config / msp430 / msp430.md
blobd9abeef545bcdd667870911708ccef9119b34618
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_topbyte"
183   [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=r")
184         (subreg:QI (match_operand:PSI 1 "msp_general_operand" "r") 2))]
185   "msp430x"
186   "PUSHM.A\t#1,%1 { POPM.W\t#1,%0 { POPM.W\t#1,%0"
189 (define_insn "movqi"
190   [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm")
191         (match_operand:QI 1 "msp_general_operand" "riYs,rmi"))]
192   ""
193   "@
194   MOV.B\t%1, %0
195   MOV%X0.B\t%1, %0"
198 (define_insn "movhi"
199   [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm")
200         (match_operand:HI 1 "msp_general_operand" "riYs,rmi"))]
201   ""
202   "@
203   MOV.W\t%1, %0
204   MOV%X0.W\t%1, %0"
207 (define_expand "movsi"
208   [(set (match_operand:SI 0 "nonimmediate_operand")
209         (match_operand:SI 1 "general_operand"))]
210   ""
211   ""
212   )
213   
214 (define_insn_and_split "movsi_x"
215   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
216         (match_operand:SI 1 "general_operand" "rmi"))]
217   ""
218   "#"
219   "reload_completed"
220   [(set (match_operand:HI 2 "nonimmediate_operand")
221         (match_operand:HI 4 "general_operand"))
222    (set (match_operand:HI 3 "nonimmediate_operand")
223         (match_operand:HI 5 "general_operand"))]
224   "msp430_split_movsi (operands);"
227 ;; Some MOVX.A cases can be done with MOVA, this is only a few of them.
228 (define_insn "movpsi"
229   [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,Ya,rm")
230         (match_operand:PSI 1 "msp_general_operand" "riYa,r,rmi"))]
231   ""
232   "@
233   MOVA\t%1, %0
234   MOVA\t%1, %0
235   MOVX.A\t%1, %0")
237 ; This pattern is identical to the truncsipsi2 pattern except
238 ; that it uses a SUBREG instead of a TRUNC.  It is needed in
239 ; order to prevent reload from converting (set:SI (SUBREG:PSI (SI)))
240 ; into (SET:PSI (PSI)).
242 ; Note: using POPM.A #1 is two bytes smaller than using POPX.A....
244 (define_insn "movsipsi2"
245   [(set (match_operand:PSI            0 "register_operand" "=r")
246         (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
247   "msp430x"
248   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0"
251 ;;------------------------------------------------------------
252 ;; Math
254 (define_insn "addpsi3"
255   [(set (match_operand:PSI           0 "msp_nonimmediate_operand" "=r,rm")
256         (plus:PSI (match_operand:PSI 1 "msp_nonimmediate_operand" "%0,0")
257                   (match_operand:PSI 2 "msp_general_operand"      "rLs,rmi")))]
258   ""
259   "@
260   ADDA\t%2, %0
261   ADDX.A\t%2, %0"
264 (define_insn "addqi3"
265   [(set (match_operand:QI          0 "msp_nonimmediate_operand" "=rYs,rm")
266         (plus:QI (match_operand:QI 1 "msp_nonimmediate_operand" "%0,0")
267                  (match_operand:QI 2 "msp_general_operand"      "riYs,rmi")))]
268   ""
269   "@
270    ADD.B\t%2, %0
271    ADD%X0.B\t%2, %0"
274 (define_insn "addhi3"
275   [(set (match_operand:HI           0 "msp_nonimmediate_operand" "=rYs,rm")
276         (plus:HI (match_operand:HI  1 "msp_nonimmediate_operand" "%0,0")
277                   (match_operand:HI 2 "msp_general_operand"      "riYs,rmi")))]
278   ""
279   "@
280    ADD.W\t%2, %0
281    ADD%X0.W\t%2, %0"
284 ; This pattern is needed in order to avoid reload problems.
285 ; It takes an SI pair of registers, adds a value to them, and
286 ; then converts them into a single PSI register.
288 (define_insn "addsipsi3"
289   [(set (subreg:SI (match_operand:PSI 0 "register_operand" "=&r") 0)
290         (plus:SI (match_operand:SI    1 "register_operand" "0")
291                  (match_operand       2 "general_operand" "rmi")))]
292   ""
293   "ADD.W\t%L2, %L0 { ADDC.W\t%H2, %H0 { PUSH.W\t%H0 { PUSH.W\t%L0 { POPM.A\t#1, %0"
296 (define_insn "addsi3"
297   [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,rm")
298         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
299                  (match_operand:SI 2 "general_operand" "r,mi")))]
300   ""
301   "@
302    ADD\t%L2, %L0 { ADDC\t%H2, %H0
303    ADD%X0\t%L2, %L0 { ADDC%X0\t%H2, %H0"
306 ; Version of addhi that exposes the carry operations, for SImode adds.
308 ; NOTE - we are playing a dangerous game with GCC here.  We have these two
309 ; add patterns and the splitter that follows because our tests have shown
310 ; that this results in a significant reduction in code size - because GCC is
311 ; able to discard any unused part of the addition.  We have to annotate the
312 ; patterns with the set and use of the carry flag because otherwise GCC will
313 ; discard parts of the addition when they are actually needed.  But we have
314 ; not annotated all the other patterns that set the CARRY flag as doing so
315 ; results in an overall increase in code size[1].  Instead we just *hope*
316 ; that GCC will not move a carry-setting instruction in between the first
317 ; and second adds.
319 ; So far our experiments have shown that GCC is likely to move MOV and CMP
320 ; instructions in between the two adds, but not other instructions.  MOV is
321 ; safe, CMP is not.  So we have annotated the CMP patterns and left the
322 ; subtract, shift and other add patterns alone.  At the moment this is
323 ; working, but with future changes to the generic parts of GCC that might
324 ; change.
326 ; [1] It is not clear exactly why the code size increases.  The cause appears
327 ; to be that reload is more prevelent to spilling a variable onto the stack
328 ; but why it does this is unknown.  Possibly the additional CLOBBERs necessary
329 ; to correctly annotate the other patterns makes reload think that there is
330 ; increased register pressure.  Or possibly reload does not handle ADD patterns
331 ; that are not single_set() very well.
333 (define_insn "addhi3_cy"
334   [(set (match_operand:HI          0 "msp_nonimmediate_operand" "=r,rm")
335         (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
336                  (match_operand:HI 2 "msp_nonimmediate_operand" "r,rm")))
337    (set (reg:BI CARRY)
338         (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
339                                            (zero_extend:SI (match_dup 2)))
340                                   (const_int 16))))
341    ]
342   ""
343   "@
344    ADD\t%2, %1 ; cy
345    ADD%X0\t%2, %1 ; cy"
346   )
348 (define_insn "addhi3_cy_i"
349   [(set (match_operand:HI          0 "nonimmediate_operand" "=r,rm")
350         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
351                  (match_operand:HI 2 "immediate_operand"     "i,i")))
352    (set (reg:BI CARRY)
353         (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
354                                            (match_operand 3 "immediate_operand" "i,i"))
355                                   (const_int 16))))
356    ]
357   ""
358   "@
359    ADD\t%2, %1 ; cy
360    ADD%X0\t%2, %1 ; cy"
361   )
363 ; Version of addhi that adds the carry, for SImode adds.
364 (define_insn "addchi4_cy"
365   [(set (match_operand:HI                   0 "msp_nonimmediate_operand" "=r,rm")
366         (plus:HI (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
367                           (match_operand:HI 2 "msp_general_operand"      "ri,rmi"))
368                  (zero_extend:HI (reg:BI CARRY))))
369    ]
370   ""
371   "@
372    ADDC\t%2, %1
373    ADDC%X0\t%2, %1"
374   )
376 ; Split an SImode add into two HImode adds, keeping track of the carry
377 ; so that gcc knows when it can and can't optimize away the two
378 ; halves.
379 (define_split
380   [(set (match_operand:SI          0 "msp430_nonsubreg_operand")
381         (plus:SI (match_operand:SI 1 "msp430_nonsubreg_operand")
382                  (match_operand:SI 2 "msp430_nonsubreg_or_imm_operand")))
383    ]
384   ""
385   [(parallel [(set (match_operand:HI 3 "nonimmediate_operand" "=&rm")
386                    (plus:HI (match_dup 4)
387                             (match_dup 5)))
388               (set (reg:BI CARRY)
389                    (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 4))
390                                                       (match_dup 9))
391                                              (const_int 16))))
392               ])
393    (set (match_operand:HI 6 "nonimmediate_operand" "=&rm")
394         (plus:HI (plus:HI (match_dup 7)
395                           (match_dup 8))
396                  (zero_extend:HI (reg:BI CARRY))))
397    ]
398   "
399    operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
400    operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
401    operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
402    operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
403    operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
404    operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
406    /* BZ 64160: Do not use this splitter when the dest partially overlaps the source.  */
407    if (reg_overlap_mentioned_p (operands[3], operands[7])
408        || reg_overlap_mentioned_p (operands[3], operands[8]))
409       FAIL;
411    if (GET_CODE (operands[5]) == CONST_INT)
412      operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
413    else
414      operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
415    "
416   )
419 ;; Alternatives 2 and 3 are to handle cases generated by reload.
420 (define_insn "subpsi3"
421   [(set (match_operand:PSI            0 "nonimmediate_operand" "=r,   rm, &?r, ?&r")
422         (minus:PSI (match_operand:PSI 1 "general_operand"       "0,   0,   !r,  !i")
423                    (match_operand:PSI 2 "general_operand"       "rLs, rmi, rmi,  r")))]
424   ""
425   "@
426   SUBA\t%2, %0
427   SUBX.A\t%2, %0
428   MOVX.A\t%1, %0 { SUBX.A\t%2, %0
429   MOVX.A\t%1, %0 { SUBA\t%2, %0"
432 ;; Alternatives 2 and 3 are to handle cases generated by reload.
433 (define_insn "subqi3"
434   [(set (match_operand:QI           0 "nonimmediate_operand" "=rYs,  rm,  &?r, ?&r")
435         (minus:QI (match_operand:QI 1 "general_operand"       "0,    0,    !r,  !i")
436                   (match_operand:QI 2 "general_operand"      " riYs, rmi, rmi,   r")))]
437   ""
438   "@
439   SUB.B\t%2, %0
440   SUB%X0.B\t%2, %0
441   MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0
442   MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0"
445 ;; Alternatives 2 and 3 are to handle cases generated by reload.
446 (define_insn "subhi3"
447   [(set (match_operand:HI           0 "nonimmediate_operand" "=rYs,  rm,  &?r, ?&r")
448         (minus:HI (match_operand:HI 1 "general_operand"       "0,    0,    !r,  !i")
449                   (match_operand:HI 2 "general_operand"      " riYs, rmi, rmi,   r")))]
450   ""
451   "@
452   SUB.W\t%2, %0
453   SUB%X0.W\t%2, %0
454   MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0
455   MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0"
458 (define_insn "subsi3"
459   [(set (match_operand:SI           0 "nonimmediate_operand" "=&rm")
460         (minus:SI (match_operand:SI 1 "nonimmediate_operand"   "0")
461                   (match_operand:SI 2 "general_operand"        "rmi")))]
462   ""
463   "SUB%X0\t%L2, %L0 { SUBC%X0\t%H2, %H0"
466 (define_insn "*bic<mode>_cg"
467   [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m")
468         (and:QHI (match_operand:QHI 1 "msp_general_operand" "0,0")
469                  (match_operand 2 "msp430_inv_constgen_operator" "n,n")))]
470   ""
471   "@
472    BIC%x0%b0\t#%I2, %0
473    BIC%X0%b0\t#%I2, %0"
476 (define_insn "bic<mode>3"
477   [(set (match_operand:QHI                   0 "msp_nonimmediate_operand" "=rYs,rm")
478         (and:QHI (not:QHI (match_operand:QHI 1 "msp_general_operand"       "rYs,rmn"))
479                  (match_operand:QHI          2 "msp_nonimmediate_operand"  "0,0")))]
480   ""
481   "@
482    BIC%x0%b0\t%1, %0
483    BIC%X0%b0\t%1, %0"
486 (define_insn "and<mode>3"
487   [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
488         (and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
489                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
490   ""
491   "@
492    AND%x0%b0\t%2, %0
493    AND%X0%b0\t%2, %0"
496 (define_insn "ior<mode>3"
497   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,rm")
498         (ior:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
499                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
500   ""
501   "@
502    BIS%x0%b0\t%2, %0
503    BIS%X0%b0\t%2, %0"
506 (define_insn "xor<mode>3"
507   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,rm")
508         (xor:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
509                  (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
510   ""
511   "@
512    XOR%x0%b0\t%2, %0
513    XOR%X0%b0\t%2, %0"
516 ;; Macro : XOR #~0, %0
517 (define_insn "one_cmpl<mode>2"
518   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,m")
519         (not:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "0,0")))]
520   ""
521   "@
522    INV%x0%b0\t%0
523    INV%X0%b0\t%0"
526 (define_insn "extendqihi2"
527   [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,m")
528         (sign_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
529   ""
530   "@
531    SXT%X0\t%0
532    SXT%X0\t%0"
535 (define_insn "zero_extendqihi2"
536   [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,m")
537         (zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
538   ""
539   "@
540    AND\t#0xff, %0
541    AND%X0\t#0xff, %0"
544 ;; Eliminate extraneous zero-extends mysteriously created by gcc.
545 (define_peephole2
546   [(set (match_operand:HI 0 "register_operand")
547         (zero_extend:HI (match_operand:QI 1 "general_operand")))
548    (set (match_operand:HI 2 "register_operand")
549         (zero_extend:HI (match_operand:QI 3 "register_operand")))]
550   "REGNO (operands[0]) == REGNO (operands[2]) && REGNO (operands[2]) == REGNO (operands[3])"
551   [(set (match_dup 0)
552         (zero_extend:HI (match_dup 1)))]
554    
555 (define_insn "zero_extendhipsi2"
556   [(set (match_operand:PSI                 0 "msp_nonimmediate_operand" "=r,m")
557         (zero_extend:PSI (match_operand:HI 1 "msp_nonimmediate_operand" "rm,r")))]
558   ""
559   "MOVX\t%1, %0"
562 (define_insn "truncpsihi2"
563   [(set (match_operand:HI               0 "msp_nonimmediate_operand" "=rm")
564         (truncate:HI (match_operand:PSI 1 "register_operand"      "r")))]
565   ""
566   "MOVX\t%1, %0"
569 (define_insn "extendhisi2"
570   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
571         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
572   ""
573   { return msp430x_extendhisi (operands); }
576 (define_insn "extendhipsi2"
577   [(set (match_operand:PSI 0 "nonimmediate_operand" "=r")
578         (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))]
579   "msp430x"
580   "RLAM.A #4, %0 { RRAM.A #4, %0"
583 ;; Look for cases where integer/pointer conversions are suboptimal due
584 ;; to missing patterns, despite us not having opcodes for these
585 ;; patterns.  Doing these manually allows for alternate optimization
586 ;; paths.
587 (define_insn "zero_extendhisi2"
588   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
589         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
590   "msp430x"
591   "MOV.W\t#0,%H0"
594 (define_insn "zero_extendhisipsi2"
595   [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r")
596         (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))]
597   "msp430x"
598   "@
599    AND.W\t#-1,%0
600    MOV.W\t%1,%0"
603 (define_insn "extend_and_shift1_hipsi2"
604   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
605         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
606                    (const_int 1)))]
607   "msp430x"
608   "RLAM.A #4, %0 { RRAM.A #3, %0"
611 (define_insn "extend_and_shift2_hipsi2"
612   [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
613         (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
614                    (const_int 2)))]
615   "msp430x"
616   "RLAM.A #4, %0 { RRAM.A #2, %0"
619 ; Nasty - we are sign-extending a 20-bit PSI value in one register into
620 ; two adjacent 16-bit registers to make an SI value.  There is no MSP430X
621 ; instruction that will do this, so we push the 20-bit value onto the stack
622 ; and then pop it off as two 16-bit values.
624 ; FIXME: The MSP430X documentation does not specify if zero-extension or
625 ; sign-extension happens when the 20-bit value is pushed onto the stack.
626 ; It is probably zero-extension, but if not this pattern will not work
627 ; when the PSI value is negative..
629 ; Note: using PUSHM.A #1 is two bytes smaller than using PUSHX.A....
631 ; Note: We use a + constraint on operand 0 as otherwise GCC gets confused
632 ; about extending a single PSI mode register into a pair of SImode registers
633 ; with the same starting register.  It thinks that the upper register of
634 ; the pair is unused and so it can clobber it.  Try compiling 20050826-2.c
635 ; at -O2 to see this.
637 (define_insn "zero_extendpsisi2"
638   [(set (match_operand:SI                  0 "register_operand" "+r")
639         (zero_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
640   ""
641   "*
642     if (REGNO (operands[1]) == SP_REGNO)
643       /* If the source register is the stack pointer, the value
644          stored in the stack slot will be the value *after* the
645          stack pointer has been decremented.  So allow for that
646          here.  */
647       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\";
648     else
649       return \"PUSHM.A\t#1, %1 { POPX.W\t%L0 { POPX.W\t%H0 ; move pointer in %1 into reg-pair %L0:%H0\";
650   "
653 ;; We also need to be able to sign-extend pointer types (eg ptrdiff_t).
654 ;; Since (we assume) pushing a 20-bit value onto the stack zero-extends
655 ;; it, we use a different method here.
657 (define_insn "extendpsisi2"
658   [(set (match_operand:SI                  0 "register_operand" "=r")
659         (sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
660   "msp430x"
661   "*
662     /* The intention here is that we copy the bottom 16-bits of
663        %1 into %L0 (zeroing the top four bits).  Then we copy the
664        entire 20-bits of %1 into %H0 and then arithmetically shift
665        it right by 16 bits, to get the top four bits of the pointer
666        sign-extended in %H0.  */
667     if (REGNO (operands[0]) == REGNO (operands[1]))
668       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\";
669     else
670       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\";
671   "
674 ; See the movsipsi2 pattern above for another way that GCC performs this
675 ; conversion.
676 (define_insn "truncsipsi2"
677   [(set (match_operand:PSI              0 "register_operand" "=r")
678         (truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
679   ""
680   "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A\t#1, %L0"
683 ;;------------------------------------------------------------
684 ;; Shift Functions
686 ;; Note:  We do not use the RPT ... SHIFT instruction sequence
687 ;; when the repeat count is in a register, because even though RPT
688 ;; accepts counts in registers, it does not work if the count is
689 ;; zero, and the actual count in the register has to be one less
690 ;; than the required number of iterations.  We could encode a
691 ;; seqeunce like this:
693 ;;   bit #0xf, Rn
694 ;;   bz  1f
695 ;;   dec Rn
696 ;;   rpt Rn
697 ;;   <shift> Rm
698 ;;   inc Rn
699 ;; 1:
701 ;; But is longer than calling a helper function, and we are mostly
702 ;; concerned with code size.  FIXME: Maybe enable a sequence like
703 ;; this at -O3 and above ?
705 ;; Note - we ignore shift counts of less than one or more than 15.
706 ;; This is permitted by the ISO C99 standard as such shifts result
707 ;; in "undefined" behaviour.  [6.5.7 (3)]
709 ;; signed A << C
711 (define_expand "ashlhi3"
712   [(set (match_operand:HI            0 "nonimmediate_operand")
713         (ashift:HI (match_operand:HI 1 "general_operand")
714                    (match_operand:HI 2 "general_operand")))]
715   ""
716   {
717     if (msp430x
718         && REG_P (operands[0])
719         && REG_P (operands[1])
720         && CONST_INT_P (operands[2]))
721       emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2]));
722     else                 
723       msp430_expand_helper (operands, \"__mspabi_slli\", true);
724     DONE;
725   }
728 (define_insn "slli_1"
729   [(set (match_operand:HI            0 "nonimmediate_operand" "=rm")
730         (ashift:HI (match_operand:HI 1 "general_operand"       "0")
731                    (const_int 1)))]
732   ""
733   "RLA.W\t%0" ;; Note - this is a macro for ADD
736 (define_insn "430x_shift_left"
737   [(set (match_operand:HI            0 "register_operand" "=r")
738         (ashift:HI (match_operand:HI 1 "register_operand"  "0")
739                    (match_operand    2 "immediate_operand" "n")))]
740   "msp430x"
741   "*
742   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
743     return \"rpt\t%2 { rlax.w\t%0\";
744   return \"# nop left shift\";
745   "
748 (define_insn "slll_1"
749   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
750         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
751                    (const_int 1)))]
752   ""
753   "RLA.W\t%L0 { RLC.W\t%H0"
756 (define_insn "slll_2"
757   [(set (match_operand:SI            0 "nonimmediate_operand" "=rm")
758         (ashift:SI (match_operand:SI 1 "general_operand"       "0")
759                    (const_int 2)))]
760   ""
761   "RLA.W\t%L0 { RLC.W\t%H0 { RLA.W\t%L0 { RLC.W\t%H0"
764 (define_expand "ashlsi3"
765   [(set (match_operand:SI            0 "nonimmediate_operand")
766         (ashift:SI (match_operand:SI 1 "general_operand")
767                    (match_operand:SI 2 "general_operand")))]
768   ""
769   "msp430_expand_helper (operands, \"__mspabi_slll\", true);
770    DONE;"
773 ;;----------
775 ;; signed A >> C
777 (define_expand "ashrhi3"
778   [(set (match_operand:HI              0 "nonimmediate_operand")
779         (ashiftrt:HI (match_operand:HI 1 "general_operand")
780                      (match_operand:HI 2 "general_operand")))]
781   ""
782   {
783     if (msp430x
784         && REG_P (operands[0])
785         && REG_P (operands[1])
786         && CONST_INT_P (operands[2]))
787       emit_insn (gen_430x_arithmetic_shift_right (operands[0], operands[1], operands[2]));
788     else                 
789        msp430_expand_helper (operands, \"__mspabi_srai\", true);
790    DONE;
791    }
794 (define_insn "srai_1"
795   [(set (match_operand:HI              0 "msp_nonimmediate_operand" "=rm")
796         (ashiftrt:HI (match_operand:HI 1 "msp_general_operand"      "0")
797                      (const_int 1)))]
798   ""
799   "RRA.W\t%0"
802 (define_insn "430x_arithmetic_shift_right"
803   [(set (match_operand:HI              0 "register_operand" "=r")
804         (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0")
805                      (match_operand    2 "immediate_operand" "n")))]
806   "msp430x"
807   "*
808   if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
809     return \"rpt\t%2 { rrax.w\t%0\";
810   return \"# nop arith right shift\";
811   "
814 (define_insn "srap_1"
815   [(set (match_operand:PSI              0 "register_operand" "=r")
816         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
817                       (const_int 1)))]
818   "msp430x"
819   "RRAM.A #1,%0"
822 (define_insn "srap_2"
823   [(set (match_operand:PSI              0 "register_operand" "=r")
824         (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
825                       (const_int 2)))]
826   "msp430x"
827   "RRAM.A #2,%0"
830 (define_insn "sral_1"
831   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
832         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
833                      (const_int 1)))]
834   ""
835   "RRA.W\t%H0 { RRC.W\t%L0"
838 (define_insn "sral_2"
839   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
840         (ashiftrt:SI (match_operand:SI 1 "general_operand"       "0")
841                      (const_int 2)))]
842   ""
843   "RRA.W\t%H0 { RRC.W\t%L0 { RRA.W\t%H0 { RRC.W\t%L0"
846 (define_expand "ashrsi3"
847   [(set (match_operand:SI              0 "nonimmediate_operand")
848         (ashiftrt:SI (match_operand:SI 1 "general_operand")
849                      (match_operand:SI 2 "general_operand")))]
850   ""
851   "msp430_expand_helper (operands, \"__mspabi_sral\", true);
852    DONE;"
855 ;;----------
857 ;; unsigned A >> C
859 (define_expand "lshrhi3"
860   [(set (match_operand:HI              0 "nonimmediate_operand")
861         (lshiftrt:HI (match_operand:HI 1 "general_operand")
862                      (match_operand:HI 2 "general_operand")))]
863   ""
864   {
865     if (msp430x
866         && REG_P (operands[0])
867         && REG_P (operands[1])
868         && CONST_INT_P (operands[2]))
869       emit_insn (gen_430x_logical_shift_right (operands[0], operands[1], operands[2]));
870     else                 
871       msp430_expand_helper (operands, \"__mspabi_srli\", true);
872     DONE;
873   }
876 (define_insn "srli_1"
877   [(set (match_operand:HI              0 "nonimmediate_operand" "=rm")
878         (lshiftrt:HI (match_operand:HI 1 "general_operand"       "0")
879                      (const_int 1)))]
880   ""
881   "CLRC { RRC.W\t%0"
884 (define_insn "430x_logical_shift_right"
885   [(set (match_operand:HI              0 "register_operand" "=r")
886         (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0")
887                      (match_operand    2 "immediate_operand" "n")))]
888   "msp430x"
889   {
890     return msp430x_logical_shift_right (operands[2]);
891   }
894 (define_insn "srlp_1"
895   [(set (match_operand:PSI              0 "register_operand" "=r")
896         (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
897                       (const_int 1)))]
898   ""
899   "RRUM.A #1,%0"
902 (define_insn "srll_1"
903   [(set (match_operand:SI              0 "nonimmediate_operand" "=rm")
904         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
905                      (const_int 1)))]
906   ""
907   "CLRC { RRC.W\t%H0 { RRC.W\t%L0"
910 (define_insn "srll_2x"
911   [(set (match_operand:SI              0 "nonimmediate_operand" "=r")
912         (lshiftrt:SI (match_operand:SI 1 "general_operand"       "0")
913                      (const_int 2)))]
914   "msp430x"
915   "RRUX.W\t%H0 { RRC.W\t%L0 { RRUX.W\t%H0 { RRC.W\t%L0"
918 (define_expand "lshrsi3"
919   [(set (match_operand:SI              0 "nonimmediate_operand")
920         (lshiftrt:SI (match_operand:SI 1 "general_operand")
921                      (match_operand:SI 2 "general_operand")))]
922   ""
923   "msp430_expand_helper (operands, \"__mspabi_srll\", true);
924    DONE;"
927 ;;------------------------------------------------------------
928 ;; Function Entry/Exit
930 (define_expand "prologue"
931   [(const_int 0)]
932   ""
933   "msp430_expand_prologue (); DONE;"
934   )
936 (define_expand "epilogue"
937   [(const_int 0)]
938   ""
939   "msp430_expand_epilogue (0); DONE;"
940   )
943 (define_insn "epilogue_helper"
944   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)]
945   ""
946   "BR%Q0\t#__mspabi_func_epilog_%J0"
947   )
950 (define_insn "prologue_start_marker"
951   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)]
952   ""
953   "; start of prologue"
954   )
956 (define_insn "prologue_end_marker"
957   [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)]
958   ""
959   "; end of prologue"
960   )
962 (define_insn "epilogue_start_marker"
963   [(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)]
964   ""
965   "; start of epilogue"
966   )
968 ;; This makes the linker add a call to exit() after the call to main()
969 ;; in crt0
970 (define_insn "msp430_refsym_need_exit"
971   [(unspec_volatile [(const_int 0)] UNS_REFSYM_NEED_EXIT)]
972   ""
973   ".refsym\t__crt0_call_exit"
974   )
976 ;;------------------------------------------------------------
977 ;; Jumps
979 (define_expand "call"
980   [(call:HI (match_operand 0 "")
981             (match_operand 1 ""))]
982   ""
983   ""
986 (define_insn "call_internal"
987   [(call (mem:HI (match_operand 0 "general_operand" "rYci"))
988          (match_operand 1 ""))]
989   ""
990   "CALL%Q0\t%0"
993 (define_expand "call_value"
994   [(set (match_operand          0 "register_operand")
995         (call:HI (match_operand 1 "general_operand")
996                  (match_operand 2 "")))]
997   ""
998   ""
1001 (define_insn "call_value_internal"
1002   [(set (match_operand               0 "register_operand" "=r")
1003         (call (mem:HI (match_operand 1 "general_operand" "rYci"))
1004               (match_operand 2 "")))]
1005   ""
1006   "CALL%Q0\t%1"
1009 (define_insn "msp_return"
1010   [(return)]
1011   ""
1012   { return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); }
1015 ;; This pattern is NOT, as expected, a return pattern.  It's called
1016 ;; before reload and must only store its operands, and emit a
1017 ;; placeholder where the epilog needs to be.  AFTER reload, the
1018 ;; placeholder should get expanded into a regular-type epilogue that
1019 ;; also does the EH return.
1020 (define_expand "eh_return"
1021   [(match_operand:HI 0 "")]
1022   ""
1023   "msp430_expand_eh_return (operands[0]);
1024    emit_jump_insn (gen_msp430_eh_epilogue ());
1025    emit_barrier ();
1026    DONE;"
1029 ;; This is the actual EH epilogue.  We emit it in the pattern above,
1030 ;; before reload, and convert it to a real epilogue after reload.
1031 (define_insn_and_split "msp430_eh_epilogue"
1032   [(eh_return)]
1033   ""
1034   "#"
1035   "reload_completed"
1036   [(const_int 0)]
1037   "msp430_expand_epilogue (1); DONE;"
1038   )
1040 (define_insn "jump"
1041   [(set (pc)
1042         (label_ref (match_operand 0 "" "")))]
1043   ""
1044   "BR%Q0\t#%l0"
1047 ;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
1048 ;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c).
1049 (define_insn "indirect_jump"
1050   [(set (pc)
1051         (match_operand 0 "nonimmediate_operand" "rYl"))]
1052   ""
1053   "BR%Q0\t%0"
1056 ;;------------------------------------------------------------
1057 ;; Various Conditionals
1059 (define_expand "cbranch<mode>4"
1060   [(parallel [(set (pc) (if_then_else
1061                          (match_operator 0 ""
1062                                          [(match_operand:QHI 1 "nonimmediate_operand")
1063                                           (match_operand:QHI 2 "general_operand")])
1064                          (label_ref (match_operand 3 "" ""))
1065                          (pc)))
1066               (clobber (reg:BI CARRY))]
1067   )]
1068   ""
1069   "msp430_fixup_compare_operands (<MODE>mode, operands);"
1070   )
1072 (define_insn "cbranchpsi4_real"
1073   [(set (pc) (if_then_else
1074               (match_operator                     0 "msp430_cmp_operator"
1075                               [(match_operand:PSI 1 "nonimmediate_operand" "r,rYs,rm")
1076                                (match_operand:PSI 2 "general_operand"      "rLs,rYsi,rmi")])
1077               (label_ref (match_operand           3 "" ""))
1078               (pc)))
1079    (clobber (reg:BI CARRY))
1080    ]
1081   ""
1082   "@
1083   CMP%Q0\t%2, %1 { J%0\t%l3
1084   CMPX.A\t%2, %1 { J%0\t%l3
1085   CMPX.A\t%2, %1 { J%0\t%l3"
1086   )
1088 (define_insn "cbranchqi4_real"
1089   [(set (pc) (if_then_else
1090               (match_operator                    0 "msp430_cmp_operator"
1091                               [(match_operand:QI 1 "nonimmediate_operand" "rYs,rm")
1092                                (match_operand:QI 2 "general_operand"      "rYsi,rmi")])
1093               (label_ref (match_operand          3 "" ""))
1094               (pc)))
1095    (clobber (reg:BI CARRY))
1096    ]
1097   ""
1098   "@
1099    CMP.B\t%2, %1 { J%0\t%l3
1100    CMP%X0.B\t%2, %1 { J%0\t%l3"
1101   )
1103 (define_insn "cbranchhi4_real"
1104   [(set (pc) (if_then_else
1105               (match_operator                    0 "msp430_cmp_operator"
1106                               [(match_operand:HI 1 "nonimmediate_operand" "rYs,rm")
1107                                (match_operand:HI 2 "general_operand"      "rYsi,rmi")])
1108               (label_ref (match_operand          3 "" ""))
1109               (pc)))
1110    (clobber (reg:BI CARRY))
1111    ]
1112   ""
1113   "@
1114    CMP.W\t%2, %1 { J%0\t%l3
1115    CMP%X0.W\t%2, %1 { J%0\t%l3"
1116   )
1118 (define_insn "cbranchpsi4_reversed"
1119   [(set (pc) (if_then_else
1120               (match_operator                     0 "msp430_reversible_cmp_operator"
1121                               [(match_operand:PSI 1 "general_operand" "rLs,rYsi,rmi")
1122                                (match_operand:PSI 2 "general_operand" "r,rYs,rm")])
1123               (label_ref (match_operand           3 "" ""))
1124               (pc)))
1125    (clobber (reg:BI CARRY))
1126    ]
1127   ""
1128   "@
1129   CMP%Q0\t%1, %2 { J%R0\t%l3
1130   CMPX.A\t%1, %2 { J%R0\t%l3
1131   CMPX.A\t%1, %2 { J%R0\t%l3"
1132   )
1134 (define_insn "cbranchqi4_reversed"
1135   [(set (pc) (if_then_else
1136               (match_operator                    0 "msp430_reversible_cmp_operator"
1137                               [(match_operand:QI 1 "general_operand" "rYsi,rmi")
1138                                (match_operand:QI 2 "general_operand" "rYs,rm")])
1139               (label_ref (match_operand          3 "" ""))
1140               (pc)))
1141    (clobber (reg:BI CARRY))
1142    ]
1143   ""
1144   "@
1145    CMP.B\t%1, %2 { J%R0\t%l3
1146    CMP%X0.B\t%1, %2 { J%R0\t%l3"
1147   )
1149 (define_insn "cbranchhi4_reversed"
1150   [(set (pc) (if_then_else
1151               (match_operator                    0 "msp430_reversible_cmp_operator"
1152                               [(match_operand:HI 1 "general_operand" "rYsi,rmi")
1153                                (match_operand:HI 2 "general_operand" "rYs,rm")])
1154               (label_ref (match_operand          3 "" ""))
1155               (pc)))
1156    (clobber (reg:BI CARRY))
1157    ]
1158   ""
1159   "@
1160    CMP.W\t%1, %2 { J%R0\t%l3
1161    CMP%X0.W\t%1, %2 { J%R0\t%l3"
1162   )
1164 (define_insn "*bitbranch<mode>4"
1165   [(set (pc) (if_then_else
1166               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1167                            (match_operand:QHI 1 "msp_general_operand" "rYsi,rmi"))
1168                   (const_int 0))
1169               (label_ref (match_operand 2 "" ""))
1170               (pc)))
1171    (clobber (reg:BI CARRY))
1172    ]
1173   ""
1174   "@
1175    BIT%x0%b0\t%1, %0 { JNE\t%l2
1176    BIT%X0%b0\t%1, %0 { JNE\t%l2"
1177   )
1179 (define_insn "*bitbranch<mode>4"
1180   [(set (pc) (if_then_else
1181               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1182                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1183                   (const_int 0))
1184               (label_ref (match_operand 2 "" ""))
1185               (pc)))
1186    (clobber (reg:BI CARRY))
1187    ]
1188   ""
1189   "BIT%x0%b0\t%1, %0 { JEQ\t%l2"
1190   )
1192 (define_insn "*bitbranch<mode>4"
1193   [(set (pc) (if_then_else
1194               (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1195                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1196                   (const_int 0))
1197               (pc)
1198               (label_ref (match_operand 2 "" ""))))
1199    (clobber (reg:BI CARRY))
1200    ]
1201   ""
1202   "BIT%X0%b0\t%1, %0 { JNE\t%l2"
1203   )
1205 (define_insn "*bitbranch<mode>4"
1206   [(set (pc) (if_then_else
1207               (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1208                            (match_operand:QHI 1 "msp_general_operand" "rmi"))
1209                   (const_int 0))
1210               (pc)
1211               (label_ref (match_operand 2 "" ""))))
1212    (clobber (reg:BI CARRY))
1213    ]
1214   ""
1215   "BIT%X0%b0\t%1, %0 { JEQ\t%l2"
1216   )
1218 ;;------------------------------------------------------------
1219 ;; zero-extract versions of the above
1221 (define_insn "*bitbranch<mode>4_z"
1222   [(set (pc) (if_then_else
1223               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1224                                     (const_int 1)
1225                                     (match_operand 1 "msp430_bitpos" "i,i"))
1226                   (const_int 0))
1227               (label_ref (match_operand 2 "" ""))
1228               (pc)))
1229    (clobber (reg:BI CARRY))
1230    ]
1231   ""
1232   "@
1233    BIT%x0%b0\t%p1, %0 { JNE\t%l2
1234    BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1235   )
1237 (define_insn "*bitbranch<mode>4_z"
1238   [(set (pc) (if_then_else
1239               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1240                                    (const_int 1)
1241                                    (match_operand 1 "msp430_bitpos" "i"))
1242                   (const_int 0))
1243               (label_ref (match_operand 2 "" ""))
1244               (pc)))
1245    (clobber (reg:BI CARRY))
1246    ]
1247   ""
1248   "BIT%x0%X0%b0\t%p1, %0 { JEQ\t%l2"
1249   )
1251 (define_insn "*bitbranch<mode>4_z"
1252   [(set (pc) (if_then_else
1253               (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1254                                    (const_int 1)
1255                                    (match_operand 1 "msp430_bitpos" "i"))
1256                   (const_int 0))
1257               (pc)
1258               (label_ref (match_operand 2 "" ""))))
1259    (clobber (reg:BI CARRY))
1260    ]
1261   ""
1262   "BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1263   )
1265 (define_insn "*bitbranch<mode>4_z"
1266   [(set (pc) (if_then_else
1267               (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1268                                    (const_int 1)
1269                                    (match_operand 1 "msp430_bitpos" "i"))
1270                   (const_int 0))
1271               (pc)
1272               (label_ref (match_operand 2 "" ""))))
1273    (clobber (reg:BI CARRY))
1274    ]
1275   ""
1276   "BIT%X0%b0\t%p1, %0 { JEQ\t%l2"
1277   )
1279 ;;------------------------------------------------------------
1280 ;; Misc
1282 (define_insn "nop"
1283   [(const_int 0)]
1284   "1"
1285   "NOP"
1288 (define_insn "disable_interrupts"
1289   [(unspec_volatile [(const_int 0)] UNS_DINT)]
1290   ""
1291   "DINT \; NOP"
1292   )
1294 (define_insn "enable_interrupts"
1295   [(unspec_volatile [(const_int 0)] UNS_EINT)]
1296   ""
1297   "EINT"
1298   )
1300 (define_insn "push_intr_state"
1301   [(unspec_volatile [(const_int 0)] UNS_PUSH_INTR)]
1302   ""
1303   "PUSH\tSR"
1304   )
1306 (define_insn "pop_intr_state"
1307   [(unspec_volatile [(const_int 0)] UNS_POP_INTR)]
1308   ""
1309   "POP\tSR"
1310   )
1312 ;; Clear bits in the copy of the status register that is currently
1313 ;; saved on the stack at the top of the interrupt handler.
1314 (define_insn "bic_SR"
1315   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIC_SR)]
1316   ""
1317   "BIC.W\t%0, %O0(SP)"
1318   )
1320 ;; Set bits in the copy of the status register that is currently
1321 ;; saved on the stack at the top of the interrupt handler.
1322 (define_insn "bis_SR"
1323   [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIS_SR)]
1324   ""
1325   "BIS.W\t%0, %O0(SP)"
1326   )
1328 ;; For some reason GCC is generating (set (reg) (and (neg (reg)) (int)))
1329 ;; very late on in the compilation and not splitting it into separate
1330 ;; instructions, so we provide a pattern to support it here.
1331 (define_insn "andneghi3"
1332   [(set (match_operand:HI                 0 "register_operand" "=r")
1333         (and:HI (neg:HI (match_operand:HI 1 "register_operand"  "r"))
1334                 (match_operand            2 "immediate_operand" "n")))]
1335   ""
1336   "*
1337     if (REGNO (operands[0]) != REGNO (operands[1]))
1338       return \"MOV.W\t%1, %0 { INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0\";
1339     else
1340       return \"INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0\";
1341   "
1342   )
1344 (define_insn "delay_cycles_start"
1345   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
1346                     UNS_DELAY_START)]
1347   ""
1348   "; Begin %J0 cycle delay"
1349   )
1351 (define_insn "delay_cycles_end"
1352   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
1353                     UNS_DELAY_END)]
1354   ""
1355   "; End %J0 cycle delay"
1356   )
1358 (define_insn "delay_cycles_32"
1359   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1360                      (match_operand 1 "immediate_operand" "i")
1361                      ] UNS_DELAY_32)]
1362   ""
1363   "PUSH r13
1364         PUSH    r14
1365         MOV.W   %A0, r13
1366         MOV.W   %B0, r14
1367 1:      SUB.W   #1, r13
1368         SUBC.W  #0, r14
1369         JNE     1b
1370         TST.W   r13
1371         JNE     1b
1372         POP     r14
1373         POP     r13"
1374   )
1376 (define_insn "delay_cycles_32x"
1377   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1378                      (match_operand 1 "immediate_operand" "i")
1379                      ] UNS_DELAY_32X)]
1380   ""
1381   "PUSHM.A      #2,r13
1382         MOV.W   %A0, r13
1383         MOV.W   %B0, r14
1384 1:      SUB.W   #1, r13
1385         SUBC.W  #0, r14
1386         JNE     1b
1387         TST.W   r13
1388         JNE     1b
1389         POPM.A  #2,r13"
1390   )
1392 (define_insn "delay_cycles_16"
1393   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1394                      (match_operand 1 "immediate_operand" "i")
1395                      ] UNS_DELAY_16)]
1396   ""
1397   "PUSH r13
1398         MOV.W   %0, r13
1399 1:      SUB.W   #1, r13
1400         JNE     1b
1401         POP     r13"
1402   )
1404 (define_insn "delay_cycles_16x"
1405   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")
1406                      (match_operand 1 "immediate_operand" "i")
1407                      ] UNS_DELAY_16X)]
1408   ""
1409   "PUSHM.A      #1,r13
1410         MOV.W   %0, r13
1411 1:      SUB.W   #1, r13
1412         JNE     1b
1413         POPM.A  #1,r13"
1414   )
1416 (define_insn "delay_cycles_2"
1417   [(unspec_volatile [(const_int 0) ] UNS_DELAY_2)]
1418   ""
1419   "JMP  .+2"
1420   )
1422 (define_insn "delay_cycles_1"
1423   [(unspec_volatile [(const_int 0) ] UNS_DELAY_1)]
1424   ""
1425   "NOP"
1426   )
1428 (define_insn "mulhisi3"
1429   [(set (match_operand:SI                          0 "register_operand" "=r")
1430         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1431                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1432   "optimize > 2 && msp430_hwmult_type != NONE"
1433   "*
1434     if (msp430_use_f5_series_hwmult ())
1435       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\";
1436     else
1437       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\";
1438   "
1441 (define_insn "umulhisi3"
1442   [(set (match_operand:SI                          0 "register_operand" "=r")
1443         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1444                  (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1445   "optimize > 2 && msp430_hwmult_type != NONE"
1446   "*
1447     if (msp430_use_f5_series_hwmult ())
1448       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\";
1449     else
1450       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\";
1451   "
1454 (define_insn "mulsidi3"
1455   [(set (match_operand:DI                          0 "register_operand" "=r")
1456         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1457                  (sign_extend:DI (match_operand:SI 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 %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\";
1462     else
1463       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\";
1464   "
1467 (define_insn "umulsidi3"
1468   [(set (match_operand:DI                          0 "register_operand" "=r")
1469         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1470                  (zero_extend:DI (match_operand:SI 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 %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\";
1475     else
1476       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\";
1477   "