+2001-07-19 Steve Ellcey <sje@cup.hp.com>
+
+ * 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 <aoliva@redhat.com>
* simplify-rtx.c (simplify_replace_rtx): Try to obtain mode from
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
/* 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);
{
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
#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
#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)
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);
#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. */
#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)
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 } \
}
#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. */
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
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
/* 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
/* 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
;; 21 flushrs
;; 22 bundle selector
;; 23 cycle display
+;; 24 addp4
;;
;; unspec_volatile:
;; 0 alloc
[(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")])
+
+# 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
@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}.
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:
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)));
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)
&& 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)
#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