1 ;; Machine Description for TI MSP43* processors
2 ;; Copyright (C) 2013 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
43 (include "predicates.md")
44 (include "constraints.md")
46 (define_mode_iterator QHI [QI HI PSI])
48 ;; There are two basic "family" tests we do here:
50 ;; msp430x - true if 430X instructions are available.
51 ;; TARGET_LARGE - true if pointers are 20-bits
53 ;; Note that there are three supported cases, since the base 430
54 ;; doesn't have 20-bit pointers:
56 ;; 1. MSP430 cpu, small model
57 ;; 2. MSP430X cpu, small model.
58 ;; 3. MSP430X cpu, large model.
60 ;;------------------------------------------------------------
63 ;; Push/Pop must be before the generic move patterns
66 [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO)))
67 (match_operand:HI 0 "register_operand" "r"))]
73 [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO)))
74 (match_operand:PSI 0 "register_operand" "r"))]
80 [(unspec_volatile [(match_operand 0 "register_operand" "r")
81 (match_operand 1 "immediate_operand" "i")] UNS_PUSHM)]
87 [(set (match_operand:HI 0 "register_operand" "=r")
88 (mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
94 [(set (match_operand:PSI 0 "register_operand" "=r")
95 (mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))]
100 ;; This is nasty. Operand0 is bogus. It is only there so that we can get a
101 ;; mode for the %B0 to work. We should use operand1 for this, but that does
104 ;; Operand1 is actually a register, but we cannot accept (REG...) because the
105 ;; cprop_hardreg pass can and will renumber registers even inside
106 ;; unspec_volatiles. So we take an integer register number parameter and
107 ;; fudge it to be a register name when we generate the assembler. We use %I
108 ;; because that is the only operator that will omit the # prefix to an
109 ;; integer value. Unfortunately it also inverts the integer value, so we
110 ;; have pre-invert it when generating this insn. (We could of course add a
111 ;; new operator, eg %D, just for this pattern...)
113 ;; The pushm pattern does not have this problem because of all of the
114 ;; frame info cruft attached to it, so cprop_hardreg leaves it alone.
116 [(unspec_volatile [(match_operand 0 "register_operand" "r")
117 (match_operand 1 "immediate_operand" "i")
118 (match_operand 2 "immediate_operand" "i")] UNS_POPM)]
123 ;; The next two patterns are here to support a "feature" of how GCC implements
124 ;; varargs. When a function uses varargs and the *second* to last named
125 ;; argument is split between argument registers and the stack, gcc expects the
126 ;; callee to allocate space on the stack that can contain the register-based
127 ;; part of the argument. This space *has* to be just before the remaining
128 ;; arguments (ie the ones that are fully on the stack).
130 ;; The problem is that the MSP430 CALL instruction pushes the return address
131 ;; onto the stack in the exact place where the callee wants to allocate
132 ;; this extra space. So we need a sequence of instructions that can allocate
133 ;; the extra space and then move the return address down the stack, so that
134 ;; the extra space is now adjacent to the remaining arguments.
136 ;; This could be constructed through regular insns, but they might be split up
137 ;; by a misguided optimization, so an unspec volatile is used instead.
139 (define_insn "grow_and_swap"
140 [(unspec_volatile [(const_int 0)] UNS_GROW_AND_SWAP)]
143 return "SUBA\t#2, r1 \n MOVX.A\t2(r1), 0(r1)";
144 return "SUB\t#2, r1 \n MOV.W\t2(r1), 0(r1)";
148 (define_insn "swap_and_shrink"
149 [(unspec_volatile [(const_int 0)] UNS_SWAP_AND_SHRINK)]
151 { return TARGET_LARGE
152 ? "MOVX.A\t0(r1), 2(r1) \n ADDA\t#2, SP"
153 : "MOV.W\t0(r1), 2(r1) \n ADD\t#2, SP";
156 ; I set LOAD_EXTEND_OP and WORD_REGISTER_OPERATIONS, but gcc puts in a
157 ; zero_extend anyway. Catch it here.
158 (define_insn "movqihi"
159 [(set (match_operand:HI 0 "register_operand" "=r,r")
160 (zero_extend:HI (match_operand:QI 1 "memory_operand" "Ys,m")))]
168 [(set (match_operand:QI 0 "nonimmediate_operand" "=rYs,rm")
169 (match_operand:QI 1 "general_operand" "riYs,rmi"))]
177 [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,rm")
178 (match_operand:HI 1 "general_operand" "riYs,rmi"))]
185 (define_expand "movsi"
186 [(set (match_operand:SI 0 "nonimmediate_operand" "")
187 (match_operand:SI 1 "general_operand" ""))]
192 (define_insn_and_split "movsi_x"
193 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
194 (match_operand:SI 1 "general_operand" "rmi"))]
198 [(set (match_operand:HI 2 "nonimmediate_operand")
199 (match_operand:HI 4 "general_operand"))
200 (set (match_operand:HI 3 "nonimmediate_operand")
201 (match_operand:HI 5 "general_operand"))]
202 "msp430_split_movsi (operands);"
205 ;; Some MOVX.A cases can be done with MOVA, this is only a few of them.
206 (define_insn "movpsi"
207 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,Ya,rm")
208 (match_operand:PSI 1 "general_operand" "riYa,r,rmi"))]
215 ; This pattern is identical to the truncsipsi2 pattern except
216 ; that it uses a SUBREG instead of a TRUNC. It is needed in
217 ; order to prevent reload from converting (set:SI (SUBREG:PSI (SI)))
218 ; into (SET:PSI (PSI)).
220 ; Note: using POPM.A #1 is two bytes smaller than using POPX.A....
222 (define_insn "movsipsi2"
223 [(set (match_operand:PSI 0 "register_operand" "=r")
224 (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
226 "PUSH.W %H1 { PUSH.W %1 { POPM.A #1, %0"
229 ;;------------------------------------------------------------
232 (define_insn "addpsi3"
233 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,rm")
234 (plus:PSI (match_operand:PSI 1 "nonimmediate_operand" "%0,0")
235 (match_operand:PSI 2 "general_operand" "rLs,rmi")))]
242 (define_insn "addqi3"
243 [(set (match_operand:QI 0 "nonimmediate_operand" "=rYs,rm")
244 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
245 (match_operand:QI 2 "general_operand" "riYs,rmi")))]
252 (define_insn "addhi3"
253 [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,rm")
254 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
255 (match_operand:HI 2 "general_operand" "riYs,rmi")))]
262 ; This pattern is needed in order to avoid reload problems.
263 ; It takes an SI pair of registers, adds a value to them, and
264 ; then converts them into a single PSI register.
266 (define_insn "addsipsi3"
267 [(set (subreg:SI (match_operand:PSI 0 "register_operand" "=&r") 0)
268 (plus:SI (match_operand:SI 1 "register_operand" "0")
269 (match_operand 2 "general_operand" "rmi")))]
271 "ADD.W\t%L2, %L0 { ADDC.W\t%H2, %H0 { PUSH.W %H0 { PUSH.W %L0 { POPM.A #1, %0"
274 (define_insn "addsi3"
275 [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,rm")
276 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
277 (match_operand:SI 2 "general_operand" "r,mi")))]
280 ADD\t%L2, %L0 { ADDC\t%H2, %H0
281 ADD%X0\t%L2, %L0 { ADDC%X0\t%H2, %H0"
284 ; Version of addhi that exposes the carry operations, for SImode adds.
286 ; NOTE - we are playing a dangerous game with GCC here. We have these two
287 ; add patterns and the splitter that follows because our tests have shown
288 ; that this results in a significant reduction in code size - because GCC is
289 ; able to discard any unused part of the addition. We have to annotate the
290 ; patterns with the set and use of the carry flag because otherwise GCC will
291 ; discard parts of the addition when they are actually needed. But we have
292 ; not annotated all the other patterns that set the CARRY flag as doing so
293 ; results in an overall increase in code size[1]. Instead we just *hope*
294 ; that GCC will not move a carry-setting instruction in between the first
297 ; So far our experiments have shown that GCC is likely to move MOV and CMP
298 ; instructions in between the two adds, but not other instructions. MOV is
299 ; safe, CMP is not. So we have annotated the CMP patterns and left the
300 ; subtract, shift and other add patterns alone. At the moment this is
301 ; working, but with future changes to the generic parts of GCC that might
304 ; [1] It is not clear exactly why the code size increases. The cause appears
305 ; to be that reload is more prevelent to spilling a variable onto the stack
306 ; but why it does this is unknown. Possibly the additional CLOBBERs necessary
307 ; to correctly annotate the other patterns makes reload think that there is
308 ; increased register pressure. Or possibly reload does not handle ADD patterns
309 ; that are not single_set() very well.
311 (define_insn "addhi3_cy"
312 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
313 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
314 (match_operand:HI 2 "general_operand" "r,rm")))
316 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
317 (zero_extend:SI (match_dup 2)))
326 (define_insn "addhi3_cy_i"
327 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
328 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
329 (match_operand:HI 2 "general_operand" "i,i")))
331 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
332 (match_operand 3 "immediate_operand" "i,i"))
341 ; Version of addhi that adds the carry, for SImode adds.
342 (define_insn "addchi4_cy"
343 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
344 (plus:HI (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
345 (match_operand:HI 2 "general_operand" "ri,rmi"))
346 (zero_extend:HI (reg:BI CARRY))))
354 ; Split an SImode add into two HImode adds, keeping track of the carry
355 ; so that gcc knows when it can and can't optimize away the two
358 [(set (match_operand:SI 0 "msp430_nonsubreg_operand" "=&rm")
359 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
360 (match_operand:SI 2 "general_operand" "rmi")))
363 [(parallel [(set (match_operand:HI 3 "nonimmediate_operand" "=&rm")
364 (plus:HI (match_dup 4)
367 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 4))
371 (set (match_operand:HI 6 "nonimmediate_operand" "=&rm")
372 (plus:HI (plus:HI (match_dup 7)
374 (zero_extend:HI (reg:BI CARRY))))
377 operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
378 operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
379 operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
380 operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
381 operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
382 operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
383 if (GET_CODE (operands[5]) == CONST_INT)
385 operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
389 operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
395 ;; Alternatives 2 and 3 are to handle cases generated by reload.
396 (define_insn "subpsi3"
397 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r, rm, &?r, ?&r")
398 (minus:PSI (match_operand:PSI 1 "general_operand" "0, 0, !r, !i")
399 (match_operand:PSI 2 "general_operand" "rLs, rmi, rmi, r")))]
404 MOVX.A\t%1, %0 { SUBX.A\t%2, %0
405 MOVX.A\t%1, %0 { SUBA\t%2, %0"
408 ;; Alternatives 2 and 3 are to handle cases generated by reload.
409 (define_insn "subqi3"
410 [(set (match_operand:QI 0 "nonimmediate_operand" "=rYs, rm, &?r, ?&r")
411 (minus:QI (match_operand:QI 1 "general_operand" "0, 0, !r, !i")
412 (match_operand:QI 2 "general_operand" " riYs, rmi, rmi, r")))]
417 MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0
418 MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0"
421 ;; Alternatives 2 and 3 are to handle cases generated by reload.
422 (define_insn "subhi3"
423 [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs, rm, &?r, ?&r")
424 (minus:HI (match_operand:HI 1 "general_operand" "0, 0, !r, !i")
425 (match_operand:HI 2 "general_operand" " riYs, rmi, rmi, r")))]
430 MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0
431 MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0"
434 (define_insn "subsi3"
435 [(set (match_operand:SI 0 "nonimmediate_operand" "=&rm")
436 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0")
437 (match_operand:SI 2 "general_operand" "rmi")))]
439 "SUB%X0\t%L2, %L0 { SUBC%X0\t%H2, %H0"
442 (define_insn "*bic<mode>_cg"
443 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m")
444 (and:QHI (match_operand:QHI 1 "msp_general_operand" "0,0")
445 (match_operand 2 "msp430_inv_constgen_operator" "n,n")))]
452 (define_insn "bic<mode>3"
453 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
454 (and:QHI (not:QHI (match_operand:QHI 1 "msp_general_operand" "rYs,rmn"))
455 (match_operand:QHI 2 "msp_nonimmediate_operand" "0,0")))]
462 (define_insn "and<mode>3"
463 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
464 (and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
465 (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
472 (define_insn "ior<mode>3"
473 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
474 (ior:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
475 (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
482 (define_insn "xor<mode>3"
483 [(set (match_operand:QHI 0 "nonimmediate_operand" "=rYs,rm")
484 (xor:QHI (match_operand:QHI 1 "nonimmediate_operand" "%0,0")
485 (match_operand:QHI 2 "general_operand" "riYs,rmi")))]
492 ;; Macro : XOR #~0, %0
493 (define_insn "one_cmpl<mode>2"
494 [(set (match_operand:QHI 0 "nonimmediate_operand" "=rYs,m")
495 (not:QHI (match_operand:QHI 1 "nonimmediate_operand" "0,0")))]
502 (define_insn "extendqihi2"
503 [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,m")
504 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
511 (define_insn "zero_extendqihi2"
512 [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,m")
513 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
520 ;; Eliminate extraneous zero-extends mysteriously created by gcc.
522 [(set (match_operand:HI 0 "register_operand")
523 (zero_extend:HI (match_operand:QI 1 "general_operand")))
524 (set (match_operand:HI 2 "register_operand")
525 (zero_extend:HI (match_operand:QI 3 "register_operand")))]
526 "REGNO (operands[0]) == REGNO (operands[2]) && REGNO (operands[2]) == REGNO (operands[3])"
528 (zero_extend:HI (match_dup 1)))]
531 (define_insn "zero_extendhipsi2"
532 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,m")
533 (zero_extend:PSI (match_operand:HI 1 "nonimmediate_operand" "rm,r")))]
538 (define_insn "truncpsihi2"
539 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
540 (truncate:HI (match_operand:PSI 1 "register_operand" "r")))]
545 (define_insn "extendhisi2"
546 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
547 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
549 { return msp430x_extendhisi (operands); }
552 (define_insn "extendhipsi2"
553 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r")
554 (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))]
556 "RLAM #4, %0 { RRAM #4, %0"
559 ;; Look for cases where integer/pointer conversions are suboptimal due
560 ;; to missing patterns, despite us not having opcodes for these
561 ;; patterns. Doing these manually allows for alternate optimization
563 (define_insn "zero_extendhisi2"
564 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
565 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
570 (define_insn "zero_extendhisipsi2"
571 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r")
572 (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))]
579 (define_insn "extend_and_shift1_hipsi2"
580 [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
581 (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
584 "RLAM #4, %0 { RRAM #3, %0"
587 (define_insn "extend_and_shift2_hipsi2"
588 [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
589 (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
592 "RLAM #4, %0 { RRAM #2, %0"
595 ; Nasty - we are sign-extending a 20-bit PSI value in one register into
596 ; two adjacent 16-bit registers to make an SI value. There is no MSP430X
597 ; instruction that will do this, so we push the 20-bit value onto the stack
598 ; and then pop it off as two 16-bit values.
600 ; FIXME: The MSP430X documentation does not specify if zero-extension or
601 ; sign-extension happens when the 20-bit value is pushed onto the stack.
602 ; It is probably zero-extension, but if not this pattern will not work
603 ; when the PSI value is negative..
605 ; Note: using PUSHM.A #1 is two bytes smaller than using PUSHX.A....
607 (define_insn "zero_extendpsisi2"
608 [(set (match_operand:SI 0 "register_operand" "=r")
609 (zero_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
612 if (REGNO (operands[1]) == SP_REGNO)
613 /* If the source register is the stack pointer, the value
614 stored in the stack slot will be the value *after* the
615 stack pointer has been decremented. So allow for that
617 return \"PUSHM.A #1, %1 { ADDX.W #4, @r1 { POPX.W %0 { POPX.W %H0\";
619 return \"PUSHM.A #1, %1 { POPX.W %0 { POPX.W %H0\";
623 ; See the movsipsi2 pattern above for another way that GCC performs this
625 (define_insn "truncsipsi2"
626 [(set (match_operand:PSI 0 "register_operand" "=r")
627 (truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
629 "PUSH.W %H1 { PUSH.W %1 { POPM.A #1, %0"
632 ;;------------------------------------------------------------
635 ;; Note: We do not use the RPT ... SHIFT instruction sequence
636 ;; when the repeat count is in a register, because even though RPT
637 ;; accepts counts in registers, it does not work if the count is
638 ;; zero, and the actual count in the register has to be one less
639 ;; than the required number of iterations. We could encode a
640 ;; seqeunce like this:
650 ;; But is longer than calling a helper function, and we are mostly
651 ;; concerned with code size. FIXME: Maybe enable a sequence like
652 ;; this at -O3 and above ?
654 ;; Note - we ignore shift counts of less than one or more than 15.
655 ;; This is permitted by the ISO C99 standard as such shifts result
656 ;; in "undefined" behaviour. [6.5.7 (3)]
660 (define_expand "ashlhi3"
661 [(set (match_operand:HI 0 "nonimmediate_operand")
662 (ashift:HI (match_operand:HI 1 "general_operand")
663 (match_operand:HI 2 "general_operand")))]
667 && REG_P (operands[0])
668 && REG_P (operands[1])
669 && CONST_INT_P (operands[2]))
670 emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2]));
672 msp430_expand_helper (operands, \"__mspabi_slli\", true);
677 (define_insn "slli_1"
678 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
679 (ashift:HI (match_operand:HI 1 "general_operand" "0")
682 "RLA.W\t%0" ;; Note - this is a macro for ADD
685 (define_insn "430x_shift_left"
686 [(set (match_operand:HI 0 "register_operand" "=r")
687 (ashift:HI (match_operand:HI 1 "register_operand" "0")
688 (match_operand 2 "immediate_operand" "n")))]
691 if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
692 return \"rpt\t%2 { rlax.w\t%0\";
693 return \"# nop left shift\";
697 (define_insn "slll_1"
698 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
699 (ashift:SI (match_operand:SI 1 "general_operand" "0")
702 "RLA.W\t%L0 { RLC.W\t%H0"
705 (define_insn "slll_2"
706 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
707 (ashift:SI (match_operand:SI 1 "general_operand" "0")
710 "RLA.W\t%L0 { RLC.W\t%H0 { RLA.W\t%L0 { RLC.W\t%H0"
713 (define_expand "ashlsi3"
714 [(set (match_operand:SI 0 "nonimmediate_operand")
715 (ashift:SI (match_operand:SI 1 "general_operand")
716 (match_operand:SI 2 "general_operand")))]
718 "msp430_expand_helper (operands, \"__mspabi_slll\", true);
726 (define_expand "ashrhi3"
727 [(set (match_operand:HI 0 "nonimmediate_operand")
728 (ashiftrt:HI (match_operand:HI 1 "general_operand")
729 (match_operand:HI 2 "general_operand")))]
733 && REG_P (operands[0])
734 && REG_P (operands[1])
735 && CONST_INT_P (operands[2]))
736 emit_insn (gen_430x_arithmetic_shift_right (operands[0], operands[1], operands[2]));
738 msp430_expand_helper (operands, \"__mspabi_srai\", true);
743 (define_insn "srai_1"
744 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
745 (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
751 (define_insn "430x_arithmetic_shift_right"
752 [(set (match_operand:HI 0 "register_operand" "=r")
753 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
754 (match_operand 2 "immediate_operand" "n")))]
757 if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
758 return \"rpt\t%2 { rrax.w\t%0\";
759 return \"# nop arith right shift\";
763 (define_insn "srap_1"
764 [(set (match_operand:PSI 0 "register_operand" "=r")
765 (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
771 (define_insn "srap_2"
772 [(set (match_operand:PSI 0 "register_operand" "=r")
773 (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
779 (define_insn "sral_1"
780 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
781 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
784 "RRA.W\t%H0 { RRC.W\t%L0"
787 (define_insn "sral_2"
788 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
789 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
792 "RRA.W\t%H0 { RRC.W\t%L0 { RRA.W\t%H0 { RRC.W\t%L0"
795 (define_expand "ashrsi3"
796 [(set (match_operand:SI 0 "nonimmediate_operand")
797 (ashiftrt:SI (match_operand:SI 1 "general_operand")
798 (match_operand:SI 2 "general_operand")))]
800 "msp430_expand_helper (operands, \"__mspabi_sral\", true);
808 (define_expand "lshrhi3"
809 [(set (match_operand:HI 0 "nonimmediate_operand")
810 (lshiftrt:HI (match_operand:HI 1 "general_operand")
811 (match_operand:HI 2 "general_operand")))]
815 && REG_P (operands[0])
816 && REG_P (operands[1])
817 && CONST_INT_P (operands[2]))
818 emit_insn (gen_430x_logical_shift_right (operands[0], operands[1], operands[2]));
820 msp430_expand_helper (operands, \"__mspabi_srli\", true);
825 (define_insn "srli_1"
826 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
827 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
833 (define_insn "430x_logical_shift_right"
834 [(set (match_operand:HI 0 "register_operand" "=r")
835 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
836 (match_operand 2 "immediate_operand" "n")))]
839 return msp430x_logical_shift_right (operands[2]);
843 (define_insn "srlp_1"
844 [(set (match_operand:PSI 0 "register_operand" "=r")
845 (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
851 (define_insn "srll_1"
852 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
853 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
856 "CLRC { RRC.W\t%H0 { RRC.W\t%L0"
859 (define_insn "srll_2x"
860 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
861 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
864 "RRUX.W\t%H0 { RRC.W\t%L0 { RRUX.W\t%H0 { RRC.W\t%L0"
867 (define_expand "lshrsi3"
868 [(set (match_operand:SI 0 "nonimmediate_operand")
869 (lshiftrt:SI (match_operand:SI 1 "general_operand")
870 (match_operand:SI 2 "general_operand")))]
872 "msp430_expand_helper (operands, \"__mspabi_srll\", true);
876 ;;------------------------------------------------------------
877 ;; Function Entry/Exit
879 (define_expand "prologue"
882 "msp430_expand_prologue (); DONE;"
885 (define_expand "epilogue"
888 "msp430_expand_epilogue (0); DONE;"
892 (define_insn "epilogue_helper"
893 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)]
895 "BR%A0\t#__mspabi_func_epilog_%D0"
899 (define_insn "prologue_start_marker"
900 [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)]
902 "; start of prologue"
905 (define_insn "prologue_end_marker"
906 [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)]
911 (define_insn "epilogue_start_marker"
912 [(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)]
914 "; start of epilogue"
917 ;;------------------------------------------------------------
920 (define_expand "call"
921 [(call:HI (match_operand 0 "")
922 (match_operand 1 ""))]
927 (define_insn "call_internal"
928 [(call (mem:HI (match_operand 0 "general_operand" "rmi"))
929 (match_operand 1 ""))]
934 (define_expand "call_value"
935 [(set (match_operand 0 "register_operand")
936 (call:HI (match_operand 1 "general_operand")
937 (match_operand 2 "")))]
942 (define_insn "call_value_internal"
943 [(set (match_operand 0 "register_operand" "=r")
944 (call (mem:HI (match_operand 1 "general_operand" "rmi"))
945 (match_operand 2 "")))]
950 (define_insn "msp_return"
953 { return TARGET_LARGE ? "RETA" : "RET"; }
956 ;; This pattern is NOT, as expected, a return pattern. It's called
957 ;; before reload and must only store its operands, and emit a
958 ;; placeholder where the epilog needs to be. AFTER reload, the
959 ;; placeholder should get expanded into a regular-type epilogue that
960 ;; also does the EH return.
961 (define_expand "eh_return"
962 [(match_operand:HI 0 "" "")]
964 "msp430_expand_eh_return (operands[0]);
965 emit_jump_insn (gen_msp430_eh_epilogue ());
970 ;; This is the actual EH epilogue. We emit it in the pattern above,
971 ;; before reload, and convert it to a real epilogue after reload.
972 (define_insn_and_split "msp430_eh_epilogue"
978 "msp430_expand_epilogue (1); DONE;"
983 (label_ref (match_operand 0 "" "")))]
988 ;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
989 ;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c).
990 (define_insn "indirect_jump"
992 (match_operand 0 "nonimmediate_operand" "rYl"))]
997 ;;------------------------------------------------------------
998 ;; Various Conditionals
1000 (define_expand "cbranch<mode>4"
1001 [(parallel [(set (pc) (if_then_else
1002 (match_operator 0 ""
1003 [(match_operand:QHI 1 "nonimmediate_operand")
1004 (match_operand:QHI 2 "general_operand")])
1005 (label_ref (match_operand 3 "" ""))
1007 (clobber (reg:BI CARRY))]
1010 "msp430_fixup_compare_operands (<MODE>mode, operands);"
1013 (define_insn "cbranchpsi4_real"
1014 [(set (pc) (if_then_else
1015 (match_operator 0 "msp430_cmp_operator"
1016 [(match_operand:PSI 1 "nonimmediate_operand" "r,rYs,rm")
1017 (match_operand:PSI 2 "general_operand" "rLs,rYsi,rmi")])
1018 (label_ref (match_operand 3 "" ""))
1020 (clobber (reg:BI CARRY))
1024 CMP%A0\t%2, %1 { J%0\t%l3
1025 CMPX.A\t%2, %1 { J%0\t%l3
1026 CMPX.A\t%2, %1 { J%0\t%l3"
1029 (define_insn "cbranchqi4_real"
1030 [(set (pc) (if_then_else
1031 (match_operator 0 "msp430_cmp_operator"
1032 [(match_operand:QI 1 "nonimmediate_operand" "rYs,rm")
1033 (match_operand:QI 2 "general_operand" "rYsi,rmi")])
1034 (label_ref (match_operand 3 "" ""))
1036 (clobber (reg:BI CARRY))
1040 CMP.B\t%2, %1 { J%0\t%l3
1041 CMP%X0.B\t%2, %1 { J%0\t%l3"
1044 (define_insn "cbranchhi4_real"
1045 [(set (pc) (if_then_else
1046 (match_operator 0 "msp430_cmp_operator"
1047 [(match_operand:HI 1 "nonimmediate_operand" "rYs,rm")
1048 (match_operand:HI 2 "general_operand" "rYsi,rmi")])
1049 (label_ref (match_operand 3 "" ""))
1051 (clobber (reg:BI CARRY))
1055 CMP.W\t%2, %1 { J%0\t%l3
1056 CMP%X0.W\t%2, %1 { J%0\t%l3"
1059 (define_insn "cbranchpsi4_reversed"
1060 [(set (pc) (if_then_else
1061 (match_operator 0 "msp430_reversible_cmp_operator"
1062 [(match_operand:PSI 1 "general_operand" "rLs,rYsi,rmi")
1063 (match_operand:PSI 2 "general_operand" "r,rYs,rm")])
1064 (label_ref (match_operand 3 "" ""))
1066 (clobber (reg:BI CARRY))
1070 CMP%A0\t%1, %2 { J%R0\t%l3
1071 CMPX.A\t%1, %2 { J%R0\t%l3
1072 CMPX.A\t%1, %2 { J%R0\t%l3"
1075 (define_insn "cbranchqi4_reversed"
1076 [(set (pc) (if_then_else
1077 (match_operator 0 "msp430_reversible_cmp_operator"
1078 [(match_operand:QI 1 "general_operand" "rYsi,rmi")
1079 (match_operand:QI 2 "general_operand" "rYs,rm")])
1080 (label_ref (match_operand 3 "" ""))
1082 (clobber (reg:BI CARRY))
1086 CMP.B\t%1, %2 { J%R0\t%l3
1087 CMP%X0.B\t%1, %2 { J%R0\t%l3"
1090 (define_insn "cbranchhi4_reversed"
1091 [(set (pc) (if_then_else
1092 (match_operator 0 "msp430_reversible_cmp_operator"
1093 [(match_operand:HI 1 "general_operand" "rYsi,rmi")
1094 (match_operand:HI 2 "general_operand" "rYs,rm")])
1095 (label_ref (match_operand 3 "" ""))
1097 (clobber (reg:BI CARRY))
1101 CMP.W\t%1, %2 { J%R0\t%l3
1102 CMP%X0.W\t%1, %2 { J%R0\t%l3"
1106 (define_insn "*bitbranch<mode>4"
1107 [(set (pc) (if_then_else
1108 (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1109 (match_operand:QHI 1 "msp_general_operand" "rYsi,rmi"))
1111 (label_ref (match_operand 2 "" ""))
1113 (clobber (reg:BI CARRY))
1117 BIT%x0%B0\t%1, %0 { JNE\t%l2
1118 BIT%X0%B0\t%1, %0 { JNE\t%l2"
1121 (define_insn "*bitbranch<mode>4"
1122 [(set (pc) (if_then_else
1123 (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1124 (match_operand:QHI 1 "msp_general_operand" "rmi"))
1126 (label_ref (match_operand 2 "" ""))
1128 (clobber (reg:BI CARRY))
1131 "BIT%x0%X0%B0\t%1, %0 { JEQ\t%l2"
1134 (define_insn "*bitbranch<mode>4"
1135 [(set (pc) (if_then_else
1136 (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1137 (match_operand:QHI 1 "msp_general_operand" "rmi"))
1140 (label_ref (match_operand 2 "" ""))))
1141 (clobber (reg:BI CARRY))
1144 "BIT%X0%B0\t%1, %0 { JNE\t%l2"
1147 (define_insn "*bitbranch<mode>4"
1148 [(set (pc) (if_then_else
1149 (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1150 (match_operand:QHI 1 "msp_general_operand" "rmi"))
1153 (label_ref (match_operand 2 "" ""))))
1154 (clobber (reg:BI CARRY))
1157 "BIT%X0%B0\t%1, %0 { JEQ\t%l2"
1160 ;;------------------------------------------------------------
1161 ;; zero-extend versions of the above
1163 (define_insn "*bitbranch<mode>4_z"
1164 [(set (pc) (if_then_else
1165 (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1167 (match_operand 1 "msp430_bitpos" "i,i"))
1169 (label_ref (match_operand 2 "" ""))
1171 (clobber (reg:BI CARRY))
1175 BIT%x0%B0\t%p1, %0 { JNE\t%l2
1176 BIT%X0%B0\t%p1, %0 { JNE\t%l2"
1179 (define_insn "*bitbranch<mode>4_z"
1180 [(set (pc) (if_then_else
1181 (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1183 (match_operand 1 "msp430_bitpos" "i"))
1185 (label_ref (match_operand 2 "" ""))
1187 (clobber (reg:BI CARRY))
1190 "BIT%x0%X0%B0\t%p1, %0 { JEQ\t%l2"
1193 (define_insn "*bitbranch<mode>4_z"
1194 [(set (pc) (if_then_else
1195 (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1197 (match_operand 1 "msp430_bitpos" "i"))
1200 (label_ref (match_operand 2 "" ""))))
1201 (clobber (reg:BI CARRY))
1204 "BIT%X0%B0\t%p1, %0 { JNE\t%l2"
1207 (define_insn "*bitbranch<mode>4_z"
1208 [(set (pc) (if_then_else
1209 (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1211 (match_operand 1 "msp430_bitpos" "i"))
1214 (label_ref (match_operand 2 "" ""))))
1215 (clobber (reg:BI CARRY))
1218 "BIT%X0%B0\t%p1, %0 { JEQ\t%l2"
1221 ;;------------------------------------------------------------