[msp430] fix call-via-sp and epilogue helper patterns
diff mbox

Message ID 201401131917.s0DJHmbn018851@greed.delorie.com
State New
Headers show

Commit Message

DJ Delorie Jan. 13, 2014, 7:17 p.m. UTC
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.

Patch
diff mbox

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;
     }