Commit 02befdf4 by Zack Weinberg

genmodes.c (struct mode_data): Add contained and next_cont fields.

	* genmodes.c (struct mode_data): Add contained and next_cont
	fields.
	(complete_mode): Maintain linked list of modes that have a
	given component.
	(emit_mode_unit_size): Delete.
	(emit_mode_nunits): New.
	(emit_insn_modes_c): Update to match.
	(emit_mode_adjustments): Propagate size and alignment
	adjustments from component modes to their containers.
	* machmode.h (mode_unit_size): Delete.
	(mode_nunits): New.
	(GET_MODE_NUNITS): Just return the value in the table.
	(GET_MODE_UNIT_SIZE): Compute using GET_MODE_INNER and
	GET_MODE_SIZE.
	* expmed.c (store_bit_field, extract_bit_field): Can use a
	plain move instruction if bitsize >= GET_MODE_BITSIZE of
	destination/source mode, respectively.
	* varasm.c (assemble_real): Write out the full size of the
	constant, not just its bitsize.
	(output_constant): Honor TYPE_MODE of TREE_REAL_CSTs.

	* config/ia64/ia64-modes.def: Define XFmode as well as TFmode.
	Use ADJUST_BYTESIZE and ADJUST_ALIGNMENT to set size and
	alignment of XF and TF modes in compliance with ia64 ABIs.
	Can now hardwire the format of both modes.
	* config/ia64/ia64.c: Change TFmode to XFmode wherever appropriate.
	(general_tfmode_operand, destination_tfmode_operand)
	(tfreg_or_fp01_operand, spill_tfmode_operand): Rename to
	general_xfmode_operand, destination_xfmode_operand,
	xfreg_or_fp01_operand, spill_xfmode_operand respectively.
	(ia64_init_builtins): Make TYPE_PRECISION of fpreg_type
	and float80_type be 96 so they get XFmode.  Use !TARGET_HPUX,
	not INTEL_EXTENDED_IEEE_FORMAT, to decide how to define
	__float128.
	* config/ia64/ia64.h: Default TARGET_HPUX to 0.
	Change TFmode to XFmode wherever appropriate.  Remove all
	references to INTEL_EXTENDED_IEEE_FORMAT.
	(LONG_DOUBLE_TYPE_SIZE): Varies with TARGET_HPUX.
	(LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Define (always 96).
	(PREDICATE_CODES): Update to match function renames.
	* config/ia64/ia64.md: Change TF to XF throughout; rename all
	patterns to match.  Remove all references to
	INTEL_EXTENDED_IEEE_FORMAT.  Update predicate calls to match
	function renames.
	* config/ia64/ia64-protos.c: Update all prototypes to match
	renamed functions.
	* config/ia64/hpux.h: Redefine TARGET_HPUX to 1.
	Remove all references to INTEL_EXTENDED_IEEE_FORMAT.
	* config/ia64/lib1funcs.asm: Add __divxf3 as new name for
	__divtf3; keep old name for backward compatibility.
	(L__compat): New section providing forwarding stubs for
	__fixtfti, __fixunstfti, __floattitf.
	* config/ia64/t-ia64: Add __compat to LIB1ASMFUNCS.

From-SVN: r72916
parent 569827c9
2003-10-24 Zack Weinberg <zack@codesourcery.com>
* genmodes.c (struct mode_data): Add contained and next_cont
fields.
(complete_mode): Maintain linked list of modes that have a
given component.
(emit_mode_unit_size): Delete.
(emit_mode_nunits): New.
(emit_insn_modes_c): Update to match.
(emit_mode_adjustments): Propagate size and alignment
adjustments from component modes to their containers.
* machmode.h (mode_unit_size): Delete.
(mode_nunits): New.
(GET_MODE_NUNITS): Just return the value in the table.
(GET_MODE_UNIT_SIZE): Compute using GET_MODE_INNER and
GET_MODE_SIZE.
* expmed.c (store_bit_field, extract_bit_field): Can use a
plain move instruction if bitsize >= GET_MODE_BITSIZE of
destination/source mode, respectively.
* varasm.c (assemble_real): Write out the full size of the
constant, not just its bitsize.
(output_constant): Honor TYPE_MODE of TREE_REAL_CSTs.
* config/ia64/ia64-modes.def: Define XFmode as well as TFmode.
Use ADJUST_BYTESIZE and ADJUST_ALIGNMENT to set size and
alignment of XF and TF modes in compliance with ia64 ABIs.
Can now hardwire the format of both modes.
* config/ia64/ia64.c: Change TFmode to XFmode wherever appropriate.
(general_tfmode_operand, destination_tfmode_operand)
(tfreg_or_fp01_operand, spill_tfmode_operand): Rename to
general_xfmode_operand, destination_xfmode_operand,
xfreg_or_fp01_operand, spill_xfmode_operand respectively.
(ia64_init_builtins): Make TYPE_PRECISION of fpreg_type
and float80_type be 96 so they get XFmode. Use !TARGET_HPUX,
not INTEL_EXTENDED_IEEE_FORMAT, to decide how to define
__float128.
* config/ia64/ia64.h: Default TARGET_HPUX to 0.
Change TFmode to XFmode wherever appropriate. Remove all
references to INTEL_EXTENDED_IEEE_FORMAT.
(LONG_DOUBLE_TYPE_SIZE): Varies with TARGET_HPUX.
(LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Define (always 96).
(PREDICATE_CODES): Update to match function renames.
* config/ia64/ia64.md: Change TF to XF throughout; rename all
patterns to match. Remove all references to
INTEL_EXTENDED_IEEE_FORMAT. Update predicate calls to match
function renames.
* config/ia64/ia64-protos.c: Update all prototypes to match
renamed functions.
* config/ia64/hpux.h: Redefine TARGET_HPUX to 1.
Remove all references to INTEL_EXTENDED_IEEE_FORMAT.
* config/ia64/lib1funcs.asm: Add __divxf3 as new name for
__divtf3; keep old name for backward compatibility.
(L__compat): New section providing forwarding stubs for
__fixtfti, __fixunstfti, __floattitf.
* config/ia64/t-ia64: Add __compat to LIB1ASMFUNCS.
2003-10-24 Geoffrey Keating <geoffk@apple.com> 2003-10-24 Geoffrey Keating <geoffk@apple.com>
PR 10757 PR 10757
...@@ -29,7 +85,7 @@ ...@@ -29,7 +85,7 @@
($(docobjdir)/%.1): Depend on .pod instead of .texi. ($(docobjdir)/%.1): Depend on .pod instead of .texi.
($(docobjdir)/%.7): Likewise. ($(docobjdir)/%.7): Likewise.
(%.pod): New implicit rule. (%.pod): New implicit rule.
(cpp.pod): New dependency only rule. (cpp.pod): New dependency only rule.
(gcc.pod): New intermediate rule with dependencies and commands. (gcc.pod): New intermediate rule with dependencies and commands.
(gfdl.pod): Likewise. (gfdl.pod): Likewise.
(fsf-funding.pod): Likewise. (fsf-funding.pod): Likewise.
......
...@@ -25,6 +25,10 @@ Boston, MA 02111-1307, USA. */ ...@@ -25,6 +25,10 @@ Boston, MA 02111-1307, USA. */
#define TARGET_VERSION fprintf (stderr, " (IA-64) HP-UX"); #define TARGET_VERSION fprintf (stderr, " (IA-64) HP-UX");
/* Enable HPUX ABI quirks. */
#undef TARGET_HPUX
#define TARGET_HPUX 1
/* Target OS builtins. */ /* Target OS builtins. */
#define TARGET_OS_CPP_BUILTINS() \ #define TARGET_OS_CPP_BUILTINS() \
do { \ do { \
...@@ -106,7 +110,8 @@ do { \ ...@@ -106,7 +110,8 @@ do { \
returned just like a char variable and that is wrong on HP-UX returned just like a char variable and that is wrong on HP-UX
IA64. */ IA64. */
#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) (TREE_CODE (TREE_TYPE (FIELD)) != REAL_TYPE || (MODE == TFmode && !INTEL_EXTENDED_IEEE_FORMAT)) #define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \
(TREE_CODE (TREE_TYPE (FIELD)) != REAL_TYPE || MODE == TFmode)
/* ASM_OUTPUT_EXTERNAL_LIBCALL defaults to just a globalize_label call, /* ASM_OUTPUT_EXTERNAL_LIBCALL defaults to just a globalize_label call,
but that doesn't put out the @function type information which causes but that doesn't put out the @function type information which causes
...@@ -187,10 +192,6 @@ do { \ ...@@ -187,10 +192,6 @@ do { \
#undef TARGET_C99_FUNCTIONS #undef TARGET_C99_FUNCTIONS
#define TARGET_C99_FUNCTIONS 1 #define TARGET_C99_FUNCTIONS 1
/* We are using IEEE quad precision, not a double-extended with padding. */
#undef INTEL_EXTENDED_IEEE_FORMAT
#define INTEL_EXTENDED_IEEE_FORMAT 0
#define TARGET_INIT_LIBFUNCS ia64_hpux_init_libfuncs #define TARGET_INIT_LIBFUNCS ia64_hpux_init_libfuncs
#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode) #define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode)
/* Definitions of target machine GNU compiler. IA-64 version. /* Definitions of target machine GNU compiler. IA-64 version.
Copyright (C) 2002 Free Software Foundation, Inc. Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by James E. Wilson <wilson@cygnus.com> and Contributed by James E. Wilson <wilson@cygnus.com> and
David Mosberger <davidm@hpl.hp.com>. David Mosberger <davidm@hpl.hp.com>.
...@@ -20,8 +20,41 @@ along with GCC; see the file COPYING. If not, write to ...@@ -20,8 +20,41 @@ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
/* hpux will override this in ia64_override_options. */ /* IA64 requires both XF and TF modes.
FLOAT_MODE (TF, 16, ieee_extended_intel_128_format); XFmode is __float80 is IEEE extended; TFmode is __float128
is IEEE quad.
IEEE extended is 128 bits wide, except in ILP32 mode, but we
have to say it's 12 bytes so that the bitsize and wider_mode
tables are correctly set up. We correct its size below. */
FLOAT_MODE (XF, 12, ieee_extended_intel_128_format);
FLOAT_MODE (TF, 16, ieee_quad_format);
/* The above produces:
mode ILP32 size/align LP64 size/align
XF 12/4 12/4
TF 16/16 16/16
psABI expectations:
mode ILP32 size/align LP64 size/align
XF - 16/16
TF - -
HPUX expectations:
mode ILP32 size/align LP64 size/align
XF 16/16 16/16
TF 16/8 -
We fix this up here. */
ADJUST_BYTESIZE (XF, (TARGET_ILP32 && !TARGET_HPUX) ? 12 : 16);
ADJUST_ALIGNMENT (XF, (TARGET_ILP32 && !TARGET_HPUX) ? 4 : 16);
ADJUST_ALIGNMENT (TF, (TARGET_ILP32 && TARGET_HPUX) ? 8 : 16);
/* 256-bit integer mode is needed for STACK_SAVEAREA_MODE. */ /* 256-bit integer mode is needed for STACK_SAVEAREA_MODE. */
INT_MODE (OI, 32); INT_MODE (OI, 32);
......
...@@ -70,9 +70,9 @@ extern int predicate_operator (rtx, enum machine_mode); ...@@ -70,9 +70,9 @@ extern int predicate_operator (rtx, enum machine_mode);
extern int ar_lc_reg_operand (rtx, enum machine_mode); extern int ar_lc_reg_operand (rtx, enum machine_mode);
extern int ar_ccv_reg_operand (rtx, enum machine_mode); extern int ar_ccv_reg_operand (rtx, enum machine_mode);
extern int ar_pfs_reg_operand (rtx, enum machine_mode); extern int ar_pfs_reg_operand (rtx, enum machine_mode);
extern int general_tfmode_operand (rtx, enum machine_mode); extern int general_xfmode_operand (rtx, enum machine_mode);
extern int destination_tfmode_operand (rtx, enum machine_mode); extern int destination_xfmode_operand (rtx, enum machine_mode);
extern int tfreg_or_fp01_operand (rtx, enum machine_mode); extern int xfreg_or_fp01_operand (rtx, enum machine_mode);
extern int basereg_operand (rtx, enum machine_mode); extern int basereg_operand (rtx, enum machine_mode);
extern rtx ia64_expand_move (rtx, rtx); extern rtx ia64_expand_move (rtx, rtx);
...@@ -81,7 +81,7 @@ extern int addp4_optimize_ok (rtx, rtx); ...@@ -81,7 +81,7 @@ extern int addp4_optimize_ok (rtx, rtx);
extern void ia64_emit_cond_move (rtx, rtx, rtx); extern void ia64_emit_cond_move (rtx, rtx, rtx);
extern int ia64_depz_field_mask (rtx, rtx); extern int ia64_depz_field_mask (rtx, rtx);
extern rtx ia64_split_timode (rtx[], rtx, rtx); extern rtx ia64_split_timode (rtx[], rtx, rtx);
extern rtx spill_tfmode_operand (rtx, int); extern rtx spill_xfmode_operand (rtx, int);
extern rtx ia64_expand_compare (enum rtx_code, enum machine_mode); extern rtx ia64_expand_compare (enum rtx_code, enum machine_mode);
extern void ia64_expand_call (rtx, rtx, rtx, int); extern void ia64_expand_call (rtx, rtx, rtx, int);
extern void ia64_split_call (rtx, rtx, rtx, rtx, rtx, int, int); extern void ia64_split_call (rtx, rtx, rtx, rtx, rtx, int, int);
......
...@@ -923,7 +923,7 @@ ar_pfs_reg_operand (register rtx op, enum machine_mode mode) ...@@ -923,7 +923,7 @@ ar_pfs_reg_operand (register rtx op, enum machine_mode mode)
/* Like general_operand, but don't allow (mem (addressof)). */ /* Like general_operand, but don't allow (mem (addressof)). */
int int
general_tfmode_operand (rtx op, enum machine_mode mode) general_xfmode_operand (rtx op, enum machine_mode mode)
{ {
if (! general_operand (op, mode)) if (! general_operand (op, mode))
return 0; return 0;
...@@ -935,7 +935,7 @@ general_tfmode_operand (rtx op, enum machine_mode mode) ...@@ -935,7 +935,7 @@ general_tfmode_operand (rtx op, enum machine_mode mode)
/* Similarly. */ /* Similarly. */
int int
destination_tfmode_operand (rtx op, enum machine_mode mode) destination_xfmode_operand (rtx op, enum machine_mode mode)
{ {
if (! destination_operand (op, mode)) if (! destination_operand (op, mode))
return 0; return 0;
...@@ -947,7 +947,7 @@ destination_tfmode_operand (rtx op, enum machine_mode mode) ...@@ -947,7 +947,7 @@ destination_tfmode_operand (rtx op, enum machine_mode mode)
/* Similarly. */ /* Similarly. */
int int
tfreg_or_fp01_operand (rtx op, enum machine_mode mode) xfreg_or_fp01_operand (rtx op, enum machine_mode mode)
{ {
if (GET_CODE (op) == SUBREG) if (GET_CODE (op) == SUBREG)
return 0; return 0;
...@@ -1430,34 +1430,34 @@ ia64_split_timode (rtx out[2], rtx in, rtx scratch) ...@@ -1430,34 +1430,34 @@ ia64_split_timode (rtx out[2], rtx in, rtx scratch)
} }
} }
/* ??? Fixing GR->FR TFmode moves during reload is hard. You need to go /* ??? Fixing GR->FR XFmode moves during reload is hard. You need to go
through memory plus an extra GR scratch register. Except that you can through memory plus an extra GR scratch register. Except that you can
either get the first from SECONDARY_MEMORY_NEEDED or the second from either get the first from SECONDARY_MEMORY_NEEDED or the second from
SECONDARY_RELOAD_CLASS, but not both. SECONDARY_RELOAD_CLASS, but not both.
We got into problems in the first place by allowing a construct like We got into problems in the first place by allowing a construct like
(subreg:TF (reg:TI)), which we got from a union containing a long double. (subreg:XF (reg:TI)), which we got from a union containing a long double.
This solution attempts to prevent this situation from occurring. When This solution attempts to prevent this situation from occurring. When
we see something like the above, we spill the inner register to memory. */ we see something like the above, we spill the inner register to memory. */
rtx rtx
spill_tfmode_operand (rtx in, int force) spill_xfmode_operand (rtx in, int force)
{ {
if (GET_CODE (in) == SUBREG if (GET_CODE (in) == SUBREG
&& GET_MODE (SUBREG_REG (in)) == TImode && GET_MODE (SUBREG_REG (in)) == TImode
&& GET_CODE (SUBREG_REG (in)) == REG) && GET_CODE (SUBREG_REG (in)) == REG)
{ {
rtx mem = gen_mem_addressof (SUBREG_REG (in), NULL_TREE, /*rescan=*/true); rtx mem = gen_mem_addressof (SUBREG_REG (in), NULL_TREE, /*rescan=*/true);
return gen_rtx_MEM (TFmode, copy_to_reg (XEXP (mem, 0))); return gen_rtx_MEM (XFmode, copy_to_reg (XEXP (mem, 0)));
} }
else if (force && GET_CODE (in) == REG) else if (force && GET_CODE (in) == REG)
{ {
rtx mem = gen_mem_addressof (in, NULL_TREE, /*rescan=*/true); rtx mem = gen_mem_addressof (in, NULL_TREE, /*rescan=*/true);
return gen_rtx_MEM (TFmode, copy_to_reg (XEXP (mem, 0))); return gen_rtx_MEM (XFmode, copy_to_reg (XEXP (mem, 0)));
} }
else if (GET_CODE (in) == MEM else if (GET_CODE (in) == MEM
&& GET_CODE (XEXP (in, 0)) == ADDRESSOF) && GET_CODE (XEXP (in, 0)) == ADDRESSOF)
return change_address (in, TFmode, copy_to_reg (XEXP (in, 0))); return change_address (in, XFmode, copy_to_reg (XEXP (in, 0)));
else else
return in; return in;
} }
...@@ -2679,7 +2679,7 @@ ia64_expand_prologue (void) ...@@ -2679,7 +2679,7 @@ ia64_expand_prologue (void)
{ {
if (cfa_off & 15) if (cfa_off & 15)
abort (); abort ();
reg = gen_rtx_REG (TFmode, regno); reg = gen_rtx_REG (XFmode, regno);
do_spill (gen_fr_spill_x, reg, cfa_off, reg); do_spill (gen_fr_spill_x, reg, cfa_off, reg);
cfa_off -= 16; cfa_off -= 16;
} }
...@@ -2849,7 +2849,7 @@ ia64_expand_epilogue (int sibcall_p) ...@@ -2849,7 +2849,7 @@ ia64_expand_epilogue (int sibcall_p)
{ {
if (cfa_off & 15) if (cfa_off & 15)
abort (); abort ();
reg = gen_rtx_REG (TFmode, regno); reg = gen_rtx_REG (XFmode, regno);
do_restore (gen_fr_restore_x, reg, cfa_off); do_restore (gen_fr_restore_x, reg, cfa_off);
cfa_off -= 16; cfa_off -= 16;
} }
...@@ -3305,16 +3305,15 @@ hfa_element_mode (tree type, int nested) ...@@ -3305,16 +3305,15 @@ hfa_element_mode (tree type, int nested)
types though. */ types though. */
case COMPLEX_TYPE: case COMPLEX_TYPE:
if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_FLOAT if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_FLOAT
&& (TYPE_MODE (type) != TCmode || INTEL_EXTENDED_IEEE_FORMAT)) && TYPE_MODE (type) != TCmode)
return mode_for_size (GET_MODE_UNIT_SIZE (TYPE_MODE (type)) return GET_MODE_INNER (TYPE_MODE (type));
* BITS_PER_UNIT, MODE_FLOAT, 0);
else else
return VOIDmode; return VOIDmode;
case REAL_TYPE: case REAL_TYPE:
/* We want to return VOIDmode for raw REAL_TYPEs, but the actual /* We want to return VOIDmode for raw REAL_TYPEs, but the actual
mode if this is contained within an aggregate. */ mode if this is contained within an aggregate. */
if (nested && (TYPE_MODE (type) != TFmode || INTEL_EXTENDED_IEEE_FORMAT)) if (nested && TYPE_MODE (type) != TFmode)
return TYPE_MODE (type); return TYPE_MODE (type);
else else
return VOIDmode; return VOIDmode;
...@@ -3482,8 +3481,8 @@ ia64_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, ...@@ -3482,8 +3481,8 @@ ia64_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
/* Integral and aggregates go in general registers. If we have run out of /* Integral and aggregates go in general registers. If we have run out of
FR registers, then FP values must also go in general registers. This can FR registers, then FP values must also go in general registers. This can
happen when we have a SFmode HFA. */ happen when we have a SFmode HFA. */
else if (((mode == TFmode) && ! INTEL_EXTENDED_IEEE_FORMAT) else if (mode == TFmode || mode == TCmode
|| (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS)) || (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS))
{ {
int byte_size = ((mode == BLKmode) int byte_size = ((mode == BLKmode)
? int_size_in_bytes (type) : GET_MODE_SIZE (mode)); ? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
...@@ -3784,8 +3783,7 @@ ia64_function_value (tree valtype, tree func ATTRIBUTE_UNUSED) ...@@ -3784,8 +3783,7 @@ ia64_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
else else
return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc)); return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
} }
else if (FLOAT_TYPE_P (valtype) && else if (FLOAT_TYPE_P (valtype) && mode != TFmode)
((mode != TFmode) || INTEL_EXTENDED_IEEE_FORMAT))
return gen_rtx_REG (mode, FR_ARG_FIRST); return gen_rtx_REG (mode, FR_ARG_FIRST);
else else
{ {
...@@ -4188,11 +4186,11 @@ ia64_register_move_cost (enum machine_mode mode, enum reg_class from, ...@@ -4188,11 +4186,11 @@ ia64_register_move_cost (enum machine_mode mode, enum reg_class from,
to = from, from = tmp; to = from, from = tmp;
} }
/* Moving from FR<->GR in TFmode must be more expensive than 2, /* Moving from FR<->GR in XFmode must be more expensive than 2,
so that we get secondary memory reloads. Between FR_REGS, so that we get secondary memory reloads. Between FR_REGS,
we have to make this at least as expensive as MEMORY_MOVE_COST we have to make this at least as expensive as MEMORY_MOVE_COST
to avoid spectacularly poor register class preferencing. */ to avoid spectacularly poor register class preferencing. */
if (mode == TFmode) if (mode == XFmode)
{ {
if (to != GR_REGS || from != GR_REGS) if (to != GR_REGS || from != GR_REGS)
return MEMORY_MOVE_COST (mode, to, 0); return MEMORY_MOVE_COST (mode, to, 0);
...@@ -4521,10 +4519,6 @@ ia64_override_options (void) ...@@ -4521,10 +4519,6 @@ ia64_override_options (void)
ia64_section_threshold = g_switch_set ? g_switch_value : IA64_DEFAULT_GVALUE; ia64_section_threshold = g_switch_set ? g_switch_value : IA64_DEFAULT_GVALUE;
init_machine_status = ia64_init_machine_status; init_machine_status = ia64_init_machine_status;
/* Tell the compiler which flavor of TFmode we're using. */
if (!INTEL_EXTENDED_IEEE_FORMAT)
REAL_MODE_FORMAT (TFmode) = &ieee_quad_format;
} }
static enum attr_itanium_class ia64_safe_itanium_class (rtx); static enum attr_itanium_class ia64_safe_itanium_class (rtx);
...@@ -7717,26 +7711,20 @@ ia64_init_builtins (void) ...@@ -7717,26 +7711,20 @@ ia64_init_builtins (void)
/* The __fpreg type. */ /* The __fpreg type. */
fpreg_type = make_node (REAL_TYPE); fpreg_type = make_node (REAL_TYPE);
/* ??? Once the IA64 back end supports both 80-bit and 128-bit /* ??? The back end should know to load/save __fpreg variables using
floating types, this type should have XFmode, not TFmode. the ldf.fill and stf.spill instructions. */
TYPE_PRECISION should be 80 bits, not 128. And, the back end TYPE_PRECISION (fpreg_type) = 96;
should know to load/save __fpreg variables using the ldf.fill and
stf.spill instructions. */
TYPE_PRECISION (fpreg_type) = 128;
layout_type (fpreg_type); layout_type (fpreg_type);
(*lang_hooks.types.register_builtin_type) (fpreg_type, "__fpreg"); (*lang_hooks.types.register_builtin_type) (fpreg_type, "__fpreg");
/* The __float80 type. */ /* The __float80 type. */
float80_type = make_node (REAL_TYPE); float80_type = make_node (REAL_TYPE);
/* ??? Once the IA64 back end supports both 80-bit and 128-bit TYPE_PRECISION (float80_type) = 96;
floating types, this type should have XFmode, not TFmode.
TYPE_PRECISION should be 80 bits, not 128. */
TYPE_PRECISION (float80_type) = 128;
layout_type (float80_type); layout_type (float80_type);
(*lang_hooks.types.register_builtin_type) (float80_type, "__float80"); (*lang_hooks.types.register_builtin_type) (float80_type, "__float80");
/* The __float128 type. */ /* The __float128 type. */
if (INTEL_EXTENDED_IEEE_FORMAT) if (!TARGET_HPUX)
{ {
tree float128_type = make_node (REAL_TYPE); tree float128_type = make_node (REAL_TYPE);
TYPE_PRECISION (float128_type) = 128; TYPE_PRECISION (float128_type) = 128;
...@@ -7744,7 +7732,7 @@ ia64_init_builtins (void) ...@@ -7744,7 +7732,7 @@ ia64_init_builtins (void)
(*lang_hooks.types.register_builtin_type) (float128_type, "__float128"); (*lang_hooks.types.register_builtin_type) (float128_type, "__float128");
} }
else else
/* This is a synonym for "long double". */ /* Under HPUX, this is a synonym for "long double". */
(*lang_hooks.types.register_builtin_type) (long_double_type_node, (*lang_hooks.types.register_builtin_type) (long_double_type_node,
"__float128"); "__float128");
...@@ -8345,8 +8333,10 @@ ia64_hpux_init_libfuncs (void) ...@@ -8345,8 +8333,10 @@ ia64_hpux_init_libfuncs (void)
set_conv_libfunc (sext_optab, TFmode, SFmode, "_U_Qfcnvff_sgl_to_quad"); set_conv_libfunc (sext_optab, TFmode, SFmode, "_U_Qfcnvff_sgl_to_quad");
set_conv_libfunc (sext_optab, TFmode, DFmode, "_U_Qfcnvff_dbl_to_quad"); set_conv_libfunc (sext_optab, TFmode, DFmode, "_U_Qfcnvff_dbl_to_quad");
set_conv_libfunc (sext_optab, TFmode, XFmode, "_U_Qfcnvff_f80_to_quad");
set_conv_libfunc (trunc_optab, SFmode, TFmode, "_U_Qfcnvff_quad_to_sgl"); set_conv_libfunc (trunc_optab, SFmode, TFmode, "_U_Qfcnvff_quad_to_sgl");
set_conv_libfunc (trunc_optab, DFmode, TFmode, "_U_Qfcnvff_quad_to_dbl"); set_conv_libfunc (trunc_optab, DFmode, TFmode, "_U_Qfcnvff_quad_to_dbl");
set_conv_libfunc (trunc_optab, XFmode, TFmode, "_U_Qfcnvff_quad_to_f80");
set_conv_libfunc (sfix_optab, SImode, TFmode, "_U_Qfcnvfxt_quad_to_sgl"); set_conv_libfunc (sfix_optab, SImode, TFmode, "_U_Qfcnvfxt_quad_to_sgl");
set_conv_libfunc (sfix_optab, DImode, TFmode, "_U_Qfcnvfxt_quad_to_dbl"); set_conv_libfunc (sfix_optab, DImode, TFmode, "_U_Qfcnvfxt_quad_to_dbl");
......
...@@ -135,6 +135,7 @@ extern int ia64_tls_size; ...@@ -135,6 +135,7 @@ extern int ia64_tls_size;
#define TARGET_TLS64 (ia64_tls_size == 64) #define TARGET_TLS64 (ia64_tls_size == 64)
#define TARGET_EARLY_STOP_BITS (target_flags & MASK_EARLY_STOP_BITS) #define TARGET_EARLY_STOP_BITS (target_flags & MASK_EARLY_STOP_BITS)
#define TARGET_HPUX 0
#define TARGET_HPUX_LD 0 #define TARGET_HPUX_LD 0
#ifndef HAVE_AS_LTOFFX_LDXMOV_RELOCS #ifndef HAVE_AS_LTOFFX_LDXMOV_RELOCS
...@@ -417,11 +418,11 @@ while (0) ...@@ -417,11 +418,11 @@ while (0)
#define DOUBLE_TYPE_SIZE 64 #define DOUBLE_TYPE_SIZE 64
#define LONG_DOUBLE_TYPE_SIZE 128 /* long double is XFmode normally, TFmode for HPUX. */
#define LONG_DOUBLE_TYPE_SIZE (TARGET_HPUX ? 128 : 96)
/* By default we use the 80-bit Intel extended float format packaged /* We always want the XFmode operations from libgcc2.c. */
in a 128-bit entity. */ #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 96
#define INTEL_EXTENDED_IEEE_FORMAT 1
#define DEFAULT_SIGNED_CHAR 1 #define DEFAULT_SIGNED_CHAR 1
...@@ -779,7 +780,7 @@ while (0) ...@@ -779,7 +780,7 @@ while (0)
((REGNO) == PR_REG (0) && (MODE) == DImode ? 64 \ ((REGNO) == PR_REG (0) && (MODE) == DImode ? 64 \
: PR_REGNO_P (REGNO) && (MODE) == BImode ? 2 \ : PR_REGNO_P (REGNO) && (MODE) == BImode ? 2 \
: PR_REGNO_P (REGNO) && (MODE) == CCImode ? 1 \ : PR_REGNO_P (REGNO) && (MODE) == CCImode ? 1 \
: FR_REGNO_P (REGNO) && (MODE) == TFmode && INTEL_EXTENDED_IEEE_FORMAT ? 1 \ : FR_REGNO_P (REGNO) && (MODE) == XFmode ? 1 \
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
/* A C expression that is nonzero if it is permissible to store a value of mode /* A C expression that is nonzero if it is permissible to store a value of mode
...@@ -791,10 +792,10 @@ while (0) ...@@ -791,10 +792,10 @@ while (0)
GET_MODE_CLASS (MODE) != MODE_CC && \ GET_MODE_CLASS (MODE) != MODE_CC && \
(MODE) != TImode && \ (MODE) != TImode && \
(MODE) != BImode && \ (MODE) != BImode && \
((MODE) != TFmode || INTEL_EXTENDED_IEEE_FORMAT) \ (MODE) != TFmode \
: PR_REGNO_P (REGNO) ? \ : PR_REGNO_P (REGNO) ? \
(MODE) == BImode || GET_MODE_CLASS (MODE) == MODE_CC \ (MODE) == BImode || GET_MODE_CLASS (MODE) == MODE_CC \
: GR_REGNO_P (REGNO) ? (MODE) != CCImode && (MODE) != TFmode \ : GR_REGNO_P (REGNO) ? (MODE) != CCImode && (MODE) != XFmode \
: AR_REGNO_P (REGNO) ? (MODE) == DImode \ : AR_REGNO_P (REGNO) ? (MODE) == DImode \
: BR_REGNO_P (REGNO) ? (MODE) == DImode \ : BR_REGNO_P (REGNO) ? (MODE) == DImode \
: 0) : 0)
...@@ -807,11 +808,11 @@ while (0) ...@@ -807,11 +808,11 @@ while (0)
ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
zero. */ zero. */
/* Don't tie integer and FP modes, as that causes us to get integer registers /* Don't tie integer and FP modes, as that causes us to get integer registers
allocated for FP instructions. TFmode only supported in FP registers so allocated for FP instructions. XFmode only supported in FP registers so
we can't tie it with any other modes. */ we can't tie it with any other modes. */
#define MODES_TIEABLE_P(MODE1, MODE2) \ #define MODES_TIEABLE_P(MODE1, MODE2) \
(GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2) \ (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2) \
&& (((MODE1) == TFmode) == ((MODE2) == TFmode)) \ && (((MODE1) == XFmode) == ((MODE2) == XFmode)) \
&& (((MODE1) == BImode) == ((MODE2) == BImode))) && (((MODE1) == BImode) == ((MODE2) == BImode)))
/* Handling Leaf Functions */ /* Handling Leaf Functions */
...@@ -1011,12 +1012,12 @@ enum reg_class ...@@ -1011,12 +1012,12 @@ enum reg_class
into a register of CLASS2. */ into a register of CLASS2. */
#if 0 #if 0
/* ??? May need this, but since we've disallowed TFmode in GR_REGS, /* ??? May need this, but since we've disallowed XFmode in GR_REGS,
I'm not quite sure how it could be invoked. The normal problems I'm not quite sure how it could be invoked. The normal problems
with unions should be solved with the addressof fiddling done by with unions should be solved with the addressof fiddling done by
movtf and friends. */ movxf and friends. */
#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
((MODE) == TFmode && (((CLASS1) == GR_REGS && (CLASS2) == FR_REGS) \ ((MODE) == XFmode && (((CLASS1) == GR_REGS && (CLASS2) == FR_REGS) \
|| ((CLASS1) == FR_REGS && (CLASS2) == GR_REGS))) || ((CLASS1) == FR_REGS && (CLASS2) == GR_REGS)))
#endif #endif
...@@ -1026,7 +1027,7 @@ enum reg_class ...@@ -1026,7 +1027,7 @@ enum reg_class
#define CLASS_MAX_NREGS(CLASS, MODE) \ #define CLASS_MAX_NREGS(CLASS, MODE) \
((MODE) == BImode && (CLASS) == PR_REGS ? 2 \ ((MODE) == BImode && (CLASS) == PR_REGS ? 2 \
: ((CLASS) == FR_REGS && (MODE) == TFmode) ? 1 \ : ((CLASS) == FR_REGS && (MODE) == XFmode) ? 1 \
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
/* In FP regs, we can't change FP values to integer values and vice /* In FP regs, we can't change FP values to integer values and vice
...@@ -1389,7 +1390,7 @@ do { \ ...@@ -1389,7 +1390,7 @@ do { \
gen_rtx_REG (MODE, \ gen_rtx_REG (MODE, \
(((GET_MODE_CLASS (MODE) == MODE_FLOAT \ (((GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) && \ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) && \
((MODE) != TFmode || INTEL_EXTENDED_IEEE_FORMAT)) \ (MODE) != TFmode) \
? FR_RET_FIRST : GR_RET_FIRST)) ? FR_RET_FIRST : GR_RET_FIRST))
/* A C expression that is nonzero if REGNO is the number of a hard register in /* A C expression that is nonzero if REGNO is the number of a hard register in
...@@ -2214,9 +2215,9 @@ do { \ ...@@ -2214,9 +2215,9 @@ do { \
{ "ar_lc_reg_operand", {REG}}, \ { "ar_lc_reg_operand", {REG}}, \
{ "ar_ccv_reg_operand", {REG}}, \ { "ar_ccv_reg_operand", {REG}}, \
{ "ar_pfs_reg_operand", {REG}}, \ { "ar_pfs_reg_operand", {REG}}, \
{ "general_tfmode_operand", {SUBREG, REG, CONST_DOUBLE, MEM}}, \ { "general_xfmode_operand", {SUBREG, REG, CONST_DOUBLE, MEM}}, \
{ "destination_tfmode_operand", {SUBREG, REG, MEM}}, \ { "destination_xfmode_operand", {SUBREG, REG, MEM}}, \
{ "tfreg_or_fp01_operand", {REG, CONST_DOUBLE}}, \ { "xfreg_or_fp01_operand", {REG, CONST_DOUBLE}}, \
{ "basereg_operand", {SUBREG, REG}}, { "basereg_operand", {SUBREG, REG}},
/* An alias for a machine mode name. This is the machine mode that elements of /* An alias for a machine mode name. This is the machine mode that elements of
......
#ifdef L__divtf3 #ifdef L__divxf3
// Compute a 80-bit IEEE double-extended quotient. // Compute a 80-bit IEEE double-extended quotient.
// //
// From the Intel IA-64 Optimization Guide, choose the minimum latency // From the Intel IA-64 Optimization Guide, choose the minimum latency
// alternative. // alternative.
// //
// farg0 holds the dividend. farg1 holds the divisor. // farg0 holds the dividend. farg1 holds the divisor.
//
// __divtf3 is an alternate symbol name for backward compatibility.
.text .text
.align 16 .align 16
.global __divxf3
.global __divtf3 .global __divtf3
.proc __divtf3 .proc __divxf3
__divxf3:
__divtf3: __divtf3:
cmp.eq p7, p0 = r0, r0 cmp.eq p7, p0 = r0, r0
frcpa.s0 f10, p6 = farg0, farg1 frcpa.s0 f10, p6 = farg0, farg1
...@@ -37,7 +41,7 @@ __divtf3: ...@@ -37,7 +41,7 @@ __divtf3:
(p6) fma.s0 fret0 = f12, f10, f11 (p6) fma.s0 fret0 = f12, f10, f11
(p7) mov fret0 = f10 (p7) mov fret0 = f10
br.ret.sptk rp br.ret.sptk rp
.endp __divtf3 .endp __divxf3
#endif #endif
#ifdef L__divdf3 #ifdef L__divdf3
...@@ -701,3 +705,39 @@ __ia64_trampoline: ...@@ -701,3 +705,39 @@ __ia64_trampoline:
} }
.endp __ia64_trampoline .endp __ia64_trampoline
#endif #endif
#ifdef L__compat
// Thunks for backward compatibility.
.text
.align 16
.global __fixtfti
.proc __fixtfti
__fixtfti:
{ .bbb
br.sptk.many __fixxfti
;;
}
.endp __fixtfti
.align 16
.global __fixunstfti
.proc __fixunstfti
__fixunstfti:
{ .bbb
br.sptk.many __fixunsxfti
;;
}
.endp __fixunstfti
.align 16
.global __floattitf
.proc __floattitf
__floattitf:
{ .bbb
br.sptk.many __floattixf
;;
}
.endp __floattitf
#endif
...@@ -5,10 +5,10 @@ LIB1ASMSRC = ia64/lib1funcs.asm ...@@ -5,10 +5,10 @@ LIB1ASMSRC = ia64/lib1funcs.asm
# we use __ as the prefix. Note that L_divdi3 in libgcc2.c actually defines # we use __ as the prefix. Note that L_divdi3 in libgcc2.c actually defines
# a TImode divide function, so there is no actual overlap here between # a TImode divide function, so there is no actual overlap here between
# libgcc2.c and lib1funcs.asm. # libgcc2.c and lib1funcs.asm.
LIB1ASMFUNCS = __divtf3 __divdf3 __divsf3 \ LIB1ASMFUNCS = __divxf3 __divdf3 __divsf3 \
__divdi3 __moddi3 __udivdi3 __umoddi3 \ __divdi3 __moddi3 __udivdi3 __umoddi3 \
__divsi3 __modsi3 __udivsi3 __umodsi3 __save_stack_nonlocal \ __divsi3 __modsi3 __udivsi3 __umodsi3 __save_stack_nonlocal \
__nonlocal_goto __restore_stack_nonlocal __trampoline __nonlocal_goto __restore_stack_nonlocal __trampoline __compat
# ??? Hack to get -P option used when compiling lib1funcs.asm, because Intel # ??? Hack to get -P option used when compiling lib1funcs.asm, because Intel
# assembler does not accept # line number as a comment. # assembler does not accept # line number as a comment.
......
...@@ -326,13 +326,16 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, ...@@ -326,13 +326,16 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
If the target is memory, storing any naturally aligned field can be If the target is memory, storing any naturally aligned field can be
done with a simple store. For targets that support fast unaligned done with a simple store. For targets that support fast unaligned
memory, any naturally sized, unit aligned field can be done directly. */ memory, any naturally sized, unit aligned field can be done directly.
It's okay if the requested bitsize is greater than fieldmode's
bitsize; that just means the mode has padding bits. */
byte_offset = (bitnum % BITS_PER_WORD) / BITS_PER_UNIT byte_offset = (bitnum % BITS_PER_WORD) / BITS_PER_UNIT
+ (offset * UNITS_PER_WORD); + (offset * UNITS_PER_WORD);
if (bitpos == 0 if (bitpos == 0
&& bitsize == GET_MODE_BITSIZE (fieldmode) && bitsize >= GET_MODE_BITSIZE (fieldmode)
&& (GET_CODE (op0) != MEM && (GET_CODE (op0) != MEM
? ((GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD ? ((GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD
|| GET_MODE_SIZE (GET_MODE (op0)) == GET_MODE_SIZE (fieldmode)) || GET_MODE_SIZE (GET_MODE (op0)) == GET_MODE_SIZE (fieldmode))
...@@ -1029,9 +1032,11 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, ...@@ -1029,9 +1032,11 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
if (GET_CODE (op0) == REG if (GET_CODE (op0) == REG
&& mode == GET_MODE (op0) && mode == GET_MODE (op0)
&& bitnum == 0 && bitnum == 0
&& bitsize == GET_MODE_BITSIZE (GET_MODE (op0))) && bitsize >= GET_MODE_BITSIZE (GET_MODE (op0)))
{ {
/* We're trying to extract a full register from itself. */ /* We're trying to extract a full register from itself.
(If the requested bitsize is greater than the bitsize of op0,
that just means op0's mode has padding bits.) */
return op0; return op0;
} }
......
...@@ -65,6 +65,10 @@ struct mode_data ...@@ -65,6 +65,10 @@ struct mode_data
struct mode_data *component; /* mode of components */ struct mode_data *component; /* mode of components */
struct mode_data *wider; /* next wider mode */ struct mode_data *wider; /* next wider mode */
struct mode_data *contained; /* Pointer to list of modes that have
this mode as a component. */
struct mode_data *next_cont; /* Next mode in that list. */
const char *file; /* file and line of definition, */ const char *file; /* file and line of definition, */
unsigned int line; /* for error reporting */ unsigned int line; /* for error reporting */
}; };
...@@ -76,7 +80,7 @@ static struct mode_data *void_mode; ...@@ -76,7 +80,7 @@ static struct mode_data *void_mode;
static const struct mode_data blank_mode = { static const struct mode_data blank_mode = {
0, "<unknown>", MAX_MODE_CLASS, 0, "<unknown>", MAX_MODE_CLASS,
-1, -1, -1, -1, -1, -1, -1, -1,
0, 0, 0, 0, 0, 0, 0, 0,
"<unknown>", 0 "<unknown>", 0
}; };
...@@ -372,6 +376,14 @@ complete_mode (struct mode_data *m) ...@@ -372,6 +376,14 @@ complete_mode (struct mode_data *m)
alignment = m->bytesize; alignment = m->bytesize;
m->alignment = alignment & (~alignment + 1); m->alignment = alignment & (~alignment + 1);
/* If this mode has components, make the component mode point back
to this mode, for the sake of adjustments. */
if (m->component)
{
m->next_cont = m->component->contained;
m->component->contained = m;
}
} }
static void static void
...@@ -912,18 +924,15 @@ emit_mode_size (void) ...@@ -912,18 +924,15 @@ emit_mode_size (void)
} }
static void static void
emit_mode_unit_size (void) emit_mode_nunits (void)
{ {
enum mode_class c; enum mode_class c;
struct mode_data *m; struct mode_data *m;
print_decl ("unsigned char", "mode_unit_size", "NUM_MACHINE_MODES"); print_decl ("unsigned char", "mode_nunits", "NUM_MACHINE_MODES");
for_all_modes (c, m) for_all_modes (c, m)
tagged_printf ("%u", tagged_printf ("%u", m->ncomponents, m->name);
m->component
? m->component->bytesize : m->bytesize,
m->name);
print_closer (); print_closer ();
} }
...@@ -1055,23 +1064,87 @@ static void ...@@ -1055,23 +1064,87 @@ static void
emit_mode_adjustments (void) emit_mode_adjustments (void)
{ {
struct mode_adjust *a; struct mode_adjust *a;
struct mode_data *m;
puts ("\nvoid\ninit_adjust_machine_modes (void)\n{"); puts ("\
\nvoid\
\ninit_adjust_machine_modes (void)\
\n{\
\n size_t s ATTRIBUTE_UNUSED;");
/* Size adjustments must be propagated to all containing modes.
A size adjustment forces us to recalculate the alignment too. */
for (a = adj_bytesize; a; a = a->next) for (a = adj_bytesize; a; a = a->next)
printf (" /* %s:%d */\n mode_size[%smode] = %s;\n", {
a->file, a->line, a->mode->name, a->adjustment); printf ("\n /* %s:%d */\n s = %s;\n",
if (adj_bytesize && (adj_alignment || adj_format)) a->file, a->line, a->adjustment);
putchar ('\n'); printf (" mode_size[%smode] = s;\n", a->mode->name);
printf (" mode_base_align[%smode] = s & (~s + 1);\n",
a->mode->name);
for (m = a->mode->contained; m; m = m->next_cont)
{
switch (m->class)
{
case MODE_COMPLEX_INT:
case MODE_COMPLEX_FLOAT:
printf (" mode_size[%smode] = 2*s;\n", m->name);
printf (" mode_base_align[%smode] = s & (~s + 1);\n",
m->name);
break;
case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT:
printf (" mode_size[%smode] = %d*s;\n",
m->name, m->ncomponents);
printf (" mode_base_align[%smode] = (%d*s) & (~(%d*s)+1);\n",
m->name, m->ncomponents, m->ncomponents);
break;
default:
internal_error (
"mode %s is neither vector nor complex but contains %s",
m->name, a->mode->name);
/* NOTREACHED */
}
}
}
/* Alignment adjustments propagate too.
??? This may not be the right thing for vector modes. */
for (a = adj_alignment; a; a = a->next) for (a = adj_alignment; a; a = a->next)
printf (" /* %s:%d */\n mode_base_align[%smode] = %s;\n", {
a->file, a->line, a->mode->name, a->adjustment); printf ("\n /* %s:%d */\n s = %s;\n",
if (adj_alignment && adj_format) a->file, a->line, a->adjustment);
putchar ('\n'); printf (" mode_base_align[%smode] = s;\n", a->mode->name);
for (m = a->mode->contained; m; m = m->next_cont)
{
switch (m->class)
{
case MODE_COMPLEX_INT:
case MODE_COMPLEX_FLOAT:
printf (" mode_base_align[%smode] = s;\n", m->name);
break;
case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT:
printf (" mode_base_align[%smode] = %d*s;\n",
m->name, m->ncomponents);
break;
default:
internal_error (
"mode %s is neither vector nor complex but contains %s",
m->name, a->mode->name);
/* NOTREACHED */
}
}
}
/* Real mode formats don't have to propagate anywhere. */
for (a = adj_format; a; a = a->next) for (a = adj_format; a; a = a->next)
printf (" /* %s:%d */\n REAL_MODE_FORMAT (%smode) = %s;\n", printf ("\n /* %s:%d */\n REAL_MODE_FORMAT (%smode) = %s;\n",
a->file, a->line, a->mode->name, a->adjustment); a->file, a->line, a->mode->name, a->adjustment);
puts ("}"); puts ("}");
...@@ -1085,7 +1158,7 @@ emit_insn_modes_c (void) ...@@ -1085,7 +1158,7 @@ emit_insn_modes_c (void)
emit_mode_class (); emit_mode_class ();
emit_mode_bitsize (); emit_mode_bitsize ();
emit_mode_size (); emit_mode_size ();
emit_mode_unit_size (); emit_mode_nunits ();
emit_mode_wider (); emit_mode_wider ();
emit_mode_mask (); emit_mode_mask ();
emit_mode_inner (); emit_mode_inner ();
......
...@@ -81,17 +81,6 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES]; ...@@ -81,17 +81,6 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES];
extern CONST_MODE_SIZE unsigned char mode_size[NUM_MACHINE_MODES]; extern CONST_MODE_SIZE unsigned char mode_size[NUM_MACHINE_MODES];
#define GET_MODE_SIZE(MODE) mode_size[MODE] #define GET_MODE_SIZE(MODE) mode_size[MODE]
/* Get the size in bytes of the basic parts of an object of mode MODE. */
extern const unsigned char mode_unit_size[NUM_MACHINE_MODES];
#define GET_MODE_UNIT_SIZE(MODE) mode_unit_size[MODE]
/* Get the number of units in the object. */
#define GET_MODE_NUNITS(MODE) \
((GET_MODE_UNIT_SIZE ((MODE)) == 0) ? 0 \
: (GET_MODE_SIZE ((MODE)) / GET_MODE_UNIT_SIZE ((MODE))))
/* Get the size in bits of an object of mode MODE. */ /* Get the size in bits of an object of mode MODE. */
extern const unsigned short mode_bitsize[NUM_MACHINE_MODES]; extern const unsigned short mode_bitsize[NUM_MACHINE_MODES];
...@@ -104,12 +93,23 @@ extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES]; ...@@ -104,12 +93,23 @@ extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES];
#define GET_MODE_MASK(MODE) mode_mask_array[MODE] #define GET_MODE_MASK(MODE) mode_mask_array[MODE]
extern const unsigned char mode_inner[NUM_MACHINE_MODES];
/* Return the mode of the inner elements in a vector. */ /* Return the mode of the inner elements in a vector. */
extern const unsigned char mode_inner[NUM_MACHINE_MODES];
#define GET_MODE_INNER(MODE) mode_inner[MODE] #define GET_MODE_INNER(MODE) mode_inner[MODE]
/* Get the size in bytes of the basic parts of an object of mode MODE. */
#define GET_MODE_UNIT_SIZE(MODE) \
(GET_MODE_INNER (MODE) == VOIDmode \
? GET_MODE_SIZE (MODE) \
: GET_MODE_SIZE (GET_MODE_INNER (MODE)))
/* Get the number of units in the object. */
extern const unsigned char mode_nunits[NUM_MACHINE_MODES];
#define GET_MODE_NUNITS(MODE) mode_nunits[MODE]
/* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */ /* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */
extern const unsigned char mode_wider[NUM_MACHINE_MODES]; extern const unsigned char mode_wider[NUM_MACHINE_MODES];
......
...@@ -1905,15 +1905,20 @@ assemble_real (REAL_VALUE_TYPE d, enum machine_mode mode, unsigned int align) ...@@ -1905,15 +1905,20 @@ assemble_real (REAL_VALUE_TYPE d, enum machine_mode mode, unsigned int align)
int i; int i;
int bitsize, nelts, nunits, units_per; int bitsize, nelts, nunits, units_per;
/* This is hairy. We have a quantity of known bitsize. real_to_target /* This is hairy. We have a quantity of known size. real_to_target
will put it into an array of *host* longs, 32 bits per element will put it into an array of *host* longs, 32 bits per element
(even if long is more than 32 bits). We need to determine the (even if long is more than 32 bits). We need to determine the
number of array elements that are occupied (nelts) and the number number of array elements that are occupied (nelts) and the number
of *target* min-addressable units that will be occupied in the of *target* min-addressable units that will be occupied in the
object file (nunits). We can assume that BITS_PER_UNIT divides object file (nunits). We cannot assume that 32 divides the
the mode's bitsize evenly, but we can not assume that 32 does. */ mode's bitsize (size * BITS_PER_UNIT) evenly.
bitsize = GET_MODE_BITSIZE (mode);
nunits = bitsize / BITS_PER_UNIT; size * BITS_PER_UNIT is used here to make sure that padding bits
(which might appear at either end of the value; real_to_target
will include the padding bits in its output array) are included. */
nunits = GET_MODE_SIZE (mode);
bitsize = nunits * BITS_PER_UNIT;
nelts = CEIL (bitsize, 32); nelts = CEIL (bitsize, 32);
units_per = 32 / BITS_PER_UNIT; units_per = 32 / BITS_PER_UNIT;
...@@ -3756,9 +3761,7 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align) ...@@ -3756,9 +3761,7 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
if (TREE_CODE (exp) != REAL_CST) if (TREE_CODE (exp) != REAL_CST)
error ("initializer for floating value is not a floating constant"); error ("initializer for floating value is not a floating constant");
assemble_real (TREE_REAL_CST (exp), assemble_real (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)), align);
mode_for_size (size * BITS_PER_UNIT, MODE_FLOAT, 0),
align);
break; break;
case COMPLEX_TYPE: case COMPLEX_TYPE:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment