* mode-classes.def (MODE_POINTER): New. * machmode.h (POINTER_MODE_P): New macro. * genopinit.c (gen_insn): Allow MODE_POINTER for some modifiers. * expr.c (convert_move): Handle MODE_POINTER like MODE_PARTIAL_INT. * recog.c (general_operand, immediate_operand): Allow MODE_POINTER. * stor-layout.c (int_mode_for_mode): Likwise. * genmodes.c (complete_mode): Likewise. (POINTER_MODE): New macro. (make_pointer_mode): New static function. * emit-rtl.c (immed_double_const): Allow MODE_POINTER. * simplify-rtx.c (simplify_immed_subreg): Likewise. * explow.c (trunc_int_for_mode): Likewise. Index: gcc/machmode.h =================================================================== --- gcc/machmode.h (revision 365245) +++ gcc/machmode.h (working copy) @@ -76,6 +76,9 @@ extern const unsigned char mode_class[NU (GET_MODE_CLASS (MODE) == MODE_INT \ || GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT) +/* True if MODE is a pointer mode. */ +#define POINTER_MODE_P(MODE) (GET_MODE_CLASS (MODE) == MODE_POINTER) + /* Nonzero if MODE is a scalar floating point mode. */ #define SCALAR_FLOAT_MODE_P(MODE) \ (GET_MODE_CLASS (MODE) == MODE_FLOAT \ Index: gcc/genopinit.c =================================================================== --- gcc/genopinit.c (revision 365109) +++ gcc/genopinit.c (working copy) @@ -368,11 +368,13 @@ gen_insn (rtx insn) if (*p == 0 && (! force_int || mode_class[i] == MODE_INT - || mode_class[i] == MODE_VECTOR_INT) + || mode_class[i] == MODE_VECTOR_INT + || mode_class[i] == MODE_POINTER) && (! force_partial_int || mode_class[i] == MODE_INT || mode_class[i] == MODE_PARTIAL_INT - || mode_class[i] == MODE_VECTOR_INT) + || mode_class[i] == MODE_VECTOR_INT + || mode_class[i] == MODE_POINTER) && (! force_float || mode_class[i] == MODE_FLOAT || mode_class[i] == MODE_DECIMAL_FLOAT Index: gcc/mode-classes.def =================================================================== --- gcc/mode-classes.def (revision 365109) +++ gcc/mode-classes.def (working copy) @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. DEF_MODE_CLASS (MODE_CC), /* condition code in a register */ \ DEF_MODE_CLASS (MODE_INT), /* integer */ \ DEF_MODE_CLASS (MODE_PARTIAL_INT), /* integer with padding bits */ \ + DEF_MODE_CLASS (MODE_POINTER), /* pointer */ \ DEF_MODE_CLASS (MODE_FRACT), /* signed fractional number */ \ DEF_MODE_CLASS (MODE_UFRACT), /* unsigned fractional number */ \ DEF_MODE_CLASS (MODE_ACCUM), /* signed accumulator */ \ Index: gcc/expr.c =================================================================== --- gcc/expr.c (revision 365245) +++ gcc/expr.c (working copy) @@ -481,7 +481,8 @@ convert_move (rtx to, rtx from, int unsi /* Handle pointer conversion. */ /* SPEE 900220. */ /* Targets are expected to provide conversion insns between PxImode and xImode for all MODE_PARTIAL_INT modes they use, but no others. */ - if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT) + if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT + || GET_MODE_CLASS (to_mode) == MODE_POINTER) { enum machine_mode full_mode = smallest_mode_for_size (GET_MODE_BITSIZE (to_mode), MODE_INT); @@ -495,7 +496,8 @@ convert_move (rtx to, rtx from, int unsi to, from, UNKNOWN); return; } - if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT) + if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT + || GET_MODE_CLASS (from_mode) == MODE_POINTER) { rtx new_from; enum machine_mode full_mode Index: gcc/recog.c =================================================================== --- gcc/recog.c (revision 365109) +++ gcc/recog.c (working copy) @@ -920,7 +920,8 @@ general_operand (rtx op, enum machine_mo if the caller wants something floating. */ if (GET_MODE (op) == VOIDmode && mode != VOIDmode && GET_MODE_CLASS (mode) != MODE_INT - && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT) + && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT + && GET_MODE_CLASS (mode) != MODE_POINTER) return 0; if (CONST_INT_P (op) @@ -1097,7 +1098,8 @@ immediate_operand (rtx op, enum machine_ if the caller wants something floating. */ if (GET_MODE (op) == VOIDmode && mode != VOIDmode && GET_MODE_CLASS (mode) != MODE_INT - && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT) + && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT + && GET_MODE_CLASS (mode) != MODE_POINTER) return 0; if (CONST_INT_P (op) Index: gcc/stor-layout.c =================================================================== --- gcc/stor-layout.c (revision 365246) +++ gcc/stor-layout.c (working copy) @@ -484,6 +484,7 @@ int_mode_for_mode (enum machine_mode mod case MODE_VECTOR_ACCUM: case MODE_VECTOR_UFRACT: case MODE_VECTOR_UACCUM: + case MODE_POINTER: mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0); break; Index: gcc/genmodes.c =================================================================== --- gcc/genmodes.c (revision 365109) +++ gcc/genmodes.c (working copy) @@ -353,6 +353,7 @@ complete_mode (struct mode_data *m) break; case MODE_INT: + case MODE_POINTER: case MODE_FLOAT: case MODE_DECIMAL_FLOAT: case MODE_FRACT: @@ -569,6 +570,19 @@ make_int_mode (const char *name, m->bytesize = bytesize; m->precision = precision; } + +#define POINTER_MODE(N, B, Y) \ + make_pointer_mode (#N, B, Y, __FILE__, __LINE__) + +static void +make_pointer_mode (const char *name, + unsigned int precision, unsigned int bytesize, + const char *file, unsigned int line) +{ + struct mode_data *m = new_mode (MODE_POINTER, name, file, line); + m->bytesize = bytesize; + m->precision = precision; +} #define FRACT_MODE(N, Y, F) \ make_fixed_point_mode (MODE_FRACT, #N, Y, 0, F, __FILE__, __LINE__) Index: gcc/emit-rtl.c =================================================================== --- gcc/emit-rtl.c (revision 365245) +++ gcc/emit-rtl.c (working copy) @@ -542,6 +542,7 @@ immed_double_const (HOST_WIDE_INT i0, HO { gcc_assert (GET_MODE_CLASS (mode) == MODE_INT || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT + || GET_MODE_CLASS (mode) == MODE_POINTER /* We can get a 0 for an error mark. */ || GET_MODE_CLASS (mode) == MODE_VECTOR_INT || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT); Index: gcc/simplify-rtx.c =================================================================== --- gcc/simplify-rtx.c (revision 365109) +++ gcc/simplify-rtx.c (working copy) @@ -5070,6 +5070,7 @@ simplify_immed_subreg (enum machine_mode { case MODE_INT: case MODE_PARTIAL_INT: + case MODE_POINTER: { unsigned HOST_WIDE_INT hi = 0, lo = 0; Index: gcc/explow.c =================================================================== --- gcc/explow.c (revision 365245) +++ gcc/explow.c (working copy) @@ -53,7 +53,7 @@ trunc_int_for_mode (HOST_WIDE_INT c, enu int width = GET_MODE_BITSIZE (mode); /* You want to truncate to a _what_? */ - gcc_assert (SCALAR_INT_MODE_P (mode)); + gcc_assert (SCALAR_INT_MODE_P (mode) || POINTER_MODE_P (mode)); /* Canonicalize BImode to 0 and STORE_FLAG_VALUE. */ if (mode == BImode)