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)
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/>.
29 (define_c_enum "unspec"
31 UNS_PROLOGUE_START_MARKER
32 UNS_PROLOGUE_END_MARKER
33 UNS_EPILOGUE_START_MARKER
52 (include "predicates.md")
53 (include "constraints.md")
55 (define_mode_iterator QHI [QI HI PSI])
57 ;; There are two basic "family" tests we do here:
59 ;; msp430x - true if 430X instructions are available.
60 ;; TARGET_LARGE - true if pointers are 20-bits
62 ;; Note that there are three supported cases, since the base 430
63 ;; doesn't have 20-bit pointers:
65 ;; 1. MSP430 cpu, small model
66 ;; 2. MSP430X cpu, small model.
67 ;; 3. MSP430X cpu, large model.
69 ;;------------------------------------------------------------
72 ;; Push/Pop must be before the generic move patterns
75 [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO)))
76 (match_operand:HI 0 "register_operand" "r"))]
82 [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO)))
83 (match_operand:PSI 0 "register_operand" "r"))]
89 [(unspec_volatile [(match_operand 0 "register_operand" "r")
90 (match_operand 1 "immediate_operand" "n")] UNS_PUSHM)]
96 [(set (match_operand:HI 0 "register_operand" "=r")
97 (mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
103 [(set (match_operand:PSI 0 "register_operand" "=r")
104 (mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))]
109 ;; This is nasty. Operand0 is bogus. It is only there so that we can get a
110 ;; mode for the %b0 to work. We should use operand1 for this, but that does
113 ;; Operand1 is actually a register, but we cannot accept (REG...) because the
114 ;; cprop_hardreg pass can and will renumber registers even inside
115 ;; unspec_volatiles. So we take an integer register number parameter and
116 ;; fudge it to be a register name when we generate the assembler.
118 ;; The pushm pattern does not have this problem because of all of the
119 ;; frame info cruft attached to it, so cprop_hardreg leaves it alone.
121 [(unspec_volatile [(match_operand 0 "register_operand" "r")
122 (match_operand 1 "immediate_operand" "i")
123 (match_operand 2 "immediate_operand" "i")] UNS_POPM)]
128 ;; The next two patterns are here to support a "feature" of how GCC implements
129 ;; varargs. When a function uses varargs and the *second* to last named
130 ;; argument is split between argument registers and the stack, gcc expects the
131 ;; callee to allocate space on the stack that can contain the register-based
132 ;; part of the argument. This space *has* to be just before the remaining
133 ;; arguments (ie the ones that are fully on the stack).
135 ;; The problem is that the MSP430 CALL instruction pushes the return address
136 ;; onto the stack in the exact place where the callee wants to allocate
137 ;; this extra space. So we need a sequence of instructions that can allocate
138 ;; the extra space and then move the return address down the stack, so that
139 ;; the extra space is now adjacent to the remaining arguments.
141 ;; This could be constructed through regular insns, but they might be split up
142 ;; by a misguided optimization, so an unspec volatile is used instead.
144 (define_insn "grow_and_swap"
145 [(unspec_volatile [(const_int 0)] UNS_GROW_AND_SWAP)]
148 return "SUBA\t#2, r1 \n MOVX.A\t2(r1), 0(r1)";
149 return "SUB\t#2, r1 \n MOV.W\t2(r1), 0(r1)";
153 (define_insn "swap_and_shrink"
154 [(unspec_volatile [(const_int 0)] UNS_SWAP_AND_SHRINK)]
156 { return TARGET_LARGE
157 ? "MOVX.A\t0(r1), 2(r1) \n ADDA\t#2, SP"
158 : "MOV.W\t0(r1), 2(r1) \n ADD\t#2, SP";
161 ; I set LOAD_EXTEND_OP and WORD_REGISTER_OPERATIONS, but gcc puts in a
162 ; zero_extend anyway. Catch it here.
163 (define_insn "movqihi"
164 [(set (match_operand:HI 0 "register_operand" "=r,r")
165 (zero_extend:HI (match_operand:QI 1 "memory_operand" "Ys,m")))]
173 [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm")
174 (match_operand:QI 1 "msp_general_operand" "riYs,rmi"))]
182 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm")
183 (match_operand:HI 1 "msp_general_operand" "riYs,rmi"))]
190 (define_expand "movsi"
191 [(set (match_operand:SI 0 "nonimmediate_operand")
192 (match_operand:SI 1 "general_operand"))]
197 (define_insn_and_split "movsi_x"
198 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
199 (match_operand:SI 1 "general_operand" "rmi"))]
203 [(set (match_operand:HI 2 "nonimmediate_operand")
204 (match_operand:HI 4 "general_operand"))
205 (set (match_operand:HI 3 "nonimmediate_operand")
206 (match_operand:HI 5 "general_operand"))]
207 "msp430_split_movsi (operands);"
210 ;; Some MOVX.A cases can be done with MOVA, this is only a few of them.
211 (define_insn "movpsi"
212 [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,Ya,rm")
213 (match_operand:PSI 1 "msp_general_operand" "riYa,r,rmi"))]
220 ; This pattern is identical to the truncsipsi2 pattern except
221 ; that it uses a SUBREG instead of a TRUNC. It is needed in
222 ; order to prevent reload from converting (set:SI (SUBREG:PSI (SI)))
223 ; into (SET:PSI (PSI)).
225 ; Note: using POPM.A #1 is two bytes smaller than using POPX.A....
227 (define_insn "movsipsi2"
228 [(set (match_operand:PSI 0 "register_operand" "=r")
229 (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
231 "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0"
234 ;;------------------------------------------------------------
237 (define_insn "addpsi3"
238 [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,rm")
239 (plus:PSI (match_operand:PSI 1 "msp_nonimmediate_operand" "%0,0")
240 (match_operand:PSI 2 "msp_general_operand" "rLs,rmi")))]
247 (define_insn "addqi3"
248 [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm")
249 (plus:QI (match_operand:QI 1 "msp_nonimmediate_operand" "%0,0")
250 (match_operand:QI 2 "msp_general_operand" "riYs,rmi")))]
257 (define_insn "addhi3"
258 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm")
259 (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
260 (match_operand:HI 2 "msp_general_operand" "riYs,rmi")))]
267 ; This pattern is needed in order to avoid reload problems.
268 ; It takes an SI pair of registers, adds a value to them, and
269 ; then converts them into a single PSI register.
271 (define_insn "addsipsi3"
272 [(set (subreg:SI (match_operand:PSI 0 "register_operand" "=&r") 0)
273 (plus:SI (match_operand:SI 1 "register_operand" "0")
274 (match_operand 2 "general_operand" "rmi")))]
276 "ADD.W\t%L2, %L0 { ADDC.W\t%H2, %H0 { PUSH.W\t%H0 { PUSH.W\t%L0 { POPM.A\t#1, %0"
279 (define_insn "addsi3"
280 [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,rm")
281 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
282 (match_operand:SI 2 "general_operand" "r,mi")))]
285 ADD\t%L2, %L0 { ADDC\t%H2, %H0
286 ADD%X0\t%L2, %L0 { ADDC%X0\t%H2, %H0"
289 ; Version of addhi that exposes the carry operations, for SImode adds.
291 ; NOTE - we are playing a dangerous game with GCC here. We have these two
292 ; add patterns and the splitter that follows because our tests have shown
293 ; that this results in a significant reduction in code size - because GCC is
294 ; able to discard any unused part of the addition. We have to annotate the
295 ; patterns with the set and use of the carry flag because otherwise GCC will
296 ; discard parts of the addition when they are actually needed. But we have
297 ; not annotated all the other patterns that set the CARRY flag as doing so
298 ; results in an overall increase in code size[1]. Instead we just *hope*
299 ; that GCC will not move a carry-setting instruction in between the first
302 ; So far our experiments have shown that GCC is likely to move MOV and CMP
303 ; instructions in between the two adds, but not other instructions. MOV is
304 ; safe, CMP is not. So we have annotated the CMP patterns and left the
305 ; subtract, shift and other add patterns alone. At the moment this is
306 ; working, but with future changes to the generic parts of GCC that might
309 ; [1] It is not clear exactly why the code size increases. The cause appears
310 ; to be that reload is more prevelent to spilling a variable onto the stack
311 ; but why it does this is unknown. Possibly the additional CLOBBERs necessary
312 ; to correctly annotate the other patterns makes reload think that there is
313 ; increased register pressure. Or possibly reload does not handle ADD patterns
314 ; that are not single_set() very well.
316 (define_insn "addhi3_cy"
317 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rm")
318 (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
319 (match_operand:HI 2 "msp_nonimmediate_operand" "r,rm")))
321 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
322 (zero_extend:SI (match_dup 2)))
331 (define_insn "addhi3_cy_i"
332 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
333 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
334 (match_operand:HI 2 "immediate_operand" "i,i")))
336 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
337 (match_operand 3 "immediate_operand" "i,i"))
346 ; Version of addhi that adds the carry, for SImode adds.
347 (define_insn "addchi4_cy"
348 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rm")
349 (plus:HI (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
350 (match_operand:HI 2 "msp_general_operand" "ri,rmi"))
351 (zero_extend:HI (reg:BI CARRY))))
359 ; Split an SImode add into two HImode adds, keeping track of the carry
360 ; so that gcc knows when it can and can't optimize away the two
363 [(set (match_operand:SI 0 "msp430_nonsubreg_operand")
364 (plus:SI (match_operand:SI 1 "nonimmediate_operand")
365 (match_operand:SI 2 "general_operand")))
368 [(parallel [(set (match_operand:HI 3 "nonimmediate_operand" "=&rm")
369 (plus:HI (match_dup 4)
372 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 4))
376 (set (match_operand:HI 6 "nonimmediate_operand" "=&rm")
377 (plus:HI (plus:HI (match_dup 7)
379 (zero_extend:HI (reg:BI CARRY))))
382 operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
383 operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
384 operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
385 operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
386 operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
387 operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
388 if (GET_CODE (operands[5]) == CONST_INT)
390 operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
394 operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
400 ;; Alternatives 2 and 3 are to handle cases generated by reload.
401 (define_insn "subpsi3"
402 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r, rm, &?r, ?&r")
403 (minus:PSI (match_operand:PSI 1 "general_operand" "0, 0, !r, !i")
404 (match_operand:PSI 2 "general_operand" "rLs, rmi, rmi, r")))]
409 MOVX.A\t%1, %0 { SUBX.A\t%2, %0
410 MOVX.A\t%1, %0 { SUBA\t%2, %0"
413 ;; Alternatives 2 and 3 are to handle cases generated by reload.
414 (define_insn "subqi3"
415 [(set (match_operand:QI 0 "nonimmediate_operand" "=rYs, rm, &?r, ?&r")
416 (minus:QI (match_operand:QI 1 "general_operand" "0, 0, !r, !i")
417 (match_operand:QI 2 "general_operand" " riYs, rmi, rmi, r")))]
422 MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0
423 MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0"
426 ;; Alternatives 2 and 3 are to handle cases generated by reload.
427 (define_insn "subhi3"
428 [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs, rm, &?r, ?&r")
429 (minus:HI (match_operand:HI 1 "general_operand" "0, 0, !r, !i")
430 (match_operand:HI 2 "general_operand" " riYs, rmi, rmi, r")))]
435 MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0
436 MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0"
439 (define_insn "subsi3"
440 [(set (match_operand:SI 0 "nonimmediate_operand" "=&rm")
441 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0")
442 (match_operand:SI 2 "general_operand" "rmi")))]
444 "SUB%X0\t%L2, %L0 { SUBC%X0\t%H2, %H0"
447 (define_insn "*bic<mode>_cg"
448 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m")
449 (and:QHI (match_operand:QHI 1 "msp_general_operand" "0,0")
450 (match_operand 2 "msp430_inv_constgen_operator" "n,n")))]
457 (define_insn "bic<mode>3"
458 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
459 (and:QHI (not:QHI (match_operand:QHI 1 "msp_general_operand" "rYs,rmn"))
460 (match_operand:QHI 2 "msp_nonimmediate_operand" "0,0")))]
467 (define_insn "and<mode>3"
468 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
469 (and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
470 (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
477 (define_insn "ior<mode>3"
478 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
479 (ior:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
480 (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
487 (define_insn "xor<mode>3"
488 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
489 (xor:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
490 (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
497 ;; Macro : XOR #~0, %0
498 (define_insn "one_cmpl<mode>2"
499 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m")
500 (not:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "0,0")))]
507 (define_insn "extendqihi2"
508 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,m")
509 (sign_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
516 (define_insn "zero_extendqihi2"
517 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,m")
518 (zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
525 ;; Eliminate extraneous zero-extends mysteriously created by gcc.
527 [(set (match_operand:HI 0 "register_operand")
528 (zero_extend:HI (match_operand:QI 1 "general_operand")))
529 (set (match_operand:HI 2 "register_operand")
530 (zero_extend:HI (match_operand:QI 3 "register_operand")))]
531 "REGNO (operands[0]) == REGNO (operands[2]) && REGNO (operands[2]) == REGNO (operands[3])"
533 (zero_extend:HI (match_dup 1)))]
536 (define_insn "zero_extendhipsi2"
537 [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,m")
538 (zero_extend:PSI (match_operand:HI 1 "msp_nonimmediate_operand" "rm,r")))]
543 (define_insn "truncpsihi2"
544 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rm")
545 (truncate:HI (match_operand:PSI 1 "register_operand" "r")))]
550 (define_insn "extendhisi2"
551 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
552 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
554 { return msp430x_extendhisi (operands); }
557 (define_insn "extendhipsi2"
558 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r")
559 (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))]
561 "RLAM #4, %0 { RRAM #4, %0"
564 ;; Look for cases where integer/pointer conversions are suboptimal due
565 ;; to missing patterns, despite us not having opcodes for these
566 ;; patterns. Doing these manually allows for alternate optimization
568 (define_insn "zero_extendhisi2"
569 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
570 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
575 (define_insn "zero_extendhisipsi2"
576 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r")
577 (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))]
584 (define_insn "extend_and_shift1_hipsi2"
585 [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
586 (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
589 "RLAM #4, %0 { RRAM #3, %0"
592 (define_insn "extend_and_shift2_hipsi2"
593 [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
594 (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
597 "RLAM #4, %0 { RRAM #2, %0"
600 ; Nasty - we are sign-extending a 20-bit PSI value in one register into
601 ; two adjacent 16-bit registers to make an SI value. There is no MSP430X
602 ; instruction that will do this, so we push the 20-bit value onto the stack
603 ; and then pop it off as two 16-bit values.
605 ; FIXME: The MSP430X documentation does not specify if zero-extension or
606 ; sign-extension happens when the 20-bit value is pushed onto the stack.
607 ; It is probably zero-extension, but if not this pattern will not work
608 ; when the PSI value is negative..
610 ; Note: using PUSHM.A #1 is two bytes smaller than using PUSHX.A....
612 (define_insn "zero_extendpsisi2"
613 [(set (match_operand:SI 0 "register_operand" "=r")
614 (zero_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
617 if (REGNO (operands[1]) == SP_REGNO)
618 /* If the source register is the stack pointer, the value
619 stored in the stack slot will be the value *after* the
620 stack pointer has been decremented. So allow for that
622 return \"PUSHM.A\t#1, %1 { ADDX.W\t#4, @r1 { POPX.W\t%L0 { POPX.W\t%H0 ; get stack pointer into %L0:%H0\";
624 return \"PUSHM.A\t#1, %1 { POPX.W\t%L0 { POPX.W\t%H0 ; move pointer in %1 into reg-pair %L0:%H0\";
628 ;; We also need to be able to sign-extend pointer types (eg ptrdiff_t).
629 ;; Since (we assume) pushing a 20-bit value onto the stack zero-extends
630 ;; it, we use a different method here.
632 (define_insn "extendpsisi2"
633 [(set (match_operand:SI 0 "register_operand" "=r")
634 (sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
637 /* The intention here is that we copy the bottom 16-bits of
638 %1 into %L0 (zeroing the top four bits). Then we copy the
639 entire 20-bits of %1 into %H0 and then arithmetically shift
640 it right by 16 bits, to get the top four bits of the pointer
641 sign-extended in %H0. */
642 if (REGNO (operands[0]) == REGNO (operands[1]))
643 return \"MOVX.A\t%1, %H0 { MOV.W\t%1, %L0 { RPT\t#16 { RRAX.A\t%H0 ; sign extend pointer in %1 into %L0:%H0\";
645 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\";
649 ; See the movsipsi2 pattern above for another way that GCC performs this
651 (define_insn "truncsipsi2"
652 [(set (match_operand:PSI 0 "register_operand" "=r")
653 (truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
655 "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A\t#1, %L0"
658 ;;------------------------------------------------------------
661 ;; Note: We do not use the RPT ... SHIFT instruction sequence
662 ;; when the repeat count is in a register, because even though RPT
663 ;; accepts counts in registers, it does not work if the count is
664 ;; zero, and the actual count in the register has to be one less
665 ;; than the required number of iterations. We could encode a
666 ;; seqeunce like this:
676 ;; But is longer than calling a helper function, and we are mostly
677 ;; concerned with code size. FIXME: Maybe enable a sequence like
678 ;; this at -O3 and above ?
680 ;; Note - we ignore shift counts of less than one or more than 15.
681 ;; This is permitted by the ISO C99 standard as such shifts result
682 ;; in "undefined" behaviour. [6.5.7 (3)]
686 (define_expand "ashlhi3"
687 [(set (match_operand:HI 0 "nonimmediate_operand")
688 (ashift:HI (match_operand:HI 1 "general_operand")
689 (match_operand:HI 2 "general_operand")))]
693 && REG_P (operands[0])
694 && REG_P (operands[1])
695 && CONST_INT_P (operands[2]))
696 emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2]));
698 msp430_expand_helper (operands, \"__mspabi_slli\", true);
703 (define_insn "slli_1"
704 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
705 (ashift:HI (match_operand:HI 1 "general_operand" "0")
708 "RLA.W\t%0" ;; Note - this is a macro for ADD
711 (define_insn "430x_shift_left"
712 [(set (match_operand:HI 0 "register_operand" "=r")
713 (ashift:HI (match_operand:HI 1 "register_operand" "0")
714 (match_operand 2 "immediate_operand" "n")))]
717 if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
718 return \"rpt\t%2 { rlax.w\t%0\";
719 return \"# nop left shift\";
723 (define_insn "slll_1"
724 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
725 (ashift:SI (match_operand:SI 1 "general_operand" "0")
728 "RLA.W\t%L0 { RLC.W\t%H0"
731 (define_insn "slll_2"
732 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
733 (ashift:SI (match_operand:SI 1 "general_operand" "0")
736 "RLA.W\t%L0 { RLC.W\t%H0 { RLA.W\t%L0 { RLC.W\t%H0"
739 (define_expand "ashlsi3"
740 [(set (match_operand:SI 0 "nonimmediate_operand")
741 (ashift:SI (match_operand:SI 1 "general_operand")
742 (match_operand:SI 2 "general_operand")))]
744 "msp430_expand_helper (operands, \"__mspabi_slll\", true);
752 (define_expand "ashrhi3"
753 [(set (match_operand:HI 0 "nonimmediate_operand")
754 (ashiftrt:HI (match_operand:HI 1 "general_operand")
755 (match_operand:HI 2 "general_operand")))]
759 && REG_P (operands[0])
760 && REG_P (operands[1])
761 && CONST_INT_P (operands[2]))
762 emit_insn (gen_430x_arithmetic_shift_right (operands[0], operands[1], operands[2]));
764 msp430_expand_helper (operands, \"__mspabi_srai\", true);
769 (define_insn "srai_1"
770 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rm")
771 (ashiftrt:HI (match_operand:HI 1 "msp_general_operand" "0")
777 (define_insn "430x_arithmetic_shift_right"
778 [(set (match_operand:HI 0 "register_operand" "=r")
779 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
780 (match_operand 2 "immediate_operand" "n")))]
783 if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
784 return \"rpt\t%2 { rrax.w\t%0\";
785 return \"# nop arith right shift\";
789 (define_insn "srap_1"
790 [(set (match_operand:PSI 0 "register_operand" "=r")
791 (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
797 (define_insn "srap_2"
798 [(set (match_operand:PSI 0 "register_operand" "=r")
799 (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
805 (define_insn "sral_1"
806 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
807 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
810 "RRA.W\t%H0 { RRC.W\t%L0"
813 (define_insn "sral_2"
814 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
815 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
818 "RRA.W\t%H0 { RRC.W\t%L0 { RRA.W\t%H0 { RRC.W\t%L0"
821 (define_expand "ashrsi3"
822 [(set (match_operand:SI 0 "nonimmediate_operand")
823 (ashiftrt:SI (match_operand:SI 1 "general_operand")
824 (match_operand:SI 2 "general_operand")))]
826 "msp430_expand_helper (operands, \"__mspabi_sral\", true);
834 (define_expand "lshrhi3"
835 [(set (match_operand:HI 0 "nonimmediate_operand")
836 (lshiftrt:HI (match_operand:HI 1 "general_operand")
837 (match_operand:HI 2 "general_operand")))]
841 && REG_P (operands[0])
842 && REG_P (operands[1])
843 && CONST_INT_P (operands[2]))
844 emit_insn (gen_430x_logical_shift_right (operands[0], operands[1], operands[2]));
846 msp430_expand_helper (operands, \"__mspabi_srli\", true);
851 (define_insn "srli_1"
852 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
853 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
859 (define_insn "430x_logical_shift_right"
860 [(set (match_operand:HI 0 "register_operand" "=r")
861 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
862 (match_operand 2 "immediate_operand" "n")))]
865 return msp430x_logical_shift_right (operands[2]);
869 (define_insn "srlp_1"
870 [(set (match_operand:PSI 0 "register_operand" "=r")
871 (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
877 (define_insn "srll_1"
878 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
879 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
882 "CLRC { RRC.W\t%H0 { RRC.W\t%L0"
885 (define_insn "srll_2x"
886 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
887 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
890 "RRUX.W\t%H0 { RRC.W\t%L0 { RRUX.W\t%H0 { RRC.W\t%L0"
893 (define_expand "lshrsi3"
894 [(set (match_operand:SI 0 "nonimmediate_operand")
895 (lshiftrt:SI (match_operand:SI 1 "general_operand")
896 (match_operand:SI 2 "general_operand")))]
898 "msp430_expand_helper (operands, \"__mspabi_srll\", true);
902 ;;------------------------------------------------------------
903 ;; Function Entry/Exit
905 (define_expand "prologue"
908 "msp430_expand_prologue (); DONE;"
911 (define_expand "epilogue"
914 "msp430_expand_epilogue (0); DONE;"
918 (define_insn "epilogue_helper"
919 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)]
921 "BR%Q0\t#__mspabi_func_epilog_%J0"
925 (define_insn "prologue_start_marker"
926 [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)]
928 "; start of prologue"
931 (define_insn "prologue_end_marker"
932 [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)]
937 (define_insn "epilogue_start_marker"
938 [(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)]
940 "; start of epilogue"
943 ;; This makes the linker add a call to exit() after the call to main()
945 (define_insn "msp430_refsym_need_exit"
946 [(unspec_volatile [(const_int 0)] UNS_REFSYM_NEED_EXIT)]
948 ".refsym\t__crt0_call_exit"
951 ;;------------------------------------------------------------
954 (define_expand "call"
955 [(call:HI (match_operand 0 "")
956 (match_operand 1 ""))]
961 (define_insn "call_internal"
962 [(call (mem:HI (match_operand 0 "general_operand" "rYci"))
963 (match_operand 1 ""))]
968 (define_expand "call_value"
969 [(set (match_operand 0 "register_operand")
970 (call:HI (match_operand 1 "general_operand")
971 (match_operand 2 "")))]
976 (define_insn "call_value_internal"
977 [(set (match_operand 0 "register_operand" "=r")
978 (call (mem:HI (match_operand 1 "general_operand" "rYci"))
979 (match_operand 2 "")))]
984 (define_insn "msp_return"
987 { return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); }
990 ;; This pattern is NOT, as expected, a return pattern. It's called
991 ;; before reload and must only store its operands, and emit a
992 ;; placeholder where the epilog needs to be. AFTER reload, the
993 ;; placeholder should get expanded into a regular-type epilogue that
994 ;; also does the EH return.
995 (define_expand "eh_return"
996 [(match_operand:HI 0 "")]
998 "msp430_expand_eh_return (operands[0]);
999 emit_jump_insn (gen_msp430_eh_epilogue ());
1004 ;; This is the actual EH epilogue. We emit it in the pattern above,
1005 ;; before reload, and convert it to a real epilogue after reload.
1006 (define_insn_and_split "msp430_eh_epilogue"
1012 "msp430_expand_epilogue (1); DONE;"
1017 (label_ref (match_operand 0 "" "")))]
1022 ;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
1023 ;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c).
1024 (define_insn "indirect_jump"
1026 (match_operand 0 "nonimmediate_operand" "rYl"))]
1031 ;;------------------------------------------------------------
1032 ;; Various Conditionals
1034 (define_expand "cbranch<mode>4"
1035 [(parallel [(set (pc) (if_then_else
1036 (match_operator 0 ""
1037 [(match_operand:QHI 1 "nonimmediate_operand")
1038 (match_operand:QHI 2 "general_operand")])
1039 (label_ref (match_operand 3 "" ""))
1041 (clobber (reg:BI CARRY))]
1044 "msp430_fixup_compare_operands (<MODE>mode, operands);"
1047 (define_insn "cbranchpsi4_real"
1048 [(set (pc) (if_then_else
1049 (match_operator 0 "msp430_cmp_operator"
1050 [(match_operand:PSI 1 "nonimmediate_operand" "r,rYs,rm")
1051 (match_operand:PSI 2 "general_operand" "rLs,rYsi,rmi")])
1052 (label_ref (match_operand 3 "" ""))
1054 (clobber (reg:BI CARRY))
1058 CMP%Q0\t%2, %1 { J%0\t%l3
1059 CMPX.A\t%2, %1 { J%0\t%l3
1060 CMPX.A\t%2, %1 { J%0\t%l3"
1063 (define_insn "cbranchqi4_real"
1064 [(set (pc) (if_then_else
1065 (match_operator 0 "msp430_cmp_operator"
1066 [(match_operand:QI 1 "nonimmediate_operand" "rYs,rm")
1067 (match_operand:QI 2 "general_operand" "rYsi,rmi")])
1068 (label_ref (match_operand 3 "" ""))
1070 (clobber (reg:BI CARRY))
1074 CMP.B\t%2, %1 { J%0\t%l3
1075 CMP%X0.B\t%2, %1 { J%0\t%l3"
1078 (define_insn "cbranchhi4_real"
1079 [(set (pc) (if_then_else
1080 (match_operator 0 "msp430_cmp_operator"
1081 [(match_operand:HI 1 "nonimmediate_operand" "rYs,rm")
1082 (match_operand:HI 2 "general_operand" "rYsi,rmi")])
1083 (label_ref (match_operand 3 "" ""))
1085 (clobber (reg:BI CARRY))
1089 CMP.W\t%2, %1 { J%0\t%l3
1090 CMP%X0.W\t%2, %1 { J%0\t%l3"
1093 (define_insn "cbranchpsi4_reversed"
1094 [(set (pc) (if_then_else
1095 (match_operator 0 "msp430_reversible_cmp_operator"
1096 [(match_operand:PSI 1 "general_operand" "rLs,rYsi,rmi")
1097 (match_operand:PSI 2 "general_operand" "r,rYs,rm")])
1098 (label_ref (match_operand 3 "" ""))
1100 (clobber (reg:BI CARRY))
1104 CMP%Q0\t%1, %2 { J%R0\t%l3
1105 CMPX.A\t%1, %2 { J%R0\t%l3
1106 CMPX.A\t%1, %2 { J%R0\t%l3"
1109 (define_insn "cbranchqi4_reversed"
1110 [(set (pc) (if_then_else
1111 (match_operator 0 "msp430_reversible_cmp_operator"
1112 [(match_operand:QI 1 "general_operand" "rYsi,rmi")
1113 (match_operand:QI 2 "general_operand" "rYs,rm")])
1114 (label_ref (match_operand 3 "" ""))
1116 (clobber (reg:BI CARRY))
1120 CMP.B\t%1, %2 { J%R0\t%l3
1121 CMP%X0.B\t%1, %2 { J%R0\t%l3"
1124 (define_insn "cbranchhi4_reversed"
1125 [(set (pc) (if_then_else
1126 (match_operator 0 "msp430_reversible_cmp_operator"
1127 [(match_operand:HI 1 "general_operand" "rYsi,rmi")
1128 (match_operand:HI 2 "general_operand" "rYs,rm")])
1129 (label_ref (match_operand 3 "" ""))
1131 (clobber (reg:BI CARRY))
1135 CMP.W\t%1, %2 { J%R0\t%l3
1136 CMP%X0.W\t%1, %2 { J%R0\t%l3"
1139 (define_insn "*bitbranch<mode>4"
1140 [(set (pc) (if_then_else
1141 (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1142 (match_operand:QHI 1 "msp_general_operand" "rYsi,rmi"))
1144 (label_ref (match_operand 2 "" ""))
1146 (clobber (reg:BI CARRY))
1150 BIT%x0%b0\t%1, %0 { JNE\t%l2
1151 BIT%X0%b0\t%1, %0 { JNE\t%l2"
1154 (define_insn "*bitbranch<mode>4"
1155 [(set (pc) (if_then_else
1156 (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1157 (match_operand:QHI 1 "msp_general_operand" "rmi"))
1159 (label_ref (match_operand 2 "" ""))
1161 (clobber (reg:BI CARRY))
1164 "BIT%x0%X0%b0\t%1, %0 { JEQ\t%l2"
1167 (define_insn "*bitbranch<mode>4"
1168 [(set (pc) (if_then_else
1169 (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1170 (match_operand:QHI 1 "msp_general_operand" "rmi"))
1173 (label_ref (match_operand 2 "" ""))))
1174 (clobber (reg:BI CARRY))
1177 "BIT%X0%b0\t%1, %0 { JNE\t%l2"
1180 (define_insn "*bitbranch<mode>4"
1181 [(set (pc) (if_then_else
1182 (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1183 (match_operand:QHI 1 "msp_general_operand" "rmi"))
1186 (label_ref (match_operand 2 "" ""))))
1187 (clobber (reg:BI CARRY))
1190 "BIT%X0%b0\t%1, %0 { JEQ\t%l2"
1193 ;;------------------------------------------------------------
1194 ;; zero-extract versions of the above
1196 (define_insn "*bitbranch<mode>4_z"
1197 [(set (pc) (if_then_else
1198 (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1200 (match_operand 1 "msp430_bitpos" "i,i"))
1202 (label_ref (match_operand 2 "" ""))
1204 (clobber (reg:BI CARRY))
1208 BIT%x0%b0\t%p1, %0 { JNE\t%l2
1209 BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1212 (define_insn "*bitbranch<mode>4_z"
1213 [(set (pc) (if_then_else
1214 (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1216 (match_operand 1 "msp430_bitpos" "i"))
1218 (label_ref (match_operand 2 "" ""))
1220 (clobber (reg:BI CARRY))
1223 "BIT%x0%X0%b0\t%p1, %0 { JEQ\t%l2"
1226 (define_insn "*bitbranch<mode>4_z"
1227 [(set (pc) (if_then_else
1228 (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1230 (match_operand 1 "msp430_bitpos" "i"))
1233 (label_ref (match_operand 2 "" ""))))
1234 (clobber (reg:BI CARRY))
1237 "BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1240 (define_insn "*bitbranch<mode>4_z"
1241 [(set (pc) (if_then_else
1242 (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1244 (match_operand 1 "msp430_bitpos" "i"))
1247 (label_ref (match_operand 2 "" ""))))
1248 (clobber (reg:BI CARRY))
1251 "BIT%X0%b0\t%p1, %0 { JEQ\t%l2"
1254 ;;------------------------------------------------------------
1263 (define_insn "disable_interrupts"
1264 [(unspec_volatile [(const_int 0)] UNS_DINT)]
1269 (define_insn "enable_interrupts"
1270 [(unspec_volatile [(const_int 0)] UNS_EINT)]
1275 (define_insn "push_intr_state"
1276 [(unspec_volatile [(const_int 0)] UNS_PUSH_INTR)]
1281 (define_insn "pop_intr_state"
1282 [(unspec_volatile [(const_int 0)] UNS_POP_INTR)]
1287 ;; Clear bits in the copy of the status register that is currently
1288 ;; saved on the stack at the top of the interrupt handler.
1289 (define_insn "bic_SR"
1290 [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIC_SR)]
1292 "BIC.W\t%0, %O0(SP)"
1295 ;; Set bits in the copy of the status register that is currently
1296 ;; saved on the stack at the top of the interrupt handler.
1297 (define_insn "bis_SR"
1298 [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIS_SR)]
1300 "BIS.W\t%0, %O0(SP)"
1303 ;; For some reason GCC is generating (set (reg) (and (neg (reg)) (int)))
1304 ;; very late on in the compilation and not splitting it into separate
1305 ;; instructions, so we provide a pattern to support it here.
1306 (define_insn "andneghi3"
1307 [(set (match_operand:HI 0 "register_operand" "=r")
1308 (and:HI (neg:HI (match_operand:HI 1 "register_operand" "r"))
1309 (match_operand 2 "immediate_operand" "n")))]
1312 if (REGNO (operands[0]) != REGNO (operands[1]))
1313 return \"MOV.W\t%1, %0 { SUB.W\t#0, %0 { AND.W\t%2, %0\";
1315 return \"SUB.W\t#0, %0 { AND.W\t%2, %0\";