This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
x86_64 merger part 19 - trivial i386.c bits
- To: rth at cygnus dot com, patches at x86-64 dot org, gcc-patches at gcc dot gnu dot org
- Subject: x86_64 merger part 19 - trivial i386.c bits
- From: Jan Hubicka <jh at suse dot cz>
- Date: Mon, 19 Mar 2001 18:29:48 +0100
Hi
Here are few assorted, but I hope trivial bits from x86_64 port to reduce noise in the
diffs.
Honza
Mon Mar 19 18:22:31 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_fp_comparison_sahf_cost): Sahf is not used in 64bit mode.
(ix86_expand_branch): DImode comparison is simple for x86_64.
(memory_address_length): Recognize memory addresses formed using PRE/POST modify.
(ix86_attr_length_immediate_default): Handle DImode.
(ix86_data_alignment, ix86_local_alignment): Align arrays to 16 bytes for x86_64.
*** i386.c Mon Mar 19 17:58:18 2001
--- /home/hubicka/x86-64/gcc/gcc/config/i386/i386.c Mon Mar 19 17:48:41 2001
*************** override_options ()
*** 738,743 ****
--- 777,785 ----
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;
*************** override_options ()
*** 779,786 ****
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);
else
ix86_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT;
}
--- 821,829 ----
if (ix86_preferred_stack_boundary_string)
{
i = atoi (ix86_preferred_stack_boundary_string);
! 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;
}
*************** ix86_valid_type_attribute_p (type, attri
*** 857,867 ****
/* Stdcall attribute says callee is responsible for popping arguments
if they are not variable. */
! if (is_attribute_p ("stdcall", identifier))
return (args == NULL_TREE);
/* Cdecl attribute says the callee is a normal C declaration. */
! if (is_attribute_p ("cdecl", identifier))
return (args == NULL_TREE);
/* Regparm attribute specifies how many integer arguments are to be
--- 914,926 ----
/* Stdcall attribute says callee is responsible for popping arguments
if they are not variable. */
! 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)
! && !TARGET_64BIT)
return (args == NULL_TREE);
/* Regparm attribute specifies how many integer arguments are to be
*************** ix86_return_pops_args (fundecl, funtype,
*** 950,956 ****
}
/* Lose any fake structure return argument. */
! if (aggregate_value_p (TREE_TYPE (funtype)))
return GET_MODE_SIZE (Pmode);
return 0;
--- 1009,1016 ----
}
/* Lose any fake structure return argument. */
! if (aggregate_value_p (TREE_TYPE (funtype))
! && !TARGET_64BIT)
return GET_MODE_SIZE (Pmode);
return 0;
*************** ext_register_operand (op, mode)
*** 1654,1660 ****
register rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
! if (GET_MODE (op) != SImode && GET_MODE (op) != HImode)
return 0;
return register_operand (op, VOIDmode);
}
--- 2776,2783 ----
register rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
! if ((!TARGET_64BIT || GET_MODE (op) != DImode)
! && GET_MODE (op) != SImode && GET_MODE (op) != HImode)
return 0;
return register_operand (op, VOIDmode);
}
*************** load_pic_register ()
*** 2179,2184 ****
--- 3135,3143 ----
{
rtx gotsym, pclab;
+ if (TARGET_64BIT)
+ abort();
+
gotsym = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
if (TARGET_DEEP_BRANCH_PREDICTION)
*************** load_pic_register ()
*** 2200,2214 ****
emit_insn (gen_prologue_set_got (pic_offset_table_rtx, gotsym, pclab));
}
! /* Generate an SImode "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,
stack_pointer_rtx)),
arg);
}
--- 3159,3173 ----
emit_insn (gen_prologue_set_got (pic_offset_table_rtx, gotsym, pclab));
}
! /* Generate an "push" pattern for input ARG. */
static rtx
gen_push (arg)
rtx arg;
{
return gen_rtx_SET (VOIDmode,
! gen_rtx_MEM (Pmode,
! gen_rtx_PRE_DEC (Pmode,
stack_pointer_rtx)),
arg);
}
*************** ix86_save_reg (regno)
*** 2219,2225 ****
int regno;
{
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
! || current_function_uses_const_pool);
return ((regs_ever_live[regno] && !call_used_regs[regno]
&& !fixed_regs[regno]
&& (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
--- 3178,3185 ----
int regno;
{
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
! || 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))
*************** ix86_emit_save_regs ()
*** 2368,2374 ****
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
if (ix86_save_reg (regno))
{
! insn = emit_insn (gen_push (gen_rtx_REG (SImode, regno)));
RTX_FRAME_RELATED_P (insn) = 1;
}
}
--- 3363,3369 ----
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
if (ix86_save_reg (regno))
{
! insn = emit_insn (gen_push (gen_rtx_REG (Pmode, regno)));
RTX_FRAME_RELATED_P (insn) = 1;
}
}
*************** void
*** 2379,2386 ****
ix86_expand_prologue ()
{
rtx insn;
! int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
! || current_function_uses_const_pool);
struct ix86_frame frame;
ix86_compute_frame_layout (&frame);
--- 3374,3382 ----
ix86_expand_prologue ()
{
rtx insn;
! 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);
*************** legitimate_address_p (mode, addr, strict
*** 2969,2998 ****
if (disp)
{
reason_rtx = disp;
if (!CONSTANT_ADDRESS_P (disp))
{
reason = "displacement is not constant";
goto report_error;
}
!
! if (GET_CODE (disp) == CONST_DOUBLE)
{
! reason = "displacement is a const_double";
! goto report_error;
}
if (flag_pic && SYMBOLIC_CONST (disp))
{
if (! legitimate_pic_address_disp_p (disp))
{
reason = "displacement is an invalid pic construct";
goto report_error;
}
/* This code used to verify that a symbolic pic displacement
includes the pic_offset_table_rtx register.
While this is good idea, unfortunately these constructs may
--- 4067,4108 ----
if (disp)
{
reason_rtx = disp;
if (!CONSTANT_ADDRESS_P (disp))
{
reason = "displacement is not constant";
goto report_error;
}
!
! if (TARGET_64BIT)
! {
! 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";
goto report_error;
}
/* This code used to verify that a symbolic pic displacement
includes the pic_offset_table_rtx register.
While this is good idea, unfortunately these constructs may
*************** print_operand (file, x, code)
*** 3958,3963 ****
--- 5121,5130 ----
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);
}
*************** print_operand_address (file, addr)
*** 4060,4065 ****
--- 5239,5248 ----
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
{
*************** split_di (operands, num, lo_half, hi_hal
*** 4165,4170 ****
--- 5348,5355 ----
}
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);
}
*************** ix86_fp_comparison_sahf_cost (code)
*** 5475,5481 ****
enum rtx_code bypass_code, first_code, second_code;
/* Return arbitarily high cost when instruction is not preferred - this
avoids gcc from using it. */
! if (!TARGET_USE_SAHF && !optimize_size)
return 1024;
ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
return (bypass_code != NIL || second_code != NIL) + 3;
--- 6667,6673 ----
enum rtx_code bypass_code, first_code, second_code;
/* Return arbitarily high cost when instruction is not preferred - this
avoids gcc from using it. */
! if ((!TARGET_USE_SAHF && !optimize_size) || TARGET_64BIT)
return 1024;
ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
return (bypass_code != NIL || second_code != NIL) + 3;
*************** ix86_expand_branch (code, label)
*** 5726,5731 ****
--- 6920,6926 ----
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),
*************** ix86_expand_branch (code, label)
*** 5769,5774 ****
--- 6964,6971 ----
}
case DImode:
+ if (TARGET_64BIT)
+ goto simple;
/* Expand DImode branch into multiple compare+branch. */
{
rtx lo[2], hi[2], label2;
*************** memory_address_length (addr)
*** 7178,7184 ****
int len;
if (GET_CODE (addr) == PRE_DEC
! || GET_CODE (addr) == POST_INC)
return 0;
if (! ix86_decompose_address (addr, &parts))
--- 9051,9059 ----
int len;
if (GET_CODE (addr) == PRE_DEC
! || GET_CODE (addr) == POST_INC
! || GET_CODE (addr) == PRE_MODIFY
! || GET_CODE (addr) == POST_MODIFY)
return 0;
if (! ix86_decompose_address (addr, &parts))
*************** ix86_attr_length_immediate_default (insn
*** 7254,7259 ****
--- 9129,9135 ----
len+=2;
break;
case MODE_SI:
+ case MODE_DI:
len+=4;
break;
default:
*************** ix86_data_alignment (type, align)
*** 7985,7990 ****
--- 9861,9878 ----
|| 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)
*************** ix86_local_alignment (type, align)
*** 8032,8037 ****
--- 9920,9936 ----
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)