i386.c (override_options): Default ix86_regparm to REGPARM_MAX.
authorJan Hubicka <jh@suse.cz>
Wed, 21 Mar 2001 19:35:48 +0000 (20:35 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 21 Mar 2001 19:35:48 +0000 (19:35 +0000)
* 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

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.h

index 15dabb0840539e116e5f9400f44dd481a7866aa2..979aa2334fb15af1db2ac80ffeb096eb9b124a6b 100644 (file)
@@ -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.
index 91dee40cf96551a53f295fad97fd96f72b367761..d5a1da118d9364702548479db095b55a4ace2735 100644 (file)
@@ -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)
index 697f2213fbe6d059877ea1fe46fb27d0b2c4b6d3..efc1e65136819f813c6d604a6ab1044c708a18a4 100644 (file)
@@ -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)