From 6dd12198d088c1e749b67c9e9a92352b2639265a Mon Sep 17 00:00:00 2001 From: Steve Ellcey Date: Thu, 19 Jul 2001 23:26:51 +0000 Subject: [PATCH] * tm.texi (POINTERS_EXTEND_UNSIGNED) Modify definition. * optabs.c (can_extend_p) Check HAVE_ptr_extend for a specialized pointer extension instruction. * combine.c (nonzero_bits,num_sign_bit_copies) Likewise. * simplify-rtx.c (simplify_unary_operation) Likewise. * explow.c (convert_memory_address) Check value of POINTERS_EXTEND_UNSIGNED to avoid some conversions when less than zero. * config/ia64/t-hpux (LIBGCC, INSTALL_LIBGCC, MULTILIB_OPTIONS, MULTILIB_DIRNAMES, MULTILIB_MATCHES) Add multilib support. * config/ia64/hpux.h (CPP_SPEC, ASM_SPEC, SUBTARGET_SWITCHES) Add Multilib Support. (POINTERS_EXTEND_UNSIGNED) Define for ILP32 support. * config/ia64/ia64.h (MASK_ILP32, TARGET_ILP32, SUBTARGET_SWITCHES) Add Multilib Support. (POINTER_SIZE, LONG_TYPE_SIZE, MAX_LONG_TYPE_SIZE) Modify for ILP32 support. * config/ia64/ia64.c (rtx_needs_barrier) Add support for addp4. * config/ia64/ia64.md (ptr_extend) New instruction to "swizzle" a 32 bit HP-UX pointer into a 64 bit HP-UX pointer. From-SVN: r44166 --- gcc/ChangeLog | 23 ++++++++++++++++++++++ gcc/combine.c | 6 +++--- gcc/config/ia64/hpux.h | 17 +++++++++++++++-- gcc/config/ia64/ia64.c | 4 ++++ gcc/config/ia64/ia64.h | 30 ++++++++++++++++------------- gcc/config/ia64/ia64.md | 13 +++++++++++++ gcc/config/ia64/t-hpux | 9 +++++++++ gcc/doc/tm.texi | 6 ++++-- gcc/explow.c | 42 ++++++++++++++++++++++++++--------------- gcc/optabs.c | 7 ++++++- gcc/simplify-rtx.c | 6 +++--- 11 files changed, 124 insertions(+), 39 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e427ce579af..5850d786690 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2001-07-19 Steve Ellcey + + * tm.texi (POINTERS_EXTEND_UNSIGNED) Modify definition. + * optabs.c (can_extend_p) Check HAVE_ptr_extend for a specialized + pointer extension instruction. + * combine.c (nonzero_bits,num_sign_bit_copies) Likewise. + * simplify-rtx.c (simplify_unary_operation) Likewise. + * explow.c (convert_memory_address) Check value of + POINTERS_EXTEND_UNSIGNED to avoid some conversions when + less than zero. + * config/ia64/t-hpux (LIBGCC, INSTALL_LIBGCC, MULTILIB_OPTIONS, + MULTILIB_DIRNAMES, MULTILIB_MATCHES) Add multilib support. + * config/ia64/hpux.h (CPP_SPEC, ASM_SPEC, SUBTARGET_SWITCHES) + Add Multilib Support. + (POINTERS_EXTEND_UNSIGNED) Define for ILP32 support. + * config/ia64/ia64.h (MASK_ILP32, TARGET_ILP32, SUBTARGET_SWITCHES) + Add Multilib Support. + (POINTER_SIZE, LONG_TYPE_SIZE, MAX_LONG_TYPE_SIZE) Modify for ILP32 + support. + * config/ia64/ia64.c (rtx_needs_barrier) Add support for addp4. + * config/ia64/ia64.md (ptr_extend) New instruction to "swizzle" + a 32 bit HP-UX pointer into a 64 bit HP-UX pointer. + 2001-07-19 Alexandre Oliva * simplify-rtx.c (simplify_replace_rtx): Try to obtain mode from diff --git a/gcc/combine.c b/gcc/combine.c index b22dd9bb41b..8658aadbddb 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -7905,7 +7905,7 @@ nonzero_bits (x, mode) switch (code) { case REG: -#ifdef POINTERS_EXTEND_UNSIGNED +#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend) /* If pointers extend unsigned and this is a pointer in Pmode, say that all the bits above ptr_mode are known to be zero. */ if (POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode @@ -8182,7 +8182,7 @@ nonzero_bits (x, mode) /* If pointers extend unsigned and this is an addition or subtraction to a pointer in Pmode, all the bits above ptr_mode are known to be zero. */ - if (POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode + if (POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode && (code == PLUS || code == MINUS) && GET_CODE (XEXP (x, 0)) == REG && REG_POINTER (XEXP (x, 0))) nonzero &= GET_MODE_MASK (ptr_mode); @@ -8363,7 +8363,7 @@ num_sign_bit_copies (x, mode) { case REG: -#ifdef POINTERS_EXTEND_UNSIGNED +#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend) /* If pointers extend signed and this is a pointer in Pmode, say that all the bits above ptr_mode are known to be sign bit copies. */ if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode && mode == Pmode diff --git a/gcc/config/ia64/hpux.h b/gcc/config/ia64/hpux.h index 7da303840f3..c9df25bc818 100644 --- a/gcc/config/ia64/hpux.h +++ b/gcc/config/ia64/hpux.h @@ -35,14 +35,15 @@ Boston, MA 02111-1307, USA. */ #undef CPP_SPEC #define CPP_SPEC "\ %{mcpu=itanium:-D__itanium__} \ - -D__LP64__ -D__LONG_MAX__=9223372036854775807L \ + %{mlp64:-D__LP64__ -D__LONG_MAX__=9223372036854775807L} \ %{!ansi:%{!std=c*:%{!std=i*: -D_HPUX_SOURCE -D__STDC_EXT__}}} \ -D__fpreg=long\\ double \ -D__float80=long\\ double \ -D__float128=long\\ double" #undef ASM_SPEC -#define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic}" +#define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic} \ + %{milp32:-milp32} %{mlp64:-mlp64}" #undef ENDFILE_SPEC @@ -66,6 +67,18 @@ Boston, MA 02111-1307, USA. */ #undef LIB_SPEC #define LIB_SPEC "%{!shared:%{!symbolic:-lc}}" +#undef SUBTARGET_SWITCHES +#define SUBTARGET_SWITCHES \ + { "ilp32", MASK_ILP32, "Generate ILP32 code" }, \ + { "lp64", -MASK_ILP32, "Generate LP64 code" }, + +/* A C expression whose value is zero if pointers that need to be extended + from being `POINTER_SIZE' bits wide to `Pmode' are sign-extended and + greater then zero if they are zero-extended and less then zero if the + ptr_extend instruction should be used. */ + +#define POINTERS_EXTEND_UNSIGNED -1 + #define DONT_USE_BUILTIN_SETJMP #define JMP_BUF_SIZE (8 * 76) diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 9d1d5061b34..63181c755f4 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -4423,6 +4423,10 @@ rtx_needs_barrier (x, flags, pred) case 23: /* cycle display */ break; + case 24: /* addp4 */ + need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred); + break; + case 5: /* recip_approx */ need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred); need_barrier |= rtx_needs_barrier (XVECEXP (x, 0, 1), flags, pred); diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 218b9a017de..7da33a4d4fe 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -53,7 +53,7 @@ extern int target_flags; #define MASK_VOL_ASM_STOP 0x00000010 /* Emit stop bits for vol ext asm. */ -/* 0x00000020 is available. */ +#define MASK_ILP32 0x00000020 /* Generate ILP32 code. */ #define MASK_B_STEP 0x00000040 /* Emit code for Itanium B step. */ @@ -81,6 +81,8 @@ extern int target_flags; #define TARGET_VOL_ASM_STOP (target_flags & MASK_VOL_ASM_STOP) +#define TARGET_ILP32 (target_flags & MASK_ILP32) + #define TARGET_B_STEP (target_flags & MASK_B_STEP) #define TARGET_REG_NAMES (target_flags & MASK_REG_NAMES) @@ -144,6 +146,7 @@ extern int target_flags; N_("Enable Dwarf 2 line debug info via GNU as")}, \ { "no-dwarf2-asm", -MASK_DWARF2_ASM, \ N_("Disable Dwarf 2 line debug info via GNU as")}, \ + SUBTARGET_SWITCHES \ { "", TARGET_DEFAULT | TARGET_CPU_DEFAULT, \ NULL } \ } @@ -158,6 +161,10 @@ extern int target_flags; #define TARGET_CPU_DEFAULT 0 #endif +#ifndef SUBTARGET_SWITCHES +#define SUBTARGET_SWITCHES +#endif + /* This macro is similar to `TARGET_SWITCHES' but defines names of command options that have values. Its definition is an initializer with a subgrouping for each command option. */ @@ -210,7 +217,7 @@ extern const char *ia64_fixed_range_string; This should be defined if `SIZE_TYPE' depends on target dependent flags which are not accessible to the preprocessor. Otherwise, it should not be defined. */ -/* ??? Needs to be defined for P64 code. */ +/* This is always "long" so it doesn't "change" in ILP32 vs. LP64. */ /* #define NO_BUILTIN_SIZE_TYPE */ /* If this macro is defined, the preprocessor will not define the builtin macro @@ -220,7 +227,7 @@ extern const char *ia64_fixed_range_string; This should be defined if `PTRDIFF_TYPE' depends on target dependent flags which are not accessible to the preprocessor. Otherwise, it should not be defined. */ -/* ??? Needs to be defined for P64 code. */ +/* This is always "long" so it doesn't "change" in ILP32 vs. LP64. */ /* #define NO_BUILTIN_PTRDIFF_TYPE */ /* A C string constant that tells the GNU CC driver program options to pass to @@ -306,16 +313,15 @@ extern const char *ia64_fixed_range_string; /* Width of a pointer, in bits. You must specify a value no wider than the width of `Pmode'. If it is not equal to the width of `Pmode', you must define `POINTERS_EXTEND_UNSIGNED'. */ -/* ??? Implement optional 32 bit pointer size later? */ -#define POINTER_SIZE 64 +#define POINTER_SIZE (TARGET_ILP32 ? 32 : 64) -/* A C expression whose value is nonzero if pointers that need to be extended - from being `POINTER_SIZE' bits wide to `Pmode' are sign-extended and zero if - they are zero-extended. +/* A C expression whose value is zero if pointers that need to be extended + from being `POINTER_SIZE' bits wide to `Pmode' are sign-extended and one if + they are zero-extended and negative one if there is an ptr_extend operation. You need not define this macro if the `POINTER_SIZE' is equal to the width of `Pmode'. */ -/* ??? May need this for 32 bit pointers. */ +/* Need this for 32 bit pointers, see hpux.h for setting it. */ /* #define POINTERS_EXTEND_UNSIGNED */ /* A macro to update MODE and UNSIGNEDP when an object whose type is TYPE and @@ -436,15 +442,13 @@ while (0) /* A C expression for the size in bits of the type `long' on the target machine. If you don't define this, the default is one word. */ -/* ??? Should be 32 for ILP32 code. */ -#define LONG_TYPE_SIZE 64 +#define LONG_TYPE_SIZE (TARGET_ILP32 ? 32 : 64) /* Maximum number for the size in bits of the type `long' on the target machine. If this is undefined, the default is `LONG_TYPE_SIZE'. Otherwise, it is the constant value that is the largest value that `LONG_TYPE_SIZE' can have at run-time. This is used in `cpp'. */ -/* ??? Should be 64 for ILP32 code. */ -/* #define MAX_LONG_TYPE_SIZE */ +#define MAX_LONG_TYPE_SIZE 64 /* A C expression for the size in bits of the type `long long' on the target machine. If you don't define this, the default is two words. If you want diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index 3a54dd5c9fe..8959fbda88d 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -66,6 +66,7 @@ ;; 21 flushrs ;; 22 bundle selector ;; 23 cycle display +;; 24 addp4 ;; ;; unspec_volatile: ;; 0 alloc @@ -5169,3 +5170,15 @@ [(set_attr "itanium_class" "ignore") (set_attr "predicable" "no")]) +;; +;; +;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit +;; pointer. This is used by the HP-UX 32 bit mode. + +(define_insn "ptr_extend" + [(set (match_operand:DI 0 "gr_register_operand" "=r") + (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")] 24))] + "" + "addp4 %0 = 0,%1" + [(set_attr "itanium_class" "ialu")]) + diff --git a/gcc/config/ia64/t-hpux b/gcc/config/ia64/t-hpux index b6234bd4903..9f8296ba892 100644 --- a/gcc/config/ia64/t-hpux +++ b/gcc/config/ia64/t-hpux @@ -1,3 +1,12 @@ +# We need multilib support for HPUX's ILP32 & LP64 modes. + +LIBGCC = stmp-multilib +INSTALL_LIBGCC = install-multilib + +MULTILIB_OPTIONS = milp32/mlp64 +MULTILIB_DIRNAMES = hpux32 hpux64 +MULTILIB_MATCHES = + # Support routines for HP-UX 128 bit floats. LIB2FUNCS_EXTRA=quadlib.c diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 6fcc3ba8a47..162dc9e4f96 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -954,9 +954,11 @@ you must define @code{POINTERS_EXTEND_UNSIGNED}. @findex POINTERS_EXTEND_UNSIGNED @item POINTERS_EXTEND_UNSIGNED -A C expression whose value is nonzero if pointers that need to be +A C expression whose value is greater than zero if pointers that need to be extended from being @code{POINTER_SIZE} bits wide to @code{Pmode} are to -be zero-extended and zero if they are to be sign-extended. +be zero-extended and zero if they are to be sign-extended. If the value +is less then zero then there must be an "ptr_extend" instruction that +extends a pointer from @code{POINTER_SIZE} to @code{Pmode}. You need not define this macro if the @code{POINTER_SIZE} is equal to the width of @code{Pmode}. diff --git a/gcc/explow.c b/gcc/explow.c index afb51d9e655..a8249999c98 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -365,25 +365,36 @@ convert_memory_address (to_mode, x) return x; case SUBREG: - if (GET_MODE (SUBREG_REG (x)) == to_mode) + if (POINTERS_EXTEND_UNSIGNED >= 0 + && GET_MODE (SUBREG_REG (x)) == to_mode) return SUBREG_REG (x); break; case LABEL_REF: - temp = gen_rtx_LABEL_REF (to_mode, XEXP (x, 0)); - LABEL_REF_NONLOCAL_P (temp) = LABEL_REF_NONLOCAL_P (x); - return temp; + if (POINTERS_EXTEND_UNSIGNED >= 0) + { + temp = gen_rtx_LABEL_REF (to_mode, XEXP (x, 0)); + LABEL_REF_NONLOCAL_P (temp) = LABEL_REF_NONLOCAL_P (x); + return temp; + } + break; case SYMBOL_REF: - temp = gen_rtx_SYMBOL_REF (to_mode, XSTR (x, 0)); - SYMBOL_REF_FLAG (temp) = SYMBOL_REF_FLAG (x); - CONSTANT_POOL_ADDRESS_P (temp) = CONSTANT_POOL_ADDRESS_P (x); - STRING_POOL_ADDRESS_P (temp) = STRING_POOL_ADDRESS_P (x); - return temp; + if (POINTERS_EXTEND_UNSIGNED >= 0) + { + temp = gen_rtx_SYMBOL_REF (to_mode, XSTR (x, 0)); + SYMBOL_REF_FLAG (temp) = SYMBOL_REF_FLAG (x); + CONSTANT_POOL_ADDRESS_P (temp) = CONSTANT_POOL_ADDRESS_P (x); + STRING_POOL_ADDRESS_P (temp) = STRING_POOL_ADDRESS_P (x); + return temp; + } + break; case CONST: - return gen_rtx_CONST (to_mode, - convert_memory_address (to_mode, XEXP (x, 0))); + if (POINTERS_EXTEND_UNSIGNED >= 0) + return gen_rtx_CONST (to_mode, + convert_memory_address (to_mode, XEXP (x, 0))); + break; case PLUS: case MULT: @@ -391,10 +402,11 @@ convert_memory_address (to_mode, x) permute the conversion and addition operation. We can always safely permute them if we are making the address narrower. In addition, always permute the operations if this is a constant. */ - if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode) - || (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT - && (INTVAL (XEXP (x, 1)) + 20000 < 40000 - || CONSTANT_P (XEXP (x, 0))))) + if (POINTERS_EXTEND_UNSIGNED >= 0 + && (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode) + || (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT + && (INTVAL (XEXP (x, 1)) + 20000 < 40000 + || CONSTANT_P (XEXP (x, 0)))))) return gen_rtx_fmt_ee (GET_CODE (x), to_mode, convert_memory_address (to_mode, XEXP (x, 0)), convert_memory_address (to_mode, XEXP (x, 1))); diff --git a/gcc/optabs.c b/gcc/optabs.c index 57c87fad16d..f135ad18765 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -3919,7 +3919,12 @@ can_extend_p (to_mode, from_mode, unsignedp) enum machine_mode to_mode, from_mode; int unsignedp; { - return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0]; +#ifdef HAVE_ptr_extend + if (unsignedp < 0) + return CODE_FOR_ptr_extend; + else +#endif + return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0]; } /* Generate the body of an insn to extend Y (with mode MFROM) diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 1d090ba7783..ed7b0ea6e55 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -699,7 +699,7 @@ simplify_unary_operation (code, mode, op, op_mode) && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF) return XEXP (op, 0); -#ifdef POINTERS_EXTEND_UNSIGNED +#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend) if (! POINTERS_EXTEND_UNSIGNED && mode == Pmode && GET_MODE (op) == ptr_mode && (CONSTANT_P (op) @@ -711,9 +711,9 @@ simplify_unary_operation (code, mode, op, op_mode) #endif break; -#ifdef POINTERS_EXTEND_UNSIGNED +#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend) case ZERO_EXTEND: - if (POINTERS_EXTEND_UNSIGNED + if (POINTERS_EXTEND_UNSIGNED > 0 && mode == Pmode && GET_MODE (op) == ptr_mode && (CONSTANT_P (op) || (GET_CODE (op) == SUBREG -- 2.30.2