The call change avoids a problem on hardware where indirect calls that use SP as a base register don't seem to do what you expect. The 'J' one fixes a link-time error wrt epilogue helper functions. Committed.
* config/msp430/msp430.md (call_internal): Don't allow memory references with SP as the base register. (call_value_internal): Likewise. * config/msp430/constraints.md (Yc): New. For memory references that don't use SP as a base register. * config/msp430/msp430.c (msp430_print_operand): Add 'J' to mean "an integer without a # prefix" * config/msp430/msp430.md (epilogue_helper): Use it. Index: config/msp430/msp430.md =================================================================== --- config/msp430/msp430.md (revision 206582) +++ config/msp430/msp430.md (working copy) @@ -917,13 +917,13 @@ ) (define_insn "epilogue_helper" [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)] "" - "BR%Q0\t#__mspabi_func_epilog_%0" + "BR%Q0\t#__mspabi_func_epilog_%J0" ) (define_insn "prologue_start_marker" [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)] "" @@ -950,13 +950,13 @@ (match_operand 1 ""))] "" "" ) (define_insn "call_internal" - [(call (mem:HI (match_operand 0 "general_operand" "rmi")) + [(call (mem:HI (match_operand 0 "general_operand" "rYci")) (match_operand 1 ""))] "" "CALL%Q0\t%0" ) (define_expand "call_value" @@ -966,13 +966,13 @@ "" "" ) (define_insn "call_value_internal" [(set (match_operand 0 "register_operand" "=r") - (call (mem:HI (match_operand 1 "general_operand" "rmi")) + (call (mem:HI (match_operand 1 "general_operand" "rYci")) (match_operand 2 "")))] "" "CALL%Q0\t%1" ) (define_insn "msp_return" Index: config/msp430/constraints.md =================================================================== --- config/msp430/constraints.md (revision 206582) +++ config/msp430/constraints.md (working copy) @@ -67,6 +67,19 @@ (and (match_code "plus" "0") (and (match_code "reg" "00") (match_test ("CONST_INT_P (XEXP (XEXP (op, 0), 1))")) (match_test ("IN_RANGE (INTVAL (XEXP (XEXP (op, 0), 1)), -1 << 15, (1 << 15)-1)")))) (match_code "reg" "0") ))) + +(define_constraint "Yc" + "Memory reference, for CALL - we can't use SP" + (and (match_code "mem") + (match_code "mem" "0") + (not (ior + (and (match_code "plus" "00") + (and (match_code "reg" "000") + (match_test ("REGNO (XEXP (XEXP (op, 0), 0)) != SP_REGNO")))) + (and (match_code "reg" "0") + (match_test ("REGNO (XEXP (XEXP (op, 0), 0)) != SP_REGNO"))) + )))) + Index: config/msp430/msp430.c =================================================================== --- config/msp430/msp430.c (revision 206582) +++ config/msp430/msp430.c (working copy) @@ -1917,12 +1917,13 @@ msp430_print_operand_addr (FILE * file, /* A low 16-bits of int/lower of register pair B high 16-bits of int/higher of register pair C bits 32-47 of a 64-bit value/reg 3 of a DImode value D bits 48-63 of a 64-bit value/reg 4 of a DImode value H like %B (for backwards compatibility) I inverse of value + J an integer without a # prefix L like %A (for backwards compatibility) O offset of the top of the stack Q like X but generates an A postfix R inverse of condition code, unsigned. X X instruction postfix in large mode Y value - 4 @@ -1947,13 +1948,12 @@ msp430_print_operand (FILE * file, rtx o return; case 'Y': gcc_assert (CONST_INT_P (op)); /* Print the constant value, less four. */ fprintf (file, "#%ld", INTVAL (op) - 4); return; - /* case 'D': used for "decimal without '#'" */ case 'I': if (GET_CODE (op) == CONST_INT) { /* Inverse of constants */ int i = INTVAL (op); fprintf (file, "%d", ~i); @@ -2107,12 +2107,14 @@ msp430_print_operand (FILE * file, rtx o because builtins are expanded before the frame layout is determined. */ fprintf (file, "%d", msp430_initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM) - 2); return; + case 'J': + gcc_assert (GET_CODE (op) == CONST_INT); case 0: break; default: output_operand_lossage ("invalid operand prefix"); return; }