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) {