aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-03-21 20:35:48 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2001-03-21 19:35:48 +0000
commit0d7d98ee650c56e48f4a12e48c4abe040497abb7 (patch)
tree25ff9172890c141022594d99d0bc53320da72a50 /gcc
parent191de4070914f7d669d4e81446ef0fc644ee7978 (diff)
downloadgcc-0d7d98ee650c56e48f4a12e48c4abe040497abb7.zip
gcc-0d7d98ee650c56e48f4a12e48c4abe040497abb7.tar.gz
gcc-0d7d98ee650c56e48f4a12e48c4abe040497abb7.tar.bz2
i386.c (override_options): Default ix86_regparm to REGPARM_MAX.
* i386.c (override_options): Default ix86_regparm to REGPARM_MAX. (override_options): Use properlimits for preferred_stack_boundary. (ix86_valid_type_attribute_p): Disable stdcall and cdecl attributes on x86_64. (ext_register_operand): Accept DImode. (load_pic_register): Abort on 64bit. (gen_push): Use Pmode instead of SImode. (ix86_save_reg): Pic reg is never used on 64bit. (ix86_expand_prologue): Likewise. (ix86_emit_save_regs): Use Pmode instead of SImode. (legitimate_address_p): Check displacement for 64bit. (print_operand): Avoid outputting of (%rip) on 64bit. (print_operand_address): Output (%rip) where possible. (split_di): Abort on 64bit registers. (ix86_expand_branch): DImode comparison is simple for x86_64. (memory_address_length): Recognize memory addresses formed using PRE/POST modify. (ix86_data_alignment, ix86_local_alignment): Align arrays to 16 bytes for x86_64. * i386.h (TARGET_USE_SAHF): Disable for 64bit. From-SVN: r40708
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/config/i386/i386.c101
-rw-r--r--gcc/config/i386/i386.h2
3 files changed, 106 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 15dabb0..979aa23 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+Wed Mar 21 20:33:26 CET 2001 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (override_options): Default ix86_regparm to REGPARM_MAX.
+ (override_options): Use properlimits for preferred_stack_boundary.
+ (ix86_valid_type_attribute_p): Disable stdcall and cdecl attributes
+ on x86_64.
+ (ext_register_operand): Accept DImode.
+ (load_pic_register): Abort on 64bit.
+ (gen_push): Use Pmode instead of SImode.
+ (ix86_save_reg): Pic reg is never used on 64bit.
+ (ix86_expand_prologue): Likewise.
+ (ix86_emit_save_regs): Use Pmode instead of SImode.
+ (legitimate_address_p): Check displacement for 64bit.
+ (print_operand): Avoid outputting of (%rip) on 64bit.
+ (print_operand_address): Output (%rip) where possible.
+ (split_di): Abort on 64bit registers.
+ (ix86_expand_branch): DImode comparison is simple for x86_64.
+ (memory_address_length): Recognize memory addresses formed using PRE/POST modify.
+ (ix86_data_alignment, ix86_local_alignment): Align arrays to 16 bytes for x86_64.
+ * i386.h (TARGET_USE_SAHF): Disable for 64bit.
+
Wed Mar 21 18:51:19 CET 2001 Jan Hubicka <jh@suse.cz>
* recog.c (push_operand): Recognize new format of push instructions.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 91dee40..d5a1da1 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -738,6 +738,9 @@ override_options ()
else
ix86_regparm = i;
}
+ else
+ if (TARGET_64BIT)
+ ix86_regparm = REGPARM_MAX;
/* Validate -malign-loops= value, or provide default. */
ix86_align_loops = processor_target_table[ix86_cpu].align_loop;
@@ -779,8 +782,9 @@ override_options ()
if (ix86_preferred_stack_boundary_string)
{
i = atoi (ix86_preferred_stack_boundary_string);
- if (i < 2 || i > 31)
- error ("-mpreferred-stack-boundary=%d is not between 2 and 31", i);
+ if (i < (TARGET_64BIT ? 3 : 2) || i > 31)
+ error ("-mpreferred-stack-boundary=%d is not between %d and 31", i,
+ TARGET_64BIT ? 3 : 2);
else
ix86_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT;
}
@@ -857,11 +861,13 @@ ix86_valid_type_attribute_p (type, attributes, identifier, args)
/* Stdcall attribute says callee is responsible for popping arguments
if they are not variable. */
- if (is_attribute_p ("stdcall", identifier))
+ if (is_attribute_p ("stdcall", identifier)
+ && !TARGET_64BIT)
return (args == NULL_TREE);
/* Cdecl attribute says the callee is a normal C declaration. */
- if (is_attribute_p ("cdecl", identifier))
+ if (is_attribute_p ("cdecl", identifier)
+ && !TARGET_64BIT)
return (args == NULL_TREE);
/* Regparm attribute specifies how many integer arguments are to be
@@ -950,7 +956,8 @@ ix86_return_pops_args (fundecl, funtype, size)
}
/* Lose any fake structure return argument. */
- if (aggregate_value_p (TREE_TYPE (funtype)))
+ if (aggregate_value_p (TREE_TYPE (funtype))
+ && !TARGET_64BIT)
return GET_MODE_SIZE (Pmode);
return 0;
@@ -1654,7 +1661,8 @@ ext_register_operand (op, mode)
register rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
- if (GET_MODE (op) != SImode && GET_MODE (op) != HImode)
+ if ((!TARGET_64BIT || GET_MODE (op) != DImode)
+ && GET_MODE (op) != SImode && GET_MODE (op) != HImode)
return 0;
return register_operand (op, VOIDmode);
}
@@ -2179,6 +2187,9 @@ load_pic_register ()
{
rtx gotsym, pclab;
+ if (TARGET_64BIT)
+ abort();
+
gotsym = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
if (TARGET_DEEP_BRANCH_PREDICTION)
@@ -2200,15 +2211,15 @@ load_pic_register ()
emit_insn (gen_prologue_set_got (pic_offset_table_rtx, gotsym, pclab));
}
-/* Generate an SImode "push" pattern for input ARG. */
+/* Generate an "push" pattern for input ARG. */
static rtx
gen_push (arg)
rtx arg;
{
return gen_rtx_SET (VOIDmode,
- gen_rtx_MEM (SImode,
- gen_rtx_PRE_DEC (SImode,
+ gen_rtx_MEM (Pmode,
+ gen_rtx_PRE_DEC (Pmode,
stack_pointer_rtx)),
arg);
}
@@ -2219,7 +2230,8 @@ ix86_save_reg (regno)
int regno;
{
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
- || current_function_uses_const_pool);
+ || current_function_uses_const_pool)
+ && !TARGET_64BIT;
return ((regs_ever_live[regno] && !call_used_regs[regno]
&& !fixed_regs[regno]
&& (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
@@ -2368,7 +2380,7 @@ ix86_emit_save_regs ()
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
if (ix86_save_reg (regno))
{
- insn = emit_insn (gen_push (gen_rtx_REG (SImode, regno)));
+ insn = emit_insn (gen_push (gen_rtx_REG (Pmode, regno)));
RTX_FRAME_RELATED_P (insn) = 1;
}
}
@@ -2379,8 +2391,9 @@ void
ix86_expand_prologue ()
{
rtx insn;
- int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
- || current_function_uses_const_pool);
+ int pic_reg_used = (flag_pic && (current_function_uses_pic_offset_table
+ || current_function_uses_const_pool)
+ && !TARGET_64BIT);
struct ix86_frame frame;
ix86_compute_frame_layout (&frame);
@@ -2976,14 +2989,30 @@ legitimate_address_p (mode, addr, strict)
goto report_error;
}
- if (GET_CODE (disp) == CONST_DOUBLE)
+ if (TARGET_64BIT)
{
- reason = "displacement is a const_double";
- goto report_error;
+ if (!x86_64_sign_extended_value (disp))
+ {
+ reason = "displacement is out of range";
+ goto report_error;
+ }
+ }
+ else
+ {
+ if (GET_CODE (disp) == CONST_DOUBLE)
+ {
+ reason = "displacement is a const_double";
+ goto report_error;
+ }
}
if (flag_pic && SYMBOLIC_CONST (disp))
{
+ if (TARGET_64BIT && (index || base))
+ {
+ reason = "non-constant pic memory reference";
+ goto report_error;
+ }
if (! legitimate_pic_address_disp_p (disp))
{
reason = "displacement is an invalid pic construct";
@@ -3958,6 +3987,10 @@ print_operand (file, x, code)
x = XEXP (x, 0);
if (flag_pic && CONSTANT_ADDRESS_P (x))
output_pic_addr_const (file, x, code);
+ /* Avoid (%rip) for call operands. */
+ else if (CONSTANT_ADDRESS_P (x) && code =='P'
+ && GET_CODE (x) != CONST_INT)
+ output_addr_const (file, x);
else
output_address (x);
}
@@ -4060,6 +4093,10 @@ print_operand_address (file, addr)
output_pic_addr_const (file, addr, 0);
else
output_addr_const (file, addr);
+
+ /* Use one byte shorter RIP relative addressing for 64bit mode. */
+ if (GET_CODE (disp) != CONST_INT && TARGET_64BIT)
+ fputs ("(%rip)", file);
}
else
{
@@ -4165,6 +4202,8 @@ split_di (operands, num, lo_half, hi_half)
}
else if (GET_CODE (op) == REG)
{
+ if (TARGET_64BIT)
+ abort();
lo_half[num] = gen_rtx_REG (SImode, REGNO (op));
hi_half[num] = gen_rtx_REG (SImode, REGNO (op) + 1);
}
@@ -5726,6 +5765,7 @@ ix86_expand_branch (code, label)
case QImode:
case HImode:
case SImode:
+ simple:
tmp = ix86_expand_compare (code, NULL, NULL);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, label),
@@ -5769,6 +5809,8 @@ ix86_expand_branch (code, label)
}
case DImode:
+ if (TARGET_64BIT)
+ goto simple;
/* Expand DImode branch into multiple compare+branch. */
{
rtx lo[2], hi[2], label2;
@@ -7178,7 +7220,9 @@ memory_address_length (addr)
int len;
if (GET_CODE (addr) == PRE_DEC
- || GET_CODE (addr) == POST_INC)
+ || GET_CODE (addr) == POST_INC
+ || GET_CODE (addr) == PRE_MODIFY
+ || GET_CODE (addr) == POST_MODIFY)
return 0;
if (! ix86_decompose_address (addr, &parts))
@@ -7985,6 +8029,18 @@ ix86_data_alignment (type, align)
|| TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 256)
return 256;
+ /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
+ to 16byte boundary. */
+ if (TARGET_64BIT)
+ {
+ if (AGGREGATE_TYPE_P (type)
+ && TYPE_SIZE (type)
+ && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
+ && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 128
+ || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 128)
+ return 128;
+ }
+
if (TREE_CODE (type) == ARRAY_TYPE)
{
if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
@@ -8032,6 +8088,17 @@ ix86_local_alignment (type, align)
tree type;
int align;
{
+ /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
+ to 16byte boundary. */
+ if (TARGET_64BIT)
+ {
+ if (AGGREGATE_TYPE_P (type)
+ && TYPE_SIZE (type)
+ && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
+ && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 16
+ || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 128)
+ return 128;
+ }
if (TREE_CODE (type) == ARRAY_TYPE)
{
if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 697f221..efc1e65 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -214,7 +214,7 @@ extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
#define TARGET_CMOVE ((x86_cmove & (1 << ix86_arch)) || TARGET_SSE)
#define TARGET_DEEP_BRANCH_PREDICTION (x86_deep_branch & CPUMASK)
#define TARGET_DOUBLE_WITH_ADD (x86_double_with_add & CPUMASK)
-#define TARGET_USE_SAHF (x86_use_sahf & CPUMASK)
+#define TARGET_USE_SAHF ((x86_use_sahf & CPUMASK) && !TARGET_64BIT)
#define TARGET_MOVX (x86_movx & CPUMASK)
#define TARGET_PARTIAL_REG_STALL (x86_partial_reg_stall & CPUMASK)
#define TARGET_USE_LOOP (x86_use_loop & CPUMASK)