OSDN Git Service

* config.gcc (xtensa-*-linux*): Add t-slibgcc-elf-ver to tmake_file.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.c
index b02fc4a..53df089 100644 (file)
@@ -1,6 +1,6 @@
 /* Subroutines used for code generation on IA-32.
    Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002 Free Software Foundation, Inc.
+   2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -21,6 +21,8 @@ Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "rtl.h"
 #include "tree.h"
 #include "tm_p.h"
@@ -48,6 +50,14 @@ Boston, MA 02111-1307, USA.  */
 #define CHECK_STACK_LIMIT (-1)
 #endif
 
+/* Return index of given mode in mult and division cost tables.  */
+#define MODE_INDEX(mode)                                       \
+  ((mode) == QImode ? 0                                                \
+   : (mode) == HImode ? 1                                      \
+   : (mode) == SImode ? 2                                      \
+   : (mode) == DImode ? 3                                      \
+   : 4)
+
 /* Processor costs (relative to an add) */
 static const
 struct processor_costs size_cost = {   /* costs for tunning for size */
@@ -55,9 +65,9 @@ struct processor_costs size_cost = {  /* costs for tunning for size */
   3,                                   /* cost of a lea instruction */
   2,                                   /* variable shift costs */
   3,                                   /* constant shift costs */
-  3,                                   /* cost of starting a multiply */
+  {3, 3, 3, 3, 5},                     /* cost of starting a multiply */
   0,                                   /* cost of multiply per each bit set */
-  3,                                   /* cost of a divide/mod */
+  {3, 3, 3, 3, 5},                     /* cost of a divide/mod */
   3,                                   /* cost of movsx */
   3,                                   /* cost of movzx */
   0,                                   /* "large" insn */
@@ -84,6 +94,7 @@ struct processor_costs size_cost = {  /* costs for tunning for size */
   3,                                   /* MMX or SSE register to integer */
   0,                                   /* size of prefetch block */
   0,                                   /* number of parallel prefetches */
+  1,                                   /* Branch cost */
   2,                                   /* cost of FADD and FSUB insns.  */
   2,                                   /* cost of FMUL instruction.  */
   2,                                   /* cost of FDIV instruction.  */
@@ -99,9 +110,9 @@ struct processor_costs i386_cost = { /* 386 specific costs */
   1,                                   /* cost of a lea instruction */
   3,                                   /* variable shift costs */
   2,                                   /* constant shift costs */
-  6,                                   /* cost of starting a multiply */
+  {6, 6, 6, 6, 6},                     /* cost of starting a multiply */
   1,                                   /* cost of multiply per each bit set */
-  23,                                  /* cost of a divide/mod */
+  {23, 23, 23, 23, 23},                        /* cost of a divide/mod */
   3,                                   /* cost of movsx */
   2,                                   /* cost of movzx */
   15,                                  /* "large" insn */
@@ -128,6 +139,7 @@ struct processor_costs i386_cost = {        /* 386 specific costs */
   3,                                   /* MMX or SSE register to integer */
   0,                                   /* size of prefetch block */
   0,                                   /* number of parallel prefetches */
+  1,                                   /* Branch cost */
   23,                                  /* cost of FADD and FSUB insns.  */
   27,                                  /* cost of FMUL instruction.  */
   88,                                  /* cost of FDIV instruction.  */
@@ -142,9 +154,9 @@ struct processor_costs i486_cost = {        /* 486 specific costs */
   1,                                   /* cost of a lea instruction */
   3,                                   /* variable shift costs */
   2,                                   /* constant shift costs */
-  12,                                  /* cost of starting a multiply */
+  {12, 12, 12, 12, 12},                        /* cost of starting a multiply */
   1,                                   /* cost of multiply per each bit set */
-  40,                                  /* cost of a divide/mod */
+  {40, 40, 40, 40, 40},                        /* cost of a divide/mod */
   3,                                   /* cost of movsx */
   2,                                   /* cost of movzx */
   15,                                  /* "large" insn */
@@ -171,6 +183,7 @@ struct processor_costs i486_cost = {        /* 486 specific costs */
   3,                                   /* MMX or SSE register to integer */
   0,                                   /* size of prefetch block */
   0,                                   /* number of parallel prefetches */
+  1,                                   /* Branch cost */
   8,                                   /* cost of FADD and FSUB insns.  */
   16,                                  /* cost of FMUL instruction.  */
   73,                                  /* cost of FDIV instruction.  */
@@ -185,9 +198,9 @@ struct processor_costs pentium_cost = {
   1,                                   /* cost of a lea instruction */
   4,                                   /* variable shift costs */
   1,                                   /* constant shift costs */
-  11,                                  /* cost of starting a multiply */
+  {11, 11, 11, 11, 11},                        /* cost of starting a multiply */
   0,                                   /* cost of multiply per each bit set */
-  25,                                  /* cost of a divide/mod */
+  {25, 25, 25, 25, 25},                        /* cost of a divide/mod */
   3,                                   /* cost of movsx */
   2,                                   /* cost of movzx */
   8,                                   /* "large" insn */
@@ -214,6 +227,7 @@ struct processor_costs pentium_cost = {
   3,                                   /* MMX or SSE register to integer */
   0,                                   /* size of prefetch block */
   0,                                   /* number of parallel prefetches */
+  2,                                   /* Branch cost */
   3,                                   /* cost of FADD and FSUB insns.  */
   3,                                   /* cost of FMUL instruction.  */
   39,                                  /* cost of FDIV instruction.  */
@@ -228,9 +242,9 @@ struct processor_costs pentiumpro_cost = {
   1,                                   /* cost of a lea instruction */
   1,                                   /* variable shift costs */
   1,                                   /* constant shift costs */
-  4,                                   /* cost of starting a multiply */
+  {4, 4, 4, 4, 4},                     /* cost of starting a multiply */
   0,                                   /* cost of multiply per each bit set */
-  17,                                  /* cost of a divide/mod */
+  {17, 17, 17, 17, 17},                        /* cost of a divide/mod */
   1,                                   /* cost of movsx */
   1,                                   /* cost of movzx */
   8,                                   /* "large" insn */
@@ -257,6 +271,7 @@ struct processor_costs pentiumpro_cost = {
   3,                                   /* MMX or SSE register to integer */
   32,                                  /* size of prefetch block */
   6,                                   /* number of parallel prefetches */
+  2,                                   /* Branch cost */
   3,                                   /* cost of FADD and FSUB insns.  */
   5,                                   /* cost of FMUL instruction.  */
   56,                                  /* cost of FDIV instruction.  */
@@ -271,9 +286,9 @@ struct processor_costs k6_cost = {
   2,                                   /* cost of a lea instruction */
   1,                                   /* variable shift costs */
   1,                                   /* constant shift costs */
-  3,                                   /* cost of starting a multiply */
+  {3, 3, 3, 3, 3},                     /* cost of starting a multiply */
   0,                                   /* cost of multiply per each bit set */
-  18,                                  /* cost of a divide/mod */
+  {18, 18, 18, 18, 18},                        /* cost of a divide/mod */
   2,                                   /* cost of movsx */
   2,                                   /* cost of movzx */
   8,                                   /* "large" insn */
@@ -300,6 +315,7 @@ struct processor_costs k6_cost = {
   6,                                   /* MMX or SSE register to integer */
   32,                                  /* size of prefetch block */
   1,                                   /* number of parallel prefetches */
+  1,                                   /* Branch cost */
   2,                                   /* cost of FADD and FSUB insns.  */
   2,                                   /* cost of FMUL instruction.  */
   56,                                  /* cost of FDIV instruction.  */
@@ -314,9 +330,9 @@ struct processor_costs athlon_cost = {
   2,                                   /* cost of a lea instruction */
   1,                                   /* variable shift costs */
   1,                                   /* constant shift costs */
-  5,                                   /* cost of starting a multiply */
+  {5, 5, 5, 5, 5},                     /* cost of starting a multiply */
   0,                                   /* cost of multiply per each bit set */
-  42,                                  /* cost of a divide/mod */
+  {18, 26, 42, 74, 74},                        /* cost of a divide/mod */
   1,                                   /* cost of movsx */
   1,                                   /* cost of movzx */
   8,                                   /* "large" insn */
@@ -343,6 +359,7 @@ struct processor_costs athlon_cost = {
   5,                                   /* MMX or SSE register to integer */
   64,                                  /* size of prefetch block */
   6,                                   /* number of parallel prefetches */
+  2,                                   /* Branch cost */
   4,                                   /* cost of FADD and FSUB insns.  */
   4,                                   /* cost of FMUL instruction.  */
   24,                                  /* cost of FDIV instruction.  */
@@ -352,14 +369,58 @@ struct processor_costs athlon_cost = {
 };
 
 static const
+struct processor_costs k8_cost = {
+  1,                                   /* cost of an add instruction */
+  2,                                   /* cost of a lea instruction */
+  1,                                   /* variable shift costs */
+  1,                                   /* constant shift costs */
+  {3, 4, 3, 4, 5},                     /* cost of starting a multiply */
+  0,                                   /* cost of multiply per each bit set */
+  {18, 26, 42, 74, 74},                        /* cost of a divide/mod */
+  1,                                   /* cost of movsx */
+  1,                                   /* cost of movzx */
+  8,                                   /* "large" insn */
+  9,                                   /* MOVE_RATIO */
+  4,                                   /* cost for loading QImode using movzbl */
+  {3, 4, 3},                           /* cost of loading integer registers
+                                          in QImode, HImode and SImode.
+                                          Relative to reg-reg move (2).  */
+  {3, 4, 3},                           /* cost of storing integer registers */
+  4,                                   /* cost of reg,reg fld/fst */
+  {4, 4, 12},                          /* cost of loading fp registers
+                                          in SFmode, DFmode and XFmode */
+  {6, 6, 8},                           /* cost of loading integer registers */
+  2,                                   /* cost of moving MMX register */
+  {3, 3},                              /* cost of loading MMX registers
+                                          in SImode and DImode */
+  {4, 4},                              /* cost of storing MMX registers
+                                          in SImode and DImode */
+  2,                                   /* cost of moving SSE register */
+  {4, 3, 6},                           /* cost of loading SSE registers
+                                          in SImode, DImode and TImode */
+  {4, 4, 5},                           /* cost of storing SSE registers
+                                          in SImode, DImode and TImode */
+  5,                                   /* MMX or SSE register to integer */
+  64,                                  /* size of prefetch block */
+  6,                                   /* number of parallel prefetches */
+  2,                                   /* Branch cost */
+  4,                                   /* cost of FADD and FSUB insns.  */
+  4,                                   /* cost of FMUL instruction.  */
+  19,                                  /* cost of FDIV instruction.  */
+  2,                                   /* cost of FABS instruction.  */
+  2,                                   /* cost of FCHS instruction.  */
+  35,                                  /* cost of FSQRT instruction.  */
+};
+
+static const
 struct processor_costs pentium4_cost = {
   1,                                   /* cost of an add instruction */
   1,                                   /* cost of a lea instruction */
-  8,                                   /* variable shift costs */
-  8,                                   /* constant shift costs */
-  30,                                  /* cost of starting a multiply */
+  4,                                   /* variable shift costs */
+  4,                                   /* constant shift costs */
+  {15, 15, 15, 15, 15},                        /* cost of starting a multiply */
   0,                                   /* cost of multiply per each bit set */
-  112,                                 /* cost of a divide/mod */
+  {56, 56, 56, 56, 56},                        /* cost of a divide/mod */
   1,                                   /* cost of movsx */
   1,                                   /* cost of movzx */
   16,                                  /* "large" insn */
@@ -386,6 +447,7 @@ struct processor_costs pentium4_cost = {
   10,                                  /* MMX or SSE register to integer */
   64,                                  /* size of prefetch block */
   6,                                   /* number of parallel prefetches */
+  2,                                   /* Branch cost */
   5,                                   /* cost of FADD and FSUB insns.  */
   7,                                   /* cost of FMUL instruction.  */
   43,                                  /* cost of FDIV instruction.  */
@@ -404,52 +466,68 @@ const struct processor_costs *ix86_cost = &pentium_cost;
 #define m_K6  (1<<PROCESSOR_K6)
 #define m_ATHLON  (1<<PROCESSOR_ATHLON)
 #define m_PENT4  (1<<PROCESSOR_PENTIUM4)
+#define m_K8  (1<<PROCESSOR_K8)
+#define m_ATHLON_K8  (m_K8 | m_ATHLON)
 
-const int x86_use_leave = m_386 | m_K6 | m_ATHLON;
-const int x86_push_memory = m_386 | m_K6 | m_ATHLON | m_PENT4;
+const int x86_use_leave = m_386 | m_K6 | m_ATHLON_K8;
+const int x86_push_memory = m_386 | m_K6 | m_ATHLON_K8 | m_PENT4;
 const int x86_zero_extend_with_and = m_486 | m_PENT;
-const int x86_movx = m_ATHLON | m_PPRO | m_PENT4 /* m_386 | m_K6 */;
+const int x86_movx = m_ATHLON_K8 | m_PPRO | m_PENT4 /* m_386 | m_K6 */;
 const int x86_double_with_add = ~m_386;
 const int x86_use_bit_test = m_386;
-const int x86_unroll_strlen = m_486 | m_PENT | m_PPRO | m_ATHLON | m_K6;
-const int x86_cmove = m_PPRO | m_ATHLON | m_PENT4;
-const int x86_3dnow_a = m_ATHLON;
-const int x86_deep_branch = m_PPRO | m_K6 | m_ATHLON | m_PENT4;
+const int x86_unroll_strlen = m_486 | m_PENT | m_PPRO | m_ATHLON_K8 | m_K6;
+const int x86_cmove = m_PPRO | m_ATHLON_K8 | m_PENT4;
+const int x86_3dnow_a = m_ATHLON_K8;
+const int x86_deep_branch = m_PPRO | m_K6 | m_ATHLON_K8 | m_PENT4;
 const int x86_branch_hints = m_PENT4;
 const int x86_use_sahf = m_PPRO | m_K6 | m_PENT4;
 const int x86_partial_reg_stall = m_PPRO;
 const int x86_use_loop = m_K6;
-const int x86_use_fiop = ~(m_PPRO | m_ATHLON | m_PENT);
+const int x86_use_fiop = ~(m_PPRO | m_ATHLON_K8 | m_PENT);
 const int x86_use_mov0 = m_K6;
 const int x86_use_cltd = ~(m_PENT | m_K6);
 const int x86_read_modify_write = ~m_PENT;
 const int x86_read_modify = ~(m_PENT | m_PPRO);
 const int x86_split_long_moves = m_PPRO;
-const int x86_promote_QImode = m_K6 | m_PENT | m_386 | m_486 | m_ATHLON;
+const int x86_promote_QImode = m_K6 | m_PENT | m_386 | m_486 | m_ATHLON_K8;
 const int x86_fast_prefix = ~(m_PENT | m_486 | m_386);
 const int x86_single_stringop = m_386 | m_PENT4;
 const int x86_qimode_math = ~(0);
 const int x86_promote_qi_regs = 0;
 const int x86_himode_math = ~(m_PPRO);
 const int x86_promote_hi_regs = m_PPRO;
-const int x86_sub_esp_4 = m_ATHLON | m_PPRO | m_PENT4;
-const int x86_sub_esp_8 = m_ATHLON | m_PPRO | m_386 | m_486 | m_PENT4;
-const int x86_add_esp_4 = m_ATHLON | m_K6 | m_PENT4;
-const int x86_add_esp_8 = m_ATHLON | m_PPRO | m_K6 | m_386 | m_486 | m_PENT4;
-const int x86_integer_DFmode_moves = ~(m_ATHLON | m_PENT4 | m_PPRO);
-const int x86_partial_reg_dependency = m_ATHLON | m_PENT4;
-const int x86_memory_mismatch_stall = m_ATHLON | m_PENT4;
-const int x86_accumulate_outgoing_args = m_ATHLON | m_PENT4 | m_PPRO;
-const int x86_prologue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
-const int x86_epilogue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
+const int x86_sub_esp_4 = m_ATHLON_K8 | m_PPRO | m_PENT4;
+const int x86_sub_esp_8 = m_ATHLON_K8 | m_PPRO | m_386 | m_486 | m_PENT4;
+const int x86_add_esp_4 = m_ATHLON_K8 | m_K6 | m_PENT4;
+const int x86_add_esp_8 = m_ATHLON_K8 | m_PPRO | m_K6 | m_386 | m_486 | m_PENT4;
+const int x86_integer_DFmode_moves = ~(m_ATHLON_K8 | m_PENT4 | m_PPRO);
+const int x86_partial_reg_dependency = m_ATHLON_K8 | m_PENT4;
+const int x86_memory_mismatch_stall = m_ATHLON_K8 | m_PENT4;
+const int x86_accumulate_outgoing_args = m_ATHLON_K8 | m_PENT4 | m_PPRO;
+const int x86_prologue_using_move = m_ATHLON_K8 | m_PENT4 | m_PPRO;
+const int x86_epilogue_using_move = m_ATHLON_K8 | m_PENT4 | m_PPRO;
 const int x86_decompose_lea = m_PENT4;
 const int x86_shift1 = ~m_486;
-const int x86_arch_always_fancy_math_387 = m_PENT | m_PPRO | m_ATHLON | m_PENT4;
-
-/* In case the avreage insn count for single function invocation is
+const int x86_arch_always_fancy_math_387 = m_PENT | m_PPRO | m_ATHLON_K8 | m_PENT4;
+const int x86_sse_partial_reg_dependency = m_PENT4 | m_PPRO;
+/* Set for machines where the type and dependencies are resolved on SSE register
+   parts instead of whole registers, so we may maintain just lower part of
+   scalar values in proper format leaving the upper part undefined.  */
+const int x86_sse_partial_regs = m_ATHLON_K8;
+/* Athlon optimizes partial-register FPS special case, thus avoiding the
+   need for extra instructions beforehand  */
+const int x86_sse_partial_regs_for_cvtsd2ss = 0;
+const int x86_sse_typeless_stores = m_ATHLON_K8;
+const int x86_sse_load0_by_pxor = m_PPRO | m_PENT4;
+const int x86_use_ffreep = m_ATHLON_K8;
+const int x86_rep_movl_optimal = m_386 | m_PENT | m_PPRO | m_K6;
+const int x86_inter_unit_moves = ~(m_ATHLON_K8);
+const int x86_ext_80387_constants = m_K6 | m_ATHLON | m_PENT4 | m_PPRO;
+
+/* In case the average insn count for single function invocation is
    lower than this constant, emit fast (but longer) prologue and
    epilogue code.  */
-#define FAST_PROLOGUE_INSN_COUNT 30
+#define FAST_PROLOGUE_INSN_COUNT 20
 
 /* Set by prologue expander and used by epilogue expander to determine
    the style used.  */
@@ -583,8 +661,8 @@ int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
   -1, 9, -1, -1, -1,                   /* arg, flags, fpsr, dir, frame */
   21, 22, 23, 24, 25, 26, 27, 28,      /* SSE registers */
   29, 30, 31, 32, 33, 34, 35, 36,      /* MMX registers */
-  -1, -1, -1, -1, -1, -1, -1, -1,      /* extemded integer registers */
-  -1, -1, -1, -1, -1, -1, -1, -1,      /* extemded SSE registers */
+  -1, -1, -1, -1, -1, -1, -1, -1,      /* extended integer registers */
+  -1, -1, -1, -1, -1, -1, -1, -1,      /* extended SSE registers */
 };
 
 /* Test and compare insns in i386.md store the information needed to
@@ -602,17 +680,15 @@ static char const tls_model_chars[] = " GLil";
 #define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)
 
 /* Define the structure for the machine field in struct function.  */
-struct machine_function GTY(())
+
+struct stack_local_entry GTY(())
 {
-  rtx stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
-  const char *some_ld_name;
-  int save_varrargs_registers;
-  int accesses_prev_frame;
+  unsigned short mode;
+  unsigned short n;
+  rtx rtl;
+  struct stack_local_entry *next;
 };
 
-#define ix86_stack_locals (cfun->machine->stack_locals)
-#define ix86_save_varrargs_registers (cfun->machine->save_varrargs_registers)
-
 /* Structure describing stack frame layout.
    Stack grows downward:
 
@@ -666,12 +742,12 @@ enum tls_dialect ix86_tls_dialect = TLS_DIALECT_GNU;
 enum fpmath_unit ix86_fpmath;
 
 /* Which cpu are we scheduling for.  */
-enum processor_type ix86_cpu;
+enum processor_type ix86_tune;
 /* Which instruction set architecture to use.  */
 enum processor_type ix86_arch;
 
 /* Strings to hold which cpu and instruction set architecture  to use.  */
-const char *ix86_cpu_string;           /* for -mcpu=<xxx> */
+const char *ix86_tune_string;          /* for -mtune=<xxx> */
 const char *ix86_arch_string;          /* for -march=<xxx> */
 const char *ix86_fpmath_string;                /* for -mfpmath=<xxx> */
 
@@ -755,6 +831,7 @@ static void x86_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
                                         HOST_WIDE_INT, tree));
 static bool x86_can_output_mi_thunk PARAMS ((tree, HOST_WIDE_INT,
                                             HOST_WIDE_INT, tree));
+bool ix86_expand_carry_flag_compare PARAMS ((enum rtx_code, rtx, rtx, rtx*));
 
 struct ix86_address
 {
@@ -763,6 +840,9 @@ struct ix86_address
 };
 
 static int ix86_decompose_address PARAMS ((rtx, struct ix86_address *));
+static int ix86_address_cost PARAMS ((rtx));
+static bool ix86_cannot_force_const_mem PARAMS ((rtx));
+static rtx ix86_delegitimize_address PARAMS ((rtx));
 
 static void ix86_encode_section_info PARAMS ((tree, int)) ATTRIBUTE_UNUSED;
 static const char *ix86_strip_name_encoding PARAMS ((const char *))
@@ -795,9 +875,15 @@ static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *));
 static int ix86_comp_type_attributes PARAMS ((tree, tree));
 static int ix86_fntype_regparm PARAMS ((tree));
 const struct attribute_spec ix86_attribute_table[];
+static bool ix86_function_ok_for_sibcall PARAMS ((tree, tree));
 static tree ix86_handle_cdecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
 static tree ix86_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *));
 static int ix86_value_regno PARAMS ((enum machine_mode));
+static bool contains_128bit_aligned_vector_p PARAMS ((tree));
+static bool ix86_ms_bitfield_layout_p PARAMS ((tree));
+static tree ix86_handle_struct_attribute PARAMS ((tree *, tree, tree, int, bool *));
+static int extended_reg_mentioned_1 PARAMS ((rtx *, void *));
+static bool ix86_rtx_costs PARAMS ((rtx, int, int, int *));
 
 #if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION)
 static void ix86_svr3_asm_out_constructor PARAMS ((rtx, int));
@@ -806,9 +892,9 @@ static void ix86_svr3_asm_out_constructor PARAMS ((rtx, int));
 /* Register class used for passing given 64bit part of the argument.
    These represent classes as documented by the PS ABI, with the exception
    of SSESF, SSEDF classes, that are basically SSE class, just gcc will
-   use SF or DFmode move instead of DImode to avoid reformating penalties.
+   use SF or DFmode move instead of DImode to avoid reformatting penalties.
 
-   Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
+   Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
    whenever possible (upper half does contain padding).
  */
 enum x86_64_reg_class
@@ -837,6 +923,11 @@ static rtx construct_container PARAMS ((enum machine_mode, tree, int, int, int,
                                        const int *, int));
 static enum x86_64_reg_class merge_classes PARAMS ((enum x86_64_reg_class,
                                                    enum x86_64_reg_class));
+
+/* Table of constants used by fldpi, fldln2, etc...  */
+static REAL_VALUE_TYPE ext_80387_constants_table [5];
+static bool ext_80387_constants_init = 0;
+static void init_ext_80387_constants PARAMS ((void));
 \f
 /* Initialize the GCC target structure.  */
 #undef TARGET_ATTRIBUTE_TABLE
@@ -896,16 +987,32 @@ static enum x86_64_reg_class merge_classes PARAMS ((enum x86_64_reg_class,
 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
   ia32_multipass_dfa_lookahead
 
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall
+
 #ifdef HAVE_AS_TLS
 #undef TARGET_HAVE_TLS
 #define TARGET_HAVE_TLS true
 #endif
+#undef TARGET_CANNOT_FORCE_CONST_MEM
+#define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem
+
+#undef TARGET_DELEGITIMIZE_ADDRESS
+#define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address
+
+#undef TARGET_MS_BITFIELD_LAYOUT_P
+#define TARGET_MS_BITFIELD_LAYOUT_P ix86_ms_bitfield_layout_p
 
 #undef TARGET_ASM_OUTPUT_MI_THUNK
 #define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk
 
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS ix86_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST ix86_address_cost
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 /* Sometimes certain combinations of command options do not make
@@ -934,17 +1041,17 @@ override_options ()
       const int align_jump;
       const int align_jump_max_skip;
       const int align_func;
-      const int branch_cost;
     }
   const processor_target_table[PROCESSOR_max] =
     {
-      {&i386_cost, 0, 0, 4, 3, 4, 3, 4, 1},
-      {&i486_cost, 0, 0, 16, 15, 16, 15, 16, 1},
-      {&pentium_cost, 0, 0, 16, 7, 16, 7, 16, 1},
-      {&pentiumpro_cost, 0, 0, 16, 15, 16, 7, 16, 1},
-      {&k6_cost, 0, 0, 32, 7, 32, 7, 32, 1},
-      {&athlon_cost, 0, 0, 16, 7, 64, 7, 16, 1},
-      {&pentium4_cost, 0, 0, 0, 0, 0, 0, 0, 1}
+      {&i386_cost, 0, 0, 4, 3, 4, 3, 4},
+      {&i486_cost, 0, 0, 16, 15, 16, 15, 16},
+      {&pentium_cost, 0, 0, 16, 7, 16, 7, 16},
+      {&pentiumpro_cost, 0, 0, 16, 15, 16, 7, 16},
+      {&k6_cost, 0, 0, 32, 7, 32, 7, 32},
+      {&athlon_cost, 0, 0, 16, 7, 16, 7, 16},
+      {&pentium4_cost, 0, 0, 0, 0, 0, 0, 0},
+      {&k8_cost, 0, 0, 16, 7, 16, 7, 16}
     };
 
   static const char * const cpu_names[] = TARGET_CPU_DEFAULT_NAMES;
@@ -959,7 +1066,8 @@ override_options ()
          PTA_MMX = 4,
          PTA_PREFETCH_SSE = 8,
          PTA_3DNOW = 16,
-         PTA_3DNOW_A = 64
+         PTA_3DNOW_A = 64,
+         PTA_64BIT = 128
        } flags;
     }
   const processor_alias_table[] =
@@ -972,6 +1080,7 @@ override_options ()
       {"winchip-c6", PROCESSOR_I486, PTA_MMX},
       {"winchip2", PROCESSOR_I486, PTA_MMX | PTA_3DNOW},
       {"c3", PROCESSOR_I486, PTA_MMX | PTA_3DNOW},
+      {"c3-2", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_PREFETCH_SSE | PTA_SSE},
       {"i686", PROCESSOR_PENTIUMPRO, 0},
       {"pentiumpro", PROCESSOR_PENTIUMPRO, 0},
       {"pentium2", PROCESSOR_PENTIUMPRO, PTA_MMX},
@@ -991,6 +1100,8 @@ override_options ()
                                      | PTA_3DNOW_A | PTA_SSE},
       {"athlon-mp", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
                                      | PTA_3DNOW_A | PTA_SSE},
+      {"k8", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW | PTA_64BIT
+                                     | PTA_3DNOW_A | PTA_SSE | PTA_SSE2},
     };
 
   int const pta_size = ARRAY_SIZE (processor_alias_table);
@@ -1001,7 +1112,7 @@ override_options ()
   real_format_for_mode[TFmode - QFmode] = &ieee_extended_intel_128_format;
 
   /* Set the default values for switches whose default depends on TARGET_64BIT
-     in case they weren't overwriten by command line options.  */
+     in case they weren't overwritten by command line options.  */
   if (TARGET_64BIT)
     {
       if (flag_omit_frame_pointer == 2)
@@ -1018,19 +1129,19 @@ override_options ()
       if (flag_asynchronous_unwind_tables == 2)
        flag_asynchronous_unwind_tables = 0;
       if (flag_pcc_struct_return == 2)
-       flag_pcc_struct_return = 1;
+       flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN;
     }
 
 #ifdef SUBTARGET_OVERRIDE_OPTIONS
   SUBTARGET_OVERRIDE_OPTIONS;
 #endif
 
-  if (!ix86_cpu_string && ix86_arch_string)
-    ix86_cpu_string = ix86_arch_string;
-  if (!ix86_cpu_string)
-    ix86_cpu_string = cpu_names [TARGET_CPU_DEFAULT];
+  if (!ix86_tune_string && ix86_arch_string)
+    ix86_tune_string = ix86_arch_string;
+  if (!ix86_tune_string)
+    ix86_tune_string = cpu_names [TARGET_CPU_DEFAULT];
   if (!ix86_arch_string)
-    ix86_arch_string = TARGET_64BIT ? "athlon-4" : "i386";
+    ix86_arch_string = TARGET_64BIT ? "k8" : "i386";
 
   if (ix86_cmodel_string != 0)
     {
@@ -1078,7 +1189,7 @@ override_options ()
       {
        ix86_arch = processor_alias_table[i].processor;
        /* Default cpu tuning to the architecture.  */
-       ix86_cpu = ix86_arch;
+       ix86_tune = ix86_arch;
        if (processor_alias_table[i].flags & PTA_MMX
            && !(target_flags_explicit & MASK_MMX))
          target_flags |= MASK_MMX;
@@ -1096,6 +1207,8 @@ override_options ()
          target_flags |= MASK_SSE2;
        if (processor_alias_table[i].flags & PTA_PREFETCH_SSE)
          x86_prefetch_sse = true;
+       if (TARGET_64BIT && !(processor_alias_table[i].flags & PTA_64BIT))
+         error ("CPU you selected does not support x86-64 instruction set");
        break;
       }
 
@@ -1103,22 +1216,24 @@ override_options ()
     error ("bad value (%s) for -march= switch", ix86_arch_string);
 
   for (i = 0; i < pta_size; i++)
-    if (! strcmp (ix86_cpu_string, processor_alias_table[i].name))
+    if (! strcmp (ix86_tune_string, processor_alias_table[i].name))
       {
-       ix86_cpu = processor_alias_table[i].processor;
+       ix86_tune = processor_alias_table[i].processor;
+       if (TARGET_64BIT && !(processor_alias_table[i].flags & PTA_64BIT))
+         error ("CPU you selected does not support x86-64 instruction set");
        break;
       }
   if (processor_alias_table[i].flags & PTA_PREFETCH_SSE)
     x86_prefetch_sse = true;
   if (i == pta_size)
-    error ("bad value (%s) for -mcpu= switch", ix86_cpu_string);
+    error ("bad value (%s) for -mtune= switch", ix86_tune_string);
 
   if (optimize_size)
     ix86_cost = &size_cost;
   else
-    ix86_cost = processor_target_table[ix86_cpu].cost;
-  target_flags |= processor_target_table[ix86_cpu].target_enable;
-  target_flags &= ~processor_target_table[ix86_cpu].target_disable;
+    ix86_cost = processor_target_table[ix86_tune].cost;
+  target_flags |= processor_target_table[ix86_tune].target_enable;
+  target_flags &= ~processor_target_table[ix86_tune].target_disable;
 
   /* Arrange to set up i386_stack_locals for all functions.  */
   init_machine_status = ix86_init_machine_status;
@@ -1181,17 +1296,17 @@ override_options ()
   /* Default align_* from the processor table.  */
   if (align_loops == 0)
     {
-      align_loops = processor_target_table[ix86_cpu].align_loop;
-      align_loops_max_skip = processor_target_table[ix86_cpu].align_loop_max_skip;
+      align_loops = processor_target_table[ix86_tune].align_loop;
+      align_loops_max_skip = processor_target_table[ix86_tune].align_loop_max_skip;
     }
   if (align_jumps == 0)
     {
-      align_jumps = processor_target_table[ix86_cpu].align_jump;
-      align_jumps_max_skip = processor_target_table[ix86_cpu].align_jump_max_skip;
+      align_jumps = processor_target_table[ix86_tune].align_jump;
+      align_jumps_max_skip = processor_target_table[ix86_tune].align_jump_max_skip;
     }
   if (align_functions == 0)
     {
-      align_functions = processor_target_table[ix86_cpu].align_func;
+      align_functions = processor_target_table[ix86_tune].align_func;
     }
 
   /* Validate -mpreferred-stack-boundary= value, or provide default.
@@ -1212,7 +1327,7 @@ override_options ()
     }
 
   /* Validate -mbranch-cost= value, or provide default.  */
-  ix86_branch_cost = processor_target_table[ix86_cpu].branch_cost;
+  ix86_branch_cost = processor_target_table[ix86_tune].cost->branch_cost;
   if (ix86_branch_cost_string)
     {
       i = atoi (ix86_branch_cost_string);
@@ -1306,12 +1421,12 @@ override_options ()
   if (TARGET_3DNOW)
     {
       target_flags |= MASK_MMX;
-      /* If we are targetting the Athlon architecture, enable the 3Dnow/MMX
+      /* If we are targeting the Athlon architecture, enable the 3Dnow/MMX
         extensions it adds.  */
       if (x86_3dnow_a & (1 << ix86_arch))
        target_flags |= MASK_3DNOW_A;
     }
-  if ((x86_accumulate_outgoing_args & CPUMASK)
+  if ((x86_accumulate_outgoing_args & TUNEMASK)
       && !(target_flags_explicit & MASK_ACCUMULATE_OUTGOING_ARGS)
       && !optimize_size)
     target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
@@ -1355,6 +1470,9 @@ const struct attribute_spec ix86_attribute_table[] =
   /* Stdcall attribute says callee is responsible for popping arguments
      if they are not variable.  */
   { "stdcall",   0, 0, false, true,  true,  ix86_handle_cdecl_attribute },
+  /* Fastcall attribute says callee is responsible for popping arguments
+     if they are not variable.  */
+  { "fastcall",  0, 0, false, true,  true,  ix86_handle_cdecl_attribute },
   /* Cdecl attribute says the callee is a normal C declaration */
   { "cdecl",     0, 0, false, true,  true,  ix86_handle_cdecl_attribute },
   /* Regparm attribute specifies how many integer arguments are to be
@@ -1365,10 +1483,65 @@ const struct attribute_spec ix86_attribute_table[] =
   { "dllexport", 0, 0, false, false, false, ix86_handle_dll_attribute },
   { "shared",    0, 0, true,  false, false, ix86_handle_shared_attribute },
 #endif
+  { "ms_struct", 0, 0, false, false,  false, ix86_handle_struct_attribute },
+  { "gcc_struct", 0, 0, false, false,  false, ix86_handle_struct_attribute },
   { NULL,        0, 0, false, false, false, NULL }
 };
 
-/* Handle a "cdecl" or "stdcall" attribute;
+/* Decide whether we can make a sibling call to a function.  DECL is the
+   declaration of the function being targeted by the call and EXP is the
+   CALL_EXPR representing the call.  */
+
+static bool
+ix86_function_ok_for_sibcall (decl, exp)
+     tree decl;
+     tree exp;
+{
+  /* If we are generating position-independent code, we cannot sibcall
+     optimize any indirect call, or a direct call to a global function,
+     as the PLT requires %ebx be live.  */
+  if (!TARGET_64BIT && flag_pic && (!decl || TREE_PUBLIC (decl)))
+    return false;
+
+  /* If we are returning floats on the 80387 register stack, we cannot
+     make a sibcall from a function that doesn't return a float to a
+     function that does or, conversely, from a function that does return
+     a float to a function that doesn't; the necessary stack adjustment
+     would not be executed.  */
+  if (STACK_REG_P (ix86_function_value (TREE_TYPE (exp)))
+      != STACK_REG_P (ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)))))
+    return false;
+
+  /* If this call is indirect, we'll need to be able to use a call-clobbered
+     register for the address of the target function.  Make sure that all 
+     such registers are not used for passing parameters.  */
+  if (!decl && !TARGET_64BIT)
+    {
+      int regparm = ix86_regparm;
+      tree attr, type;
+
+      /* We're looking at the CALL_EXPR, we need the type of the function.  */
+      type = TREE_OPERAND (exp, 0);            /* pointer expression */
+      type = TREE_TYPE (type);                 /* pointer type */
+      type = TREE_TYPE (type);                 /* function type */
+
+      attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
+      if (attr)
+        regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
+
+      if (regparm >= 3)
+       {
+         /* ??? Need to count the actual number of registers to be used,
+            not the possible number of registers.  Fix later.  */
+         return false;
+       }
+    }
+
+  /* Otherwise okay.  That also includes certain types of indirect calls.  */
+  return true;
+}
+
+/* Handle a "cdecl", "stdcall", or "fastcall" attribute;
    arguments as in struct attribute_spec.handler.  */
 static tree
 ix86_handle_cdecl_attribute (node, name, args, flags, no_add_attrs)
@@ -1387,6 +1560,27 @@ ix86_handle_cdecl_attribute (node, name, args, flags, no_add_attrs)
               IDENTIFIER_POINTER (name));
       *no_add_attrs = true;
     }
+  else
+    {
+      if (is_attribute_p ("fastcall", name))
+        {
+          if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (*node)))
+            {
+              error ("fastcall and stdcall attributes are not compatible");
+            }
+           else if (lookup_attribute ("regparm", TYPE_ATTRIBUTES (*node)))
+            {
+              error ("fastcall and regparm attributes are not compatible");
+            }
+        }
+      else if (is_attribute_p ("stdcall", name))
+        {
+          if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
+            {
+              error ("fastcall and stdcall attributes are not compatible");
+            }
+        }
+    }
 
   if (TARGET_64BIT)
     {
@@ -1433,6 +1627,11 @@ ix86_handle_regparm_attribute (node, name, args, flags, no_add_attrs)
                   IDENTIFIER_POINTER (name), REGPARM_MAX);
          *no_add_attrs = true;
        }
+
+      if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
+    {
+      error ("fastcall and regparm attributes are not compatible");
+    }
     }
 
   return NULL_TREE;
@@ -1453,6 +1652,11 @@ ix86_comp_type_attributes (type1, type2)
   if (TREE_CODE (type1) != FUNCTION_TYPE)
     return 1;
 
+  /*  Check for mismatched fastcall types */ 
+  if (!lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type1))
+      != !lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type2)))
+    return 0; 
+
   /* Check for mismatched return types (cdecl vs stdcall).  */
   if (!lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type1))
       != !lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type2)))
@@ -1503,8 +1707,9 @@ ix86_return_pops_args (fundecl, funtype, size)
     /* Cdecl functions override -mrtd, and never pop the stack.  */
   if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) {
 
-    /* Stdcall functions will pop the stack if not variable args.  */
-    if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))
+    /* Stdcall and fastcall functions will pop the stack if not variable args. */
+    if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype))
+        || lookup_attribute ("fastcall", TYPE_ATTRIBUTES (funtype)))
       rtd = 1;
 
     if (rtd
@@ -1590,6 +1795,17 @@ init_cumulative_args (cum, fntype, libname)
     }
   cum->maybe_vaarg = false;
 
+  /* Use ecx and edx registers if function has fastcall attribute */
+  if (fntype && !TARGET_64BIT)
+    {
+      if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)))
+       {
+         cum->nregs = 2;
+         cum->fastcall = 1;
+       }
+    }
+
+
   /* Determine if this function has variable arguments.  This is
      indicated by the last argument being 'void_type_mode' if there
      are no variable arguments.  If there are variable arguments, then
@@ -1604,7 +1820,10 @@ init_cumulative_args (cum, fntype, libname)
          if (next_param == 0 && TREE_VALUE (param) != void_type_node)
            {
              if (!TARGET_64BIT)
-               cum->nregs = 0;
+               {
+                 cum->nregs = 0;
+                 cum->fastcall = 0;
+               }
              cum->maybe_vaarg = true;
            }
        }
@@ -1619,7 +1838,7 @@ init_cumulative_args (cum, fntype, libname)
   return;
 }
 
-/* x86-64 register passing impleemntation.  See x86-64 ABI for details.  Goal
+/* x86-64 register passing implementation.  See x86-64 ABI for details.  Goal
    of this code is to classify each 8bytes of incoming argument by the register
    class and assign registers accordingly.  */
 
@@ -2083,7 +2302,7 @@ construct_container (mode, type, in_return, nintregs, nsseregs, intreg, sse_regn
            break;
          case X86_64_INTEGER_CLASS:
          case X86_64_INTEGERSI_CLASS:
-           /* Merge TImodes on aligned occassions here too.  */
+           /* Merge TImodes on aligned occasions here too.  */
            if (i * 8 + 8 > bytes)
              tmpmode = mode_for_size ((bytes - i * 8) * BITS_PER_UNIT, MODE_INT, 0);
            else if (class[i] == X86_64_INTEGERSI_CLASS)
@@ -2223,7 +2442,7 @@ function_arg (cum, mode, type, named)
     (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
   int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
 
-  /* Handle an hidden AL argument containing number of registers for varargs
+  /* Handle a hidden AL argument containing number of registers for varargs
      x86-64 functions.  For i386 ABI just return constm1_rtx to avoid
      any AL settings.  */
   if (mode == VOIDmode)
@@ -2249,12 +2468,30 @@ function_arg (cum, mode, type, named)
        break;
 
       case BLKmode:
+       if (bytes < 0)
+         break;
+       /* FALLTHRU */
       case DImode:
       case SImode:
       case HImode:
       case QImode:
        if (words <= cum->nregs)
-         ret = gen_rtx_REG (mode, cum->regno);
+         {
+           int regno = cum->regno;
+
+           /* Fastcall allocates the first two DWORD (SImode) or
+              smaller arguments to ECX and EDX.  */
+           if (cum->fastcall)
+             {
+               if (mode == BLKmode || mode == DImode)
+                 break;
+               /* ECX not EAX is the first allocated register.  */
+               if (regno == 0)
+                     regno = 2;
+             }
+           ret = gen_rtx_REG (mode, regno);
+         }
        break;
       case TImode:
        if (cum->sse_nregs)
@@ -2279,6 +2516,90 @@ function_arg (cum, mode, type, named)
   return ret;
 }
 
+/* A C expression that indicates when an argument must be passed by
+   reference.  If nonzero for an argument, a copy of that argument is
+   made in memory and a pointer to the argument is passed instead of
+   the argument itself.  The pointer is passed in whatever way is
+   appropriate for passing a pointer to that type.  */
+
+int
+function_arg_pass_by_reference (cum, mode, type, named)
+     CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+     tree type;
+     int named ATTRIBUTE_UNUSED;
+{
+  if (!TARGET_64BIT)
+    return 0;
+
+  if (type && int_size_in_bytes (type) == -1)
+    {
+      if (TARGET_DEBUG_ARG)
+       fprintf (stderr, "function_arg_pass_by_reference\n");
+      return 1;
+    }
+
+  return 0;
+}
+
+/* Return true when TYPE should be 128bit aligned for 32bit argument passing
+   ABI  */
+static bool
+contains_128bit_aligned_vector_p (type)
+     tree type;
+{
+  enum machine_mode mode = TYPE_MODE (type);
+  if (SSE_REG_MODE_P (mode)
+      && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
+    return true;
+  if (TYPE_ALIGN (type) < 128)
+    return false;
+
+  if (AGGREGATE_TYPE_P (type))
+    {
+      /* Walk the agregates recursivly.  */
+      if (TREE_CODE (type) == RECORD_TYPE
+         || TREE_CODE (type) == UNION_TYPE
+         || TREE_CODE (type) == QUAL_UNION_TYPE)
+       {
+         tree field;
+
+         if (TYPE_BINFO (type) != NULL
+             && TYPE_BINFO_BASETYPES (type) != NULL)
+           {
+             tree bases = TYPE_BINFO_BASETYPES (type);
+             int n_bases = TREE_VEC_LENGTH (bases);
+             int i;
+
+             for (i = 0; i < n_bases; ++i)
+               {
+                 tree binfo = TREE_VEC_ELT (bases, i);
+                 tree type = BINFO_TYPE (binfo);
+
+                 if (contains_128bit_aligned_vector_p (type))
+                   return true;
+               }
+           }
+         /* And now merge the fields of structure.   */
+         for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+           {
+             if (TREE_CODE (field) == FIELD_DECL
+                 && contains_128bit_aligned_vector_p (TREE_TYPE (field)))
+               return true;
+           }
+       }
+      /* Just for use if some languages passes arrays by value.  */
+      else if (TREE_CODE (type) == ARRAY_TYPE)
+       {
+         if (contains_128bit_aligned_vector_p (TREE_TYPE (type)))
+           return true;
+       }
+      else
+       abort ();
+    }
+  return false;
+}
+
 /* Gives the alignment boundary, in bits, of an argument with the specified mode
    and type.   */
 
@@ -2288,14 +2609,34 @@ ix86_function_arg_boundary (mode, type)
      tree type;
 {
   int align;
-  if (!TARGET_64BIT)
-    return PARM_BOUNDARY;
   if (type)
     align = TYPE_ALIGN (type);
   else
     align = GET_MODE_ALIGNMENT (mode);
   if (align < PARM_BOUNDARY)
     align = PARM_BOUNDARY;
+  if (!TARGET_64BIT)
+    {
+      /* i386 ABI defines all arguments to be 4 byte aligned.  We have to
+        make an exception for SSE modes since these require 128bit
+        alignment.  
+
+        The handling here differs from field_alignment.  ICC aligns MMX
+        arguments to 4 byte boundaries, while structure fields are aligned
+        to 8 byte boundaries.  */
+      if (!type)
+       {
+         if (!SSE_REG_MODE_P (mode))
+           align = PARM_BOUNDARY;
+       }
+      else
+       {
+         if (!contains_128bit_aligned_vector_p (type))
+           align = PARM_BOUNDARY;
+       }
+      if (align != PARM_BOUNDARY && !TARGET_SSE)
+       abort();
+    }
   if (align > 128)
     align = 128;
   return align;
@@ -2330,8 +2671,8 @@ ix86_function_value (valtype)
       rtx ret = construct_container (TYPE_MODE (valtype), valtype, 1,
                                     REGPARM_MAX, SSE_REGPARM_MAX,
                                     x86_64_int_return_registers, 0);
-      /* For zero sized structures, construct_continer return NULL, but we need
-         to keep rest of compiler happy by returning meaningfull value.  */
+      /* For zero sized structures, construct_container return NULL, but we need
+         to keep rest of compiler happy by returning meaningful value.  */
       if (!ret)
        ret = gen_rtx_REG (TYPE_MODE (valtype), 0);
       return ret;
@@ -2354,12 +2695,18 @@ ix86_return_in_memory (type)
     }
   else
     {
-      if (TYPE_MODE (type) == BLKmode
-         || (VECTOR_MODE_P (TYPE_MODE (type))
-             && int_size_in_bytes (type) == 8)
-         || (int_size_in_bytes (type) > 12 && TYPE_MODE (type) != TImode
-             && TYPE_MODE (type) != TFmode
-             && !VECTOR_MODE_P (TYPE_MODE (type))))
+      if (TYPE_MODE (type) == BLKmode)
+       return 1;
+      else if (MS_AGGREGATE_RETURN
+              && AGGREGATE_TYPE_P (type)
+              && int_size_in_bytes(type) <= 8)
+       return 0;
+      else if ((VECTOR_MODE_P (TYPE_MODE (type))
+               && int_size_in_bytes (type) == 8)
+              || (int_size_in_bytes (type) > 12
+                  && TYPE_MODE (type) != TImode
+                  && TYPE_MODE (type) != TFmode
+                  && !VECTOR_MODE_P (TYPE_MODE (type))))
        return 1;
       return 0;
     }
@@ -2513,7 +2860,7 @@ ix86_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
   if (next_cum.sse_nregs)
     {
       /* Now emit code to save SSE registers.  The AX parameter contains number
-        of SSE parameter regsiters used to call this function.  We use
+        of SSE parameter registers used to call this function.  We use
         sse_prologue_save insn template that produces computed jump across
         SSE saves.  We need some preparation work to get this working.  */
 
@@ -2634,6 +2981,7 @@ ix86_va_arg (valist, type)
   rtx lab_false, lab_over = NULL_RTX;
   rtx addr_rtx, r;
   rtx container;
+  int indirect_p = 0;
 
   /* Only 64bit target needs something special.  */
   if (!TARGET_64BIT)
@@ -2653,6 +3001,13 @@ ix86_va_arg (valist, type)
   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
 
   size = int_size_in_bytes (type);
+  if (size == -1)
+    {
+      /* Passed by reference.  */
+      indirect_p = 1;
+      type = build_pointer_type (type);
+      size = int_size_in_bytes (type);
+    }
   rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
 
   container = construct_container (TYPE_MODE (type), type, 0,
@@ -2679,11 +3034,11 @@ ix86_va_arg (valist, type)
       need_temp = ((needed_intregs && TYPE_ALIGN (type) > 64)
                   || TYPE_ALIGN (type) > 128);
 
-      /* In case we are passing structure, verify that it is consetuctive block
+      /* In case we are passing structure, verify that it is consecutive block
          on the register save area.  If not we need to do moves.  */
       if (!need_temp && !REG_P (container))
        {
-         /* Verify that all registers are strictly consetuctive  */
+         /* Verify that all registers are strictly consecutive  */
          if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0))))
            {
              int i;
@@ -2843,6 +3198,13 @@ ix86_va_arg (valist, type)
   if (container)
     emit_label (lab_over);
 
+  if (indirect_p)
+    {
+      r = gen_rtx_MEM (Pmode, addr_rtx);
+      set_mem_alias_set (r, get_varargs_alias_set ());
+      emit_move_insn (addr_rtx, r);
+    }
+
   return addr_rtx;
 }
 \f
@@ -2873,7 +3235,7 @@ register_and_not_any_fp_reg_operand (op, mode)
   return register_operand (op, mode) && !ANY_FP_REG_P (op);
 }
 
-/* Return nonzero of OP is a register operand other than an
+/* Return nonzero if OP is a register operand other than an
    i387 fp register.  */
 int
 register_and_not_fp_reg_operand (op, mode)
@@ -2894,7 +3256,7 @@ x86_64_general_operand (op, mode)
     return general_operand (op, mode);
   if (nonimmediate_operand (op, mode))
     return 1;
-  return x86_64_sign_extended_value (op, 1);
+  return x86_64_sign_extended_value (op);
 }
 
 /* Return nonzero if OP is general operand representable on x86_64
@@ -2909,7 +3271,7 @@ x86_64_szext_general_operand (op, mode)
     return general_operand (op, mode);
   if (nonimmediate_operand (op, mode))
     return 1;
-  return x86_64_sign_extended_value (op, 1) || x86_64_zero_extended_value (op);
+  return x86_64_sign_extended_value (op) || x86_64_zero_extended_value (op);
 }
 
 /* Return nonzero if OP is nonmemory operand representable on x86_64.  */
@@ -2923,7 +3285,7 @@ x86_64_nonmemory_operand (op, mode)
     return nonmemory_operand (op, mode);
   if (register_operand (op, mode))
     return 1;
-  return x86_64_sign_extended_value (op, 1);
+  return x86_64_sign_extended_value (op);
 }
 
 /* Return nonzero if OP is nonmemory operand acceptable by movabs patterns.  */
@@ -2935,7 +3297,7 @@ x86_64_movabs_operand (op, mode)
 {
   if (!TARGET_64BIT || !flag_pic)
     return nonmemory_operand (op, mode);
-  if (register_operand (op, mode) || x86_64_sign_extended_value (op, 0))
+  if (register_operand (op, mode) || x86_64_sign_extended_value (op))
     return 1;
   if (CONSTANT_P (op) && !symbolic_reference_mentioned_p (op))
     return 1;
@@ -2953,7 +3315,7 @@ x86_64_szext_nonmemory_operand (op, mode)
     return nonmemory_operand (op, mode);
   if (register_operand (op, mode))
     return 1;
-  return x86_64_sign_extended_value (op, 0) || x86_64_zero_extended_value (op);
+  return x86_64_sign_extended_value (op) || x86_64_zero_extended_value (op);
 }
 
 /* Return nonzero if OP is immediate operand representable on x86_64.  */
@@ -2965,7 +3327,7 @@ x86_64_immediate_operand (op, mode)
 {
   if (!TARGET_64BIT)
     return immediate_operand (op, mode);
-  return x86_64_sign_extended_value (op, 0);
+  return x86_64_sign_extended_value (op);
 }
 
 /* Return nonzero if OP is immediate operand representable on x86_64.  */
@@ -3085,10 +3447,7 @@ local_symbolic_operand (op, mode)
 {
   if (GET_CODE (op) == CONST
       && GET_CODE (XEXP (op, 0)) == PLUS
-      && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
-      && (ix86_cmodel != CM_SMALL_PIC
-         || (INTVAL (XEXP (XEXP (op, 0), 1)) >= -16*1024*1024
-             && INTVAL (XEXP (XEXP (op, 0), 1)) < 16*1024*1024)))
+      && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
     op = XEXP (XEXP (op, 0), 0);
 
   if (GET_CODE (op) == LABEL_REF)
@@ -3209,6 +3568,32 @@ call_insn_operand (op, mode)
   return general_operand (op, Pmode);
 }
 
+/* Test for a valid operand for a call instruction.  Don't allow the
+   arg pointer register or virtual regs since they may decay into
+   reg + const, which the patterns can't handle.  */
+
+int
+sibcall_insn_operand (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  /* Disallow indirect through a virtual register.  This leads to
+     compiler aborts when trying to eliminate them.  */
+  if (GET_CODE (op) == REG
+      && (op == arg_pointer_rtx
+         || op == frame_pointer_rtx
+         || (REGNO (op) >= FIRST_PSEUDO_REGISTER
+             && REGNO (op) <= LAST_VIRTUAL_REGISTER)))
+    return 0;
+
+  /* Explicitly allow SYMBOL_REF even if pic.  */
+  if (GET_CODE (op) == SYMBOL_REF)
+    return 1;
+
+  /* Otherwise we can only allow register operands.  */
+  return register_operand (op, Pmode);
+}
+
 int
 constant_call_address_operand (op, mode)
      rtx op;
@@ -3250,7 +3635,7 @@ const248_operand (op, mode)
          && (INTVAL (op) == 2 || INTVAL (op) == 4 || INTVAL (op) == 8));
 }
 
-/* True if this is a constant appropriate for an increment or decremenmt.  */
+/* True if this is a constant appropriate for an increment or decrement.  */
 
 int
 incdec_operand (op, mode)
@@ -3387,6 +3772,18 @@ q_regs_operand (op, mode)
   return ANY_QI_REG_P (op);
 }
 
+/* Return true if op is an flags register.  */
+
+int
+flags_reg_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+{
+  if (mode != VOIDmode && GET_MODE (op) != mode)
+    return 0;
+  return REG_P (op) && REGNO (op) == FLAGS_REG && GET_MODE (op) != VOIDmode;
+}
+
 /* Return true if op is a NON_Q_REGS class register.  */
 
 int
@@ -3401,6 +3798,44 @@ non_q_regs_operand (op, mode)
   return NON_QI_REG_P (op);
 }
 
+int
+zero_extended_scalar_load_operand (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  unsigned n_elts;
+  if (GET_CODE (op) != MEM)
+    return 0;
+  op = maybe_get_pool_constant (op);
+  if (!op)
+    return 0;
+  if (GET_CODE (op) != CONST_VECTOR)
+    return 0;
+  n_elts =
+    (GET_MODE_SIZE (GET_MODE (op)) /
+     GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (op))));
+  for (n_elts--; n_elts > 0; n_elts--)
+    {
+      rtx elt = CONST_VECTOR_ELT (op, n_elts);
+      if (elt != CONST0_RTX (GET_MODE_INNER (GET_MODE (op))))
+       return 0;
+    }
+  return 1;
+}
+
+/*  Return 1 when OP is operand acceptable for standard SSE move.  */
+int
+vector_move_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (nonimmediate_operand (op, mode))
+    return 1;
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return 0;
+  return (op == CONST0_RTX (GET_MODE (op)));
+}
+
 /* Return 1 if OP is a comparison that can be used in the CMPSS/CMPPS
    insns.  */
 int
@@ -3475,6 +3910,40 @@ ix86_comparison_operator (op, mode)
     }
 }
 
+/* Return 1 if OP is a valid comparison operator testing carry flag
+   to be set.  */
+int
+ix86_carry_flag_operator (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+{
+  enum machine_mode inmode;
+  enum rtx_code code = GET_CODE (op);
+
+  if (mode != VOIDmode && GET_MODE (op) != mode)
+    return 0;
+  if (GET_RTX_CLASS (code) != '<')
+    return 0;
+  inmode = GET_MODE (XEXP (op, 0));
+  if (GET_CODE (XEXP (op, 0)) != REG
+      || REGNO (XEXP (op, 0)) != 17
+      || XEXP (op, 1) != const0_rtx)
+    return 0;
+
+  if (inmode == CCFPmode || inmode == CCFPUmode)
+    {
+      enum rtx_code second_code, bypass_code;
+
+      ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
+      if (bypass_code != NIL || second_code != NIL)
+       return 0;
+      code = ix86_fp_compare_code_to_integer (code);
+    }
+  else if (inmode != CCmode)
+    return 0;
+  return code == LTU;
+}
+
 /* Return 1 if OP is a comparison operator that can be issued by fcmov.  */
 
 int
@@ -3484,6 +3953,7 @@ fcmov_comparison_operator (op, mode)
 {
   enum machine_mode inmode;
   enum rtx_code code = GET_CODE (op);
+
   if (mode != VOIDmode && GET_MODE (op) != mode)
     return 0;
   if (GET_RTX_CLASS (code) != '<')
@@ -3492,6 +3962,7 @@ fcmov_comparison_operator (op, mode)
   if (inmode == CCFPmode || inmode == CCFPUmode)
     {
       enum rtx_code second_code, bypass_code;
+
       ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
       if (bypass_code != NIL || second_code != NIL)
        return 0;
@@ -3524,7 +3995,7 @@ promotable_binary_operator (op, mode)
     case MULT:
       /* Modern CPUs have same latency for HImode and SImode multiply,
          but 386 and 486 do HImode multiply faster.  */
-      return ix86_cpu > PROCESSOR_I486;
+      return ix86_tune > PROCESSOR_I486;
     case PLUS:
     case AND:
     case IOR:
@@ -3567,7 +4038,7 @@ ext_register_operand (op, mode)
   if (!register_operand (op, VOIDmode))
     return 0;
 
-  /* Be curefull to accept only registers having upper parts.  */
+  /* Be careful to accept only registers having upper parts.  */
   regno = REG_P (op) ? REGNO (op) : REGNO (SUBREG_REG (op));
   return (regno > LAST_VIRTUAL_REGISTER || regno < 4);
 }
@@ -3731,33 +4202,131 @@ aligned_operand (op, mode)
     }
   if (parts.disp)
     {
-      if (GET_CODE (parts.disp) != CONST_INT
-         || (INTVAL (parts.disp) & 3) != 0)
-       return 0;
+      if (GET_CODE (parts.disp) != CONST_INT
+         || (INTVAL (parts.disp) & 3) != 0)
+       return 0;
+    }
+
+  /* Didn't find one -- this must be an aligned address.  */
+  return 1;
+}
+\f
+/* Initialize the table of extra 80387 mathematical constants.  */
+
+static void
+init_ext_80387_constants ()
+{
+  static const char * cst[5] =
+  {
+    "0.3010299956639811952256464283594894482",  /* 0: fldlg2  */
+    "0.6931471805599453094286904741849753009",  /* 1: fldln2  */
+    "1.4426950408889634073876517827983434472",  /* 2: fldl2e  */
+    "3.3219280948873623478083405569094566090",  /* 3: fldl2t  */
+    "3.1415926535897932385128089594061862044",  /* 4: fldpi   */
+  };
+  int i;
+
+  for (i = 0; i < 5; i++)
+    {
+      real_from_string (&ext_80387_constants_table[i], cst[i]);
+      /* Ensure each constant is rounded to XFmode precision.  */
+      real_convert (&ext_80387_constants_table[i], XFmode,
+                   &ext_80387_constants_table[i]);
+    }
+
+  ext_80387_constants_init = 1;
+}
+
+/* Return true if the constant is something that can be loaded with
+   a special instruction.  */
+
+int
+standard_80387_constant_p (x)
+     rtx x;
+{
+  if (GET_CODE (x) != CONST_DOUBLE || !FLOAT_MODE_P (GET_MODE (x)))
+    return -1;
+
+  if (x == CONST0_RTX (GET_MODE (x)))
+    return 1;
+  if (x == CONST1_RTX (GET_MODE (x)))
+    return 2;
+
+  /* For XFmode constants, try to find a special 80387 instruction on
+     those CPUs that benefit from them.  */
+  if (GET_MODE (x) == XFmode
+      && x86_ext_80387_constants & TUNEMASK)
+    {
+      REAL_VALUE_TYPE r;
+      int i;
+
+      if (! ext_80387_constants_init)
+       init_ext_80387_constants ();
+
+      REAL_VALUE_FROM_CONST_DOUBLE (r, x);
+      for (i = 0; i < 5; i++)
+        if (real_identical (&r, &ext_80387_constants_table[i]))
+         return i + 3;
+    }
+
+  return 0;
+}
+
+/* Return the opcode of the special instruction to be used to load
+   the constant X.  */
+
+const char *
+standard_80387_constant_opcode (x)
+     rtx x;
+{
+  switch (standard_80387_constant_p (x))
+    {
+    case 1: 
+      return "fldz";
+    case 2:
+      return "fld1";
+    case 3: 
+      return "fldlg2";
+    case 4:
+      return "fldln2";
+    case 5: 
+      return "fldl2e";
+    case 6:
+      return "fldl2t";
+    case 7: 
+      return "fldpi";
     }
-
-  /* Didn't find one -- this must be an aligned address.  */
-  return 1;
+  abort ();
 }
-\f
-/* Return true if the constant is something that can be loaded with
-   a special instruction.  Only handle 0.0 and 1.0; others are less
-   worthwhile.  */
 
-int
-standard_80387_constant_p (x)
-     rtx x;
+/* Return the CONST_DOUBLE representing the 80387 constant that is
+   loaded by the specified special instruction.  The argument IDX
+   matches the return value from standard_80387_constant_p.  */
+
+rtx
+standard_80387_constant_rtx (idx)
+     int idx;
 {
-  if (GET_CODE (x) != CONST_DOUBLE || !FLOAT_MODE_P (GET_MODE (x)))
-    return -1;
-  /* Note that on the 80387, other constants, such as pi, that we should support
-     too.  On some machines, these are much slower to load as standard constant,
-     than to load from doubles in memory.  */
-  if (x == CONST0_RTX (GET_MODE (x)))
-    return 1;
-  if (x == CONST1_RTX (GET_MODE (x)))
-    return 2;
-  return 0;
+  int i;
+
+  if (! ext_80387_constants_init)
+    init_ext_80387_constants ();
+
+  switch (idx)
+    {
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+      i = idx - 3;
+      break;
+
+    default:
+      abort ();
+    }
+
+  return CONST_DOUBLE_FROM_REAL_VALUE (ext_80387_constants_table[i], XFmode);
 }
 
 /* Return 1 if X is FP constant we can load to SSE register w/o using memory.
@@ -3839,9 +4408,8 @@ ix86_can_use_return_insn_p ()
 \f
 /* Return 1 if VALUE can be stored in the sign extended immediate field.  */
 int
-x86_64_sign_extended_value (value, allow_rip)
+x86_64_sign_extended_value (value)
      rtx value;
-     int allow_rip;
 {
   switch (GET_CODE (value))
     {
@@ -3863,17 +4431,12 @@ x86_64_sign_extended_value (value, allow_rip)
         library.  Don't count TLS SYMBOL_REFs here, since they should fit
         only if inside of UNSPEC handled below.  */
       case SYMBOL_REF:
-       return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL
-               || (allow_rip
-                   && ix86_cmodel == CM_SMALL_PIC
-                   && (CONSTANT_POOL_ADDRESS_P (value)
-                       || SYMBOL_REF_FLAG (value))
-                   && ! tls_symbolic_operand (value, GET_MODE (value))));
+       return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL);
 
       /* For certain code models, the code is near as well.  */
       case LABEL_REF:
-       return ix86_cmodel != CM_LARGE
-              && (allow_rip || ix86_cmodel != CM_SMALL_PIC);
+       return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM
+               || ix86_cmodel == CM_KERNEL);
 
       /* We also may accept the offsetted memory references in certain special
          cases.  */
@@ -3919,26 +4482,11 @@ x86_64_sign_extended_value (value, allow_rip)
                      && offset > 0
                      && trunc_int_for_mode (offset, SImode) == offset)
                    return 1;
-                 /* For CM_SMALL_PIC, we can make similar assumptions
-                    as for CM_SMALL model, if we know the symbol is local
-                    to the shared library.  Disallow any TLS symbols,
-                    since they should always be enclosed in an UNSPEC.  */
-                 if (ix86_cmodel == CM_SMALL_PIC
-                     && allow_rip
-                     && (CONSTANT_POOL_ADDRESS_P (op1)
-                         || SYMBOL_REF_FLAG (op1))
-                     && ! tls_symbolic_operand (op1, GET_MODE (op1))
-                     && offset < 16*1024*1024
-                     && offset >= -16*1024*1024
-                     && trunc_int_for_mode (offset, SImode) == offset)
-                   return 1;
                  break;
                case LABEL_REF:
                  /* These conditions are similar to SYMBOL_REF ones, just the
                     constraints for code models differ.  */
-                 if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM
-                      || (ix86_cmodel == CM_SMALL_PIC && allow_rip
-                          && offset >= -16*1024*1024))
+                 if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM)
                      && offset < 16*1024*1024
                      && trunc_int_for_mode (offset, SImode) == offset)
                    return 1;
@@ -4181,7 +4729,7 @@ output_set_got (dest)
          is what will be referred to by the Mach-O PIC subsystem.  */
       ASM_OUTPUT_LABEL (asm_out_file, machopic_function_base_name ());
 #endif
-      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
+      (*targetm.asm_out.internal_label) (asm_out_file, "L",
                                 CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
 
       if (flag_pic)
@@ -4477,14 +5025,32 @@ ix86_expand_prologue ()
   int use_mov = 0;
   HOST_WIDE_INT allocate;
 
+  ix86_compute_frame_layout (&frame);
   if (!optimize_size)
     {
-      use_fast_prologue_epilogue
-        = !expensive_function_p (FAST_PROLOGUE_INSN_COUNT);
+      int count = frame.nregs;
+
+      /* The fast prologue uses move instead of push to save registers.  This
+         is significantly longer, but also executes faster as modern hardware
+         can execute the moves in parallel, but can't do that for push/pop.
+        
+        Be careful about choosing what prologue to emit:  When function takes
+        many instructions to execute we may use slow version as well as in
+        case function is known to be outside hot spot (this is known with
+        feedback only).  Weight the size of function by number of registers
+        to save as it is cheap to use one or two push instructions but very
+        slow to use many of them.  */
+      if (count)
+       count = (count - 1) * FAST_PROLOGUE_INSN_COUNT;
+      if (cfun->function_frequency < FUNCTION_FREQUENCY_NORMAL
+         || (flag_branch_probabilities
+             && cfun->function_frequency < FUNCTION_FREQUENCY_HOT))
+       use_fast_prologue_epilogue = 0;
+      else
+        use_fast_prologue_epilogue = !expensive_function_p (count);
       if (TARGET_PROLOGUE_USING_MOVE)
         use_mov = use_fast_prologue_epilogue;
     }
-  ix86_compute_frame_layout (&frame);
 
   /* Note: AT&T enter does NOT have reversed args.  Enter is probably
      slower on all targets.  Also sdb doesn't like it.  */
@@ -4537,6 +5103,10 @@ ix86_expand_prologue ()
       CALL_INSN_FUNCTION_USAGE (insn)
        = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, arg0),
                             CALL_INSN_FUNCTION_USAGE (insn));
+
+      /* Don't allow scheduling pass to move insns across __alloca
+         call.  */
+      emit_insn (gen_blockage (const0_rtx));
     }
   if (use_mov)
     {
@@ -4571,7 +5141,7 @@ ix86_expand_prologue ()
       /* Even with accurate pre-reload life analysis, we can wind up
         deleting all references to the pic register after reload.
         Consider if cross-jumping unifies two sides of a branch
-        controled by a comparison vs the only read from a global.
+        controlled by a comparison vs the only read from a global.
         In which case, allow the set_got to be deleted, though we're
         too late to do anything about the ebx save in the prologue.  */
       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx, NULL);
@@ -4633,7 +5203,7 @@ ix86_expand_epilogue (style)
      while this code results in LEAVE instruction (or discrete equivalent),
      so it is profitable in some other cases as well.  Especially when there
      are no registers to restore.  We also use this code when TARGET_USE_LEAVE
-     and there is exactly one register to pop. This heruistic may need some
+     and there is exactly one register to pop. This heuristic may need some
      tuning in future.  */
   if ((!sp_valid && frame.nregs <= 1)
       || (TARGET_EPILOGUE_USING_MOVE
@@ -4889,7 +5459,7 @@ ix86_decompose_address (addr, out)
 
   /* Special case: on K6, [%esi] makes the instruction vector decoded.
      Avoid this by transforming to [%esi+0].  */
-  if (ix86_cpu == PROCESSOR_K6 && !optimize_size
+  if (ix86_tune == PROCESSOR_K6 && !optimize_size
       && base && !index && !disp
       && REG_P (base)
       && REGNO_REG_CLASS (REGNO (base)) == SIREG)
@@ -4916,7 +5486,7 @@ ix86_decompose_address (addr, out)
    the address into a reg and make a new pseudo.  But not if the address
    requires to two regs - that would mean more pseudos with longer
    lifetimes.  */
-int
+static int
 ix86_address_cost (x)
      rtx x;
 {
@@ -5006,21 +5576,7 @@ ix86_find_base_term (x)
       return term;
     }
 
-  if (GET_CODE (x) != PLUS
-      || XEXP (x, 0) != pic_offset_table_rtx
-      || GET_CODE (XEXP (x, 1)) != CONST)
-    return x;
-
-  term = XEXP (XEXP (x, 1), 0);
-
-  if (GET_CODE (term) == PLUS && GET_CODE (XEXP (term, 1)) == CONST_INT)
-    term = XEXP (term, 0);
-
-  if (GET_CODE (term) != UNSPEC
-      || XINT (term, 1) != UNSPEC_GOTOFF)
-    return x;
-
-  term = XVECEXP (term, 0, 0);
+  term = ix86_delegitimize_address (x);
 
   if (GET_CODE (term) != SYMBOL_REF
       && GET_CODE (term) != LABEL_REF)
@@ -5074,6 +5630,17 @@ legitimate_constant_p (x)
   return true;
 }
 
+/* Determine if it's legal to put X into the constant pool.  This
+   is not possible for the address of thread-local symbols, which
+   is checked above.  */
+
+static bool
+ix86_cannot_force_const_mem (x)
+     rtx x;
+{
+  return !legitimate_constant_p (x);
+}
+
 /* Determine if a given RTX is a valid constant address.  */
 
 bool
@@ -5148,8 +5715,30 @@ legitimate_pic_address_disp_p (disp)
 
   /* In 64bit mode we can allow direct addresses of symbols and labels
      when they are not dynamic symbols.  */
-  if (TARGET_64BIT && local_symbolic_operand (disp, Pmode))
-    return 1;
+  if (TARGET_64BIT)
+    {
+      /* TLS references should always be enclosed in UNSPEC.  */
+      if (tls_symbolic_operand (disp, GET_MODE (disp)))
+       return 0;
+      if (GET_CODE (disp) == SYMBOL_REF
+         && ix86_cmodel == CM_SMALL_PIC
+         && (CONSTANT_POOL_ADDRESS_P (disp)
+             || SYMBOL_REF_FLAG (disp)))
+       return 1;
+      if (GET_CODE (disp) == LABEL_REF)
+       return 1;
+      if (GET_CODE (disp) == CONST
+         && GET_CODE (XEXP (disp, 0)) == PLUS
+         && ((GET_CODE (XEXP (XEXP (disp, 0), 0)) == SYMBOL_REF
+              && ix86_cmodel == CM_SMALL_PIC
+              && (CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (disp, 0), 0))
+                  || SYMBOL_REF_FLAG (XEXP (XEXP (disp, 0), 0))))
+             || GET_CODE (XEXP (XEXP (disp, 0), 0)) == LABEL_REF)
+         && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT
+         && INTVAL (XEXP (XEXP (disp, 0), 1)) < 16*1024*1024
+         && INTVAL (XEXP (XEXP (disp, 0), 1)) >= -16*1024*1024)
+       return 1;
+    }
   if (GET_CODE (disp) != CONST)
     return 0;
   disp = XEXP (disp, 0);
@@ -5356,23 +5945,6 @@ legitimate_address_p (mode, addr, strict)
     {
       reason_rtx = disp;
 
-      if (TARGET_64BIT)
-       {
-         if (!x86_64_sign_extended_value (disp, !(index || base)))
-           {
-             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 (GET_CODE (disp) == CONST
          && GET_CODE (XEXP (disp, 0)) == UNSPEC)
        switch (XINT (XEXP (disp, 0), 1))
@@ -5450,6 +6022,16 @@ legitimate_address_p (mode, addr, strict)
          reason = "displacement is not constant";
          goto report_error;
        }
+      else if (TARGET_64BIT && !x86_64_sign_extended_value (disp))
+       {
+         reason = "displacement is out of range";
+         goto report_error;
+       }
+      else if (!TARGET_64BIT && GET_CODE (disp) == CONST_DOUBLE)
+       {
+         reason = "displacement is a const_double";
+         goto report_error;
+       }
     }
 
   /* Everything looks valid.  */
@@ -5511,28 +6093,24 @@ legitimize_pic_address (orig, reg)
   return machopic_legitimize_pic_address (orig, GET_MODE (orig), reg);
 #endif
 
-  if (local_symbolic_operand (addr, Pmode))
+  if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
+    new = addr;
+  else if (!TARGET_64BIT && local_symbolic_operand (addr, Pmode))
     {
-      /* In 64bit mode we can address such objects directly.  */
-      if (TARGET_64BIT)
-       new = addr;
-      else
-       {
-         /* This symbol may be referenced via a displacement from the PIC
-            base address (@GOTOFF).  */
+      /* This symbol may be referenced via a displacement from the PIC
+        base address (@GOTOFF).  */
 
-         if (reload_in_progress)
-           regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
-         new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
-         new = gen_rtx_CONST (Pmode, new);
-         new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
+      if (reload_in_progress)
+       regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+      new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
+      new = gen_rtx_CONST (Pmode, new);
+      new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
 
-         if (reg != 0)
-           {
-             emit_move_insn (reg, new);
-             new = reg;
-           }
-       }
+      if (reg != 0)
+       {
+         emit_move_insn (reg, new);
+         new = reg;
+       }
     }
   else if (GET_CODE (addr) == SYMBOL_REF)
     {
@@ -6232,8 +6810,8 @@ i386_output_dwarf_dtprel (file, size, x)
    general assembler losage, recognize PIC+GOTOFF and turn it back
    into a direct symbol reference.  */
 
-rtx
-i386_simplify_dwarf_addr (orig_x)
+static rtx
+ix86_delegitimize_address (orig_x)
      rtx orig_x;
 {
   rtx x = orig_x, y;
@@ -6795,7 +7373,7 @@ print_operand (file, x, code)
                    int cputaken = final_forward_branch_p (current_output_insn) == 0;
 
                    /* Emit hints only in the case default branch prediction
-                      heruistics would fail.  */
+                      heuristics would fail.  */
                    if (taken != cputaken)
                      {
                        /* We use 3e (DS) prefix for taken branches and
@@ -7483,12 +8061,12 @@ output_fp_compare (insn, operands, eflags_p, unordered_p)
        if (unordered_p)
          return "ucomiss\t{%1, %0|%0, %1}";
        else
-         return "comiss\t{%1, %0|%0, %y}";
+         return "comiss\t{%1, %0|%0, %1}";
       else
        if (unordered_p)
          return "ucomisd\t{%1, %0|%0, %1}";
        else
-         return "comisd\t{%1, %0|%0, %y}";
+         return "comisd\t{%1, %0|%0, %1}";
     }
 
   if (! STACK_TOP_P (cmp_op0))
@@ -7663,24 +8241,7 @@ static rtx
 maybe_get_pool_constant (x)
      rtx x;
 {
-  x = XEXP (x, 0);
-
-  if (flag_pic && ! TARGET_64BIT)
-    {
-      if (GET_CODE (x) != PLUS)
-       return NULL_RTX;
-      if (XEXP (x, 0) != pic_offset_table_rtx)
-       return NULL_RTX;
-      x = XEXP (x, 1);
-      if (GET_CODE (x) != CONST)
-       return NULL_RTX;
-      x = XEXP (x, 0);
-      if (GET_CODE (x) != UNSPEC)
-       return NULL_RTX;
-      if (XINT (x, 1) != UNSPEC_GOTOFF)
-       return NULL_RTX;
-      x = XVECEXP (x, 0, 0);
-    }
+  x = ix86_delegitimize_address (XEXP (x, 0));
 
   if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
     return get_pool_constant (x);
@@ -7699,29 +8260,6 @@ ix86_expand_move (mode, operands)
   op0 = operands[0];
   op1 = operands[1];
 
-  /* ??? We have a slight problem.  We need to say that tls symbols are
-     not legitimate constants so that reload does not helpfully reload
-     these constants from a REG_EQUIV, which we cannot handle.  (Recall
-     that general- and local-dynamic address resolution requires a
-     function call.)
-
-     However, if we say that tls symbols are not legitimate constants,
-     then emit_move_insn helpfully drop them into the constant pool.
-
-     It is far easier to work around emit_move_insn than reload.  Recognize
-     the MEM that we would have created and extract the symbol_ref.  */
-
-  if (mode == Pmode
-      && GET_CODE (op1) == MEM
-      && RTX_UNCHANGING_P (op1))
-    {
-      tmp = maybe_get_pool_constant (op1);
-      /* Note that we only care about symbolic constants here, which
-        unlike CONST_INT will always have a proper mode.  */
-      if (tmp && GET_MODE (tmp) == Pmode)
-       op1 = tmp;
-    }
-
   if (tls_symbolic_operand (op1, Pmode))
     {
       op1 = legitimize_address (op1, op1, VOIDmode);
@@ -7821,8 +8359,8 @@ ix86_expand_vector_move (mode, operands)
      to handle some of them more efficiently.  */
   if ((reload_in_progress | reload_completed) == 0
       && register_operand (operands[0], mode)
-      && CONSTANT_P (operands[1]))
-    operands[1] = force_const_mem (mode, operands[1]);
+      && CONSTANT_P (operands[1]) && operands[1] != CONST0_RTX (mode))
+    operands[1] = validize_mem (force_const_mem (mode, operands[1]));
 
   /* Make operand1 a register if it isn't already.  */
   if (!no_new_pseudos
@@ -8155,7 +8693,7 @@ ix86_cc_mode (code, op0, op1)
        return CCGCmode;
       /* Codes doable only with sign flag when comparing
          against zero, but we miss jump instruction for it
-         so we need to use relational tests agains overflow
+         so we need to use relational tests against overflow
          that thus needs to be zero.  */
     case GT:                   /* ZF=0 & SF=OF */
     case LE:                   /* ZF=1 | SF<>OF */
@@ -8186,7 +8724,7 @@ ix86_use_fcomi_compare (code)
 
 /* Swap, force into registers, or otherwise massage the two operands
    to a fp comparison.  The operands are updated in place; the new
-   comparsion code is returned.  */
+   comparison code is returned.  */
 
 static enum rtx_code
 ix86_prepare_fp_compare_args (code, pop0, pop1)
@@ -8357,7 +8895,7 @@ ix86_fp_comparison_codes (code, bypass_code, first_code, second_code)
 }
 
 /* Return cost of comparison done fcom + arithmetics operations on AX.
-   All following functions do use number of instructions as an cost metrics.
+   All following functions do use number of instructions as a cost metrics.
    In future this should be tweaked to compute bytes for optimize_size and
    take into account performance of various instructions on various CPUs.  */
 static int
@@ -8401,7 +8939,7 @@ ix86_fp_comparison_fcomi_cost (code)
      enum rtx_code code;
 {
   enum rtx_code bypass_code, first_code, second_code;
-  /* Return arbitarily high cost when instruction is not supported - this
+  /* Return arbitrarily high cost when instruction is not supported - this
      prevents gcc from using it.  */
   if (!TARGET_CMOVE)
     return 1024;
@@ -8416,7 +8954,7 @@ ix86_fp_comparison_sahf_cost (code)
      enum rtx_code code;
 {
   enum rtx_code bypass_code, first_code, second_code;
-  /* Return arbitarily high cost when instruction is not preferred - this
+  /* Return arbitrarily high cost when instruction is not preferred - this
      avoids gcc from using it.  */
   if (!TARGET_USE_SAHF && !optimize_size)
     return 1024;
@@ -8982,6 +9520,128 @@ ix86_expand_setcc (code, dest)
   return 1; /* DONE */
 }
 
+/* Expand comparison setting or clearing carry flag.  Return true when successful
+   and set pop for the operation.  */
+bool
+ix86_expand_carry_flag_compare (code, op0, op1, pop)
+     rtx op0, op1, *pop;
+     enum rtx_code code;
+{
+  enum machine_mode mode =
+    GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
+
+  /* Do not handle DImode compares that go trought special path.  Also we can't
+     deal with FP compares yet.  This is possible to add.   */
+  if ((mode == DImode && !TARGET_64BIT))
+    return false;
+  if (FLOAT_MODE_P (mode))
+    {
+      rtx second_test = NULL, bypass_test = NULL;
+      rtx compare_op, compare_seq;
+
+      /* Shortcut:  following common codes never translate into carry flag compares.  */
+      if (code == EQ || code == NE || code == UNEQ || code == LTGT
+         || code == ORDERED || code == UNORDERED)
+       return false;
+
+      /* These comparisons require zero flag; swap operands so they won't.  */
+      if ((code == GT || code == UNLE || code == LE || code == UNGT)
+         && !TARGET_IEEE_FP)
+       {
+         rtx tmp = op0;
+         op0 = op1;
+         op1 = tmp;
+         code = swap_condition (code);
+       }
+
+      /* Try to expand the comparsion and verify that we end up with carry flag
+        based comparsion.  This is fails to be true only when we decide to expand
+        comparsion using arithmetic that is not too common scenario.  */
+      start_sequence ();
+      compare_op = ix86_expand_fp_compare (code, op0, op1, NULL_RTX,
+                                          &second_test, &bypass_test);
+      compare_seq = get_insns ();
+      end_sequence ();
+
+      if (second_test || bypass_test)
+       return false;
+      if (GET_MODE (XEXP (compare_op, 0)) == CCFPmode
+         || GET_MODE (XEXP (compare_op, 0)) == CCFPUmode)
+        code = ix86_fp_compare_code_to_integer (GET_CODE (compare_op));
+      else
+       code = GET_CODE (compare_op);
+      if (code != LTU && code != GEU)
+       return false;
+      emit_insn (compare_seq);
+      *pop = compare_op;
+      return true;
+    }
+  if (!INTEGRAL_MODE_P (mode))
+    return false;
+  switch (code)
+    {
+    case LTU:
+    case GEU:
+      break;
+
+    /* Convert a==0 into (unsigned)a<1.  */
+    case EQ:
+    case NE:
+      if (op1 != const0_rtx)
+       return false;
+      op1 = const1_rtx;
+      code = (code == EQ ? LTU : GEU);
+      break;
+
+    /* Convert a>b into b<a or a>=b-1.  */
+    case GTU:
+    case LEU:
+      if (GET_CODE (op1) == CONST_INT)
+       {
+         op1 = gen_int_mode (INTVAL (op1) + 1, GET_MODE (op0));
+         /* Bail out on overflow.  We still can swap operands but that
+            would force loading of the constant into register. */
+         if (op1 == const0_rtx
+             || !x86_64_immediate_operand (op1, GET_MODE (op1)))
+           return false;
+         code = (code == GTU ? GEU : LTU);
+       }
+      else
+       {
+         rtx tmp = op1;
+         op1 = op0;
+         op0 = tmp;
+         code = (code == GTU ? LTU : GEU);
+       }
+      break;
+
+    /* Convert a>0 into (unsigned)a<0x7fffffff.  */
+    case LT:
+    case GE:
+      if (mode == DImode || op1 != const0_rtx)
+       return false;
+      op1 = gen_int_mode (~(1 << (GET_MODE_BITSIZE (mode) - 1)), mode);
+      code = (code == LT ? GEU : LTU);
+      break;
+    case LE:
+    case GT:
+      if (mode == DImode || op1 != constm1_rtx)
+       return false;
+      op1 = gen_int_mode (~(1 << (GET_MODE_BITSIZE (mode) - 1)), mode);
+      code = (code == LE ? GEU : LTU);
+      break;
+
+    default:
+      return false;
+    }
+  ix86_compare_op0 = op0;
+  ix86_compare_op1 = op1;
+  *pop = ix86_expand_compare (code, NULL, NULL);
+  if (GET_CODE (*pop) != LTU && GET_CODE (*pop) != GEU)
+    abort ();
+  return true;
+}
+
 int
 ix86_expand_int_movcc (operands)
      rtx operands[];
@@ -8990,30 +9650,7 @@ ix86_expand_int_movcc (operands)
   rtx compare_seq, compare_op;
   rtx second_test, bypass_test;
   enum machine_mode mode = GET_MODE (operands[0]);
-
-  /* When the compare code is not LTU or GEU, we can not use sbbl case.
-     In case comparsion is done with immediate, we can convert it to LTU or
-     GEU by altering the integer.  */
-
-  if ((code == LEU || code == GTU)
-      && GET_CODE (ix86_compare_op1) == CONST_INT
-      && mode != HImode
-      && INTVAL (ix86_compare_op1) != -1
-      /* For x86-64, the immediate field in the instruction is 32-bit
-        signed, so we can't increment a DImode value above 0x7fffffff.  */
-      && (!TARGET_64BIT
-         || GET_MODE (ix86_compare_op0) != DImode
-         || INTVAL (ix86_compare_op1) != 0x7fffffff)
-      && GET_CODE (operands[2]) == CONST_INT
-      && GET_CODE (operands[3]) == CONST_INT)
-    {
-      if (code == LEU)
-       code = LTU;
-      else
-       code = GEU;
-      ix86_compare_op1 = gen_int_mode (INTVAL (ix86_compare_op1) + 1,
-                                      GET_MODE (ix86_compare_op0));
-    }
+  bool sign_bit_compare_p = false;;
 
   start_sequence ();
   compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
@@ -9022,10 +9659,14 @@ ix86_expand_int_movcc (operands)
 
   compare_code = GET_CODE (compare_op);
 
+  if ((ix86_compare_op1 == const0_rtx && (code == GE || code == LT))
+      || (ix86_compare_op1 == constm1_rtx && (code == GT || code == LE)))
+    sign_bit_compare_p = true;
+
   /* Don't attempt mode expansion here -- if we had to expand 5 or 6
      HImode insns, we'd be swallowed in word prefix ops.  */
 
-  if (mode != HImode
+  if ((mode != HImode || TARGET_FAST_PREFIX)
       && (mode != DImode || TARGET_64BIT)
       && GET_CODE (operands[2]) == CONST_INT
       && GET_CODE (operands[3]) == CONST_INT)
@@ -9035,32 +9676,72 @@ ix86_expand_int_movcc (operands)
       HOST_WIDE_INT cf = INTVAL (operands[3]);
       HOST_WIDE_INT diff;
 
-      if ((compare_code == LTU || compare_code == GEU)
-         && !second_test && !bypass_test)
+      diff = ct - cf;
+      /*  Sign bit compares are better done using shifts than we do by using
+         sbb.  */
+      if (sign_bit_compare_p
+         || ix86_expand_carry_flag_compare (code, ix86_compare_op0,
+                                            ix86_compare_op1, &compare_op))
        {
          /* Detect overlap between destination and compare sources.  */
          rtx tmp = out;
 
-         /* To simplify rest of code, restrict to the GEU case.  */
-         if (compare_code == LTU)
+          if (!sign_bit_compare_p)
            {
-             int tmp = ct;
-             ct = cf;
-             cf = tmp;
-             compare_code = reverse_condition (compare_code);
-             code = reverse_condition (code);
-           }
-         diff = ct - cf;
+             bool fpcmp = false;
+
+             compare_code = GET_CODE (compare_op);
+
+             if (GET_MODE (XEXP (compare_op, 0)) == CCFPmode
+                 || GET_MODE (XEXP (compare_op, 0)) == CCFPUmode)
+               {
+                 fpcmp = true;
+                 compare_code = ix86_fp_compare_code_to_integer (compare_code);
+               }
+
+             /* To simplify rest of code, restrict to the GEU case.  */
+             if (compare_code == LTU)
+               {
+                 HOST_WIDE_INT tmp = ct;
+                 ct = cf;
+                 cf = tmp;
+                 compare_code = reverse_condition (compare_code);
+                 code = reverse_condition (code);
+               }
+             else
+               {
+                 if (fpcmp)
+                   PUT_CODE (compare_op,
+                             reverse_condition_maybe_unordered
+                               (GET_CODE (compare_op)));
+                 else
+                   PUT_CODE (compare_op, reverse_condition (GET_CODE (compare_op)));
+               }
+             diff = ct - cf;
 
-         if (reg_overlap_mentioned_p (out, ix86_compare_op0)
-             || reg_overlap_mentioned_p (out, ix86_compare_op1))
-           tmp = gen_reg_rtx (mode);
+             if (reg_overlap_mentioned_p (out, ix86_compare_op0)
+                 || reg_overlap_mentioned_p (out, ix86_compare_op1))
+               tmp = gen_reg_rtx (mode);
 
-         emit_insn (compare_seq);
-         if (mode == DImode)
-           emit_insn (gen_x86_movdicc_0_m1_rex64 (tmp));
+             if (mode == DImode)
+               emit_insn (gen_x86_movdicc_0_m1_rex64 (tmp, compare_op));
+             else
+               emit_insn (gen_x86_movsicc_0_m1 (gen_lowpart (SImode, tmp), compare_op));
+           }
          else
-           emit_insn (gen_x86_movsicc_0_m1 (tmp));
+           {
+             if (code == GT || code == GE)
+               code = reverse_condition (code);
+             else
+               {
+                 HOST_WIDE_INT tmp = ct;
+                 ct = cf;
+                 cf = tmp;
+                 diff = ct - cf;
+               }
+             tmp = emit_store_flag (tmp, code, ix86_compare_op0,
+                                    ix86_compare_op1, VOIDmode, 0, -1);
+           }
 
          if (diff == 1)
            {
@@ -9074,7 +9755,7 @@ ix86_expand_int_movcc (operands)
              if (ct)
                tmp = expand_simple_binop (mode, PLUS,
                                           tmp, GEN_INT (ct),
-                                          tmp, 1, OPTAB_DIRECT);
+                                          copy_rtx (tmp), 1, OPTAB_DIRECT);
            }
          else if (cf == -1)
            {
@@ -9087,7 +9768,7 @@ ix86_expand_int_movcc (operands)
               */
              tmp = expand_simple_binop (mode, IOR,
                                         tmp, GEN_INT (ct),
-                                        tmp, 1, OPTAB_DIRECT);
+                                        copy_rtx (tmp), 1, OPTAB_DIRECT);
            }
          else if (diff == -1 && ct)
            {
@@ -9099,11 +9780,11 @@ ix86_expand_int_movcc (operands)
               *
               * Size 8 - 11.
               */
-             tmp = expand_simple_unop (mode, NOT, tmp, tmp, 1);
+             tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1);
              if (cf)
                tmp = expand_simple_binop (mode, PLUS,
-                                          tmp, GEN_INT (cf),
-                                          tmp, 1, OPTAB_DIRECT);
+                                          copy_rtx (tmp), GEN_INT (cf),
+                                          copy_rtx (tmp), 1, OPTAB_DIRECT);
            }
          else
            {
@@ -9121,26 +9802,25 @@ ix86_expand_int_movcc (operands)
                {
                  cf = ct;
                  ct = 0;
-                 tmp = expand_simple_unop (mode, NOT, tmp, tmp, 1);
+                 tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1);
                }
 
              tmp = expand_simple_binop (mode, AND,
-                                        tmp,
+                                        copy_rtx (tmp),
                                         gen_int_mode (cf - ct, mode),
-                                        tmp, 1, OPTAB_DIRECT);
+                                        copy_rtx (tmp), 1, OPTAB_DIRECT);
              if (ct)
                tmp = expand_simple_binop (mode, PLUS,
-                                          tmp, GEN_INT (ct),
-                                          tmp, 1, OPTAB_DIRECT);
+                                          copy_rtx (tmp), GEN_INT (ct),
+                                          copy_rtx (tmp), 1, OPTAB_DIRECT);
            }
 
-         if (tmp != out)
-           emit_move_insn (out, tmp);
+         if (!rtx_equal_p (tmp, out))
+           emit_move_insn (copy_rtx (out), copy_rtx (tmp));
 
          return 1; /* DONE */
        }
 
-      diff = ct - cf;
       if (diff < 0)
        {
          HOST_WIDE_INT tmp;
@@ -9216,9 +9896,11 @@ ix86_expand_int_movcc (operands)
            }
        }
 
+
       if ((diff == 1 || diff == 2 || diff == 4 || diff == 8
           || diff == 3 || diff == 5 || diff == 9)
-         && (mode != DImode || x86_64_sign_extended_value (GEN_INT (cf), 0)))
+         && ((mode != QImode && mode != HImode) || !TARGET_PARTIAL_REG_STALL)
+         && (mode != DImode || x86_64_sign_extended_value (GEN_INT (cf))))
        {
          /*
           * xorl dest,dest
@@ -9241,11 +9923,11 @@ ix86_expand_int_movcc (operands)
          /* On x86_64 the lea instruction operates on Pmode, so we need
             to get arithmetics done in proper mode to match.  */
          if (diff == 1)
-           tmp = out;
+           tmp = copy_rtx (out);
          else
            {
              rtx out1;
-             out1 = out;
+             out1 = copy_rtx (out);
              tmp = gen_rtx_MULT (mode, out1, GEN_INT (diff & ~1));
              nops++;
              if (diff & 1)
@@ -9259,24 +9941,14 @@ ix86_expand_int_movcc (operands)
              tmp = gen_rtx_PLUS (mode, tmp, GEN_INT (cf));
              nops++;
            }
-         if (tmp != out
-             && (GET_CODE (tmp) != SUBREG || SUBREG_REG (tmp) != out))
+         if (!rtx_equal_p (tmp, out))
            {
              if (nops == 1)
-               {
-                 rtx clob;
-
-                 clob = gen_rtx_REG (CCmode, FLAGS_REG);
-                 clob = gen_rtx_CLOBBER (VOIDmode, clob);
-
-                 tmp = gen_rtx_SET (VOIDmode, out, tmp);
-                 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
-                 emit_insn (tmp);
-               }
+               out = force_operand (tmp, copy_rtx (out));
              else
-               emit_insn (gen_rtx_SET (VOIDmode, out, tmp));
+               emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (out), copy_rtx (tmp)));
            }
-         if (out != operands[0])
+         if (!rtx_equal_p (out, operands[0]))
            emit_move_insn (operands[0], copy_rtx (out));
 
          return 1; /* DONE */
@@ -9296,12 +9968,10 @@ ix86_expand_int_movcc (operands)
        * This is reasonably steep, but branch mispredict costs are
        * high on modern cpus, so consider failing only if optimizing
        * for space.
-       *
-       * %%% Parameterize branch_cost on the tuning architecture, then
-       * use that.  The 80386 couldn't care less about mispredicts.
        */
 
-      if (!optimize_size && !TARGET_CMOVE)
+      if ((!TARGET_CMOVE || (mode == QImode && TARGET_PARTIAL_REG_STALL))
+         && BRANCH_COST >= 2)
        {
          if (cf == 0)
            {
@@ -9355,31 +10025,31 @@ ix86_expand_int_movcc (operands)
              out = emit_store_flag (out, code, ix86_compare_op0,
                                     ix86_compare_op1, VOIDmode, 0, 1);
 
-             out = expand_simple_binop (mode, PLUS, out, constm1_rtx,
-                                        out, 1, OPTAB_DIRECT);
+             out = expand_simple_binop (mode, PLUS, copy_rtx (out), constm1_rtx,
+                                        copy_rtx (out), 1, OPTAB_DIRECT);
            }
 
-         out = expand_simple_binop (mode, AND, out,
+         out = expand_simple_binop (mode, AND, copy_rtx (out),
                                     gen_int_mode (cf - ct, mode),
-                                    out, 1, OPTAB_DIRECT);
+                                    copy_rtx (out), 1, OPTAB_DIRECT);
          if (ct)
-           out = expand_simple_binop (mode, PLUS, out, GEN_INT (ct),
-                                      out, 1, OPTAB_DIRECT);
-         if (out != operands[0])
-           emit_move_insn (operands[0], out);
+           out = expand_simple_binop (mode, PLUS, copy_rtx (out), GEN_INT (ct),
+                                      copy_rtx (out), 1, OPTAB_DIRECT);
+         if (!rtx_equal_p (out, operands[0]))
+           emit_move_insn (operands[0], copy_rtx (out));
 
          return 1; /* DONE */
        }
     }
 
-  if (!TARGET_CMOVE)
+  if (!TARGET_CMOVE || (mode == QImode && TARGET_PARTIAL_REG_STALL))
     {
       /* Try a few things more with specific constants and a variable.  */
 
       optab op;
       rtx var, orig_out, out, tmp;
 
-      if (optimize_size)
+      if (BRANCH_COST <= 2)
        return 0; /* FAIL */
 
       /* If one of the two operands is an interesting constant, load a
@@ -9388,9 +10058,9 @@ ix86_expand_int_movcc (operands)
       if (GET_CODE (operands[2]) == CONST_INT)
        {
          var = operands[3];
-         if (INTVAL (operands[2]) == 0)
+         if (INTVAL (operands[2]) == 0 && operands[3] != constm1_rtx)
            operands[3] = constm1_rtx, op = and_optab;
-         else if (INTVAL (operands[2]) == -1)
+         else if (INTVAL (operands[2]) == -1 && operands[3] != const0_rtx)
            operands[3] = const0_rtx, op = ior_optab;
          else
            return 0; /* FAIL */
@@ -9398,9 +10068,9 @@ ix86_expand_int_movcc (operands)
       else if (GET_CODE (operands[3]) == CONST_INT)
        {
          var = operands[2];
-         if (INTVAL (operands[3]) == 0)
+         if (INTVAL (operands[3]) == 0 && operands[2] != constm1_rtx)
            operands[2] = constm1_rtx, op = and_optab;
-         else if (INTVAL (operands[3]) == -1)
+         else if (INTVAL (operands[3]) == -1 && operands[3] != const0_rtx)
            operands[2] = const0_rtx, op = ior_optab;
          else
            return 0; /* FAIL */
@@ -9419,8 +10089,8 @@ ix86_expand_int_movcc (operands)
       /* Mask in the interesting variable.  */
       out = expand_binop (mode, op, var, tmp, orig_out, 0,
                          OPTAB_WIDEN);
-      if (out != orig_out)
-       emit_move_insn (orig_out, out);
+      if (!rtx_equal_p (out, orig_out))
+       emit_move_insn (copy_rtx (orig_out), copy_rtx (out));
 
       return 1; /* DONE */
     }
@@ -9453,27 +10123,33 @@ ix86_expand_int_movcc (operands)
       emit_move_insn (tmp, operands[2]);
       operands[2] = tmp;
     }
+
   if (! register_operand (operands[2], VOIDmode)
-      && ! register_operand (operands[3], VOIDmode))
+      && (mode == QImode 
+          || ! register_operand (operands[3], VOIDmode)))
     operands[2] = force_reg (mode, operands[2]);
 
+  if (mode == QImode
+      && ! register_operand (operands[3], VOIDmode))
+    operands[3] = force_reg (mode, operands[3]);
+
   emit_insn (compare_seq);
   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
                          gen_rtx_IF_THEN_ELSE (mode,
                                                compare_op, operands[2],
                                                operands[3])));
   if (bypass_test)
-    emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+    emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (operands[0]),
                            gen_rtx_IF_THEN_ELSE (mode,
                                  bypass_test,
-                                 operands[3],
-                                 operands[0])));
+                                 copy_rtx (operands[3]),
+                                 copy_rtx (operands[0]))));
   if (second_test)
-    emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+    emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (operands[0]),
                            gen_rtx_IF_THEN_ELSE (mode,
                                  second_test,
-                                 operands[2],
-                                 operands[0])));
+                                 copy_rtx (operands[2]),
+                                 copy_rtx (operands[0]))));
 
   return 1; /* DONE */
 }
@@ -9514,8 +10190,14 @@ ix86_expand_fp_movcc (operands)
       if (rtx_equal_p (operands[2], op0) && rtx_equal_p (operands[3], op1))
        {
          /* Check for min operation.  */
-         if (code == LT)
+         if (code == LT || code == UNLE)
            {
+              if (code == UNLE)
+               {
+                 rtx tmp = op0;
+                 op0 = op1;
+                 op1 = tmp;
+               }
               operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
               if (memory_operand (op0, VOIDmode))
                 op0 = force_reg (GET_MODE (operands[0]), op0);
@@ -9526,8 +10208,14 @@ ix86_expand_fp_movcc (operands)
               return 1;
            }
          /* Check for max operation.  */
-         if (code == GT)
+         if (code == GT || code == UNGE)
            {
+              if (code == UNGE)
+               {
+                 rtx tmp = op0;
+                 op0 = op1;
+                 op1 = tmp;
+               }
               operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
               if (memory_operand (op0, VOIDmode))
                 op0 = force_reg (GET_MODE (operands[0]), op0);
@@ -9552,7 +10240,7 @@ ix86_expand_fp_movcc (operands)
                                        VOIDmode, ix86_compare_op0,
                                        ix86_compare_op1);
        }
-      /* Similary try to manage result to be first operand of conditional
+      /* Similarly try to manage result to be first operand of conditional
         move. We also don't support the NE comparison on SSE, so try to
         avoid it.  */
       if ((rtx_equal_p (operands[0], operands[3])
@@ -9632,6 +10320,91 @@ ix86_expand_fp_movcc (operands)
   return 1;
 }
 
+/* Expand conditional increment or decrement using adb/sbb instructions.
+   The default case using setcc followed by the conditional move can be
+   done by generic code.  */
+int
+ix86_expand_int_addcc (operands)
+     rtx operands[];
+{
+  enum rtx_code code = GET_CODE (operands[1]);
+  rtx compare_op;
+  rtx val = const0_rtx;
+  bool fpcmp = false;
+  enum machine_mode mode = GET_MODE (operands[0]);
+
+  if (operands[3] != const1_rtx
+      && operands[3] != constm1_rtx)
+    return 0;
+  if (!ix86_expand_carry_flag_compare (code, ix86_compare_op0,
+                                      ix86_compare_op1, &compare_op))
+     return 0;
+  code = GET_CODE (compare_op);
+
+  if (GET_MODE (XEXP (compare_op, 0)) == CCFPmode
+      || GET_MODE (XEXP (compare_op, 0)) == CCFPUmode)
+    {
+      fpcmp = true;
+      code = ix86_fp_compare_code_to_integer (code);
+    }
+
+  if (code != LTU)
+    {
+      val = constm1_rtx;
+      if (fpcmp)
+       PUT_CODE (compare_op,
+                 reverse_condition_maybe_unordered
+                   (GET_CODE (compare_op)));
+      else
+       PUT_CODE (compare_op, reverse_condition (GET_CODE (compare_op)));
+    }
+  PUT_MODE (compare_op, mode);
+
+  /* Construct either adc or sbb insn.  */
+  if ((code == LTU) == (operands[3] == constm1_rtx))
+    {
+      switch (GET_MODE (operands[0]))
+       {
+         case QImode:
+            emit_insn (gen_subqi3_carry (operands[0], operands[2], val, compare_op));
+           break;
+         case HImode:
+            emit_insn (gen_subhi3_carry (operands[0], operands[2], val, compare_op));
+           break;
+         case SImode:
+            emit_insn (gen_subsi3_carry (operands[0], operands[2], val, compare_op));
+           break;
+         case DImode:
+            emit_insn (gen_subdi3_carry_rex64 (operands[0], operands[2], val, compare_op));
+           break;
+         default:
+           abort ();
+       }
+    }
+  else
+    {
+      switch (GET_MODE (operands[0]))
+       {
+         case QImode:
+            emit_insn (gen_addqi3_carry (operands[0], operands[2], val, compare_op));
+           break;
+         case HImode:
+            emit_insn (gen_addhi3_carry (operands[0], operands[2], val, compare_op));
+           break;
+         case SImode:
+            emit_insn (gen_addsi3_carry (operands[0], operands[2], val, compare_op));
+           break;
+         case DImode:
+            emit_insn (gen_adddi3_carry_rex64 (operands[0], operands[2], val, compare_op));
+           break;
+         default:
+           abort ();
+       }
+    }
+  return 1; /* DONE */
+}
+
+
 /* Split operands 0 and 1 into SImode parts.  Similar to split_di, but
    works for floating pointer parameters and nonoffsetable memories.
    For pushes, it returns just stack offsets; the values will be saved
@@ -10179,17 +10952,23 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
   unsigned HOST_WIDE_INT count = 0;
   rtx insns;
 
-  start_sequence ();
-
   if (GET_CODE (align_exp) == CONST_INT)
     align = INTVAL (align_exp);
 
+  /* Can't use any of this if the user has appropriated esi or edi.  */
+  if (global_regs[4] || global_regs[5])
+    return 0;
+
   /* This simple hack avoids all inlining code and simplifies code below.  */
   if (!TARGET_ALIGN_STRINGOPS)
     align = 64;
 
   if (GET_CODE (count_exp) == CONST_INT)
-    count = INTVAL (count_exp);
+    {
+      count = INTVAL (count_exp);
+      if (!TARGET_INLINE_ALL_STRINGOPS && count > 64)
+       return 0;
+    }
 
   /* Figure out proper mode for counter.  For 32bits it is always SImode,
      for 64bits use SImode when possible, otherwise DImode.
@@ -10200,6 +10979,8 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
   else
     counter_mode = DImode;
 
+  start_sequence ();
+
   if (counter_mode != SImode && counter_mode != DImode)
     abort ();
 
@@ -10273,8 +11054,12 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
 
       /* In case we don't know anything about the alignment, default to
          library version, since it is usually equally fast and result in
-         shorter code.  */
-      if (!TARGET_INLINE_ALL_STRINGOPS && align < UNITS_PER_WORD)
+         shorter code. 
+
+        Also emit call when we know that the count is large and call overhead
+        will not be important.  */
+      if (!TARGET_INLINE_ALL_STRINGOPS
+         && (align < UNITS_PER_WORD || !TARGET_REP_MOVL_OPTIMAL))
        {
          end_sequence ();
          return 0;
@@ -10292,11 +11077,11 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
          able to predict the branches) and also it is friendlier to the
          hardware branch prediction.
 
-         Using loops is benefical for generic case, because we can
+         Using loops is beneficial for generic case, because we can
          handle small counts using the loops.  Many CPUs (such as Athlon)
          have large REP prefix setup costs.
 
-         This is quite costy.  Maybe we can revisit this decision later or
+         This is quite costly.  Maybe we can revisit this decision later or
          add some customizability to this code.  */
 
       if (count == 0 && align < desired_alignment)
@@ -10408,12 +11193,20 @@ ix86_expand_clrstr (src, count_exp, align_exp)
   if (GET_CODE (align_exp) == CONST_INT)
     align = INTVAL (align_exp);
 
+  /* Can't use any of this if the user has appropriated esi.  */
+  if (global_regs[4])
+    return 0;
+
   /* This simple hack avoids all inlining code and simplifies code below.  */
   if (!TARGET_ALIGN_STRINGOPS)
     align = 32;
 
   if (GET_CODE (count_exp) == CONST_INT)
-    count = INTVAL (count_exp);
+    {
+      count = INTVAL (count_exp);
+      if (!TARGET_INLINE_ALL_STRINGOPS && count > 64)
+       return 0;
+    }
   /* Figure out proper mode for counter.  For 32bits it is always SImode,
      for 64bits use SImode when possible, otherwise DImode.
      Set count to number of bytes copied when known at compile time.  */
@@ -10488,8 +11281,12 @@ ix86_expand_clrstr (src, count_exp, align_exp)
 
       /* In case we don't know anything about the alignment, default to
          library version, since it is usually equally fast and result in
-         shorter code.  */
-      if (!TARGET_INLINE_ALL_STRINGOPS && align < UNITS_PER_WORD)
+         shorter code.
+
+        Also emit call when we know that the count is large and call overhead
+        will not be important.  */
+      if (!TARGET_INLINE_ALL_STRINGOPS
+         && (align < UNITS_PER_WORD || !TARGET_REP_MOVL_OPTIMAL))
        return 0;
 
       if (TARGET_SINGLE_STRINGOP)
@@ -10692,6 +11489,7 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx)
   rtx mem;
   rtx tmpreg = gen_reg_rtx (SImode);
   rtx scratch = gen_reg_rtx (SImode);
+  rtx cmp;
 
   align = 0;
   if (GET_CODE (align_rtx) == CONST_INT)
@@ -10850,17 +11648,19 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx)
   /* Avoid branch in fixing the byte.  */
   tmpreg = gen_lowpart (QImode, tmpreg);
   emit_insn (gen_addqi3_cc (tmpreg, tmpreg, tmpreg));
+  cmp = gen_rtx_LTU (Pmode, gen_rtx_REG (CCmode, 17), const0_rtx);
   if (TARGET_64BIT)
-    emit_insn (gen_subdi3_carry_rex64 (out, out, GEN_INT (3)));
+    emit_insn (gen_subdi3_carry_rex64 (out, out, GEN_INT (3), cmp));
   else
-    emit_insn (gen_subsi3_carry (out, out, GEN_INT (3)));
+    emit_insn (gen_subsi3_carry (out, out, GEN_INT (3), cmp));
 
   emit_label (end_0_label);
 }
 
 void
-ix86_expand_call (retval, fnaddr, callarg1, callarg2, pop)
+ix86_expand_call (retval, fnaddr, callarg1, callarg2, pop, sibcall)
      rtx retval, fnaddr, callarg1, callarg2, pop;
+     int sibcall;
 {
   rtx use = NULL, call;
 
@@ -10892,6 +11692,15 @@ ix86_expand_call (retval, fnaddr, callarg1, callarg2, pop)
       fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
       fnaddr = gen_rtx_MEM (QImode, fnaddr);
     }
+  if (sibcall && TARGET_64BIT
+      && !constant_call_address_operand (XEXP (fnaddr, 0), Pmode))
+    {
+      rtx addr;
+      addr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
+      fnaddr = gen_rtx_REG (Pmode, 40);
+      emit_move_insn (fnaddr, addr);
+      fnaddr = gen_rtx_MEM (QImode, fnaddr);
+    }
 
   call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
   if (retval)
@@ -10930,14 +11739,24 @@ assign_386_stack_local (mode, n)
      enum machine_mode mode;
      int n;
 {
+  struct stack_local_entry *s;
+
   if (n < 0 || n >= MAX_386_STACK_LOCALS)
     abort ();
 
-  if (ix86_stack_locals[(int) mode][n] == NULL_RTX)
-    ix86_stack_locals[(int) mode][n]
-      = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
+  for (s = ix86_stack_locals; s; s = s->next)
+    if (s->mode == mode && s->n == n)
+      return s->rtl;
 
-  return ix86_stack_locals[(int) mode][n];
+  s = (struct stack_local_entry *)
+    ggc_alloc (sizeof (struct stack_local_entry));
+  s->n = n;
+  s->mode = mode;
+  s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
+
+  s->next = ix86_stack_locals;
+  ix86_stack_locals = s;
+  return s->rtl;
 }
 
 /* Construct the SYMBOL_REF for the tls_get_addr function.  */
@@ -11082,7 +11901,7 @@ ix86_attr_length_address_default (insn)
 static int
 ix86_issue_rate ()
 {
-  switch (ix86_cpu)
+  switch (ix86_tune)
     {
     case PROCESSOR_PENTIUM:
     case PROCESSOR_K6:
@@ -11091,6 +11910,7 @@ ix86_issue_rate ()
     case PROCESSOR_PENTIUMPRO:
     case PROCESSOR_PENTIUM4:
     case PROCESSOR_ATHLON:
+    case PROCESSOR_K8:
       return 3;
 
     default:
@@ -11195,7 +12015,7 @@ ix86_adjust_cost (insn, link, dep_insn, cost)
   rtx set, set2;
   int dep_insn_code_number;
 
-  /* Anti and output depenancies have zero cost on all CPUs.  */
+  /* Anti and output dependencies have zero cost on all CPUs.  */
   if (REG_NOTE_KIND (link) != 0)
     return 0;
 
@@ -11208,7 +12028,7 @@ ix86_adjust_cost (insn, link, dep_insn, cost)
   insn_type = get_attr_type (insn);
   dep_insn_type = get_attr_type (dep_insn);
 
-  switch (ix86_cpu)
+  switch (ix86_tune)
     {
     case PROCESSOR_PENTIUM:
       /* Address Generation Interlock adds a cycle of latency.  */
@@ -11219,7 +12039,7 @@ ix86_adjust_cost (insn, link, dep_insn, cost)
       if (ix86_flags_dependant (insn, dep_insn, insn_type))
        cost = 0;
 
-      /* Floating point stores require value to be ready one cycle ealier.  */
+      /* Floating point stores require value to be ready one cycle earlier.  */
       if (insn_type == TYPE_FMOV
          && get_attr_memory (insn) == MEMORY_STORE
          && !ix86_agi_dependant (insn, dep_insn, insn_type))
@@ -11302,16 +12122,10 @@ ix86_adjust_cost (insn, link, dep_insn, cost)
       break;
 
     case PROCESSOR_ATHLON:
+    case PROCESSOR_K8:
       memory = get_attr_memory (insn);
       dep_memory = get_attr_memory (dep_insn);
 
-      if (dep_memory == MEMORY_LOAD || dep_memory == MEMORY_BOTH)
-       {
-         if (dep_insn_type == TYPE_IMOV || dep_insn_type == TYPE_FMOV)
-           cost += 2;
-         else
-           cost += 3;
-        }
       /* Show ability of reorder buffer to hide latency of load by executing
         in parallel with previous instruction in case
         previous instruction is not needed to compute the address.  */
@@ -11505,7 +12319,7 @@ ix86_sched_reorder (dump, sched_verbose, ready, n_readyp, clock_var)
       goto out;
     }
 
-  switch (ix86_cpu)
+  switch (ix86_tune)
     {
     default:
       break;
@@ -11530,7 +12344,7 @@ ix86_variable_issue (dump, sched_verbose, insn, can_issue_more)
      int can_issue_more;
 {
   int i;
-  switch (ix86_cpu)
+  switch (ix86_tune)
     {
     default:
       return can_issue_more - 1;
@@ -11585,7 +12399,7 @@ ix86_variable_issue (dump, sched_verbose, insn, can_issue_more)
 static int
 ia32_use_dfa_pipeline_interface ()
 {
-  if (ix86_cpu == PROCESSOR_PENTIUM)
+  if (TARGET_PENTIUM || TARGET_ATHLON_K8)
     return 1;
   return 0;
 }
@@ -11597,7 +12411,7 @@ ia32_use_dfa_pipeline_interface ()
 static int
 ia32_multipass_dfa_lookahead ()
 {
-  if (ix86_cpu == PROCESSOR_PENTIUM)
+  if (ix86_tune == PROCESSOR_PENTIUM)
     return 2;
   else
    return 0;
@@ -11865,7 +12679,8 @@ x86_initialize_trampoline (tramp, fnaddr, cxt)
 \f
 #define def_builtin(MASK, NAME, TYPE, CODE)                    \
 do {                                                           \
-  if ((MASK) & target_flags)                                   \
+  if ((MASK) & target_flags                                    \
+      && (!((MASK) & MASK_64BIT) || TARGET_64BIT))             \
     builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD,     \
                      NULL, NULL_TREE);                         \
 } while (0)
@@ -11882,6 +12697,8 @@ struct builtin_description
 
 /* Used for builtins that are enabled both by -msse and -msse2.  */
 #define MASK_SSE1 (MASK_SSE | MASK_SSE2)
+#define MASK_SSE164 (MASK_SSE | MASK_SSE2 | MASK_64BIT)
+#define MASK_SSE264 (MASK_SSE2 | MASK_64BIT)
 
 static const struct builtin_description bdesc_comi[] =
 {
@@ -11964,9 +12781,11 @@ static const struct builtin_description bdesc_2arg[] =
   { MASK_MMX, CODE_FOR_addv8qi3, "__builtin_ia32_paddb", IX86_BUILTIN_PADDB, 0, 0 },
   { MASK_MMX, CODE_FOR_addv4hi3, "__builtin_ia32_paddw", IX86_BUILTIN_PADDW, 0, 0 },
   { MASK_MMX, CODE_FOR_addv2si3, "__builtin_ia32_paddd", IX86_BUILTIN_PADDD, 0, 0 },
+  { MASK_MMX, CODE_FOR_mmx_adddi3, "__builtin_ia32_paddq", IX86_BUILTIN_PADDQ, 0, 0 },
   { MASK_MMX, CODE_FOR_subv8qi3, "__builtin_ia32_psubb", IX86_BUILTIN_PSUBB, 0, 0 },
   { MASK_MMX, CODE_FOR_subv4hi3, "__builtin_ia32_psubw", IX86_BUILTIN_PSUBW, 0, 0 },
   { MASK_MMX, CODE_FOR_subv2si3, "__builtin_ia32_psubd", IX86_BUILTIN_PSUBD, 0, 0 },
+  { MASK_MMX, CODE_FOR_mmx_subdi3, "__builtin_ia32_psubq", IX86_BUILTIN_PSUBQ, 0, 0 },
 
   { MASK_MMX, CODE_FOR_ssaddv8qi3, "__builtin_ia32_paddsb", IX86_BUILTIN_PADDSB, 0, 0 },
   { MASK_MMX, CODE_FOR_ssaddv4hi3, "__builtin_ia32_paddsw", IX86_BUILTIN_PADDSW, 0, 0 },
@@ -12015,6 +12834,7 @@ static const struct builtin_description bdesc_2arg[] =
 
   { MASK_SSE1, CODE_FOR_cvtpi2ps, 0, IX86_BUILTIN_CVTPI2PS, 0, 0 },
   { MASK_SSE1, CODE_FOR_cvtsi2ss, 0, IX86_BUILTIN_CVTSI2SS, 0, 0 },
+  { MASK_SSE164, CODE_FOR_cvtsi2ssq, 0, IX86_BUILTIN_CVTSI642SS, 0, 0 },
 
   { MASK_MMX, CODE_FOR_ashlv4hi3, 0, IX86_BUILTIN_PSLLW, 0, 0 },
   { MASK_MMX, CODE_FOR_ashlv4hi3, 0, IX86_BUILTIN_PSLLWI, 0, 0 },
@@ -12087,11 +12907,11 @@ static const struct builtin_description bdesc_2arg[] =
   { MASK_SSE2, CODE_FOR_addv16qi3, "__builtin_ia32_paddb128", IX86_BUILTIN_PADDB128, 0, 0 },
   { MASK_SSE2, CODE_FOR_addv8hi3, "__builtin_ia32_paddw128", IX86_BUILTIN_PADDW128, 0, 0 },
   { MASK_SSE2, CODE_FOR_addv4si3, "__builtin_ia32_paddd128", IX86_BUILTIN_PADDD128, 0, 0 },
-  { MASK_SSE2, CODE_FOR_addv4si3, "__builtin_ia32_paddq128", IX86_BUILTIN_PADDQ128, 0, 0 },
+  { MASK_SSE2, CODE_FOR_addv2di3, "__builtin_ia32_paddq128", IX86_BUILTIN_PADDQ128, 0, 0 },
   { MASK_SSE2, CODE_FOR_subv16qi3, "__builtin_ia32_psubb128", IX86_BUILTIN_PSUBB128, 0, 0 },
   { MASK_SSE2, CODE_FOR_subv8hi3, "__builtin_ia32_psubw128", IX86_BUILTIN_PSUBW128, 0, 0 },
   { MASK_SSE2, CODE_FOR_subv4si3, "__builtin_ia32_psubd128", IX86_BUILTIN_PSUBD128, 0, 0 },
-  { MASK_SSE2, CODE_FOR_subv4si3, "__builtin_ia32_psubq128", IX86_BUILTIN_PSUBQ128, 0, 0 },
+  { MASK_SSE2, CODE_FOR_subv2di3, "__builtin_ia32_psubq128", IX86_BUILTIN_PSUBQ128, 0, 0 },
 
   { MASK_MMX, CODE_FOR_ssaddv16qi3, "__builtin_ia32_paddsb128", IX86_BUILTIN_PADDSB128, 0, 0 },
   { MASK_MMX, CODE_FOR_ssaddv8hi3, "__builtin_ia32_paddsw128", IX86_BUILTIN_PADDSW128, 0, 0 },
@@ -12165,6 +12985,7 @@ static const struct builtin_description bdesc_2arg[] =
   { MASK_SSE2, CODE_FOR_sse2_pmaddwd, 0, IX86_BUILTIN_PMADDWD128, 0, 0 },
 
   { MASK_SSE2, CODE_FOR_cvtsi2sd, 0, IX86_BUILTIN_CVTSI2SD, 0, 0 },
+  { MASK_SSE264, CODE_FOR_cvtsi2sdq, 0, IX86_BUILTIN_CVTSI642SD, 0, 0 },
   { MASK_SSE2, CODE_FOR_cvtsd2ss, 0, IX86_BUILTIN_CVTSD2SS, 0, 0 },
   { MASK_SSE2, CODE_FOR_cvtss2sd, 0, IX86_BUILTIN_CVTSS2SD, 0, 0 }
 };
@@ -12180,8 +13001,10 @@ static const struct builtin_description bdesc_1arg[] =
 
   { MASK_SSE1, CODE_FOR_cvtps2pi, 0, IX86_BUILTIN_CVTPS2PI, 0, 0 },
   { MASK_SSE1, CODE_FOR_cvtss2si, 0, IX86_BUILTIN_CVTSS2SI, 0, 0 },
+  { MASK_SSE164, CODE_FOR_cvtss2siq, 0, IX86_BUILTIN_CVTSS2SI64, 0, 0 },
   { MASK_SSE1, CODE_FOR_cvttps2pi, 0, IX86_BUILTIN_CVTTPS2PI, 0, 0 },
   { MASK_SSE1, CODE_FOR_cvttss2si, 0, IX86_BUILTIN_CVTTSS2SI, 0, 0 },
+  { MASK_SSE164, CODE_FOR_cvttss2siq, 0, IX86_BUILTIN_CVTTSS2SI64, 0, 0 },
 
   { MASK_SSE2, CODE_FOR_sse2_pmovmskb, 0, IX86_BUILTIN_PMOVMSKB128, 0, 0 },
   { MASK_SSE2, CODE_FOR_sse2_movmskpd, 0, IX86_BUILTIN_MOVMSKPD, 0, 0 },
@@ -12203,6 +13026,8 @@ static const struct builtin_description bdesc_1arg[] =
 
   { MASK_SSE2, CODE_FOR_cvtsd2si, 0, IX86_BUILTIN_CVTSD2SI, 0, 0 },
   { MASK_SSE2, CODE_FOR_cvttsd2si, 0, IX86_BUILTIN_CVTTSD2SI, 0, 0 },
+  { MASK_SSE264, CODE_FOR_cvtsd2siq, 0, IX86_BUILTIN_CVTSD2SI64, 0, 0 },
+  { MASK_SSE264, CODE_FOR_cvttsd2siq, 0, IX86_BUILTIN_CVTTSD2SI64, 0, 0 },
 
   { MASK_SSE2, CODE_FOR_cvtps2dq, 0, IX86_BUILTIN_CVTPS2DQ, 0, 0 },
   { MASK_SSE2, CODE_FOR_cvtps2pd, 0, IX86_BUILTIN_CVTPS2PD, 0, 0 },
@@ -12228,7 +13053,11 @@ ix86_init_mmx_sse_builtins ()
   size_t i;
 
   tree pchar_type_node = build_pointer_type (char_type_node);
+  tree pcchar_type_node = build_pointer_type (
+                            build_type_variant (char_type_node, 1, 0));
   tree pfloat_type_node = build_pointer_type (float_type_node);
+  tree pcfloat_type_node = build_pointer_type (
+                            build_type_variant (float_type_node, 1, 0));
   tree pv2si_type_node = build_pointer_type (V2SI_type_node);
   tree pv2di_type_node = build_pointer_type (V2DI_type_node);
   tree pdi_type_node = build_pointer_type (long_long_unsigned_type_node);
@@ -12244,11 +13073,18 @@ ix86_init_mmx_sse_builtins ()
   tree int_ftype_v4sf
     = build_function_type_list (integer_type_node,
                                V4SF_type_node, NULL_TREE);
+  tree int64_ftype_v4sf
+    = build_function_type_list (long_long_integer_type_node,
+                               V4SF_type_node, NULL_TREE);
   tree int_ftype_v8qi
     = build_function_type_list (integer_type_node, V8QI_type_node, NULL_TREE);
   tree v4sf_ftype_v4sf_int
     = build_function_type_list (V4SF_type_node,
                                V4SF_type_node, integer_type_node, NULL_TREE);
+  tree v4sf_ftype_v4sf_int64
+    = build_function_type_list (V4SF_type_node,
+                               V4SF_type_node, long_long_integer_type_node,
+                               NULL_TREE);
   tree v4sf_ftype_v4sf_v2si
     = build_function_type_list (V4SF_type_node,
                                V4SF_type_node, V2SI_type_node, NULL_TREE);
@@ -12301,8 +13137,8 @@ ix86_init_mmx_sse_builtins ()
     = build_function_type_list (void_type_node,
                                V8QI_type_node, V8QI_type_node,
                                pchar_type_node, NULL_TREE);
-  tree v4sf_ftype_pfloat
-    = build_function_type_list (V4SF_type_node, pfloat_type_node, NULL_TREE);
+  tree v4sf_ftype_pcfloat
+    = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
   /* @@@ the type is bogus */
   tree v4sf_ftype_v4sf_pv2si
     = build_function_type_list (V4SF_type_node,
@@ -12357,7 +13193,11 @@ ix86_init_mmx_sse_builtins ()
     = build_function_type_list (V2SI_type_node,
                                V2SF_type_node, V2SF_type_node, NULL_TREE);
   tree pint_type_node    = build_pointer_type (integer_type_node);
+  tree pcint_type_node = build_pointer_type (
+                            build_type_variant (integer_type_node, 1, 0));
   tree pdouble_type_node = build_pointer_type (double_type_node);
+  tree pcdouble_type_node = build_pointer_type (
+                               build_type_variant (double_type_node, 1, 0));
   tree int_ftype_v2df_v2df
     = build_function_type_list (integer_type_node,
                                V2DF_type_node, V2DF_type_node, NULL_TREE);
@@ -12369,8 +13209,8 @@ ix86_init_mmx_sse_builtins ()
   tree ti_ftype_ti_ti
     = build_function_type_list (intTI_type_node,
                                intTI_type_node, intTI_type_node, NULL_TREE);
-  tree void_ftype_pvoid
-    = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
+  tree void_ftype_pcvoid
+    = build_function_type_list (void_type_node, const_ptr_type_node, NULL_TREE);
   tree v2di_ftype_di
     = build_function_type_list (V2DI_type_node,
                                long_long_unsigned_type_node, NULL_TREE);
@@ -12395,9 +13235,16 @@ ix86_init_mmx_sse_builtins ()
     = build_function_type_list (V2DF_type_node, V4SF_type_node, NULL_TREE);
   tree int_ftype_v2df
     = build_function_type_list (integer_type_node, V2DF_type_node, NULL_TREE);
+  tree int64_ftype_v2df
+    = build_function_type_list (long_long_integer_type_node,
+                               V2DF_type_node, NULL_TREE);
   tree v2df_ftype_v2df_int
     = build_function_type_list (V2DF_type_node,
                                V2DF_type_node, integer_type_node, NULL_TREE);
+  tree v2df_ftype_v2df_int64
+    = build_function_type_list (V2DF_type_node,
+                               V2DF_type_node, long_long_integer_type_node,
+                               NULL_TREE);
   tree v4sf_ftype_v4sf_v2df
     = build_function_type_list (V4SF_type_node,
                                V4SF_type_node, V2DF_type_node, NULL_TREE);
@@ -12425,8 +13272,8 @@ ix86_init_mmx_sse_builtins ()
     = build_function_type_list (void_type_node,
                                V16QI_type_node, V16QI_type_node,
                                pchar_type_node, NULL_TREE);
-  tree v2df_ftype_pdouble
-    = build_function_type_list (V2DF_type_node, pdouble_type_node, NULL_TREE);
+  tree v2df_ftype_pcdouble
+    = build_function_type_list (V2DF_type_node, pcdouble_type_node, NULL_TREE);
   tree v2df_ftype_v2df_v2df
     = build_function_type_list (V2DF_type_node,
                                V2DF_type_node, V2DF_type_node, NULL_TREE);
@@ -12485,16 +13332,16 @@ ix86_init_mmx_sse_builtins ()
                                V16QI_type_node, V16QI_type_node, NULL_TREE);
   tree int_ftype_v16qi
     = build_function_type_list (integer_type_node, V16QI_type_node, NULL_TREE);
-  tree v16qi_ftype_pchar
-    = build_function_type_list (V16QI_type_node, pchar_type_node, NULL_TREE);
+  tree v16qi_ftype_pcchar
+    = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
   tree void_ftype_pchar_v16qi
     = build_function_type_list (void_type_node,
                                pchar_type_node, V16QI_type_node, NULL_TREE);
-  tree v4si_ftype_pchar
-    = build_function_type_list (V4SI_type_node, pchar_type_node, NULL_TREE);
-  tree void_ftype_pchar_v4si
+  tree v4si_ftype_pcint
+    = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
+  tree void_ftype_pcint_v4si
     = build_function_type_list (void_type_node,
-                               pchar_type_node, V4SI_type_node, NULL_TREE);
+                               pcint_type_node, V4SI_type_node, NULL_TREE);
   tree v2di_ftype_v2di
     = build_function_type_list (V2DI_type_node, V2DI_type_node, NULL_TREE);
 
@@ -12570,8 +13417,6 @@ ix86_init_mmx_sse_builtins ()
   /* Add the remaining MMX insns with somewhat more complicated types.  */
   def_builtin (MASK_MMX, "__builtin_ia32_mmx_zero", di_ftype_void, IX86_BUILTIN_MMX_ZERO);
   def_builtin (MASK_MMX, "__builtin_ia32_emms", void_ftype_void, IX86_BUILTIN_EMMS);
-  def_builtin (MASK_MMX, "__builtin_ia32_ldmxcsr", void_ftype_unsigned, IX86_BUILTIN_LDMXCSR);
-  def_builtin (MASK_MMX, "__builtin_ia32_stmxcsr", unsigned_ftype_void, IX86_BUILTIN_STMXCSR);
   def_builtin (MASK_MMX, "__builtin_ia32_psllw", v4hi_ftype_v4hi_di, IX86_BUILTIN_PSLLW);
   def_builtin (MASK_MMX, "__builtin_ia32_pslld", v2si_ftype_v2si_di, IX86_BUILTIN_PSLLD);
   def_builtin (MASK_MMX, "__builtin_ia32_psllq", di_ftype_di_di, IX86_BUILTIN_PSLLQ);
@@ -12597,21 +13442,26 @@ ix86_init_mmx_sse_builtins ()
   def_builtin (MASK_MMX, "__builtin_ia32_packssdw", v4hi_ftype_v2si_v2si, IX86_BUILTIN_PACKSSDW);
   def_builtin (MASK_MMX, "__builtin_ia32_packuswb", v8qi_ftype_v4hi_v4hi, IX86_BUILTIN_PACKUSWB);
 
+  def_builtin (MASK_SSE1, "__builtin_ia32_ldmxcsr", void_ftype_unsigned, IX86_BUILTIN_LDMXCSR);
+  def_builtin (MASK_SSE1, "__builtin_ia32_stmxcsr", unsigned_ftype_void, IX86_BUILTIN_STMXCSR);
   def_builtin (MASK_SSE1, "__builtin_ia32_cvtpi2ps", v4sf_ftype_v4sf_v2si, IX86_BUILTIN_CVTPI2PS);
   def_builtin (MASK_SSE1, "__builtin_ia32_cvtps2pi", v2si_ftype_v4sf, IX86_BUILTIN_CVTPS2PI);
   def_builtin (MASK_SSE1, "__builtin_ia32_cvtsi2ss", v4sf_ftype_v4sf_int, IX86_BUILTIN_CVTSI2SS);
+  def_builtin (MASK_SSE164, "__builtin_ia32_cvtsi642ss", v4sf_ftype_v4sf_int64, IX86_BUILTIN_CVTSI642SS);
   def_builtin (MASK_SSE1, "__builtin_ia32_cvtss2si", int_ftype_v4sf, IX86_BUILTIN_CVTSS2SI);
+  def_builtin (MASK_SSE164, "__builtin_ia32_cvtss2si64", int64_ftype_v4sf, IX86_BUILTIN_CVTSS2SI64);
   def_builtin (MASK_SSE1, "__builtin_ia32_cvttps2pi", v2si_ftype_v4sf, IX86_BUILTIN_CVTTPS2PI);
   def_builtin (MASK_SSE1, "__builtin_ia32_cvttss2si", int_ftype_v4sf, IX86_BUILTIN_CVTTSS2SI);
+  def_builtin (MASK_SSE164, "__builtin_ia32_cvttss2si64", int64_ftype_v4sf, IX86_BUILTIN_CVTTSS2SI64);
 
   def_builtin (MASK_SSE1 | MASK_3DNOW_A, "__builtin_ia32_pextrw", int_ftype_v4hi_int, IX86_BUILTIN_PEXTRW);
   def_builtin (MASK_SSE1 | MASK_3DNOW_A, "__builtin_ia32_pinsrw", v4hi_ftype_v4hi_int_int, IX86_BUILTIN_PINSRW);
 
   def_builtin (MASK_SSE1 | MASK_3DNOW_A, "__builtin_ia32_maskmovq", void_ftype_v8qi_v8qi_pchar, IX86_BUILTIN_MASKMOVQ);
 
-  def_builtin (MASK_SSE1, "__builtin_ia32_loadaps", v4sf_ftype_pfloat, IX86_BUILTIN_LOADAPS);
-  def_builtin (MASK_SSE1, "__builtin_ia32_loadups", v4sf_ftype_pfloat, IX86_BUILTIN_LOADUPS);
-  def_builtin (MASK_SSE1, "__builtin_ia32_loadss", v4sf_ftype_pfloat, IX86_BUILTIN_LOADSS);
+  def_builtin (MASK_SSE1, "__builtin_ia32_loadaps", v4sf_ftype_pcfloat, IX86_BUILTIN_LOADAPS);
+  def_builtin (MASK_SSE1, "__builtin_ia32_loadups", v4sf_ftype_pcfloat, IX86_BUILTIN_LOADUPS);
+  def_builtin (MASK_SSE1, "__builtin_ia32_loadss", v4sf_ftype_pcfloat, IX86_BUILTIN_LOADSS);
   def_builtin (MASK_SSE1, "__builtin_ia32_storeaps", void_ftype_pfloat_v4sf, IX86_BUILTIN_STOREAPS);
   def_builtin (MASK_SSE1, "__builtin_ia32_storeups", void_ftype_pfloat_v4sf, IX86_BUILTIN_STOREUPS);
   def_builtin (MASK_SSE1, "__builtin_ia32_storess", void_ftype_pfloat_v4sf, IX86_BUILTIN_STORESS);
@@ -12679,9 +13529,9 @@ ix86_init_mmx_sse_builtins ()
   def_builtin (MASK_SSE2, "__builtin_ia32_movq2dq", v2di_ftype_di, IX86_BUILTIN_MOVQ2DQ);
   def_builtin (MASK_SSE2, "__builtin_ia32_movdq2q", di_ftype_v2di, IX86_BUILTIN_MOVDQ2Q);
 
-  def_builtin (MASK_SSE2, "__builtin_ia32_loadapd", v2df_ftype_pdouble, IX86_BUILTIN_LOADAPD);
-  def_builtin (MASK_SSE2, "__builtin_ia32_loadupd", v2df_ftype_pdouble, IX86_BUILTIN_LOADUPD);
-  def_builtin (MASK_SSE2, "__builtin_ia32_loadsd", v2df_ftype_pdouble, IX86_BUILTIN_LOADSD);
+  def_builtin (MASK_SSE2, "__builtin_ia32_loadapd", v2df_ftype_pcdouble, IX86_BUILTIN_LOADAPD);
+  def_builtin (MASK_SSE2, "__builtin_ia32_loadupd", v2df_ftype_pcdouble, IX86_BUILTIN_LOADUPD);
+  def_builtin (MASK_SSE2, "__builtin_ia32_loadsd", v2df_ftype_pcdouble, IX86_BUILTIN_LOADSD);
   def_builtin (MASK_SSE2, "__builtin_ia32_storeapd", void_ftype_pdouble_v2df, IX86_BUILTIN_STOREAPD);
   def_builtin (MASK_SSE2, "__builtin_ia32_storeupd", void_ftype_pdouble_v2df, IX86_BUILTIN_STOREUPD);
   def_builtin (MASK_SSE2, "__builtin_ia32_storesd", void_ftype_pdouble_v2df, IX86_BUILTIN_STORESD);
@@ -12720,33 +13570,36 @@ ix86_init_mmx_sse_builtins ()
 
   def_builtin (MASK_SSE2, "__builtin_ia32_cvtsd2si", int_ftype_v2df, IX86_BUILTIN_CVTSD2SI);
   def_builtin (MASK_SSE2, "__builtin_ia32_cvttsd2si", int_ftype_v2df, IX86_BUILTIN_CVTTSD2SI);
+  def_builtin (MASK_SSE264, "__builtin_ia32_cvtsd2si64", int64_ftype_v2df, IX86_BUILTIN_CVTSD2SI64);
+  def_builtin (MASK_SSE264, "__builtin_ia32_cvttsd2si64", int64_ftype_v2df, IX86_BUILTIN_CVTTSD2SI64);
 
   def_builtin (MASK_SSE2, "__builtin_ia32_cvtps2dq", v4si_ftype_v4sf, IX86_BUILTIN_CVTPS2DQ);
   def_builtin (MASK_SSE2, "__builtin_ia32_cvtps2pd", v2df_ftype_v4sf, IX86_BUILTIN_CVTPS2PD);
   def_builtin (MASK_SSE2, "__builtin_ia32_cvttps2dq", v4si_ftype_v4sf, IX86_BUILTIN_CVTTPS2DQ);
 
   def_builtin (MASK_SSE2, "__builtin_ia32_cvtsi2sd", v2df_ftype_v2df_int, IX86_BUILTIN_CVTSI2SD);
+  def_builtin (MASK_SSE264, "__builtin_ia32_cvtsi642sd", v2df_ftype_v2df_int64, IX86_BUILTIN_CVTSI642SD);
   def_builtin (MASK_SSE2, "__builtin_ia32_cvtsd2ss", v4sf_ftype_v4sf_v2df, IX86_BUILTIN_CVTSD2SS);
   def_builtin (MASK_SSE2, "__builtin_ia32_cvtss2sd", v2df_ftype_v2df_v4sf, IX86_BUILTIN_CVTSS2SD);
 
   def_builtin (MASK_SSE2, "__builtin_ia32_setpd1", v2df_ftype_double, IX86_BUILTIN_SETPD1);
   def_builtin (MASK_SSE2, "__builtin_ia32_setpd", v2df_ftype_double_double, IX86_BUILTIN_SETPD);
   def_builtin (MASK_SSE2, "__builtin_ia32_setzeropd", ti_ftype_void, IX86_BUILTIN_CLRPD);
-  def_builtin (MASK_SSE2, "__builtin_ia32_loadpd1", v2df_ftype_pdouble, IX86_BUILTIN_LOADPD1);
-  def_builtin (MASK_SSE2, "__builtin_ia32_loadrpd", v2df_ftype_pdouble, IX86_BUILTIN_LOADRPD);
+  def_builtin (MASK_SSE2, "__builtin_ia32_loadpd1", v2df_ftype_pcdouble, IX86_BUILTIN_LOADPD1);
+  def_builtin (MASK_SSE2, "__builtin_ia32_loadrpd", v2df_ftype_pcdouble, IX86_BUILTIN_LOADRPD);
   def_builtin (MASK_SSE2, "__builtin_ia32_storepd1", void_ftype_pdouble_v2df, IX86_BUILTIN_STOREPD1);
   def_builtin (MASK_SSE2, "__builtin_ia32_storerpd", void_ftype_pdouble_v2df, IX86_BUILTIN_STORERPD);
 
-  def_builtin (MASK_SSE2, "__builtin_ia32_clflush", void_ftype_pvoid, IX86_BUILTIN_CLFLUSH);
+  def_builtin (MASK_SSE2, "__builtin_ia32_clflush", void_ftype_pcvoid, IX86_BUILTIN_CLFLUSH);
   def_builtin (MASK_SSE2, "__builtin_ia32_lfence", void_ftype_void, IX86_BUILTIN_LFENCE);
   def_builtin (MASK_SSE2, "__builtin_ia32_mfence", void_ftype_void, IX86_BUILTIN_MFENCE);
 
-  def_builtin (MASK_SSE2, "__builtin_ia32_loaddqa", v16qi_ftype_pchar, IX86_BUILTIN_LOADDQA);
-  def_builtin (MASK_SSE2, "__builtin_ia32_loaddqu", v16qi_ftype_pchar, IX86_BUILTIN_LOADDQU);
-  def_builtin (MASK_SSE2, "__builtin_ia32_loadd", v4si_ftype_pchar, IX86_BUILTIN_LOADD);
+  def_builtin (MASK_SSE2, "__builtin_ia32_loaddqa", v16qi_ftype_pcchar, IX86_BUILTIN_LOADDQA);
+  def_builtin (MASK_SSE2, "__builtin_ia32_loaddqu", v16qi_ftype_pcchar, IX86_BUILTIN_LOADDQU);
+  def_builtin (MASK_SSE2, "__builtin_ia32_loadd", v4si_ftype_pcint, IX86_BUILTIN_LOADD);
   def_builtin (MASK_SSE2, "__builtin_ia32_storedqa", void_ftype_pchar_v16qi, IX86_BUILTIN_STOREDQA);
   def_builtin (MASK_SSE2, "__builtin_ia32_storedqu", void_ftype_pchar_v16qi, IX86_BUILTIN_STOREDQU);
-  def_builtin (MASK_SSE2, "__builtin_ia32_stored", void_ftype_pchar_v4si, IX86_BUILTIN_STORED);
+  def_builtin (MASK_SSE2, "__builtin_ia32_stored", void_ftype_pcint_v4si, IX86_BUILTIN_STORED);
   def_builtin (MASK_SSE2, "__builtin_ia32_movq", v2di_ftype_v2di, IX86_BUILTIN_MOVQ);
 
   def_builtin (MASK_SSE1, "__builtin_ia32_setzero128", v2di_ftype_void, IX86_BUILTIN_CLRTI);
@@ -12795,7 +13648,8 @@ safe_vector_operand (x, mode)
                              : gen_rtx_SUBREG (DImode, x, 0)));
   else
     emit_insn (gen_sse_clrv4sf (mode == V4SFmode ? x
-                               : gen_rtx_SUBREG (V4SFmode, x, 0)));
+                               : gen_rtx_SUBREG (V4SFmode, x, 0),
+                               CONST0_RTX (V4SFmode)));
   return x;
 }
 
@@ -12826,6 +13680,13 @@ ix86_expand_binop_builtin (icode, arglist, target)
       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
     target = gen_reg_rtx (tmode);
 
+  if (GET_MODE (op1) == SImode && mode1 == TImode)
+    {
+      rtx x = gen_reg_rtx (V4SImode);
+      emit_insn (gen_sse2_loadd (x, op1));
+      op1 = gen_lowpart (TImode, x);
+    }
+
   /* In case the insn wants input operands in modes different from
      the result, abort.  */
   if (GET_MODE (op0) != mode0 || GET_MODE (op1) != mode1)
@@ -12868,9 +13729,7 @@ ix86_expand_store_builtin (icode, arglist)
     op1 = safe_vector_operand (op1, mode1);
 
   op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
-
-  if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
-    op1 = copy_to_mode_reg (mode1, op1);
+  op1 = copy_to_mode_reg (mode1, op1);
 
   pat = GEN_FCN (icode) (op0, op1);
   if (pat)
@@ -13465,7 +14324,7 @@ ix86_expand_builtin (exp, target, subtarget, mode, ignore)
 
     case IX86_BUILTIN_SSE_ZERO:
       target = gen_reg_rtx (V4SFmode);
-      emit_insn (gen_sse_clrv4sf (target));
+      emit_insn (gen_sse_clrv4sf (target, CONST0_RTX (V4SFmode)));
       return target;
 
     case IX86_BUILTIN_MMX_ZERO:
@@ -13786,10 +14645,10 @@ ix86_secondary_memory_needed (class1, class2, mode, strict)
        return 1;
     }
   return (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2)
-         || (SSE_CLASS_P (class1) != SSE_CLASS_P (class2)
-             && (mode) != SImode)
-         || (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)
-             && (mode) != SImode));
+         || ((SSE_CLASS_P (class1) != SSE_CLASS_P (class2)
+              || MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
+             && ((mode != SImode && (mode != DImode || !TARGET_64BIT))
+                 || (!TARGET_INTER_UNIT_MOVES && !optimize_size))));
 }
 /* Return the cost of moving data from a register in class CLASS1 to
    one in class CLASS2.
@@ -13817,7 +14676,7 @@ ix86_register_move_cost (mode, class1, class2)
       
       /* In case of copying from general_purpose_register we may emit multiple
          stores followed by single load causing memory size mismatch stall.
-         Count this as arbitarily high cost of 20.  */
+         Count this as arbitrarily high cost of 20.  */
       if (CLASS_MAX_NREGS (class1, mode) > CLASS_MAX_NREGS (class2, mode))
        cost += 20;
 
@@ -13967,6 +14826,258 @@ ix86_memory_move_cost (mode, class, in)
     }
 }
 
+/* Compute a (partial) cost for rtx X.  Return true if the complete
+   cost has been computed, and false if subexpressions should be
+   scanned.  In either case, *TOTAL contains the cost result.  */
+
+static bool
+ix86_rtx_costs (x, code, outer_code, total)
+     rtx x;
+     int code, outer_code;
+     int *total;
+{
+  enum machine_mode mode = GET_MODE (x);
+
+  switch (code)
+    {
+    case CONST_INT:
+    case CONST:
+    case LABEL_REF:
+    case SYMBOL_REF:
+      if (TARGET_64BIT && !x86_64_sign_extended_value (x))
+       *total = 3;
+      else if (TARGET_64BIT && !x86_64_zero_extended_value (x))
+       *total = 2;
+      else if (flag_pic && SYMBOLIC_CONST (x))
+       *total = 1;
+      else
+       *total = 0;
+      return true;
+
+    case CONST_DOUBLE:
+      if (mode == VOIDmode)
+       *total = 0;
+      else
+       switch (standard_80387_constant_p (x))
+         {
+         case 1: /* 0.0 */
+           *total = 1;
+           break;
+         default: /* Other constants */
+           *total = 2;
+           break;
+         case 0:
+         case -1:
+           /* Start with (MEM (SYMBOL_REF)), since that's where
+              it'll probably end up.  Add a penalty for size.  */
+           *total = (COSTS_N_INSNS (1)
+                     + (flag_pic != 0)
+                     + (mode == SFmode ? 0 : mode == DFmode ? 1 : 2));
+           break;
+         }
+      return true;
+
+    case ZERO_EXTEND:
+      /* The zero extensions is often completely free on x86_64, so make
+        it as cheap as possible.  */
+      if (TARGET_64BIT && mode == DImode
+         && GET_MODE (XEXP (x, 0)) == SImode)
+       *total = 1;
+      else if (TARGET_ZERO_EXTEND_WITH_AND)
+       *total = COSTS_N_INSNS (ix86_cost->add);
+      else
+       *total = COSTS_N_INSNS (ix86_cost->movzx);
+      return false;
+
+    case SIGN_EXTEND:
+      *total = COSTS_N_INSNS (ix86_cost->movsx);
+      return false;
+
+    case ASHIFT:
+      if (GET_CODE (XEXP (x, 1)) == CONST_INT
+         && (GET_MODE (XEXP (x, 0)) != DImode || TARGET_64BIT))
+       {
+         HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
+         if (value == 1)
+           {
+             *total = COSTS_N_INSNS (ix86_cost->add);
+             return false;
+           }
+         if ((value == 2 || value == 3)
+             && !TARGET_DECOMPOSE_LEA
+             && ix86_cost->lea <= ix86_cost->shift_const)
+           {
+             *total = COSTS_N_INSNS (ix86_cost->lea);
+             return false;
+           }
+       }
+      /* FALLTHRU */
+
+    case ROTATE:
+    case ASHIFTRT:
+    case LSHIFTRT:
+    case ROTATERT:
+      if (!TARGET_64BIT && GET_MODE (XEXP (x, 0)) == DImode)
+       {
+         if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+           {
+             if (INTVAL (XEXP (x, 1)) > 32)
+               *total = COSTS_N_INSNS(ix86_cost->shift_const + 2);
+             else
+               *total = COSTS_N_INSNS(ix86_cost->shift_const * 2);
+           }
+         else
+           {
+             if (GET_CODE (XEXP (x, 1)) == AND)
+               *total = COSTS_N_INSNS(ix86_cost->shift_var * 2);
+             else
+               *total = COSTS_N_INSNS(ix86_cost->shift_var * 6 + 2);
+           }
+       }
+      else
+       {
+         if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+           *total = COSTS_N_INSNS (ix86_cost->shift_const);
+         else
+           *total = COSTS_N_INSNS (ix86_cost->shift_var);
+       }
+      return false;
+
+    case MULT:
+      if (FLOAT_MODE_P (mode))
+       *total = COSTS_N_INSNS (ix86_cost->fmul);
+      else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+       {
+         unsigned HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
+         int nbits;
+
+         for (nbits = 0; value != 0; value >>= 1)
+           nbits++;
+
+         *total = COSTS_N_INSNS (ix86_cost->mult_init[MODE_INDEX (mode)]
+                                 + nbits * ix86_cost->mult_bit);
+       }
+      else
+       {
+         /* This is arbitrary */
+         *total = COSTS_N_INSNS (ix86_cost->mult_init[MODE_INDEX (mode)]
+                                 + 7 * ix86_cost->mult_bit);
+       }
+      return false;
+
+    case DIV:
+    case UDIV:
+    case MOD:
+    case UMOD:
+      if (FLOAT_MODE_P (mode))
+       *total = COSTS_N_INSNS (ix86_cost->fdiv);
+      else
+       *total = COSTS_N_INSNS (ix86_cost->divide[MODE_INDEX (mode)]);
+      return false;
+
+    case PLUS:
+      if (FLOAT_MODE_P (mode))
+       *total = COSTS_N_INSNS (ix86_cost->fadd);
+      else if (!TARGET_DECOMPOSE_LEA
+              && GET_MODE_CLASS (mode) == MODE_INT
+              && GET_MODE_BITSIZE (mode) <= GET_MODE_BITSIZE (Pmode))
+       {
+         if (GET_CODE (XEXP (x, 0)) == PLUS
+             && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
+             && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
+             && CONSTANT_P (XEXP (x, 1)))
+           {
+             HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1));
+             if (val == 2 || val == 4 || val == 8)
+               {
+                 *total = COSTS_N_INSNS (ix86_cost->lea);
+                 *total += rtx_cost (XEXP (XEXP (x, 0), 1), outer_code);
+                 *total += rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0),
+                                     outer_code);
+                 *total += rtx_cost (XEXP (x, 1), outer_code);
+                 return true;
+               }
+           }
+         else if (GET_CODE (XEXP (x, 0)) == MULT
+                  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
+           {
+             HOST_WIDE_INT val = INTVAL (XEXP (XEXP (x, 0), 1));
+             if (val == 2 || val == 4 || val == 8)
+               {
+                 *total = COSTS_N_INSNS (ix86_cost->lea);
+                 *total += rtx_cost (XEXP (XEXP (x, 0), 0), outer_code);
+                 *total += rtx_cost (XEXP (x, 1), outer_code);
+                 return true;
+               }
+           }
+         else if (GET_CODE (XEXP (x, 0)) == PLUS)
+           {
+             *total = COSTS_N_INSNS (ix86_cost->lea);
+             *total += rtx_cost (XEXP (XEXP (x, 0), 0), outer_code);
+             *total += rtx_cost (XEXP (XEXP (x, 0), 1), outer_code);
+             *total += rtx_cost (XEXP (x, 1), outer_code);
+             return true;
+           }
+       }
+      /* FALLTHRU */
+
+    case MINUS:
+      if (FLOAT_MODE_P (mode))
+       {
+         *total = COSTS_N_INSNS (ix86_cost->fadd);
+         return false;
+       }
+      /* FALLTHRU */
+
+    case AND:
+    case IOR:
+    case XOR:
+      if (!TARGET_64BIT && mode == DImode)
+       {
+         *total = (COSTS_N_INSNS (ix86_cost->add) * 2
+                   + (rtx_cost (XEXP (x, 0), outer_code)
+                      << (GET_MODE (XEXP (x, 0)) != DImode))
+                   + (rtx_cost (XEXP (x, 1), outer_code)
+                      << (GET_MODE (XEXP (x, 1)) != DImode)));
+         return true;
+       }
+      /* FALLTHRU */
+
+    case NEG:
+      if (FLOAT_MODE_P (mode))
+       {
+         *total = COSTS_N_INSNS (ix86_cost->fchs);
+         return false;
+       }
+      /* FALLTHRU */
+
+    case NOT:
+      if (!TARGET_64BIT && mode == DImode)
+       *total = COSTS_N_INSNS (ix86_cost->add * 2);
+      else
+       *total = COSTS_N_INSNS (ix86_cost->add);
+      return false;
+
+    case FLOAT_EXTEND:
+      if (!TARGET_SSE_MATH || !VALID_SSE_REG_MODE (mode))
+       *total = 0;
+      return false;
+
+    case ABS:
+      if (FLOAT_MODE_P (mode))
+       *total = COSTS_N_INSNS (ix86_cost->fabs);
+      return false;
+
+    case SQRT:
+      if (FLOAT_MODE_P (mode))
+       *total = COSTS_N_INSNS (ix86_cost->fsqrt);
+      return false;
+
+    default:
+      return false;
+    }
+}
+
 #if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION)
 static void
 ix86_svr3_asm_out_constructor (symbol, priority)
@@ -14075,7 +15186,7 @@ x86_order_regs_for_local_alloc ()
    for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
      reg_alloc_order [pos++] = i;
 
-   /* x87 registerts.  */
+   /* x87 registers.  */
    if (TARGET_SSE_MATH)
      for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
        reg_alloc_order [pos++] = i;
@@ -14089,6 +15200,58 @@ x86_order_regs_for_local_alloc ()
      reg_alloc_order [pos++] = 0;
 }
 
+#ifndef TARGET_USE_MS_BITFIELD_LAYOUT
+#define TARGET_USE_MS_BITFIELD_LAYOUT 0
+#endif
+
+/* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
+   struct attribute_spec.handler.  */
+static tree
+ix86_handle_struct_attribute (node, name, args, flags, no_add_attrs)
+     tree *node;
+     tree name;
+     tree args ATTRIBUTE_UNUSED;
+     int flags ATTRIBUTE_UNUSED;
+     bool *no_add_attrs;
+{
+  tree *type = NULL;
+  if (DECL_P (*node))
+    {
+      if (TREE_CODE (*node) == TYPE_DECL)
+       type = &TREE_TYPE (*node);
+    }
+  else
+    type = node;
+
+  if (!(type && (TREE_CODE (*type) == RECORD_TYPE
+                || TREE_CODE (*type) == UNION_TYPE)))
+    {
+      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+      *no_add_attrs = true;
+    }
+
+  else if ((is_attribute_p ("ms_struct", name)
+           && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
+          || ((is_attribute_p ("gcc_struct", name)
+               && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
+    {
+      warning ("`%s' incompatible attribute ignored",
+               IDENTIFIER_POINTER (name));
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
+static bool
+ix86_ms_bitfield_layout_p (record_type)
+     tree record_type;
+{
+  return (TARGET_USE_MS_BITFIELD_LAYOUT &&
+      !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
+    || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
+}
+
 /* Returns an expression indicating where the this parameter is
    located on entry to the FUNCTION.  */
 
@@ -14157,7 +15320,7 @@ x86_can_output_mi_thunk (thunk, delta, vcall_offset, function)
 /* Output the assembler code for a thunk function.  THUNK_DECL is the
    declaration for the thunk function itself, FUNCTION is the decl for
    the target function.  DELTA is an immediate constant offset to be
-   added to THIS.  If VCALL_OFFSET is non-zero, the word at
+   added to THIS.  If VCALL_OFFSET is nonzero, the word at
    *(*this + vcall_offset) should be added to THIS.  */
 
 static void
@@ -14267,6 +15430,17 @@ x86_output_mi_thunk (file, thunk, delta, vcall_offset, function)
       if (!flag_pic || (*targetm.binds_local_p) (function))
        output_asm_insn ("jmp\t%P0", xops);
       else
+#if TARGET_MACHO
+       if (TARGET_MACHO)
+         {
+           char *ip = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function));
+           tmp = gen_rtx_SYMBOL_REF (Pmode, machopic_stub_name (ip));
+           tmp = gen_rtx_MEM (QImode, tmp);
+           xops[0] = tmp;
+           output_asm_insn ("jmp\t%0", xops);
+         }
+       else
+#endif /* TARGET_MACHO */
        {
          tmp = gen_rtx_REG (SImode, 2 /* ECX */);
          output_set_got (tmp);
@@ -14297,9 +15471,49 @@ x86_field_alignment (field, computed)
   return computed;
 }
 
+/* Output assembler code to FILE to increment profiler label # LABELNO
+   for profiling a function entry.  */
+void
+x86_function_profiler (file, labelno)
+     FILE *file;
+     int labelno ATTRIBUTE_UNUSED;
+{
+  if (TARGET_64BIT)
+    if (flag_pic)
+      {
+#ifndef NO_PROFILE_COUNTERS
+       fprintf (file, "\tleaq\t%sP%d@(%%rip),%%r11\n", LPREFIX, labelno);
+#endif
+       fprintf (file, "\tcall\t*%s@GOTPCREL(%%rip)\n", MCOUNT_NAME);
+      }
+    else
+      {
+#ifndef NO_PROFILE_COUNTERS
+       fprintf (file, "\tmovq\t$%sP%d,%%r11\n", LPREFIX, labelno);
+#endif
+       fprintf (file, "\tcall\t%s\n", MCOUNT_NAME);
+      }
+  else if (flag_pic)
+    {
+#ifndef NO_PROFILE_COUNTERS
+      fprintf (file, "\tleal\t%sP%d@GOTOFF(%%ebx),%%%s\n",
+              LPREFIX, labelno, PROFILE_COUNT_REGISTER);
+#endif
+      fprintf (file, "\tcall\t*%s@GOT(%%ebx)\n", MCOUNT_NAME);
+    }
+  else
+    {
+#ifndef NO_PROFILE_COUNTERS
+      fprintf (file, "\tmovl\t$%sP%d,%%%s\n", LPREFIX, labelno,
+              PROFILE_COUNT_REGISTER);
+#endif
+      fprintf (file, "\tcall\t%s\n", MCOUNT_NAME);
+    }
+}
+
 /* Implement machine specific optimizations.  
    At the moment we implement single transformation: AMD Athlon works faster
-   when RET is not destination of conditional jump or directly preceeded
+   when RET is not destination of conditional jump or directly preceded
    by other jump instruction.  We avoid the penalty by inserting NOP just
    before the RET instructions in such cases.  */
 void
@@ -14308,7 +15522,7 @@ x86_machine_dependent_reorg (first)
 {
   edge e;
 
-  if (!TARGET_ATHLON || !optimize || optimize_size)
+  if (!TARGET_ATHLON_K8 || !optimize || optimize_size)
     return;
   for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
   {
@@ -14319,25 +15533,104 @@ x86_machine_dependent_reorg (first)
 
     if (!returnjump_p (ret) || !maybe_hot_bb_p (bb))
       continue;
-    prev = prev_nonnote_insn (ret);
+    for (prev = PREV_INSN (ret); prev; prev = PREV_INSN (prev))
+      if (active_insn_p (prev) || GET_CODE (prev) == CODE_LABEL)
+       break;
     if (prev && GET_CODE (prev) == CODE_LABEL)
       {
        edge e;
        for (e = bb->pred; e; e = e->pred_next)
-         if (EDGE_FREQUENCY (e) && e->src->index > 0
+         if (EDGE_FREQUENCY (e) && e->src->index >= 0
              && !(e->flags & EDGE_FALLTHRU))
            insert = 1;
       }
     if (!insert)
       {
-       prev = prev_real_insn (ret);
+       prev = prev_active_insn (ret);
        if (prev && GET_CODE (prev) == JUMP_INSN
            && any_condjump_p (prev))
          insert = 1;
+       /* Empty functions get branch misspredict even when the jump destination
+          is not visible to us.  */
+       if (!prev && cfun->function_frequency > FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)
+         insert = 1;
       }
     if (insert)
       emit_insn_before (gen_nop (), ret);
   }
 }
 
+/* Return nonzero when QImode register that must be represented via REX prefix
+   is used.  */
+bool
+x86_extended_QIreg_mentioned_p (insn)
+     rtx insn;
+{
+  int i;
+  extract_insn_cached (insn);
+  for (i = 0; i < recog_data.n_operands; i++)
+    if (REG_P (recog_data.operand[i])
+       && REGNO (recog_data.operand[i]) >= 4)
+       return true;
+  return false;
+}
+
+/* Return nonzero when P points to register encoded via REX prefix.
+   Called via for_each_rtx.  */
+static int
+extended_reg_mentioned_1 (p, data)
+       rtx *p;
+       void *data ATTRIBUTE_UNUSED;
+{
+   unsigned int regno;
+   if (!REG_P (*p))
+     return 0;
+   regno = REGNO (*p);
+   return REX_INT_REGNO_P (regno) || REX_SSE_REGNO_P (regno);
+}
+
+/* Return true when INSN mentions register that must be encoded using REX
+   prefix.  */
+bool
+x86_extended_reg_mentioned_p (insn)
+     rtx insn;
+{
+  return for_each_rtx (&PATTERN (insn), extended_reg_mentioned_1, NULL);
+}
+
+/* Generate an unsigned DImode to FP conversion.  This is the same code
+   optabs would emit if we didn't have TFmode patterns.  */
+
+void
+x86_emit_floatuns (operands)
+     rtx operands[2];
+{
+  rtx neglab, donelab, i0, i1, f0, in, out;
+  enum machine_mode mode;
+
+  out = operands[0];
+  in = force_reg (DImode, operands[1]);
+  mode = GET_MODE (out);
+  neglab = gen_label_rtx ();
+  donelab = gen_label_rtx ();
+  i1 = gen_reg_rtx (Pmode);
+  f0 = gen_reg_rtx (mode);
+
+  emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, Pmode, 0, neglab);
+
+  emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
+  emit_jump_insn (gen_jump (donelab));
+  emit_barrier ();
+
+  emit_label (neglab);
+
+  i0 = expand_simple_binop (Pmode, LSHIFTRT, in, const1_rtx, NULL, 1, OPTAB_DIRECT);
+  i1 = expand_simple_binop (Pmode, AND, in, const1_rtx, NULL, 1, OPTAB_DIRECT);
+  i0 = expand_simple_binop (Pmode, IOR, i0, i1, i0, 1, OPTAB_DIRECT);
+  expand_float (f0, i0, 0);
+  emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
+
+  emit_label (donelab);
+}
+
 #include "gt-i386.h"