There are two ways symbols can be output in ptx, either as plain "x",
which represents the address in the .global address space, or as
"generic(x)" which is the converted form to a generic address. To
distinguish the cases, it's necessary to allow ADDR_SPACE_CONVERT_EXPRs
in initializers, and to deal with them when emitting constants.  This
patch handles the second part, by translating them to an AS_CONVERT rtx
code. There'll be a followup patch to relax some C frontend restrictions
later.

	gcc/
	* rtl.def (AS_CONVERT): New expression.
	* expr.c (expand_expr_real_2) <case ADDR_SPACE_CONVERT_EXPR>: Generate
	it if modifier is EXPAND_INITIALIZER.
	* varasm.c (copy_constant, output_addressed_constants,
	initializer_constant_valid_p_1): Handle ADDR_SPACE_CONVERT_EXPR.

------------------------------------------------------------------------
Index: gcc/rtl.def
===================================================================
--- gcc/rtl.def	(revision 422356)
+++ gcc/rtl.def	(revision 422357)
@@ -632,6 +632,11 @@ DEF_RTL_EXPR(SAT_FRACT, "sat_fract", "e"
    NOTE: fractional can be either signed or unsigned for conversions.  */
 DEF_RTL_EXPR(UNSIGNED_SAT_FRACT, "unsigned_sat_fract", "e", RTX_UNARY)
 
+/* Conversions from one address space into another.  The second operand
+   gives the target address space, the third operand the source address
+   space.  */
+DEF_RTL_EXPR(AS_CONVERT, "as_convert", "eii", RTX_EXTRA)
+
 /* Absolute value */
 DEF_RTL_EXPR(ABS, "abs", "e", RTX_UNARY)
 
Index: gcc/expr.c
===================================================================
--- gcc/expr.c	(revision 422356)
+++ gcc/expr.c	(revision 422357)
@@ -8124,6 +8124,19 @@ expand_expr_real_2 (sepops ops, rtx targ
 	    || targetm.addr_space.subset_p (as_from, as_to))
 	  {
 	    op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
+	    if (modifier == EXPAND_INITIALIZER)
+	      {
+		enum machine_mode new_mode;
+		rtx t = op0;
+		if (GET_CODE (t) == CONST)
+		  t = XEXP (t, 0);
+		new_mode = targetm.addr_space.address_mode (as_to);
+		t = gen_rtx_AS_CONVERT (new_mode, t, as_to, as_from);
+		if (CONSTANT_P (op0))
+		  t = gen_rtx_CONST (new_mode, t);
+		return t;
+	      }
+
 	    op0 = targetm.addr_space.convert (op0, treeop0_type, type);
 	    gcc_assert (op0);
 	    return op0;
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	(revision 422356)
+++ gcc/varasm.c	(revision 422357)
@@ -3115,6 +3115,10 @@ copy_constant (tree exp)
       else
 	return copy_node (exp);
 
+    case ADDR_SPACE_CONVERT_EXPR:
+      return build1 (ADDR_SPACE_CONVERT_EXPR, TREE_TYPE (exp),
+		     copy_constant (TREE_OPERAND (exp, 0)));
+
     case INTEGER_CST:
     case REAL_CST:
     case FIXED_CST:
@@ -4145,6 +4149,7 @@ output_addressed_constants (tree exp)
       /* Fall through.  */
 
     CASE_CONVERT:
+    case ADDR_SPACE_CONVERT_EXPR:
     case VIEW_CONVERT_EXPR:
       output_addressed_constants (TREE_OPERAND (exp, 0));
       break;
@@ -4315,6 +4320,11 @@ initializer_constant_valid_p_1 (tree val
 
       return TREE_STATIC (value) ? null_pointer_node : NULL_TREE;
 
+    case ADDR_SPACE_CONVERT_EXPR:
+      return initializer_constant_valid_p_1 (TREE_OPERAND (value, 0),
+					     TREE_TYPE (TREE_OPERAND (value, 0)),
+					     cache);
+      
     case INTEGER_CST:
     case VECTOR_CST:
     case REAL_CST:
@@ -5396,7 +5406,7 @@ weak_finish_1 (tree decl)
 #endif
 }
 
-/* Fiven an assembly name, find the decl it is associated with.  */
+/* Given an assembly name, find the decl it is associated with.  */
 static tree
 find_decl (tree target)
 {

Reply via email to