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
50 (include "predicates.md")
51 (include "constraints.md")
53 (define_mode_iterator QHI [QI HI PSI])
55 ;; There are two basic "family" tests we do here:
57 ;; msp430x - true if 430X instructions are available.
58 ;; TARGET_LARGE - true if pointers are 20-bits
60 ;; Note that there are three supported cases, since the base 430
61 ;; doesn't have 20-bit pointers:
63 ;; 1. MSP430 cpu, small model
64 ;; 2. MSP430X cpu, small model.
65 ;; 3. MSP430X cpu, large model.
67 ;;------------------------------------------------------------
70 ;; Push/Pop must be before the generic move patterns
73 [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO)))
74 (match_operand:HI 0 "register_operand" "r"))]
80 [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO)))
81 (match_operand:PSI 0 "register_operand" "r"))]
87 [(unspec_volatile [(match_operand 0 "register_operand" "r")
88 (match_operand 1 "immediate_operand" "n")] UNS_PUSHM)]
94 [(set (match_operand:HI 0 "register_operand" "=r")
95 (mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
101 [(set (match_operand:PSI 0 "register_operand" "=r")
102 (mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))]
107 ;; This is nasty. Operand0 is bogus. It is only there so that we can get a
108 ;; mode for the %b0 to work. We should use operand1 for this, but that does
111 ;; Operand1 is actually a register, but we cannot accept (REG...) because the
112 ;; cprop_hardreg pass can and will renumber registers even inside
113 ;; unspec_volatiles. So we take an integer register number parameter and
114 ;; fudge it to be a register name when we generate the assembler.
116 ;; The pushm pattern does not have this problem because of all of the
117 ;; frame info cruft attached to it, so cprop_hardreg leaves it alone.
119 [(unspec_volatile [(match_operand 0 "register_operand" "r")
120 (match_operand 1 "immediate_operand" "i")
121 (match_operand 2 "immediate_operand" "i")] UNS_POPM)]
126 ;; The next two patterns are here to support a "feature" of how GCC implements
127 ;; varargs. When a function uses varargs and the *second* to last named
128 ;; argument is split between argument registers and the stack, gcc expects the
129 ;; callee to allocate space on the stack that can contain the register-based
130 ;; part of the argument. This space *has* to be just before the remaining
131 ;; arguments (ie the ones that are fully on the stack).
133 ;; The problem is that the MSP430 CALL instruction pushes the return address
134 ;; onto the stack in the exact place where the callee wants to allocate
135 ;; this extra space. So we need a sequence of instructions that can allocate
136 ;; the extra space and then move the return address down the stack, so that
137 ;; the extra space is now adjacent to the remaining arguments.
139 ;; This could be constructed through regular insns, but they might be split up
140 ;; by a misguided optimization, so an unspec volatile is used instead.
142 (define_insn "grow_and_swap"
143 [(unspec_volatile [(const_int 0)] UNS_GROW_AND_SWAP)]
146 return "SUBA\t#2, r1 \n MOVX.A\t2(r1), 0(r1)";
147 return "SUB\t#2, r1 \n MOV.W\t2(r1), 0(r1)";
151 (define_insn "swap_and_shrink"
152 [(unspec_volatile [(const_int 0)] UNS_SWAP_AND_SHRINK)]
154 { return TARGET_LARGE
155 ? "MOVX.A\t0(r1), 2(r1) \n ADDA\t#2, SP"
156 : "MOV.W\t0(r1), 2(r1) \n ADD\t#2, SP";
159 ; I set LOAD_EXTEND_OP and WORD_REGISTER_OPERATIONS, but gcc puts in a
160 ; zero_extend anyway. Catch it here.
161 (define_insn "movqihi"
162 [(set (match_operand:HI 0 "register_operand" "=r,r")
163 (zero_extend:HI (match_operand:QI 1 "memory_operand" "Ys,m")))]
171 [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm")
172 (match_operand:QI 1 "msp_general_operand" "riYs,rmi"))]
180 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm")
181 (match_operand:HI 1 "msp_general_operand" "riYs,rmi"))]
188 (define_expand "movsi"
189 [(set (match_operand:SI 0 "nonimmediate_operand")
190 (match_operand:SI 1 "general_operand"))]
195 (define_insn_and_split "movsi_x"
196 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
197 (match_operand:SI 1 "general_operand" "rmi"))]
201 [(set (match_operand:HI 2 "nonimmediate_operand")
202 (match_operand:HI 4 "general_operand"))
203 (set (match_operand:HI 3 "nonimmediate_operand")
204 (match_operand:HI 5 "general_operand"))]
205 "msp430_split_movsi (operands);"
208 ;; Some MOVX.A cases can be done with MOVA, this is only a few of them.
209 (define_insn "movpsi"
210 [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,Ya,rm")
211 (match_operand:PSI 1 "msp_general_operand" "riYa,r,rmi"))]
218 ; This pattern is identical to the truncsipsi2 pattern except
219 ; that it uses a SUBREG instead of a TRUNC. It is needed in
220 ; order to prevent reload from converting (set:SI (SUBREG:PSI (SI)))
221 ; into (SET:PSI (PSI)).
223 ; Note: using POPM.A #1 is two bytes smaller than using POPX.A....
225 (define_insn "movsipsi2"
226 [(set (match_operand:PSI 0 "register_operand" "=r")
227 (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
229 "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0"
232 ;;------------------------------------------------------------
235 (define_insn "addpsi3"
236 [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,rm")
237 (plus:PSI (match_operand:PSI 1 "msp_nonimmediate_operand" "%0,0")
238 (match_operand:PSI 2 "msp_general_operand" "rLs,rmi")))]
245 (define_insn "addqi3"
246 [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm")
247 (plus:QI (match_operand:QI 1 "msp_nonimmediate_operand" "%0,0")
248 (match_operand:QI 2 "msp_general_operand" "riYs,rmi")))]
255 (define_insn "addhi3"
256 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm")
257 (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
258 (match_operand:HI 2 "msp_general_operand" "riYs,rmi")))]
265 ; This pattern is needed in order to avoid reload problems.
266 ; It takes an SI pair of registers, adds a value to them, and
267 ; then converts them into a single PSI register.
269 (define_insn "addsipsi3"
270 [(set (subreg:SI (match_operand:PSI 0 "register_operand" "=&r") 0)
271 (plus:SI (match_operand:SI 1 "register_operand" "0")
272 (match_operand 2 "general_operand" "rmi")))]
274 "ADD.W\t%L2, %L0 { ADDC.W\t%H2, %H0 { PUSH.W\t%H0 { PUSH.W\t%L0 { POPM.A\t#1, %0"
277 (define_insn "addsi3"
278 [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,rm")
279 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
280 (match_operand:SI 2 "general_operand" "r,mi")))]
283 ADD\t%L2, %L0 { ADDC\t%H2, %H0
284 ADD%X0\t%L2, %L0 { ADDC%X0\t%H2, %H0"
287 ; Version of addhi that exposes the carry operations, for SImode adds.
289 ; NOTE - we are playing a dangerous game with GCC here. We have these two
290 ; add patterns and the splitter that follows because our tests have shown
291 ; that this results in a significant reduction in code size - because GCC is
292 ; able to discard any unused part of the addition. We have to annotate the
293 ; patterns with the set and use of the carry flag because otherwise GCC will
294 ; discard parts of the addition when they are actually needed. But we have
295 ; not annotated all the other patterns that set the CARRY flag as doing so
296 ; results in an overall increase in code size[1]. Instead we just *hope*
297 ; that GCC will not move a carry-setting instruction in between the first
300 ; So far our experiments have shown that GCC is likely to move MOV and CMP
301 ; instructions in between the two adds, but not other instructions. MOV is
302 ; safe, CMP is not. So we have annotated the CMP patterns and left the
303 ; subtract, shift and other add patterns alone. At the moment this is
304 ; working, but with future changes to the generic parts of GCC that might
307 ; [1] It is not clear exactly why the code size increases. The cause appears
308 ; to be that reload is more prevelent to spilling a variable onto the stack
309 ; but why it does this is unknown. Possibly the additional CLOBBERs necessary
310 ; to correctly annotate the other patterns makes reload think that there is
311 ; increased register pressure. Or possibly reload does not handle ADD patterns
312 ; that are not single_set() very well.
314 (define_insn "addhi3_cy"
315 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rm")
316 (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
317 (match_operand:HI 2 "msp_nonimmediate_operand" "r,rm")))
319 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
320 (zero_extend:SI (match_dup 2)))
329 (define_insn "addhi3_cy_i"
330 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
331 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
332 (match_operand:HI 2 "immediate_operand" "i,i")))
334 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
335 (match_operand 3 "immediate_operand" "i,i"))
344 ; Version of addhi that adds the carry, for SImode adds.
345 (define_insn "addchi4_cy"
346 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rm")
347 (plus:HI (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
348 (match_operand:HI 2 "msp_general_operand" "ri,rmi"))
349 (zero_extend:HI (reg:BI CARRY))))
357 ; Split an SImode add into two HImode adds, keeping track of the carry
358 ; so that gcc knows when it can and can't optimize away the two
361 [(set (match_operand:SI 0 "msp430_nonsubreg_operand")
362 (plus:SI (match_operand:SI 1 "nonimmediate_operand")
363 (match_operand:SI 2 "general_operand")))
366 [(parallel [(set (match_operand:HI 3 "nonimmediate_operand" "=&rm")
367 (plus:HI (match_dup 4)
370 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 4))
374 (set (match_operand:HI 6 "nonimmediate_operand" "=&rm")
375 (plus:HI (plus:HI (match_dup 7)
377 (zero_extend:HI (reg:BI CARRY))))
380 operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
381 operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
382 operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
383 operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
384 operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
385 operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
386 if (GET_CODE (operands[5]) == CONST_INT)
388 operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
392 operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
398 ;; Alternatives 2 and 3 are to handle cases generated by reload.
399 (define_insn "subpsi3"
400 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r, rm, &?r, ?&r")
401 (minus:PSI (match_operand:PSI 1 "general_operand" "0, 0, !r, !i")
402 (match_operand:PSI 2 "general_operand" "rLs, rmi, rmi, r")))]
407 MOVX.A\t%1, %0 { SUBX.A\t%2, %0
408 MOVX.A\t%1, %0 { SUBA\t%2, %0"
411 ;; Alternatives 2 and 3 are to handle cases generated by reload.
412 (define_insn "subqi3"
413 [(set (match_operand:QI 0 "nonimmediate_operand" "=rYs, rm, &?r, ?&r")
414 (minus:QI (match_operand:QI 1 "general_operand" "0, 0, !r, !i")
415 (match_operand:QI 2 "general_operand" " riYs, rmi, rmi, r")))]
420 MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0
421 MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0"
424 ;; Alternatives 2 and 3 are to handle cases generated by reload.
425 (define_insn "subhi3"
426 [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs, rm, &?r, ?&r")
427 (minus:HI (match_operand:HI 1 "general_operand" "0, 0, !r, !i")
428 (match_operand:HI 2 "general_operand" " riYs, rmi, rmi, r")))]
433 MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0
434 MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0"
437 (define_insn "subsi3"
438 [(set (match_operand:SI 0 "nonimmediate_operand" "=&rm")
439 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0")
440 (match_operand:SI 2 "general_operand" "rmi")))]
442 "SUB%X0\t%L2, %L0 { SUBC%X0\t%H2, %H0"
445 (define_insn "*bic<mode>_cg"
446 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m")
447 (and:QHI (match_operand:QHI 1 "msp_general_operand" "0,0")
448 (match_operand 2 "msp430_inv_constgen_operator" "n,n")))]
455 (define_insn "bic<mode>3"
456 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
457 (and:QHI (not:QHI (match_operand:QHI 1 "msp_general_operand" "rYs,rmn"))
458 (match_operand:QHI 2 "msp_nonimmediate_operand" "0,0")))]
465 (define_insn "and<mode>3"
466 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
467 (and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
468 (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
475 (define_insn "ior<mode>3"
476 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
477 (ior:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
478 (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
485 (define_insn "xor<mode>3"
486 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
487 (xor:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
488 (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
495 ;; Macro : XOR #~0, %0
496 (define_insn "one_cmpl<mode>2"
497 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m")
498 (not:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "0,0")))]
505 (define_insn "extendqihi2"
506 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,m")
507 (sign_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
514 (define_insn "zero_extendqihi2"
515 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,m")
516 (zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
523 ;; Eliminate extraneous zero-extends mysteriously created by gcc.
525 [(set (match_operand:HI 0 "register_operand")
526 (zero_extend:HI (match_operand:QI 1 "general_operand")))
527 (set (match_operand:HI 2 "register_operand")
528 (zero_extend:HI (match_operand:QI 3 "register_operand")))]
529 "REGNO (operands[0]) == REGNO (operands[2]) && REGNO (operands[2]) == REGNO (operands[3])"
531 (zero_extend:HI (match_dup 1)))]
534 (define_insn "zero_extendhipsi2"
535 [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,m")
536 (zero_extend:PSI (match_operand:HI 1 "msp_nonimmediate_operand" "rm,r")))]
541 (define_insn "truncpsihi2"
542 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rm")
543 (truncate:HI (match_operand:PSI 1 "register_operand" "r")))]
548 (define_insn "extendhisi2"
549 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
550 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
552 { return msp430x_extendhisi (operands); }
555 (define_insn "extendhipsi2"
556 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r")
557 (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))]
559 "RLAM #4, %0 { RRAM #4, %0"
562 ;; Look for cases where integer/pointer conversions are suboptimal due
563 ;; to missing patterns, despite us not having opcodes for these
564 ;; patterns. Doing these manually allows for alternate optimization
566 (define_insn "zero_extendhisi2"
567 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
568 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
573 (define_insn "zero_extendhisipsi2"
574 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r")
575 (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))]
582 (define_insn "extend_and_shift1_hipsi2"
583 [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
584 (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
587 "RLAM #4, %0 { RRAM #3, %0"
590 (define_insn "extend_and_shift2_hipsi2"
591 [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
592 (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
595 "RLAM #4, %0 { RRAM #2, %0"
598 ; Nasty - we are sign-extending a 20-bit PSI value in one register into
599 ; two adjacent 16-bit registers to make an SI value. There is no MSP430X
600 ; instruction that will do this, so we push the 20-bit value onto the stack
601 ; and then pop it off as two 16-bit values.
603 ; FIXME: The MSP430X documentation does not specify if zero-extension or
604 ; sign-extension happens when the 20-bit value is pushed onto the stack.
605 ; It is probably zero-extension, but if not this pattern will not work
606 ; when the PSI value is negative..
608 ; Note: using PUSHM.A #1 is two bytes smaller than using PUSHX.A....
610 (define_insn "zero_extendpsisi2"
611 [(set (match_operand:SI 0 "register_operand" "=r")
612 (zero_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
615 if (REGNO (operands[1]) == SP_REGNO)
616 /* If the source register is the stack pointer, the value
617 stored in the stack slot will be the value *after* the
618 stack pointer has been decremented. So allow for that
620 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\";
622 return \"PUSHM.A\t#1, %1 { POPX.W\t%L0 { POPX.W\t%H0 ; move pointer in %1 into reg-pair %L0:%H0\";
626 ;; We also need to be able to sign-extend pointer types (eg ptrdiff_t).
627 ;; Since (we assume) pushing a 20-bit value onto the stack zero-extends
628 ;; it, we use a different method here.
630 (define_insn "extendpsisi2"
631 [(set (match_operand:SI 0 "register_operand" "=r")
632 (sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
635 /* The intention here is that we copy the bottom 16-bits of
636 %1 into %L0 (zeroing the top four bits). Then we copy the
637 entire 20-bits of %1 into %H0 and then arithmetically shift
638 it right by 16 bits, to get the top four bits of the pointer
639 sign-extended in %H0. */
640 if (REGNO (operands[0]) == REGNO (operands[1]))
641 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\";
643 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\";
647 ; See the movsipsi2 pattern above for another way that GCC performs this
649 (define_insn "truncsipsi2"
650 [(set (match_operand:PSI 0 "register_operand" "=r")
651 (truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
653 "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A\t#1, %L0"
656 ;;------------------------------------------------------------
659 ;; Note: We do not use the RPT ... SHIFT instruction sequence
660 ;; when the repeat count is in a register, because even though RPT
661 ;; accepts counts in registers, it does not work if the count is
662 ;; zero, and the actual count in the register has to be one less
663 ;; than the required number of iterations. We could encode a
664 ;; seqeunce like this:
674 ;; But is longer than calling a helper function, and we are mostly
675 ;; concerned with code size. FIXME: Maybe enable a sequence like
676 ;; this at -O3 and above ?
678 ;; Note - we ignore shift counts of less than one or more than 15.
679 ;; This is permitted by the ISO C99 standard as such shifts result
680 ;; in "undefined" behaviour. [6.5.7 (3)]
684 (define_expand "ashlhi3"
685 [(set (match_operand:HI 0 "nonimmediate_operand")
686 (ashift:HI (match_operand:HI 1 "general_operand")
687 (match_operand:HI 2 "general_operand")))]
691 && REG_P (operands[0])
692 && REG_P (operands[1])
693 && CONST_INT_P (operands[2]))
694 emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2]));
696 msp430_expand_helper (operands, \"__mspabi_slli\", true);
701 (define_insn "slli_1"
702 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
703 (ashift:HI (match_operand:HI 1 "general_operand" "0")
706 "RLA.W\t%0" ;; Note - this is a macro for ADD
709 (define_insn "430x_shift_left"
710 [(set (match_operand:HI 0 "register_operand" "=r")
711 (ashift:HI (match_operand:HI 1 "register_operand" "0")
712 (match_operand 2 "immediate_operand" "n")))]
715 if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
716 return \"rpt\t%2 { rlax.w\t%0\";
717 return \"# nop left shift\";
721 (define_insn "slll_1"
722 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
723 (ashift:SI (match_operand:SI 1 "general_operand" "0")
726 "RLA.W\t%L0 { RLC.W\t%H0"
729 (define_insn "slll_2"
730 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
731 (ashift:SI (match_operand:SI 1 "general_operand" "0")
734 "RLA.W\t%L0 { RLC.W\t%H0 { RLA.W\t%L0 { RLC.W\t%H0"
737 (define_expand "ashlsi3"
738 [(set (match_operand:SI 0 "nonimmediate_operand")
739 (ashift:SI (match_operand:SI 1 "general_operand")
740 (match_operand:SI 2 "general_operand")))]
742 "msp430_expand_helper (operands, \"__mspabi_slll\", true);
750 (define_expand "ashrhi3"
751 [(set (match_operand:HI 0 "nonimmediate_operand")
752 (ashiftrt:HI (match_operand:HI 1 "general_operand")
753 (match_operand:HI 2 "general_operand")))]
757 && REG_P (operands[0])
758 && REG_P (operands[1])
759 && CONST_INT_P (operands[2]))
760 emit_insn (gen_430x_arithmetic_shift_right (operands[0], operands[1], operands[2]));
762 msp430_expand_helper (operands, \"__mspabi_srai\", true);
767 (define_insn "srai_1"
768 [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rm")
769 (ashiftrt:HI (match_operand:HI 1 "msp_general_operand" "0")
775 (define_insn "430x_arithmetic_shift_right"
776 [(set (match_operand:HI 0 "register_operand" "=r")
777 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
778 (match_operand 2 "immediate_operand" "n")))]
781 if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
782 return \"rpt\t%2 { rrax.w\t%0\";
783 return \"# nop arith right shift\";
787 (define_insn "srap_1"
788 [(set (match_operand:PSI 0 "register_operand" "=r")
789 (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
795 (define_insn "srap_2"
796 [(set (match_operand:PSI 0 "register_operand" "=r")
797 (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
803 (define_insn "sral_1"
804 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
805 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
808 "RRA.W\t%H0 { RRC.W\t%L0"
811 (define_insn "sral_2"
812 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
813 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
816 "RRA.W\t%H0 { RRC.W\t%L0 { RRA.W\t%H0 { RRC.W\t%L0"
819 (define_expand "ashrsi3"
820 [(set (match_operand:SI 0 "nonimmediate_operand")
821 (ashiftrt:SI (match_operand:SI 1 "general_operand")
822 (match_operand:SI 2 "general_operand")))]
824 "msp430_expand_helper (operands, \"__mspabi_sral\", true);
832 (define_expand "lshrhi3"
833 [(set (match_operand:HI 0 "nonimmediate_operand")
834 (lshiftrt:HI (match_operand:HI 1 "general_operand")
835 (match_operand:HI 2 "general_operand")))]
839 && REG_P (operands[0])
840 && REG_P (operands[1])
841 && CONST_INT_P (operands[2]))
842 emit_insn (gen_430x_logical_shift_right (operands[0], operands[1], operands[2]));
844 msp430_expand_helper (operands, \"__mspabi_srli\", true);
849 (define_insn "srli_1"
850 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
851 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
857 (define_insn "430x_logical_shift_right"
858 [(set (match_operand:HI 0 "register_operand" "=r")
859 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
860 (match_operand 2 "immediate_operand" "n")))]
863 return msp430x_logical_shift_right (operands[2]);
867 (define_insn "srlp_1"
868 [(set (match_operand:PSI 0 "register_operand" "=r")
869 (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
875 (define_insn "srll_1"
876 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
877 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
880 "CLRC { RRC.W\t%H0 { RRC.W\t%L0"
883 (define_insn "srll_2x"
884 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
885 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
888 "RRUX.W\t%H0 { RRC.W\t%L0 { RRUX.W\t%H0 { RRC.W\t%L0"
891 (define_expand "lshrsi3"
892 [(set (match_operand:SI 0 "nonimmediate_operand")
893 (lshiftrt:SI (match_operand:SI 1 "general_operand")
894 (match_operand:SI 2 "general_operand")))]
896 "msp430_expand_helper (operands, \"__mspabi_srll\", true);
900 ;;------------------------------------------------------------
901 ;; Function Entry/Exit
903 (define_expand "prologue"
906 "msp430_expand_prologue (); DONE;"
909 (define_expand "epilogue"
912 "msp430_expand_epilogue (0); DONE;"
916 (define_insn "epilogue_helper"
917 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)]
919 "BR%Q0\t#__mspabi_func_epilog_%J0"
923 (define_insn "prologue_start_marker"
924 [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)]
926 "; start of prologue"
929 (define_insn "prologue_end_marker"
930 [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)]
935 (define_insn "epilogue_start_marker"
936 [(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)]
938 "; start of epilogue"
941 ;;------------------------------------------------------------
944 (define_expand "call"
945 [(call:HI (match_operand 0 "")
946 (match_operand 1 ""))]
951 (define_insn "call_internal"
952 [(call (mem:HI (match_operand 0 "general_operand" "rYci"))
953 (match_operand 1 ""))]
958 (define_expand "call_value"
959 [(set (match_operand 0 "register_operand")
960 (call:HI (match_operand 1 "general_operand")
961 (match_operand 2 "")))]
966 (define_insn "call_value_internal"
967 [(set (match_operand 0 "register_operand" "=r")
968 (call (mem:HI (match_operand 1 "general_operand" "rYci"))
969 (match_operand 2 "")))]
974 (define_insn "msp_return"
977 { return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); }
980 ;; This pattern is NOT, as expected, a return pattern. It's called
981 ;; before reload and must only store its operands, and emit a
982 ;; placeholder where the epilog needs to be. AFTER reload, the
983 ;; placeholder should get expanded into a regular-type epilogue that
984 ;; also does the EH return.
985 (define_expand "eh_return"
986 [(match_operand:HI 0 "")]
988 "msp430_expand_eh_return (operands[0]);
989 emit_jump_insn (gen_msp430_eh_epilogue ());
994 ;; This is the actual EH epilogue. We emit it in the pattern above,
995 ;; before reload, and convert it to a real epilogue after reload.
996 (define_insn_and_split "msp430_eh_epilogue"
1002 "msp430_expand_epilogue (1); DONE;"
1007 (label_ref (match_operand 0 "" "")))]
1012 ;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
1013 ;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c).
1014 (define_insn "indirect_jump"
1016 (match_operand 0 "nonimmediate_operand" "rYl"))]
1021 ;;------------------------------------------------------------
1022 ;; Various Conditionals
1024 (define_expand "cbranch<mode>4"
1025 [(parallel [(set (pc) (if_then_else
1026 (match_operator 0 ""
1027 [(match_operand:QHI 1 "nonimmediate_operand")
1028 (match_operand:QHI 2 "general_operand")])
1029 (label_ref (match_operand 3 "" ""))
1031 (clobber (reg:BI CARRY))]
1034 "msp430_fixup_compare_operands (<MODE>mode, operands);"
1037 (define_insn "cbranchpsi4_real"
1038 [(set (pc) (if_then_else
1039 (match_operator 0 "msp430_cmp_operator"
1040 [(match_operand:PSI 1 "nonimmediate_operand" "r,rYs,rm")
1041 (match_operand:PSI 2 "general_operand" "rLs,rYsi,rmi")])
1042 (label_ref (match_operand 3 "" ""))
1044 (clobber (reg:BI CARRY))
1048 CMP%Q0\t%2, %1 { J%0\t%l3
1049 CMPX.A\t%2, %1 { J%0\t%l3
1050 CMPX.A\t%2, %1 { J%0\t%l3"
1053 (define_insn "cbranchqi4_real"
1054 [(set (pc) (if_then_else
1055 (match_operator 0 "msp430_cmp_operator"
1056 [(match_operand:QI 1 "nonimmediate_operand" "rYs,rm")
1057 (match_operand:QI 2 "general_operand" "rYsi,rmi")])
1058 (label_ref (match_operand 3 "" ""))
1060 (clobber (reg:BI CARRY))
1064 CMP.B\t%2, %1 { J%0\t%l3
1065 CMP%X0.B\t%2, %1 { J%0\t%l3"
1068 (define_insn "cbranchhi4_real"
1069 [(set (pc) (if_then_else
1070 (match_operator 0 "msp430_cmp_operator"
1071 [(match_operand:HI 1 "nonimmediate_operand" "rYs,rm")
1072 (match_operand:HI 2 "general_operand" "rYsi,rmi")])
1073 (label_ref (match_operand 3 "" ""))
1075 (clobber (reg:BI CARRY))
1079 CMP.W\t%2, %1 { J%0\t%l3
1080 CMP%X0.W\t%2, %1 { J%0\t%l3"
1083 (define_insn "cbranchpsi4_reversed"
1084 [(set (pc) (if_then_else
1085 (match_operator 0 "msp430_reversible_cmp_operator"
1086 [(match_operand:PSI 1 "general_operand" "rLs,rYsi,rmi")
1087 (match_operand:PSI 2 "general_operand" "r,rYs,rm")])
1088 (label_ref (match_operand 3 "" ""))
1090 (clobber (reg:BI CARRY))
1094 CMP%Q0\t%1, %2 { J%R0\t%l3
1095 CMPX.A\t%1, %2 { J%R0\t%l3
1096 CMPX.A\t%1, %2 { J%R0\t%l3"
1099 (define_insn "cbranchqi4_reversed"
1100 [(set (pc) (if_then_else
1101 (match_operator 0 "msp430_reversible_cmp_operator"
1102 [(match_operand:QI 1 "general_operand" "rYsi,rmi")
1103 (match_operand:QI 2 "general_operand" "rYs,rm")])
1104 (label_ref (match_operand 3 "" ""))
1106 (clobber (reg:BI CARRY))
1110 CMP.B\t%1, %2 { J%R0\t%l3
1111 CMP%X0.B\t%1, %2 { J%R0\t%l3"
1114 (define_insn "cbranchhi4_reversed"
1115 [(set (pc) (if_then_else
1116 (match_operator 0 "msp430_reversible_cmp_operator"
1117 [(match_operand:HI 1 "general_operand" "rYsi,rmi")
1118 (match_operand:HI 2 "general_operand" "rYs,rm")])
1119 (label_ref (match_operand 3 "" ""))
1121 (clobber (reg:BI CARRY))
1125 CMP.W\t%1, %2 { J%R0\t%l3
1126 CMP%X0.W\t%1, %2 { J%R0\t%l3"
1129 (define_insn "*bitbranch<mode>4"
1130 [(set (pc) (if_then_else
1131 (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1132 (match_operand:QHI 1 "msp_general_operand" "rYsi,rmi"))
1134 (label_ref (match_operand 2 "" ""))
1136 (clobber (reg:BI CARRY))
1140 BIT%x0%b0\t%1, %0 { JNE\t%l2
1141 BIT%X0%b0\t%1, %0 { JNE\t%l2"
1144 (define_insn "*bitbranch<mode>4"
1145 [(set (pc) (if_then_else
1146 (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1147 (match_operand:QHI 1 "msp_general_operand" "rmi"))
1149 (label_ref (match_operand 2 "" ""))
1151 (clobber (reg:BI CARRY))
1154 "BIT%x0%X0%b0\t%1, %0 { JEQ\t%l2"
1157 (define_insn "*bitbranch<mode>4"
1158 [(set (pc) (if_then_else
1159 (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1160 (match_operand:QHI 1 "msp_general_operand" "rmi"))
1163 (label_ref (match_operand 2 "" ""))))
1164 (clobber (reg:BI CARRY))
1167 "BIT%X0%b0\t%1, %0 { JNE\t%l2"
1170 (define_insn "*bitbranch<mode>4"
1171 [(set (pc) (if_then_else
1172 (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1173 (match_operand:QHI 1 "msp_general_operand" "rmi"))
1176 (label_ref (match_operand 2 "" ""))))
1177 (clobber (reg:BI CARRY))
1180 "BIT%X0%b0\t%1, %0 { JEQ\t%l2"
1183 ;;------------------------------------------------------------
1184 ;; zero-extract versions of the above
1186 (define_insn "*bitbranch<mode>4_z"
1187 [(set (pc) (if_then_else
1188 (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1190 (match_operand 1 "msp430_bitpos" "i,i"))
1192 (label_ref (match_operand 2 "" ""))
1194 (clobber (reg:BI CARRY))
1198 BIT%x0%b0\t%p1, %0 { JNE\t%l2
1199 BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1202 (define_insn "*bitbranch<mode>4_z"
1203 [(set (pc) (if_then_else
1204 (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1206 (match_operand 1 "msp430_bitpos" "i"))
1208 (label_ref (match_operand 2 "" ""))
1210 (clobber (reg:BI CARRY))
1213 "BIT%x0%X0%b0\t%p1, %0 { JEQ\t%l2"
1216 (define_insn "*bitbranch<mode>4_z"
1217 [(set (pc) (if_then_else
1218 (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1220 (match_operand 1 "msp430_bitpos" "i"))
1223 (label_ref (match_operand 2 "" ""))))
1224 (clobber (reg:BI CARRY))
1227 "BIT%X0%b0\t%p1, %0 { JNE\t%l2"
1230 (define_insn "*bitbranch<mode>4_z"
1231 [(set (pc) (if_then_else
1232 (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1234 (match_operand 1 "msp430_bitpos" "i"))
1237 (label_ref (match_operand 2 "" ""))))
1238 (clobber (reg:BI CARRY))
1241 "BIT%X0%b0\t%p1, %0 { JEQ\t%l2"
1244 ;;------------------------------------------------------------
1253 (define_insn "disable_interrupts"
1254 [(unspec_volatile [(const_int 0)] UNS_DINT)]
1259 (define_insn "enable_interrupts"
1260 [(unspec_volatile [(const_int 0)] UNS_EINT)]
1265 (define_insn "push_intr_state"
1266 [(unspec_volatile [(const_int 0)] UNS_PUSH_INTR)]
1271 (define_insn "pop_intr_state"
1272 [(unspec_volatile [(const_int 0)] UNS_POP_INTR)]
1277 ;; Clear bits in the copy of the status register that is currently
1278 ;; saved on the stack at the top of the interrupt handler.
1279 (define_insn "bic_SR"
1280 [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIC_SR)]
1282 "BIC.W\t%0, %O0(SP)"
1285 ;; Set bits in the copy of the status register that is currently
1286 ;; saved on the stack at the top of the interrupt handler.
1287 (define_insn "bis_SR"
1288 [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIS_SR)]
1290 "BIS.W\t%0, %O0(SP)"
1293 ;; For some reason GCC is generating (set (reg) (and (neg (reg)) (int)))
1294 ;; very late on in the compilation and not splitting it into separate
1295 ;; instructions, so we provide a pattern to support it here.
1296 (define_insn "andneghi3"
1297 [(set (match_operand:HI 0 "register_operand" "=r")
1298 (and:HI (neg:HI (match_operand:HI 1 "register_operand" "r"))
1299 (match_operand 2 "immediate_operand" "n")))]
1302 if (REGNO (operands[0]) != REGNO (operands[1]))
1303 return \"MOV.W\t%1, %0 { SUB.W\t#0, %0 { AND.W\t%2, %0\";
1305 return \"SUB.W\t#0, %0 { AND.W\t%2, %0\";