Update RISC-V XCC toolchain
authorAndrew Waterman <waterman@cs.berkeley.edu>
Sat, 23 Mar 2013 23:16:14 +0000 (16:16 -0700)
committerAndrew Waterman <waterman@cs.berkeley.edu>
Sat, 23 Mar 2013 23:16:14 +0000 (16:16 -0700)
I folded the gcc 4.6 patch to support compilation under gcc 4.7 into the
RISC-V patches.

kern/arch/riscv/boot.S
kern/arch/riscv/entry.S
tools/compilers/gcc-glibc/Makefile
tools/compilers/gcc-glibc/binutils-2.21.1-riscv.patch
tools/compilers/gcc-glibc/gcc-4.6.1-compile.patch [deleted file]
tools/compilers/gcc-glibc/gcc-4.6.1-riscv.patch
tools/compilers/gcc-glibc/glibc-2.14.1-riscv.patch

index fb41ecd..c182f7b 100644 (file)
@@ -20,7 +20,6 @@
 .text
 
 .global _start
-.ent _start
 _start:
   // This is the first kernel code that executes; it is run only by core 0.
 
@@ -95,9 +94,6 @@ notcore0:
   la     t0, smp_init
   jr     t0
 
-.end _start
-
-.ent enable_mmu
 enable_mmu:
   la     t0, l1pt_boot
   li     t1, KERN_LOAD_ADDR
@@ -106,7 +102,6 @@ enable_mmu:
   li     t0, PCR0 | SR_VM
   mtpcr  t0, ASM_CR(PCR_SR)
   ret
-.end enable_mmu
 
 ///////////////////////////////////////////////////////////////////
 // boot stack and regular stacks.
index 4707db5..08d0369 100644 (file)
@@ -14,7 +14,6 @@
 #define REGBYTES (1 << LOG_REGBYTES)
 
   .text
-  .ent    save_kernel_tf_asm
   .global save_kernel_tf_asm
 save_kernel_tf_asm:
   STORE  s0,20*REGBYTES(a0)
@@ -35,10 +34,8 @@ save_kernel_tf_asm:
   # set EPC to this function's return address
   STORE  ra,33*REGBYTES(a0)
   ret
-  .end  save_kernel_tf_asm
 
   .text
-  .ent    pop_kernel_tf
   .global pop_kernel_tf
 pop_kernel_tf:
   LOAD  t0,32*REGBYTES(a0)
@@ -59,16 +56,12 @@ pop_kernel_tf:
   mtpcr  t0,ASM_CR(PCR_SR)
   ret
 
-  .end  pop_kernel_tf
 
-  .ent  save_tf
 save_tf:  # write the trap frame onto the stack
 
   ret
-  .end  save_tf
 
   .globl  env_pop_tf
-  .ent  env_pop_tf
 env_pop_tf:  # write the trap frame onto the stack
   # restore gprs
   LOAD  t0,32*REGBYTES(a0)  # restore sr (should disable interrupts)
@@ -119,10 +112,8 @@ env_pop_tf:  # write the trap frame onto the stack
   mfpcr x1,ASM_CR(PCR_K0)
   mfpcr x2,ASM_CR(PCR_K1)
   eret
-  .end  env_pop_tf
 
   .global  trap_entry
-  .ent  trap_entry
 trap_entry:
   # save x1 and x2 so we can use them as temporaries
   mtpcr x1, ASM_CR(PCR_K0)
@@ -192,14 +183,11 @@ trap_entry:
   move  sp, x2
   move  a0, x2
   j     handle_trap
-  .end  trap_entry
 
   .global  cpu_halt
   .global  after_cpu_halt
-  .ent  cpu_halt
 cpu_halt:
   setpcr ASM_CR(PCR_SR), SR_ET
 1:b     1b   # handle_ipi can advance the PC to break out of this loop.
   ret
 after_cpu_halt:
-  .end  cpu_halt
index 8d14028..0b1e485 100644 (file)
@@ -145,7 +145,6 @@ gcc-$(GCC_VERSION): gcc-$(GCC_VERSION).tar.bz2
        rm -rf gcc-$(GCC_VERSION)
        tar -jxf gcc-$(GCC_VERSION).tar.bz2
        $(MAKE) .gcc-ros-patch
-       patch --no-backup-if-mismatch -p1 < gcc-4.6.1-compile.patch
        patch --no-backup-if-mismatch -p0 < gcc-$(GCC_VERSION)-riscv.patch
 
 .gcc-ros-patch:
index fdc8b75..c355113 100644 (file)
@@ -14617,10 +14617,10 @@ index 1aa9bb4..435df2b 100644
  @am__fastdepCC_TRUE@  $(am__mv) $(DEPDIR)/tc-rx.Tpo $(DEPDIR)/tc-rx.Po
 diff --git a/binutils-2.21.1/gas/config/tc-riscv.c b/binutils-2.21.1/gas/config/tc-riscv.c
 new file mode 100644
-index 0000000..20549f1
+index 0000000..26ee5ed
 --- /dev/null
 +++ binutils-2.21.1/gas/config/tc-riscv.c
-@@ -0,0 +1,4894 @@
+@@ -0,0 +1,4138 @@
 +/* tc-mips.c -- assemble code for a MIPS chip.
 +   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
 +   2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
@@ -14691,8 +14691,6 @@ index 0000000..20549f1
 +#include "elf/riscv.h"
 +#endif
 +
-+int mips_flag_pdr = TRUE;
-+
 +#include "ecoff.h"
 +
 +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
@@ -14744,13 +14742,12 @@ index 0000000..20549f1
 +/* The ABI to use.  */
 +enum mips_abi_level
 +{
-+  NO_ABI = 0,
 +  ABI_32,
 +  ABI_64,
 +};
 +
 +/* MIPS ABI we are using for this output file.  */
-+static enum mips_abi_level mips_abi = NO_ABI;
++static enum mips_abi_level mips_abi = ABI_64;
 +
 +/* Whether or not we have code that can call pic code.  */
 +int mips_abicalls = FALSE;
@@ -14761,34 +14758,13 @@ index 0000000..20549f1
 +
 +struct mips_set_options
 +{
-+  /* MIPS ISA (Instruction Set Architecture) level.  This is set to -1
-+     if it has not been initialized.  Changed by `.set mipsN', and the
-+     -mipsN command line option, and the default CPU.  */
-+  int isa;
 +  /* Enable RVC instruction compression */
 +  int rvc;
-+  /* Restrict general purpose registers and floating point registers
-+     to 32 bit.  This is initially determined when -mgp32 or -mfp32
-+     is passed but can changed if the assembler code uses .set mipsN.  */
-+  int gp32;
-+  /* True if ".set sym32" is in effect.  */
-+  bfd_boolean sym32;
 +};
 +
-+/* This is the struct we use to hold the current set of options.  Note
-+   that we must set the isa field to ISA_UNKNOWN and the ASE fields to
-+   -1 to indicate that they have not been initialized.  */
-+
-+/* True if -mrvc was passed.  */
-+static int file_mips_rvc = 0;
-+
-+/* True if -mgp32 was passed.  */
-+static int file_mips_gp32 = -1;
-+
 +static struct mips_set_options mips_opts =
 +{
-+  /* isa */ ISA_UNKNOWN, /* rvc */ 0,
-+  /* gp32 */ 0, /* sym32 */ TRUE
++  /* rvc */ 0
 +};
 +
 +/* These variables are filled in with the masks of registers used.
@@ -14797,25 +14773,17 @@ index 0000000..20549f1
 +unsigned long mips_gprmask;
 +unsigned long mips_fprmask;
 +
-+/* The argument of the -march= flag.  The architecture we are assembling.  */
-+static int file_mips_arch = CPU_UNKNOWN;
-+static const char *mips_arch_string;
-+
 +/* True if the given ABI requires 32-bit registers.  */
 +#define ABI_NEEDS_32BIT_REGS(ABI) ((ABI) == ABI_32)
 +
 +/* Likewise 64-bit registers.  */
 +#define ABI_NEEDS_64BIT_REGS(ABI) ((ABI) == ABI_64)
 +
-+/*  Return true if ISA supports 64 bit wide gp registers.  */
-+#define ISA_HAS_64BIT_REGS(ISA) ((ISA) == ISA_RV64)
-+
-+#define HAVE_32BIT_GPRS                                  \
-+    (mips_opts.gp32 || !ISA_HAS_64BIT_REGS (mips_opts.isa))
++#define HAVE_32BIT_GPRS ABI_NEEDS_32BIT_REGS (mips_abi)
 +
 +#define HAVE_64BIT_GPRS (!HAVE_32BIT_GPRS)
 +
-+#define HAVE_64BIT_OBJECTS (mips_abi == ABI_64)
++#define HAVE_64BIT_OBJECTS ABI_NEEDS_64BIT_REGS (mips_abi)
 +
 +/* The ABI-derived address size.  */
 +#define HAVE_64BIT_ADDRESSES HAVE_64BIT_GPRS
@@ -14823,8 +14791,7 @@ index 0000000..20549f1
 +
 +/* The size of symbolic constants (i.e., expressions of the form
 +   "SYMBOL" or "SYMBOL + OFFSET").  */
-+#define HAVE_32BIT_SYMBOLS \
-+  (HAVE_32BIT_ADDRESSES || !HAVE_64BIT_OBJECTS || mips_opts.sym32)
++#define HAVE_32BIT_SYMBOLS 1
 +#define HAVE_64BIT_SYMBOLS (!HAVE_32BIT_SYMBOLS)
 +
 +/* MIPS PIC level.  */
@@ -14991,10 +14958,6 @@ index 0000000..20549f1
 +static void s_gpword (int);
 +static void s_gpdword (int);
 +static void s_insn (int);
-+static void s_mips_ent (int);
-+static void s_mips_end (int);
-+static void s_mips_frame (int);
-+static void s_mips_mask (int reg_type);
 +static void s_mips_stab (int);
 +static void s_mips_weakext (int);
 +static void s_mips_file (int);
@@ -15002,22 +14965,6 @@ index 0000000..20549f1
 +static int validate_mips_insn (const struct riscv_opcode *);
 +static int relaxed_branch_length (fragS *fragp, asection *sec, int update);
 +
-+/* Table and functions used to map between CPU/ISA names, and
-+   ISA levels, and CPU numbers.  */
-+
-+struct mips_cpu_info
-+{
-+  const char *name;           /* CPU or ISA name.  */
-+  int flags;                  /* ASEs available, or ISA flag.  */
-+  int isa;                    /* ISA level.  */
-+  int cpu;                    /* CPU number (default CPU if ISA).  */
-+};
-+
-+#define MIPS_CPU_IS_ISA               0x0001  /* Is this an ISA?  (If 0, a CPU.) */
-+
-+static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
-+static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
-+\f
 +/* Pseudo-op table.
 +
 +   The following pseudo-ops from the Kane and Heinrich MIPS book
@@ -15089,16 +15036,10 @@ index 0000000..20549f1
 +{
 +  /* These pseudo-ops should be defined by the object file format.
 +     However, a.out doesn't support them, so we have versions here.  */
-+  {"aent", s_mips_ent, 1},
 +  {"bgnb", s_ignore, 0},
-+  {"end", s_mips_end, 0},
 +  {"endb", s_ignore, 0},
-+  {"ent", s_mips_ent, 0},
 +  {"file", s_mips_file, 0},
-+  {"fmask", s_mips_mask, 'F'},
-+  {"frame", s_mips_frame, 0},
 +  {"loc", s_mips_loc, 0},
-+  {"mask", s_mips_mask, 'R'},
 +  {"verstamp", s_ignore, 0},
 +  { NULL, NULL, 0 },
 +};
@@ -15157,13 +15098,6 @@ index 0000000..20549f1
 +static bfd_reloc_code_real_type offset_reloc[3]
 +  = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
 +
-+#ifdef OBJ_ELF
-+/* The pdr segment for per procedure frame/regmask info.  Not used for
-+   ECOFF debugging.  */
-+
-+static segT pdr_seg;
-+#endif
-+
 +/* The default target format to use.  */
 +
 +const char *
@@ -15845,7 +15779,7 @@ index 0000000..20549f1
 +  int i = 0;
 +  int broken = 0;
 +
-+  if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, file_mips_arch))
++  if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, CPU_UNKNOWN))
 +    as_warn (_("Could not set architecture and machine"));
 +
 +  op_hash = hash_new ();
@@ -15968,15 +15902,6 @@ index 0000000..20549f1
 +          }
 +        }
 +
-+      if (mips_flag_pdr)
-+        {
-+          pdr_seg = subseg_new (".pdr", (subsegT) 0);
-+          (void) bfd_set_section_flags (stdoutput, pdr_seg,
-+                                        SEC_READONLY | SEC_RELOC
-+                                        | SEC_DEBUGGING);
-+          (void) bfd_set_section_alignment (stdoutput, pdr_seg, 2);
-+        }
-+
 +      subseg_set (seg, subseg);
 +      }
 +    }
@@ -17469,76 +17394,29 @@ index 0000000..20549f1
 +enum options
 +  {
 +    OPTION_MARCH = OPTION_MD_BASE,
-+    OPTION_MTUNE,
++    OPTION_MABI,
 +    OPTION_EB,
 +    OPTION_EL,
 +    OPTION_MRVC,
 +    OPTION_MNO_RVC,
-+    OPTION_GP32,
-+    OPTION_GP64,
-+    OPTION_MSYM32,
-+    OPTION_MNO_SYM32,
-+#ifdef OBJ_ELF
-+    OPTION_CALL_SHARED,
-+    OPTION_CALL_NONPIC,
-+    OPTION_NON_SHARED,
-+    OPTION_XGOT,
-+    OPTION_MABI,
-+    OPTION_PDR,
-+    OPTION_NO_PDR,
-+#endif /* OBJ_ELF */
 +    OPTION_END_OF_ENUM    
 +  };
 +  
 +struct option md_longopts[] =
 +{
 +  /* Options which specify architecture.  */
-+  {"march", required_argument, NULL, OPTION_MARCH},
-+  {"mtune", required_argument, NULL, OPTION_MTUNE},
++  {"mabi", required_argument, NULL, OPTION_MABI},
 +
 +  /* Miscellaneous options.  */
 +  {"EB", no_argument, NULL, OPTION_EB},
 +  {"EL", no_argument, NULL, OPTION_EL},
 +  {"mrvc", no_argument, NULL, OPTION_MRVC},
 +  {"mno-rvc", no_argument, NULL, OPTION_MNO_RVC},
-+  {"mgp32", no_argument, NULL, OPTION_GP32},
-+  {"mgp64", no_argument, NULL, OPTION_GP64},
-+  {"msym32", no_argument, NULL, OPTION_MSYM32},
-+  {"mno-sym32", no_argument, NULL, OPTION_MNO_SYM32},
-+  
-+  /* ELF-specific options.  */
-+#ifdef OBJ_ELF
-+  {"KPIC",        no_argument, NULL, OPTION_CALL_SHARED},
-+  {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
-+  {"call_nonpic", no_argument, NULL, OPTION_CALL_NONPIC},
-+  {"non_shared",  no_argument, NULL, OPTION_NON_SHARED},
-+  {"xgot",        no_argument, NULL, OPTION_XGOT},
-+  {"mabi", required_argument, NULL, OPTION_MABI},
-+  {"mpdr", no_argument, NULL, OPTION_PDR},
-+  {"mno-pdr", no_argument, NULL, OPTION_NO_PDR},
-+#endif /* OBJ_ELF */
 +
 +  {NULL, no_argument, NULL, 0}
 +};
 +size_t md_longopts_size = sizeof (md_longopts);
 +
-+/* Set STRING_PTR (either &mips_arch_string or &mips_tune_string) to
-+   NEW_VALUE.  Warn if another value was already specified.  Note:
-+   we have to defer parsing the -march and -mtune arguments in order
-+   to handle 'from-abi' correctly, since the ABI might be specified
-+   in a later argument.  */
-+
-+static void
-+mips_set_option_string (const char **string_ptr, const char *new_value)
-+{
-+  if (*string_ptr != 0 && strcasecmp (*string_ptr, new_value) != 0)
-+    as_warn (_("A different %s was already specified, is now %s"),
-+           string_ptr == &mips_arch_string ? "-march" : "-mtune",
-+           new_value);
-+
-+  *string_ptr = new_value;
-+}
-+
 +int
 +md_parse_option (int c, char *arg)
 +{
@@ -17559,77 +17437,15 @@ index 0000000..20549f1
 +      mips_debug = atoi (arg);
 +      break;
 +
-+    case OPTION_MARCH:
-+      mips_set_option_string (&mips_arch_string, arg);
-+      break;
-+
-+    case OPTION_MSYM32:
-+      mips_opts.sym32 = TRUE;
-+      break;
-+
-+    case OPTION_MNO_SYM32:
-+      mips_opts.sym32 = FALSE;
-+      break;
-+
-+#ifdef OBJ_ELF
-+      /* When generating ELF code, we permit -KPIC and -call_shared to
-+       select SVR4_PIC, and -non_shared to select no PIC.  This is
-+       intended to be compatible with Irix 5.  */
-+    case OPTION_CALL_SHARED:
-+      if (!IS_ELF)
-+      {
-+        as_bad (_("-call_shared is supported only for ELF format"));
-+        return 0;
-+      }
-+      mips_pic = SVR4_PIC;
-+      mips_abicalls = TRUE;
-+      break;
-+
-+    case OPTION_CALL_NONPIC:
-+      if (!IS_ELF)
-+      {
-+        as_bad (_("-call_nonpic is supported only for ELF format"));
-+        return 0;
-+      }
-+      mips_pic = NO_PIC;
-+      mips_abicalls = TRUE;
-+      break;
-+
-+    case OPTION_NON_SHARED:
-+      if (!IS_ELF)
-+      {
-+        as_bad (_("-non_shared is supported only for ELF format"));
-+        return 0;
-+      }
-+      mips_pic = NO_PIC;
-+      mips_abicalls = FALSE;
-+      break;
-+
-+#endif /* OBJ_ELF */
-+
-+    case OPTION_GP32:
-+      file_mips_gp32 = 1;
-+      break;
-+
-+    case OPTION_GP64:
-+      file_mips_gp32 = 0;
-+      break;
-+
 +    case OPTION_MRVC:
-+      file_mips_rvc = 1;
++      mips_opts.rvc = 1;
 +      break;
 +
 +    case OPTION_MNO_RVC:
-+      file_mips_rvc = 0;
++      mips_opts.rvc = 0;
 +      break;
 +
-+#ifdef OBJ_ELF
 +    case OPTION_MABI:
-+      if (!IS_ELF)
-+      {
-+        as_bad (_("-mabi is supported for ELF format only"));
-+        return 0;
-+      }
 +      if (strcmp (arg, "32") == 0)
 +      mips_abi = ABI_32;
 +      else if (strcmp (arg, "64") == 0)
@@ -17640,17 +17456,6 @@ index 0000000..20549f1
 +        return 0;
 +      }
 +      break;
-+#endif /* OBJ_ELF */
-+
-+#ifdef OBJ_ELF
-+    case OPTION_PDR:
-+      mips_flag_pdr = TRUE;
-+      break;
-+
-+    case OPTION_NO_PDR:
-+      mips_flag_pdr = FALSE;
-+      break;
-+#endif /* OBJ_ELF */
 +
 +    default:
 +      return 0;
@@ -17658,72 +17463,12 @@ index 0000000..20549f1
 +
 +  return 1;
 +}
-+\f
-+/* Set up globals to generate code for the ISA or processor
-+   described by INFO.  */
-+
-+static void
-+mips_set_architecture (const struct mips_cpu_info *info)
-+{
-+  if (info != 0)
-+    {
-+      file_mips_arch = info->cpu;
-+      mips_opts.isa = info->isa;
-+    }
-+}
-+
 +
 +void
 +mips_after_parse_args (void)
 +{
-+  const struct mips_cpu_info *arch_info = 0;
-+
-+  if (mips_abi == NO_ABI)
-+    mips_abi = ABI_64;
-+
-+  /* The following code determines the architecture and register size.
-+     Similar code was added to GCC 3.3 (see override_options() in
-+     config/mips/mips.c).  The GAS and GCC code should be kept in sync
-+     as much as possible.  */
-+
-+  if (mips_arch_string != 0)
-+    arch_info = mips_parse_cpu ("-march", mips_arch_string);
-+
-+  if (arch_info == 0)
-+    arch_info = mips_parse_cpu ("default CPU", "from-abi");
-+
-+  if (ABI_NEEDS_64BIT_REGS (mips_abi) && !ISA_HAS_64BIT_REGS (arch_info->isa))
-+    as_bad ("-march=%s is not compatible with the selected ABI",
-+          arch_info->name);
-+
-+  mips_set_architecture (arch_info);
-+
-+  if (file_mips_gp32 >= 0)
-+    {
-+      /* The user specified the size of the integer registers.  Make sure
-+       it agrees with the ABI and ISA.  */
-+      if (file_mips_gp32 == 0 && !ISA_HAS_64BIT_REGS (mips_opts.isa))
-+      as_bad (_("-mgp64 used with a 32-bit processor"));
-+      else if (file_mips_gp32 == 1 && ABI_NEEDS_64BIT_REGS (mips_abi))
-+      as_bad (_("-mgp32 used with a 64-bit ABI"));
-+      else if (file_mips_gp32 == 0 && ABI_NEEDS_32BIT_REGS (mips_abi))
-+      as_bad (_("-mgp64 used with a 32-bit ABI"));
-+    }
-+  else
-+    {
-+      /* Infer the integer register size from the ABI and processor.
-+       Restrict ourselves to 32-bit registers if that's all the
-+       processor has, or if the ABI cannot handle 64-bit registers.  */
-+      file_mips_gp32 = (ABI_NEEDS_32BIT_REGS (mips_abi)
-+                      || !ISA_HAS_64BIT_REGS (mips_opts.isa));
-+    }
-+
-+  /* End of GCC-shared inference code.  */
-+
-+  mips_opts.rvc = file_mips_rvc;
-+  mips_opts.gp32 = file_mips_gp32;
 +}
-+\f
++
 +void
 +mips_init_after_args (void)
 +{
@@ -17981,20 +17726,6 @@ index 0000000..20549f1
 +  fixP->fx_addnumber = *valP;
 +}
 +
-+static symbolS *
-+get_symbol (void)
-+{
-+  int c;
-+  char *name;
-+  symbolS *p;
-+
-+  name = input_line_pointer;
-+  c = get_symbol_end ();
-+  p = (symbolS *) symbol_find_or_make (name);
-+  *input_line_pointer = c;
-+  return p;
-+}
-+
 +/* Align the current frag to a given power of two.  If a particular
 +   fill byte should be used, FILL points to an integer that contains
 +   that byte, otherwise FILL is null.
@@ -18357,18 +18088,7 @@ index 0000000..20549f1
 +  ch = *input_line_pointer;
 +  *input_line_pointer = '\0';
 +
-+  if (strcmp (name, "gp=default") == 0)
-+    mips_opts.gp32 = file_mips_gp32;
-+  else if (strcmp (name, "gp=32") == 0)
-+    mips_opts.gp32 = 1;
-+  else if (strcmp (name, "gp=64") == 0)
-+    {
-+      if (!ISA_HAS_64BIT_REGS (mips_opts.isa))
-+      as_warn ("%s isa does not support 64-bit registers",
-+               mips_cpu_info_from_isa (mips_opts.isa)->name);
-+      mips_opts.gp32 = 0;
-+    }
-+  else if (strcmp (name, "rvc") == 0)
++  if (strcmp (name, "rvc") == 0)
 +    mips_opts.rvc = 1;
 +  else if (strcmp (name, "norvc") == 0)
 +    mips_opts.rvc = 0;
@@ -18395,10 +18115,6 @@ index 0000000..20549f1
 +        free (s);
 +      }
 +    }
-+  else if (strcmp (name, "sym32") == 0)
-+    mips_opts.sym32 = TRUE;
-+  else if (strcmp (name, "nosym32") == 0)
-+    mips_opts.sym32 = FALSE;
 +  else if (strchr (name, ','))
 +    {
 +      /* Generic ".set" directive; use the generic handler.  */
@@ -18634,19 +18350,6 @@ index 0000000..20549f1
 +  demand_empty_rest_of_line ();
 +}
 +
-+/* Parse a register string into a number. */
-+
-+static int
-+tc_get_register (void)
-+{
-+  unsigned int reg;
-+
-+  SKIP_WHITESPACE ();
-+  if (! reg_lookup (&input_line_pointer, RWARN | RTYPE_NUM | RTYPE_GP, &reg))
-+    reg = 0;
-+  return reg;
-+}
-+
 +valueT
 +md_section_align (asection *seg, valueT addr)
 +{
@@ -18961,22 +18664,6 @@ index 0000000..20549f1
 +}
 +
 +#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
-+\f
-+typedef struct proc {
-+  symbolS *func_sym;
-+  symbolS *func_end_sym;
-+  unsigned long reg_mask;
-+  unsigned long reg_offset;
-+  unsigned long fpreg_mask;
-+  unsigned long fpreg_offset;
-+  unsigned long frame_offset;
-+  unsigned long frame_reg;
-+  unsigned long pc_reg;
-+} procS;
-+
-+static procS cur_proc;
-+static procS *cur_proc_ptr;
-+static int numprocs;
 +
 +void
 +mips_handle_align (fragS *fragp)
@@ -18991,64 +18678,6 @@ index 0000000..20549f1
 +  fragp->fr_var = 4;
 +}
 +
-+void
-+md_mips_end (void)
-+{
-+  if (cur_proc_ptr)
-+    as_warn (_("missing .end at end of assembly"));
-+}
-+
-+static long
-+get_number (void)
-+{
-+  int negative = 0;
-+  long val = 0;
-+
-+  if (*input_line_pointer == '-')
-+    {
-+      ++input_line_pointer;
-+      negative = 1;
-+    }
-+  if (!ISDIGIT (*input_line_pointer))
-+    as_bad (_("expected simple number"));
-+  if (input_line_pointer[0] == '0')
-+    {
-+      if (input_line_pointer[1] == 'x')
-+      {
-+        input_line_pointer += 2;
-+        while (ISXDIGIT (*input_line_pointer))
-+          {
-+            val <<= 4;
-+            val |= hex_value (*input_line_pointer++);
-+          }
-+        return negative ? -val : val;
-+      }
-+      else
-+      {
-+        ++input_line_pointer;
-+        while (ISDIGIT (*input_line_pointer))
-+          {
-+            val <<= 3;
-+            val |= *input_line_pointer++ - '0';
-+          }
-+        return negative ? -val : val;
-+      }
-+    }
-+  if (!ISDIGIT (*input_line_pointer))
-+    {
-+      printf (_(" *input_line_pointer == '%c' 0x%02x\n"),
-+            *input_line_pointer, *input_line_pointer);
-+      as_warn (_("invalid number"));
-+      return -1;
-+    }
-+  while (ISDIGIT (*input_line_pointer))
-+    {
-+      val *= 10;
-+      val += *input_line_pointer++ - '0';
-+    }
-+  return negative ? -val : val;
-+}
-+
 +/* The .file directive; just like the usual .file directive, but there
 +   is an initial number which is the ECOFF file index.  In the non-ECOFF
 +   case .file implies DWARF-2.  */
@@ -19082,401 +18711,16 @@ index 0000000..20549f1
 +  dwarf2_directive_loc (0);
 +}
 +
-+/* The .end directive.  */
-+
-+static void
-+s_mips_end (int x ATTRIBUTE_UNUSED)
-+{
-+  symbolS *p;
-+
-+  if (!is_end_of_line[(unsigned char) *input_line_pointer])
-+    {
-+      p = get_symbol ();
-+      demand_empty_rest_of_line ();
-+    }
-+  else
-+    p = NULL;
-+
-+  if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) == 0)
-+    as_warn (_(".end not in text section"));
-+
-+  if (!cur_proc_ptr)
-+    {
-+      as_warn (_(".end directive without a preceding .ent directive."));
-+      demand_empty_rest_of_line ();
-+      return;
-+    }
-+
-+  if (p != NULL)
-+    {
-+      gas_assert (S_GET_NAME (p));
-+      if (strcmp (S_GET_NAME (p), S_GET_NAME (cur_proc_ptr->func_sym)))
-+      as_warn (_(".end symbol does not match .ent symbol."));
-+
-+      if (debug_type == DEBUG_STABS)
-+      stabs_generate_asm_endfunc (S_GET_NAME (p),
-+                                  S_GET_NAME (p));
-+    }
-+  else
-+    as_warn (_(".end directive missing or unknown symbol"));
-+
-+#ifdef OBJ_ELF
-+  /* Create an expression to calculate the size of the function.  */
-+  if (p && cur_proc_ptr)
-+    {
-+      OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (p);
-+      expressionS *exp = xmalloc (sizeof (expressionS));
-+
-+      obj->size = exp;
-+      exp->X_op = O_subtract;
-+      exp->X_add_symbol = symbol_temp_new_now ();
-+      exp->X_op_symbol = p;
-+      exp->X_add_number = 0;
-+
-+      cur_proc_ptr->func_end_sym = exp->X_add_symbol;
-+    }
-+
-+  /* Generate a .pdr section.  */
-+  if (IS_ELF && mips_flag_pdr)
-+    {
-+      segT saved_seg = now_seg;
-+      subsegT saved_subseg = now_subseg;
-+      expressionS exp;
-+      char *fragp;
-+
-+#ifdef md_flush_pending_output
-+      md_flush_pending_output ();
-+#endif
-+
-+      gas_assert (pdr_seg);
-+      subseg_set (pdr_seg, 0);
-+
-+      /* Write the symbol.  */
-+      exp.X_op = O_symbol;
-+      exp.X_add_symbol = p;
-+      exp.X_add_number = 0;
-+      emit_expr (&exp, 4);
-+
-+      fragp = frag_more (7 * 4);
-+
-+      md_number_to_chars (fragp, cur_proc_ptr->reg_mask, 4);
-+      md_number_to_chars (fragp + 4, cur_proc_ptr->reg_offset, 4);
-+      md_number_to_chars (fragp + 8, cur_proc_ptr->fpreg_mask, 4);
-+      md_number_to_chars (fragp + 12, cur_proc_ptr->fpreg_offset, 4);
-+      md_number_to_chars (fragp + 16, cur_proc_ptr->frame_offset, 4);
-+      md_number_to_chars (fragp + 20, cur_proc_ptr->frame_reg, 4);
-+      md_number_to_chars (fragp + 24, cur_proc_ptr->pc_reg, 4);
-+
-+      subseg_set (saved_seg, saved_subseg);
-+    }
-+#endif /* OBJ_ELF */
-+
-+  cur_proc_ptr = NULL;
-+}
-+
-+/* The .aent and .ent directives.  */
-+
-+static void
-+s_mips_ent (int aent)
-+{
-+  symbolS *symbolP;
-+
-+  symbolP = get_symbol ();
-+  if (*input_line_pointer == ',')
-+    ++input_line_pointer;
-+  SKIP_WHITESPACE ();
-+  if (ISDIGIT (*input_line_pointer)
-+      || *input_line_pointer == '-')
-+    get_number ();
-+
-+  if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) == 0)
-+    as_warn (_(".ent or .aent not in text section."));
-+
-+  if (!aent && cur_proc_ptr)
-+    as_warn (_("missing .end"));
-+
-+  if (!aent)
-+    {
-+      cur_proc_ptr = &cur_proc;
-+      memset (cur_proc_ptr, '\0', sizeof (procS));
-+
-+      cur_proc_ptr->func_sym = symbolP;
-+
-+      symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION;
-+
-+      ++numprocs;
-+
-+      if (debug_type == DEBUG_STABS)
-+        stabs_generate_asm_func (S_GET_NAME (symbolP),
-+                               S_GET_NAME (symbolP));
-+    }
-+
-+  demand_empty_rest_of_line ();
-+}
-+
-+/* The .frame directive. If the mdebug section is present (IRIX 5 native)
-+   then ecoff.c (ecoff_directive_frame) is used. For embedded targets,
-+   s_mips_frame is used so that we can set the PDR information correctly.
-+   We can't use the ecoff routines because they make reference to the ecoff
-+   symbol table (in the mdebug section).  */
-+
-+static void
-+s_mips_frame (int ignore ATTRIBUTE_UNUSED)
-+{
-+#ifdef OBJ_ELF
-+  if (IS_ELF)
-+    {
-+      long val;
-+
-+      if (cur_proc_ptr == (procS *) NULL)
-+      {
-+        as_warn (_(".frame outside of .ent"));
-+        demand_empty_rest_of_line ();
-+        return;
-+      }
-+
-+      cur_proc_ptr->frame_reg = tc_get_register ();
-+
-+      SKIP_WHITESPACE ();
-+      if (*input_line_pointer++ != ','
-+        || get_absolute_expression_and_terminator (&val) != ',')
-+      {
-+        as_warn (_("Bad .frame directive"));
-+        --input_line_pointer;
-+        demand_empty_rest_of_line ();
-+        return;
-+      }
-+
-+      cur_proc_ptr->frame_offset = val;
-+      cur_proc_ptr->pc_reg = tc_get_register ();
-+
-+      demand_empty_rest_of_line ();
-+    }
-+  else
-+#endif /* OBJ_ELF */
-+    s_ignore (ignore);
-+}
-+
-+/* The .fmask and .mask directives. If the mdebug section is present
-+   (IRIX 5 native) then ecoff.c (ecoff_directive_mask) is used. For
-+   embedded targets, s_mips_mask is used so that we can set the PDR
-+   information correctly. We can't use the ecoff routines because they
-+   make reference to the ecoff symbol table (in the mdebug section).  */
-+
-+static void
-+s_mips_mask (int reg_type)
-+{
-+#ifdef OBJ_ELF
-+  if (IS_ELF)
-+    {
-+      long mask, off;
-+
-+      if (cur_proc_ptr == (procS *) NULL)
-+      {
-+        as_warn (_(".mask/.fmask outside of .ent"));
-+        demand_empty_rest_of_line ();
-+        return;
-+      }
-+
-+      if (get_absolute_expression_and_terminator (&mask) != ',')
-+      {
-+        as_warn (_("Bad .mask/.fmask directive"));
-+        --input_line_pointer;
-+        demand_empty_rest_of_line ();
-+        return;
-+      }
-+
-+      off = get_absolute_expression ();
-+
-+      if (reg_type == 'F')
-+      {
-+        cur_proc_ptr->fpreg_mask = mask;
-+        cur_proc_ptr->fpreg_offset = off;
-+      }
-+      else
-+      {
-+        cur_proc_ptr->reg_mask = mask;
-+        cur_proc_ptr->reg_offset = off;
-+      }
-+
-+      demand_empty_rest_of_line ();
-+    }
-+  else
-+#endif /* OBJ_ELF */
-+    s_ignore (reg_type);
-+}
-+
-+/* A table describing all the processors gas knows about.  Names are
-+   matched in the order listed.
-+
-+   To ease comparison, please keep this table in the same order as
-+   gcc's mips_cpu_info_table[].  */
-+static const struct mips_cpu_info mips_cpu_info_table[] =
-+{
-+  /* Entries for generic ISAs */
-+  { "rv32",           MIPS_CPU_IS_ISA,                ISA_RV32,       CPU_ROCKET32 },
-+  { "rv64",           MIPS_CPU_IS_ISA,                ISA_RV64,       CPU_ROCKET64 },
-+  { "riscv",          MIPS_CPU_IS_ISA,                ISA_RV64,       CPU_ROCKET64 },
-+
-+  /* End marker */
-+  { NULL, 0, 0, 0 }
-+};
-+
-+
-+/* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL
-+   with a final "000" replaced by "k".  Ignore case.
-+
-+   Note: this function is shared between GCC and GAS.  */
-+
-+static bfd_boolean
-+mips_strict_matching_cpu_name_p (const char *canonical, const char *given)
-+{
-+  while (*given != 0 && TOLOWER (*given) == TOLOWER (*canonical))
-+    given++, canonical++;
-+
-+  return ((*given == 0 && *canonical == 0)
-+        || (strcmp (canonical, "000") == 0 && strcasecmp (given, "k") == 0));
-+}
-+
-+/* Parse an option that takes the name of a processor as its argument.
-+   OPTION is the name of the option and CPU_STRING is the argument.
-+   Return the corresponding processor enumeration if the CPU_STRING is
-+   recognized, otherwise report an error and return null.
-+
-+   A similar function exists in GCC.  */
-+
-+static const struct mips_cpu_info *
-+mips_parse_cpu (const char *option, const char *cpu_string)
-+{
-+  const struct mips_cpu_info *p;
-+
-+  /* 'from-abi' selects the most compatible architecture for the given
-+     ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs.  For the
-+     EABIs, we have to decide whether we're using the 32-bit or 64-bit
-+     version.  Look first at the -mgp options, if given, otherwise base
-+     the choice on MIPS_DEFAULT_64BIT.
-+
-+     Treat NO_ABI like the EABIs.  One reason to do this is that the
-+     plain 'mips' and 'mips64' configs have 'from-abi' as their default
-+     architecture.  This code picks MIPS I for 'mips' and MIPS III for
-+     'mips64', just as we did in the days before 'from-abi'.  */
-+  if (strcasecmp (cpu_string, "from-abi") == 0)
-+    {
-+      if (ABI_NEEDS_32BIT_REGS (mips_abi))
-+      return mips_cpu_info_from_isa (ISA_RV32);
-+
-+      if (ABI_NEEDS_64BIT_REGS (mips_abi))
-+      return mips_cpu_info_from_isa (ISA_RV64);
-+
-+      if (file_mips_gp32 >= 0)
-+      return mips_cpu_info_from_isa (file_mips_gp32 ? ISA_RV32 : ISA_RV64);
-+
-+      return mips_cpu_info_from_isa (ISA_RV64);
-+    }
-+
-+  /* 'default' has traditionally been a no-op.  Probably not very useful.  */
-+  if (strcasecmp (cpu_string, "default") == 0)
-+    return 0;
-+
-+  for (p = mips_cpu_info_table; p->name != 0; p++)
-+    if (mips_strict_matching_cpu_name_p (p->name, cpu_string))
-+      return p;
-+
-+  as_bad ("Bad value (%s) for %s", cpu_string, option);
-+  return 0;
-+}
-+
-+/* Return the canonical processor information for ISA (a member of the
-+   ISA_MIPS* enumeration).  */
-+
-+static const struct mips_cpu_info *
-+mips_cpu_info_from_isa (int isa)
-+{
-+  int i;
-+
-+  for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
-+    if ((mips_cpu_info_table[i].flags & MIPS_CPU_IS_ISA)
-+      && isa == mips_cpu_info_table[i].isa)
-+      return (&mips_cpu_info_table[i]);
-+
-+  return NULL;
-+}
-+
-+static void
-+show (FILE *stream, const char *string, int *col_p, int *first_p)
-+{
-+  if (*first_p)
-+    {
-+      fprintf (stream, "%24s", "");
-+      *col_p = 24;
-+    }
-+  else
-+    {
-+      fprintf (stream, ", ");
-+      *col_p += 2;
-+    }
-+
-+  if (*col_p + strlen (string) > 72)
-+    {
-+      fprintf (stream, "\n%24s", "");
-+      *col_p = 24;
-+    }
-+
-+  fprintf (stream, "%s", string);
-+  *col_p += strlen (string);
-+
-+  *first_p = 0;
-+}
-+
 +void
 +md_show_usage (FILE *stream)
 +{
-+  int column, first;
-+  size_t i;
-+
 +  fprintf (stream, _("\
 +MIPS options:\n\
-+-EB                   generate big endian output\n\
-+-EL                   generate little endian output\n"));
-+  fprintf (stream, _("\
-+-march=CPU/-mtune=CPU generate code/schedule for CPU, where CPU is one of:\n"));
-+
-+  first = 1;
-+
-+  for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
-+    show (stream, mips_cpu_info_table[i].name, &column, &first);
-+  show (stream, "from-abi", &column, &first);
-+  fputc ('\n', stream);
-+
-+  fprintf (stream, _("\
-+-mgp32                        use 32-bit GPRs, regardless of the chosen ISA\n\
-+-msym32                       assume all symbols have 32-bit values\n"));
-+#ifdef OBJ_ELF
-+  fprintf (stream, _("\
-+-KPIC, -call_shared   generate SVR4 position independent code\n\
-+-call_nonpic          generate non-PIC code that can operate with DSOs\n\
-+-non_shared           do not generate code that can operate with DSOs\n\
-+-xgot                 assume a 32 bit GOT\n\
-+-mpdr, -mno-pdr               enable/disable creation of .pdr sections\n\
-+-mshared, -mno-shared   disable/enable .cpload optimization for\n\
-+                        position dependent (non shared) code\n\
-+-mabi=ABI             create ABI conformant object file for:\n"));
-+
-+  first = 1;
-+
-+  show (stream, "32", &column, &first);
-+  show (stream, "o64", &column, &first);
-+  show (stream, "n32", &column, &first);
-+  show (stream, "64", &column, &first);
-+  show (stream, "eabi", &column, &first);
-+
-+  fputc ('\n', stream);
-+
-+  fprintf (stream, _("\
-+-32                   create o32 ABI object file (default)\n\
-+-n32                  create n32 ABI object file\n\
-+-64                   create 64 ABI object file\n"));
-+#endif
++-EB            generate big endian output\n\
++-EL            generate little endian output\n\
++-mabi=ABI      create ABI conformant object file for:\n\
++                 32, 64\n\
++"));
 +}
 +
 +enum dwarf2_format
@@ -19517,10 +18761,10 @@ index 0000000..20549f1
 +}
 diff --git a/binutils-2.21.1/gas/config/tc-riscv.h b/binutils-2.21.1/gas/config/tc-riscv.h
 new file mode 100644
-index 0000000..ccde0c0
+index 0000000..f1c56ae
 --- /dev/null
 +++ binutils-2.21.1/gas/config/tc-riscv.h
-@@ -0,0 +1,162 @@
+@@ -0,0 +1,159 @@
 +/* tc-mips.h -- header file for tc-mips.c.
 +   Copyright 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004,
 +   2005, 2006, 2007  Free Software Foundation, Inc.
@@ -19651,9 +18895,6 @@ index 0000000..ccde0c0
 +
 +#endif
 +
-+extern void md_mips_end (void);
-+#define md_end()      md_mips_end()
-+
 +extern void mips_pop_insert (void);
 +#define md_pop_insert()               mips_pop_insert()
 +
diff --git a/tools/compilers/gcc-glibc/gcc-4.6.1-compile.patch b/tools/compilers/gcc-glibc/gcc-4.6.1-compile.patch
deleted file mode 100644 (file)
index 9dea910..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-diff --git a/gcc-4.6.1/gcc/gengtype.c b/gcc-4.6.1/gcc/gengtype.c
-index abf17f8..550d3bb 100644
---- a/gcc-4.6.1/gcc/gengtype.c
-+++ b/gcc-4.6.1/gcc/gengtype.c
-@@ -3594,13 +3594,13 @@ write_field_root (outf_p f, pair_p v, type_p type, const char *name,
-                 int has_length, struct fileloc *line, const char *if_marked,
-                 bool emit_pch, type_p field_type, const char *field_name)
- {
-+  struct pair newv;
-   /* If the field reference is relative to V, rather than to some
-      subcomponent of V, we can mark any subarrays with a single stride.
-      We're effectively treating the field as a global variable in its
-      own right.  */
-   if (v && type == v->type)
-     {
--      struct pair newv;
-
-       newv = *v;
-       newv.type = field_type;
index 08f1eb7..2596ac6 100644 (file)
@@ -69,10 +69,10 @@ index ada68dd..321d4f2 100644
  
 diff --git a/gcc-4.6.1/gcc/config/riscv/constraints.md b/gcc-4.6.1/gcc/config/riscv/constraints.md
 new file mode 100644
-index 0000000..d7fbe0b
+index 0000000..d994f47
 --- /dev/null
 +++ gcc-4.6.1/gcc/config/riscv/constraints.md
-@@ -0,0 +1,164 @@
+@@ -0,0 +1,137 @@
 +;; Constraint definitions for MIPS.
 +;; Copyright (C) 2006, 2007, 2008, 2010 Free Software Foundation, Inc.
 +;;
@@ -102,7 +102,7 @@ index 0000000..d7fbe0b
 +
 +;; Register constraints
 +
-+(define_register_constraint "d" "BASE_REG_CLASS"
++(define_register_constraint "d" "GR_REGS"
 +  "An address register.  This is equivalent to @code{r} unless
 +   generating MIPS16 code.")
 +
@@ -121,9 +121,6 @@ index 0000000..d7fbe0b
 +  "A register suitable for use in an indirect jump.  This will always be
 +   @code{$25} for @option{-mabicalls}.")
 +
-+(define_register_constraint "e" "LEA_REGS"
-+  "@internal")
-+
 +(define_register_constraint "j" "PIC_FN_ADDR_REG"
 +  "@internal")
 +
@@ -133,9 +130,6 @@ index 0000000..d7fbe0b
 +  "Register @code{$3}.  Do not use this constraint in new code;
 +   it is retained only for compatibility with glibc.")
 +
-+(define_register_constraint "y" "GR_REGS"
-+  "Equivalent to @code{r}; retained for backwards compatibility.")
-+
 +(define_register_constraint "z" "GR_REGS"
 +  "A floating-point condition code register.")
 +
@@ -153,12 +147,12 @@ index 0000000..d7fbe0b
 +;; Integer constraints
 +
 +(define_constraint "Z"
-+  "A signed 16-bit constant (for arithmetic instructions)."
++  "@internal"
 +  (and (match_code "const_int")
 +       (match_test "1")))
 +
 +(define_constraint "I"
-+  "A signed 16-bit constant (for arithmetic instructions)."
++  "An I-type 12-bit signed immediate."
 +  (and (match_code "const_int")
 +       (match_test "SMALL_OPERAND (ival)")))
 +
@@ -166,19 +160,6 @@ index 0000000..d7fbe0b
 +  "Integer zero."
 +  (and (match_code "const_int")
 +       (match_test "ival == 0")))
-+ 
-+(define_constraint "L"
-+  "A signed 32-bit constant in which the lower 16 bits are zero.
-+   Such constants can be loaded using @code{lui}."
-+  (and (match_code "const_int")
-+       (match_test "LUI_OPERAND (ival)")))
-+
-+(define_constraint "M"
-+  "A constant that cannot be loaded using @code{lui}, @code{addiu}
-+   or @code{ori}."
-+  (and (match_code "const_int")
-+       (match_test "!SMALL_OPERAND (ival)")
-+       (match_test "!LUI_OPERAND (ival)")))
 +
 +;; Floating-point constraints
 +
@@ -211,15 +192,7 @@ index 0000000..d7fbe0b
 +
 +(define_constraint "T"
 +  "@internal
-+   A constant @code{move_operand} that cannot be safely loaded into @code{$25}
-+   using @code{la}."
-+  (and (match_operand 0 "move_operand")
-+       (match_test "CONSTANT_P (op)")))
-+
-+(define_constraint "U"
-+  "@internal
-+   A constant @code{move_operand} that can be safely loaded into @code{$25}
-+   using @code{la}."
++   A constant @code{move_operand}."
 +  (and (match_operand 0 "move_operand")
 +       (match_test "CONSTANT_P (op)")))
 +
@@ -640,10 +613,10 @@ index 0000000..02f7cd5
 +#endif
 diff --git a/gcc-4.6.1/gcc/config/riscv/linux.h b/gcc-4.6.1/gcc/config/riscv/linux.h
 new file mode 100644
-index 0000000..3eca2e7
+index 0000000..cbae60e
 --- /dev/null
 +++ gcc-4.6.1/gcc/config/riscv/linux.h
-@@ -0,0 +1,128 @@
+@@ -0,0 +1,124 @@
 +/* Definitions for MIPS running Linux-based GNU systems with ELF format.
 +   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
 +   2007, 2008, 2010, 2011 Free Software Foundation, Inc.
@@ -714,10 +687,6 @@ index 0000000..3eca2e7
 +      -dynamic-linker " LINUX_DYNAMIC_LINKER "} \
 +      %{static:-static}}"
 +
-+#undef SUBTARGET_ASM_SPEC
-+#define SUBTARGET_ASM_SPEC \
-+  "%{fPIC:-KPIC}"
-+
 +/* The MIPS assembler has different syntax for .set. We set it to
 +   .dummy to trap any errors.  */
 +#undef SET_ASM_OP
@@ -774,10 +743,10 @@ index 0000000..3eca2e7
 +   "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
 diff --git a/gcc-4.6.1/gcc/config/riscv/linux64.h b/gcc-4.6.1/gcc/config/riscv/linux64.h
 new file mode 100644
-index 0000000..2d12160
+index 0000000..7262396
 --- /dev/null
 +++ gcc-4.6.1/gcc/config/riscv/linux64.h
-@@ -0,0 +1,61 @@
+@@ -0,0 +1,58 @@
 +/* Definitions for MIPS running Linux-based GNU systems with ELF format
 +   using n32/64 abi.
 +   Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
@@ -831,9 +800,6 @@ index 0000000..2d12160
 +%{mabi=64:-melf64%{EB:b}%{EL:l}riscv} \
 +%{mabi=32:-melf32%{EB:b}%{EL:l}riscv}"
 +
-+#undef LOCAL_LABEL_PREFIX
-+#define LOCAL_LABEL_PREFIX "."
-+
 +/* GNU/Linux doesn't use the same floating-point format that IRIX uses
 +   for long double.  There's no need to override this here, since
 +   ieee_quad_format is the default, but let's put this here to make
@@ -2136,7 +2102,7 @@ index 0000000..e417397
 +#define  MASK_SD 0x3ff
 diff --git a/gcc-4.6.1/gcc/config/riscv/riscv-protos.h b/gcc-4.6.1/gcc/config/riscv/riscv-protos.h
 new file mode 100644
-index 0000000..f2a4f11
+index 0000000..7b8a972
 --- /dev/null
 +++ gcc-4.6.1/gcc/config/riscv/riscv-protos.h
 @@ -0,0 +1,205 @@
@@ -2268,7 +2234,7 @@ index 0000000..f2a4f11
 +extern rtx mips_got_load (rtx, rtx, enum mips_symbol_type);
 +extern bool mips_split_symbol (rtx, rtx, enum machine_mode, rtx *);
 +extern rtx mips_unspec_address (rtx, enum mips_symbol_type);
-+extern void mips_move_integer (rtx, rtx, unsigned HOST_WIDE_INT);
++extern void mips_move_integer (rtx, rtx, HOST_WIDE_INT);
 +extern bool mips_legitimize_move (enum machine_mode, rtx, rtx);
 +extern bool mips_legitimize_vector_move (enum machine_mode, rtx, rtx);
 +
@@ -2314,7 +2280,7 @@ index 0000000..f2a4f11
 +extern void mips_declare_object_name (FILE *, const char *, tree);
 +extern void mips_finish_declare_object (FILE *, tree, int, int);
 +
-+extern HOST_WIDE_INT mips_initial_elimination_offset (int);
++extern HOST_WIDE_INT mips_initial_elimination_offset (int, int);
 +extern rtx mips_return_addr (int, rtx);
 +extern bool mips_must_initialize_gp_p (void);
 +extern enum mips_loadgp_style mips_current_loadgp_style (void);
@@ -2347,10 +2313,10 @@ index 0000000..f2a4f11
 +#endif /* ! GCC_MIPS_PROTOS_H */
 diff --git a/gcc-4.6.1/gcc/config/riscv/riscv.c b/gcc-4.6.1/gcc/config/riscv/riscv.c
 new file mode 100644
-index 0000000..45dd285
+index 0000000..a4d85c4
 --- /dev/null
 +++ gcc-4.6.1/gcc/config/riscv/riscv.c
-@@ -0,0 +1,6776 @@
+@@ -0,0 +1,6416 @@
 +/* Subroutines used for MIPS code generation.
 +   Copyright (C) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
 +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@@ -2539,69 +2505,27 @@ index 0000000..45dd285
 +  MIPS_BUILTIN_DIRECT_NO_TARGET
 +};
 +
-+/* Invoke MACRO (COND) for each C.cond.fmt condition.  */
-+#define MIPS_FP_CONDITIONS(MACRO) \
-+  MACRO (f),  \
-+  MACRO (un), \
-+  MACRO (eq), \
-+  MACRO (ueq),        \
-+  MACRO (olt),        \
-+  MACRO (ult),        \
-+  MACRO (ole),        \
-+  MACRO (ule),        \
-+  MACRO (sf), \
-+  MACRO (ngle),       \
-+  MACRO (seq),        \
-+  MACRO (ngl),        \
-+  MACRO (lt), \
-+  MACRO (nge),        \
-+  MACRO (le), \
-+  MACRO (ngt)
-+
-+/* Enumerates the codes above as MIPS_FP_COND_<X>.  */
-+#define DECLARE_MIPS_COND(X) MIPS_FP_COND_ ## X
-+enum mips_fp_condition {
-+  MIPS_FP_CONDITIONS (DECLARE_MIPS_COND)
-+};
-+
-+/* Index X provides the string representation of MIPS_FP_COND_<X>.  */
-+#define STRINGIFY(X) #X
-+static const char *const mips_fp_conditions[] = {
-+  MIPS_FP_CONDITIONS (STRINGIFY)
-+};
-+
 +/* Information about a function's frame layout.  */
 +struct GTY(())  mips_frame_info {
 +  /* The size of the frame in bytes.  */
 +  HOST_WIDE_INT total_size;
 +
-+  /* The number of bytes allocated to variables.  */
-+  HOST_WIDE_INT var_size;
-+
-+  /* The number of bytes allocated to outgoing function arguments.  */
-+  HOST_WIDE_INT args_size;
-+
 +  /* Bit X is set if the function saves or restores GPR X.  */
 +  unsigned int mask;
 +
 +  /* Likewise FPR X.  */
 +  unsigned int fmask;
 +
-+  /* The number of GPRs, FPRs, doubleword accumulators and COP0
-+     registers saved.  */
-+  unsigned int num_gp;
-+  unsigned int num_fp;
-+
-+  /* The offset of the topmost GPR, FPR, accumulator and COP0-register
-+     save slots from the top of the frame, or zero if no such slots are
-+     needed.  */
-+  HOST_WIDE_INT gp_save_offset;
-+  HOST_WIDE_INT fp_save_offset;
-+
-+  /* Likewise, but giving offsets from the bottom of the frame.  */
++  /* Offsets of fixed-point and floating-point save areas from frame bottom */
 +  HOST_WIDE_INT gp_sp_offset;
 +  HOST_WIDE_INT fp_sp_offset;
 +
++  /* Offset of virtual frame pointer from stack pointer/frame bottom */
++  HOST_WIDE_INT frame_pointer_offset;
++
++  /* Offset of hard frame pointer from stack pointer/frame bottom */
++  HOST_WIDE_INT hard_frame_pointer_offset;
++
 +  /* The offset of arg_pointer_rtx from the bottom of the frame.  */
 +  HOST_WIDE_INT arg_pointer_offset;
 +};
@@ -2726,22 +2650,13 @@ index 0000000..45dd285
 +   written anything yet.  */
 +const char *current_function_file = "";
 +
-+/* A label counter used by PUT_SDB_BLOCK_START and PUT_SDB_BLOCK_END.  */
-+int sdb_label_count;
-+
 +/* Arrays that map GCC register numbers to debugger register numbers.  */
 +int mips_dbx_regno[FIRST_PSEUDO_REGISTER];
 +int mips_dwarf_regno[FIRST_PSEUDO_REGISTER];
 +
-+/* The current instruction-set architecture.  */
-+enum processor mips_arch;
-+
 +/* The processor that we should tune the code for.  */
 +enum processor mips_tune;
 +
-+/* The ISA level associated with mips_arch.  */
-+int mips_isa;
-+
 +/* Which ABI to use.  */
 +int mips_abi = MIPS_ABI_DEFAULT;
 +
@@ -2836,8 +2751,7 @@ index 0000000..45dd285
 +   options correctly.  */
 +static const struct mips_cpu_info mips_cpu_info_table[] = {
 +  /* Entries for generic ISAs.  */
-+  { "rocket32", PROCESSOR_ROCKET32, ISA_RV32, 0 },
-+  { "rocket64", PROCESSOR_ROCKET64, ISA_RV64, 0 }
++  { "rocket", PROCESSOR_ROCKET, 0 },
 +};
 +
 +/* Default costs.  If these are used for a processor we should look
@@ -2880,8 +2794,7 @@ index 0000000..45dd285
 +/* Costs to use when optimizing for speed, indexed by processor.  */
 +static const struct mips_rtx_cost_data
 +  mips_rtx_cost_data[NUM_PROCESSOR_VALUES] = {
-+  { /* Rocket32 */ DEFAULT_COSTS},
-+  { /* Rocket64 */ DEFAULT_COSTS}
++  { /* Rocket */ DEFAULT_COSTS},
 +};
 +\f
 +static int mips_register_move_cost (enum machine_mode, reg_class_t,
@@ -2938,58 +2851,81 @@ index 0000000..45dd285
 +/* Fill CODES with a sequence of rtl operations to load VALUE.
 +   Return the number of operations needed.  */
 +
-+static unsigned int
-+mips_build_integer (struct mips_integer_op *codes,
-+                  unsigned HOST_WIDE_INT value)
++static int
++riscv_build_integer_simple (struct mips_integer_op *codes, HOST_WIDE_INT value)
 +{
-+  unsigned HOST_WIDE_INT high_part = RISCV_CONST_HIGH_PART (value);
-+  unsigned HOST_WIDE_INT low_part = RISCV_CONST_LOW_PART (value);
-+  unsigned cost = UINT_MAX;
++  HOST_WIDE_INT low_part = RISCV_CONST_LOW_PART (value);
++  int cost = INT_MAX, alt_cost;
++  struct mips_integer_op alt_codes[MIPS_MAX_INTEGER_OPS];
 +
 +  if (SMALL_OPERAND (value) || LUI_OPERAND (value))
 +    {
-+      /* The value can be loaded with a single instruction.  */
++      /* Simply ADDI or LUI */
 +      codes[0].code = UNKNOWN;
 +      codes[0].value = value;
 +      return 1;
 +    }
 +
-+  if (LUI_OPERAND (high_part))
++  /* End with ADDI */
++  if (low_part != 0)
 +    {
-+      /* The value can be loaded with a LUI/ADDI combination. */
-+      codes[0].code = UNKNOWN;
-+      codes[0].value = high_part;
-+      codes[1].code = PLUS;
-+      codes[1].value = low_part;
-+      return 2;
++      cost = 1 + riscv_build_integer_simple (codes, value - low_part);
++      codes[cost-1].code = PLUS;
++      codes[cost-1].value = low_part;
 +    }
 +
++  /* End with XORI */
++  if (low_part < 0)
++    {
++      alt_cost = 1 + riscv_build_integer_simple (alt_codes, value ^ low_part);
++      alt_codes[alt_cost-1].code = XOR;
++      alt_codes[alt_cost-1].value = low_part;
++      if (alt_cost < cost)
++      cost = alt_cost, memcpy (codes, alt_codes, sizeof(alt_codes));
++    }
++
++  /* Eliminate trailing zeros and end with SLLI */
 +  if ((value & 1) == 0)
 +    {
-+      /* Try eliminating all trailing zeros by ending with SLL. */
-+      unsigned lshift = __builtin_ctzl (value);
-+      cost = mips_build_integer (codes, (int64_t)value >> lshift);
-+      codes[cost].code = ASHIFT;
-+      codes[cost].value = lshift;
-+      cost++;
++      int shift = __builtin_ctzl(value);
++      alt_cost = 1 + riscv_build_integer_simple (alt_codes, value >> shift);
++      alt_codes[alt_cost-1].code = ASHIFT;
++      alt_codes[alt_cost-1].value = shift;
++      if (alt_cost < cost)
++      cost = alt_cost, memcpy (codes, alt_codes, sizeof(alt_codes));
 +    }
 +
-+  if (low_part != 0)
++  gcc_assert (cost <= MIPS_MAX_INTEGER_OPS);
++  return cost;
++}
++
++static int
++riscv_build_integer (struct mips_integer_op *codes, HOST_WIDE_INT value)
++{
++  int cost = riscv_build_integer_simple (codes, value);
++
++  /* Eliminate leading zeros and end with SRLI */
++  if (value > 0 && cost > 2)
 +    {
-+      struct mips_integer_op add_codes[MIPS_MAX_INTEGER_OPS];
-+      unsigned add_cost = mips_build_integer (add_codes, high_part);
-+      add_codes[add_cost].code = PLUS;
-+      add_codes[add_cost].value = low_part;
-+      add_cost++;
++      struct mips_integer_op alt_codes[MIPS_MAX_INTEGER_OPS];
++      int alt_cost, shift;
 +
-+      if (add_cost < cost)
-+      {
-+        memcpy (codes, add_codes, add_cost * sizeof (codes[0]));
-+          cost = add_cost;
-+      }
-+    }
++      shift = __builtin_clzl(value);
++      alt_cost = 1 + riscv_build_integer_simple (alt_codes, value << shift);
++      alt_codes[alt_cost-1].code = LSHIFTRT;
++      alt_codes[alt_cost-1].value = shift;
++      if (alt_cost < cost)
++      cost = alt_cost, memcpy (codes, alt_codes, sizeof(alt_codes));
 +
-+  gcc_assert (cost != UINT_MAX);
++      /* Also try filling discarded bits with 1s */
++      shift = __builtin_clzl(value);
++      alt_cost = 1 + riscv_build_integer_simple (alt_codes,
++                      value << shift | ((1L<<shift)-1));
++      alt_codes[alt_cost-1].code = LSHIFTRT;
++      alt_codes[alt_cost-1].value = shift;
++      if (alt_cost < cost)
++      cost = alt_cost, memcpy (codes, alt_codes, sizeof(alt_codes));
++    }
 +
 +  return cost;
 +}
@@ -3413,7 +3349,7 @@ index 0000000..45dd285
 +      return 1;
 +
 +    case CONST_INT:
-+      return mips_build_integer (codes, INTVAL (x));
++      return riscv_build_integer (codes, INTVAL (x));
 +
 +    case CONST_DOUBLE:
 +    case CONST_VECTOR:
@@ -3442,7 +3378,7 @@ index 0000000..45dd285
 +            if (SMALL_INT (offset))
 +              return n + 1;
 +            else if (!targetm.cannot_force_const_mem (x))
-+              return n + 1 + mips_build_integer (codes, INTVAL (offset));
++              return n + 1 + riscv_build_integer (codes, INTVAL (offset));
 +          }
 +      }
 +      return 0;
@@ -3886,7 +3822,7 @@ index 0000000..45dd285
 +/* Load VALUE into DEST.  TEMP is as for mips_force_temporary.  */
 +
 +void
-+mips_move_integer (rtx temp, rtx dest, unsigned HOST_WIDE_INT value)
++mips_move_integer (rtx temp, rtx dest, HOST_WIDE_INT value)
 +{
 +  struct mips_integer_op codes[MIPS_MAX_INTEGER_OPS];
 +  enum machine_mode mode;
@@ -3894,35 +3830,28 @@ index 0000000..45dd285
 +  rtx x;
 +
 +  mode = GET_MODE (dest);
-+  num_ops = mips_build_integer (codes, value);
-+
-+  /* Apply each binary operation to X.  Invariant: X is a legitimate
-+     source operand for a SET pattern.  */
-+  x = GEN_INT (codes[0].value);
++  num_ops = riscv_build_integer (codes, value);
 +
-+  if(mode == HImode && num_ops == 2)
++  if (can_create_pseudo_p () && num_ops > 4)
 +    {
-+      /* Some HImode constants are loaded with a LUI/ADDI[W] pair, whose
-+         result would ordinarily be SImode.  For the ADDI[W], we invoke a
-+         special addsihi instruction to mark the output as HImode instead.
-+         The instruction doesn't actually canonicalize the result to 16 bits,
-+       as it's really just ADDI[W], but that's OK here because any HImode
-+       constant is already canonical. */
-+      gcc_assert(codes[1].code == PLUS);
-+      gcc_assert((codes[0].value + codes[1].value) == value);
++      /* Split into two 32-bit constants. Account for SExt of lower word. */
++      rtx upper = gen_reg_rtx (mode);
++      HOST_WIDE_INT correction = (value & 0x80000000L) ? 1 : 0;
++      mips_move_integer (upper, upper, (value >> 32) + correction);
 +
-+      if (!can_create_pseudo_p ())
-+      {
-+                emit_insn (gen_rtx_SET (SImode, temp, x));
-+                x = temp;
-+              }
-+      else
-+        x = force_reg (SImode, x);
++      rtx lower = gen_reg_rtx (mode);
++      mips_move_integer (lower, lower, value << 32 >> 32);
++
++      upper = gen_rtx_fmt_ee (ASHIFT, mode, upper, GEN_INT (32));
++      upper = force_reg (mode, upper);
 +
-+      emit_insn (gen_bullshit_addsihi(dest, x, GEN_INT (codes[1].value)));
++      x = gen_rtx_fmt_ee (PLUS, mode, upper, lower);
 +    }
 +  else
 +    {
++      /* Apply each binary operation to X. */
++      x = GEN_INT (codes[0].value);
++
 +      for (i = 1; i < num_ops; i++)
 +        {
 +          if (!can_create_pseudo_p ())
@@ -3931,13 +3860,13 @@ index 0000000..45dd285
 +              x = temp;
 +            }
 +          else
-+            x = force_reg (mode, x);
++            x = force_reg (mode == HImode ? SImode : mode, x);
 +
 +          x = gen_rtx_fmt_ee (codes[i].code, mode, x, GEN_INT (codes[i].value));
 +        }
-+
-+      emit_insn (gen_rtx_SET (VOIDmode, dest, x));
 +    }
++
++  emit_insn (gen_rtx_SET (VOIDmode, dest, x));
 +}
 +
 +/* Subroutine of mips_legitimize_move.  Move constant SRC into register
@@ -4315,7 +4244,7 @@ index 0000000..45dd285
 +
 +           Also, if we have a CONST_INT, we don't know whether it is
 +           for a word or doubleword operation, so we cannot rely on
-+           the result of mips_build_integer.  */
++           the result of riscv_build_integer.  */
 +        else if (outer_code == SET || mode == VOIDmode)
 +          cost = 1;
 +        *total = COSTS_N_INSNS (cost);
@@ -5552,38 +5481,6 @@ index 0000000..45dd285
 +  std_expand_builtin_va_start (valist, nextarg);
 +}
 +
-+/* Start a definition of function NAME. */
-+
-+static void
-+mips_start_function_definition (const char *name)
-+{
-+  if (!flag_inhibit_size_directive)
-+    {
-+      fputs ("\t.ent\t", asm_out_file);
-+      assemble_name (asm_out_file, name);
-+      fputs ("\n", asm_out_file);
-+    }
-+
-+  ASM_OUTPUT_TYPE_DIRECTIVE (asm_out_file, name, "function");
-+
-+  /* Start the definition proper.  */
-+  assemble_name (asm_out_file, name);
-+  fputs (":\n", asm_out_file);
-+}
-+
-+/* End a function definition started by mips_start_function_definition.  */
-+
-+static void
-+mips_end_function_definition (const char *name)
-+{
-+  if (!flag_inhibit_size_directive)
-+    {
-+      fputs ("\t.end\t", asm_out_file);
-+      assemble_name (asm_out_file, name);
-+      fputs ("\n", asm_out_file);
-+    }
-+}
-+
 +/* Return true if SYMBOL_REF X binds locally.  */
 +
 +static bool
@@ -5864,39 +5761,28 @@ index 0000000..45dd285
 +
 +  mips_lo_relocs[SYMBOL_32_HIGH] = "%hi(";
 +
-+  if (TARGET_XGOT)
-+    {
-+      /* The HIGH and LO_SUM are matched by special .md patterns.  */
-+      mips_split_p[SYMBOL_GOT_DISP] = true;
++  /* The HIGH and LO_SUM are matched by special .md patterns.  */
++  mips_split_p[SYMBOL_GOT_DISP] = true;
 +
-+      mips_split_p[SYMBOL_GOTOFF_DISP] = true;
-+      mips_hi_relocs[SYMBOL_GOTOFF_DISP] = "%got_hi(";
-+      mips_lo_relocs[SYMBOL_GOTOFF_DISP] = "%got_lo(";
++  mips_split_p[SYMBOL_GOTOFF_DISP] = true;
++  mips_hi_relocs[SYMBOL_GOTOFF_DISP] = "%got_hi(";
++  mips_lo_relocs[SYMBOL_GOTOFF_DISP] = "%got_lo(";
 +
-+      mips_split_p[SYMBOL_GOTOFF_CALL] = true;
-+      mips_hi_relocs[SYMBOL_GOTOFF_CALL] = "%call_hi(";
-+      mips_lo_relocs[SYMBOL_GOTOFF_CALL] = "%call_lo(";
++  mips_split_p[SYMBOL_GOTOFF_CALL] = true;
++  mips_hi_relocs[SYMBOL_GOTOFF_CALL] = "%call_hi(";
++  mips_lo_relocs[SYMBOL_GOTOFF_CALL] = "%call_lo(";
 +
-+      mips_split_p[SYMBOL_GOTTPREL] = true;
-+      mips_hi_relocs[SYMBOL_GOTTPREL] = "%gottp_hi(";
-+      mips_lo_relocs[SYMBOL_GOTTPREL] = "%gottp_lo(";
++  mips_split_p[SYMBOL_GOTTPREL] = true;
++  mips_hi_relocs[SYMBOL_GOTTPREL] = "%gottp_hi(";
++  mips_lo_relocs[SYMBOL_GOTTPREL] = "%gottp_lo(";
 +
-+      mips_split_p[SYMBOL_TLSGD] = true;
-+      mips_hi_relocs[SYMBOL_TLSGD] = "%tlsgd_hi(";
-+      mips_lo_relocs[SYMBOL_TLSGD] = "%tlsgd_lo(";
++  mips_split_p[SYMBOL_TLSGD] = true;
++  mips_hi_relocs[SYMBOL_TLSGD] = "%tlsgd_hi(";
++  mips_lo_relocs[SYMBOL_TLSGD] = "%tlsgd_lo(";
 +
-+      mips_split_p[SYMBOL_TLSLDM] = true;
-+      mips_hi_relocs[SYMBOL_TLSLDM] = "%tlsldm_hi(";
-+      mips_lo_relocs[SYMBOL_TLSLDM] = "%tlsldm_lo(";
-+    }
-+  else
-+    {
-+      mips_lo_relocs[SYMBOL_GOTOFF_DISP] = "%got_disp(";
-+      mips_lo_relocs[SYMBOL_GOTOFF_CALL] = "%call16(";
-+      mips_lo_relocs[SYMBOL_GOTTPREL] = "%gottprel(";
-+      mips_lo_relocs[SYMBOL_TLSGD] = "%tlsgd(";
-+      mips_lo_relocs[SYMBOL_TLSLDM] = "%tlsldm(";
-+    }
++  mips_split_p[SYMBOL_TLSLDM] = true;
++  mips_hi_relocs[SYMBOL_TLSLDM] = "%tlsldm_hi(";
++  mips_lo_relocs[SYMBOL_TLSLDM] = "%tlsldm_lo(";
 +
 +  mips_split_p[SYMBOL_GOTOFF_LOADGP] = true;
 +  mips_hi_relocs[SYMBOL_GOTOFF_LOADGP] = "%hi(%neg(%gp_rel(";
@@ -5974,7 +5860,6 @@ index 0000000..45dd285
 +   'T'        Print 'f' for (eq:CC ...), 't' for (ne:CC ...),
 +            'z' for (eq:?I ...), 'n' for (ne:?I ...).
 +   't'        Like 'T', but with the EQ/NE cases reversed
-+   'Y'        Print mips_fp_conditions[INTVAL (OP)]
 +   'Z'        Print OP and a comma for ISA_HAS_8CC, otherwise print nothing.
 +   'D'        Print the second part of a double-word register or memory operand.
 +   'L'        Print the low-order register in a double-word register operand.
@@ -6049,14 +5934,6 @@ index 0000000..45dd285
 +      }
 +      break;
 +
-+    case 'Y':
-+      if (code == CONST_INT && UINTVAL (op) < ARRAY_SIZE (mips_fp_conditions))
-+      fputs (mips_fp_conditions[UINTVAL (op)], file);
-+      else
-+      output_operand_lossage ("'%%%c' is not a valid operand prefix",
-+                              letter);
-+      break;
-+
 +    case 'Z':
 +      mips_print_operand (file, op, 0);
 +      fputc (',', file);
@@ -6167,14 +6044,13 @@ index 0000000..45dd285
 +  rtx offset2 = const0_rtx;
 +  rtx reg = eliminate_constant_term (addr, &offset2);
 +
-+  gcc_assert (reg == stack_pointer_rtx
-+              || reg == frame_pointer_rtx
-+              || reg == hard_frame_pointer_rtx);
-+
 +  if (offset == 0)
 +    offset = INTVAL (offset2);
 +  
-+  offset -= cfun->machine->frame.total_size;
++  if (reg == stack_pointer_rtx)
++    offset -= cfun->machine->frame.total_size;
++  else
++    gcc_assert (reg == frame_pointer_rtx || reg == hard_frame_pointer_rtx);
 +
 +  return offset;
 +}
@@ -6381,23 +6257,6 @@ index 0000000..45dd285
 +    }
 +}
 +#endif
-+\f
-+/* Return the FOO in the name of the ".mdebug.FOO" section associated
-+   with the current ABI.  */
-+
-+static const char *
-+mips_mdebug_abi_name (void)
-+{
-+  switch (mips_abi)
-+    {
-+    case ABI_32:
-+      return "abi32";
-+    case ABI_64:
-+      return "abi64";
-+    default:
-+      gcc_unreachable ();
-+    }
-+}
 +
 +/* Implement TARGET_ASM_FILE_START.  */
 +
@@ -6406,38 +6265,6 @@ index 0000000..45dd285
 +{
 +  default_file_start ();
 +
-+  /* Generate a special section to describe the ABI switches used to
-+     produce the resultant binary.  This is unnecessary on IRIX and
-+     causes unwanted warnings from the native linker.  */
-+  if (!TARGET_IRIX6)
-+    {
-+      /* Record the ABI itself.  Modern versions of binutils encode
-+       this information in the ELF header flags, but GDB needs the
-+       information in order to correctly debug binaries produced by
-+       older binutils.  See the function mips_gdbarch_init in
-+       gdb/mips-tdep.c.  */
-+      fprintf (asm_out_file, "\t.section .mdebug.%s\n\t.previous\n",
-+             mips_mdebug_abi_name ());
-+
-+#ifdef HAVE_AS_GNU_ATTRIBUTE
-+      {
-+      int attr;
-+
-+      /* Soft-float code, -msoft-float.  */
-+      if (!TARGET_HARD_FLOAT_ABI)
-+        attr = 3;
-+      /* 64-bit FP registers on a 32-bit target. */
-+      else if (!TARGET_64BIT)
-+        attr = 4;
-+      /* Regular FP code, FP regs same size as GP regs, -mdouble-float.  */
-+      else
-+        attr = 1;
-+
-+      fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n", attr);
-+      }
-+#endif
-+    }
-+
 +  /* If TARGET_ABICALLS, tell GAS to generate -KPIC code.  */
 +  if (TARGET_ABICALLS)
 +    {
@@ -6470,13 +6297,6 @@ index 0000000..45dd285
 +{
 +  rtx set;
 +
-+  /* If we're saving the return address register and the DWARF return
-+     address column differs from the hard register number, adjust the
-+     note reg to refer to the former.  */
-+  if (REGNO (reg) == RETURN_ADDR_REGNUM
-+      && DWARF_FRAME_RETURN_COLUMN != RETURN_ADDR_REGNUM)
-+    reg = gen_rtx_REG (GET_MODE (reg), DWARF_FRAME_RETURN_COLUMN);
-+
 +  set = gen_rtx_SET (VOIDmode, mem, reg);
 +  RTX_FRAME_RELATED_P (set) = 1;
 +
@@ -6677,32 +6497,28 @@ index 0000000..45dd285
 +      C |  callee-allocated save area   |
 +      |  for register varargs         |
 +      |                               |
++      +-------------------------------+ <-- hard_frame_pointer_rtx;
++      |                               |     stack_pointer_rtx + gp_sp_offset
++      |  GPR save area                |       + UNITS_PER_WORD
++      |                               |
 +      +-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset
-+      |                               |       + UNITS_PER_HWFPVALUE
++      |                               |       + UNITS_PER_HWVALUE
 +      |  FPR save area                |
 +      |                               |
-+      +-------------------------------+ <-- stack_pointer_rtx + gp_sp_offset
-+      |                               |       + UNITS_PER_WORD
-+      |  GPR save area                |
++      +-------------------------------+ <-- frame_pointer_rtx (virtual)
++      |                               |
++      |  local variables              |
++      |                               |
++      P +-------------------------------+
++      |                               |
++      |  outgoing stack arguments     |
++      |                               |
++      +-------------------------------+
++      |                               |
++      |  caller-allocated save area   |
++      |  for register arguments       |
 +      |                               |
-+      +-------------------------------+ <-- frame_pointer_rtx with
-+      |                               | \     -fstack-protector
-+      |  local variables              |  | var_size
-+      |                               | /
-+      P +-------------------------------+ <-- hard_frame_pointer_rtx for
-+      |                               | \     MIPS16 code
-+      |  outgoing stack arguments     |  |
-+      |                               |  |
-+      +-------------------------------+  | args_size
-+      |                               |  |
-+      |  caller-allocated save area   |  |
-+      |  for register arguments       |  |
-+      |                               | /
 +      +-------------------------------+ <-- stack_pointer_rtx
-+                                            frame_pointer_rtx without
-+                                              -fstack-protector
-+                                            hard_frame_pointer_rtx for
-+                                              non-MIPS16 code.
 +
 +   At least two of A, B and C will be empty.
 +
@@ -6714,94 +6530,61 @@ index 0000000..45dd285
 +mips_compute_frame_info (void)
 +{
 +  struct mips_frame_info *frame;
-+  HOST_WIDE_INT offset, size;
++  HOST_WIDE_INT offset;
 +  unsigned int regno, i;
 +
 +  frame = &cfun->machine->frame;
 +  memset (frame, 0, sizeof (*frame));
-+  size = get_frame_size ();
 +
 +  cfun->machine->global_pointer = mips_global_pointer ();
 +
-+  /* The first two blocks contain the outgoing argument area and the $gp save
-+     slot.  This area isn't needed in leaf functions, but if the
-+     target-independent frame size is nonzero, we have already committed to
-+     allocating these in STARTING_FRAME_OFFSET for !FRAME_GROWS_DOWNWARD.  */
-+  if ((size == 0 || FRAME_GROWS_DOWNWARD) && current_function_is_leaf)
-+    {
-+      /* The MIPS 3.0 linker does not like functions that dynamically
-+       allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
-+       looks like we are trying to create a second frame pointer to the
-+       function, so allocate some stack space to make it happy.  */
-+      if (cfun->calls_alloca)
-+      frame->args_size = REG_PARM_STACK_SPACE (cfun->decl);
-+      else
-+      frame->args_size = 0;
-+    }
-+  else
-+    {
-+      frame->args_size = crtl->outgoing_args_size;
-+    }
-+  offset = frame->args_size;
-+
-+  /* Move above the local variables.  */
-+  frame->var_size = MIPS_STACK_ALIGN (size);
-+  offset += frame->var_size;
-+
 +  /* Find out which GPRs we need to save.  */
 +  for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
 +    if (mips_save_reg_p (regno))
-+      {
-+      frame->num_gp++;
-+      frame->mask |= 1 << (regno - GP_REG_FIRST);
-+      }
++      frame->mask |= 1 << (regno - GP_REG_FIRST);
 +
 +  /* If this function calls eh_return, we must also save and restore the
 +     EH data registers.  */
 +  if (crtl->calls_eh_return)
 +    for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; i++)
-+      {
-+      frame->num_gp++;
-+      frame->mask |= 1 << (EH_RETURN_DATA_REGNO (i) - GP_REG_FIRST);
-+      }
-+
-+  /* Move above the GPR save area.  */
-+  if (frame->num_gp > 0)
-+    {
-+      offset += MIPS_STACK_ALIGN (frame->num_gp * UNITS_PER_WORD);
-+      frame->gp_sp_offset = offset - UNITS_PER_WORD;
-+    }
++      frame->mask |= 1 << (EH_RETURN_DATA_REGNO (i) - GP_REG_FIRST);
 +
 +  /* Find out which FPRs we need to save.  This loop must iterate over
 +     the same space as its companion in mips_for_each_saved_gpr_and_fpr.  */
 +  if (TARGET_HARD_FLOAT)
 +    for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
 +      if (mips_save_reg_p (regno))
-+      {
-+        frame->num_fp++;
-+        frame->fmask |= 1 << (regno - FP_REG_FIRST);
-+      }
-+
-+  /* Move above the FPR save area.  */
-+  if (frame->num_fp > 0)
-+    {
-+      offset += MIPS_STACK_ALIGN (frame->num_fp * UNITS_PER_FPREG);
++        frame->fmask |= 1 << (regno - FP_REG_FIRST);
++
++  /* At the bottom of the frame are any outgoing stack arguments. */
++  offset = crtl->outgoing_args_size;
++  /* Next are local stack variables. */
++  offset += MIPS_STACK_ALIGN (get_frame_size ());
++  /* The virtual frame pointer points above the local variables. */
++  frame->frame_pointer_offset = offset;
++  /* Next are the callee-saved FPRs. */
++  if (frame->fmask)
++    {
++      unsigned num_saved = __builtin_popcount(frame->fmask);
++      offset += MIPS_STACK_ALIGN (num_saved * UNITS_PER_FPREG);
 +      frame->fp_sp_offset = offset - UNITS_PER_HWFPVALUE;
 +    }
-+
-+  /* Move above the callee-allocated varargs save area.  */
++  /* Next are the callee-saved GPRs. */
++  if (frame->mask)
++    {
++      unsigned num_saved = __builtin_popcount(frame->mask);
++      offset += MIPS_STACK_ALIGN (num_saved * UNITS_PER_WORD);
++      frame->gp_sp_offset = offset - UNITS_PER_WORD;
++    }
++  /* The hard frame pointer points above the callee-saved GPRs. */
++  frame->hard_frame_pointer_offset = offset;
++  /* Above the hard frame pointer is the callee-allocated varags save area. */
 +  offset += MIPS_STACK_ALIGN (cfun->machine->varargs_size);
 +  frame->arg_pointer_offset = offset;
-+
-+  /* Move above the callee-allocated area for pretend stack arguments.  */
++  /* Next is the callee-allocated area for pretend stack arguments.  */
 +  offset += crtl->args.pretend_args_size;
 +  frame->total_size = offset;
-+
-+  /* Work out the offsets of the save areas from the top of the frame.  */
-+  if (frame->gp_sp_offset > 0)
-+    frame->gp_save_offset = frame->gp_sp_offset - offset;
-+  if (frame->fp_sp_offset > 0)
-+    frame->fp_save_offset = frame->fp_sp_offset - offset;
++  /* Next points the incoming stack pointer and any incoming arguments. */
 +}
 +
 +/* Return the style of GP load sequence that is being used for the
@@ -6819,14 +6602,6 @@ index 0000000..45dd285
 +  return LOADGP_NEWABI;
 +}
 +
-+/* Implement TARGET_FRAME_POINTER_REQUIRED.  */
-+
-+static bool
-+mips_frame_pointer_required (void)
-+{
-+  return cfun->calls_alloca;
-+}
-+
 +/* Make sure that we're not trying to eliminate to the wrong hard frame
 +   pointer.  */
 +
@@ -6841,32 +6616,27 @@ index 0000000..45dd285
 +   pointer.  */
 +
 +HOST_WIDE_INT
-+mips_initial_elimination_offset (int from)
++mips_initial_elimination_offset (int from, int to)
 +{
-+  HOST_WIDE_INT offset;
++  HOST_WIDE_INT src, dest;
 +
 +  mips_compute_frame_info ();
 +
-+  /* Set OFFSET to the offset from the end-of-prologue stack pointer.  */
-+  switch (from)
-+    {
-+    case FRAME_POINTER_REGNUM:
-+      if (FRAME_GROWS_DOWNWARD)
-+      offset = (cfun->machine->frame.args_size
-+                + cfun->machine->frame.var_size);
-+      else
-+      offset = 0;
-+      break;
-+
-+    case ARG_POINTER_REGNUM:
-+      offset = cfun->machine->frame.arg_pointer_offset;
-+      break;
++  if (to == HARD_FRAME_POINTER_REGNUM)
++    dest = cfun->machine->frame.hard_frame_pointer_offset;
++  else if (to == STACK_POINTER_REGNUM)
++    dest = 0; /* this is the base of all offsets */
++  else
++    gcc_unreachable ();
 +
-+    default:
-+      gcc_unreachable ();
-+    }
++  if (from == FRAME_POINTER_REGNUM)
++    src = cfun->machine->frame.frame_pointer_offset;
++  else if (from == ARG_POINTER_REGNUM)
++    src = cfun->machine->frame.arg_pointer_offset;
++  else
++    gcc_unreachable ();
 +
-+  return offset;
++  return src - dest;
 +}
 +
 +/* Implement TARGET_EXTRA_LIVE_ON_ENTRY.  */
@@ -6942,27 +6712,31 @@ index 0000000..45dd285
 +  HOST_WIDE_INT offset;
 +  int regno;
 +
-+  /* Save registers starting from high to low.  The debuggers prefer at least
-+     the return register be stored at func+4, and also it allows us not to
-+     need a nop in the epilogue if at least one register is reloaded in
-+     addition to return address.  */
++  /* Save the return address at the top of the frame. */
 +  offset = cfun->machine->frame.gp_sp_offset - sp_offset;
-+  for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
-+    if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
-+      {
-+      mips_save_restore_reg (word_mode, regno, offset, fn);
-+      offset -= UNITS_PER_WORD;
-+      }
++  if (BITSET_P (cfun->machine->frame.mask, LINK_REG))
++    {
++      mips_save_restore_reg (word_mode, LINK_REG + GP_REG_FIRST, offset, fn);
++      offset -= UNITS_PER_WORD;
++    }
++
++  /* Save the s-registers in reverse order. */
++  for (regno = GP_REG_NUM-1; regno >= 0; regno--, regno -= (regno == LINK_REG))
++    {
++      if (BITSET_P (cfun->machine->frame.mask, regno))
++        {
++          mips_save_restore_reg (word_mode, regno + GP_REG_FIRST, offset, fn);
++          offset -= UNITS_PER_WORD;
++        }
++    }
 +
 +  /* This loop must iterate over the same space as its companion in
 +     mips_compute_frame_info.  */
 +  offset = cfun->machine->frame.fp_sp_offset - sp_offset;
-+  for (regno = FP_REG_LAST - 1;
-+       regno >= FP_REG_FIRST;
-+       regno --)
-+    if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
++  for (regno = FP_REG_NUM-1; regno >= 0; regno--)
++    if (BITSET_P (cfun->machine->frame.fmask, regno))
 +      {
-+      mips_save_restore_reg (DFmode, regno, offset, fn);
++      mips_save_restore_reg (DFmode, regno + FP_REG_FIRST, offset, fn);
 +      offset -= GET_MODE_SIZE (DFmode);
 +      }
 +}
@@ -7026,51 +6800,19 @@ index 0000000..45dd285
 +/* Implement TARGET_OUTPUT_FUNCTION_PROLOGUE.  */
 +
 +static void
-+mips_output_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
++mips_output_function_prologue (FILE *file ATTRIBUTE_UNUSED,
++                               HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 +{
 +  const char *fnname;
 +
-+#ifdef SDB_DEBUGGING_INFO
-+  if (debug_info_level != DINFO_LEVEL_TERSE && write_symbols == SDB_DEBUG)
-+    SDB_OUTPUT_SOURCE_LINE (file, DECL_SOURCE_LINE (current_function_decl));
-+#endif
-+
 +  /* Get the function name the same way that toplev.c does before calling
 +     assemble_start_function.  This is needed so that the name used here
 +     exactly matches the name used in ASM_DECLARE_FUNCTION_NAME.  */
 +  fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
-+  mips_start_function_definition (fnname);
-+
-+  /* Output MIPS-specific frame information.  */
-+  if (!flag_inhibit_size_directive)
-+    {
-+      const struct mips_frame_info *frame;
-+
-+      frame = &cfun->machine->frame;
-+
-+      /* .frame FRAMEREG, FRAMESIZE, RETREG.  */
-+      fprintf (file,
-+             "\t.frame\t%s," HOST_WIDE_INT_PRINT_DEC ",%s\t\t"
-+             "# vars= " HOST_WIDE_INT_PRINT_DEC
-+             ", regs= %d/%d"
-+             ", args= " HOST_WIDE_INT_PRINT_DEC "\n",
-+             reg_names[frame_pointer_needed
-+                       ? HARD_FRAME_POINTER_REGNUM
-+                       : STACK_POINTER_REGNUM],
-+             frame->total_size,
-+             reg_names[RETURN_ADDR_REGNUM],
-+             frame->var_size,
-+             frame->num_gp, frame->num_fp,
-+             frame->args_size);
 +
-+      /* .mask MASK, OFFSET.  */
-+      fprintf (file, "\t.mask\t0x%08x," HOST_WIDE_INT_PRINT_DEC "\n",
-+             frame->mask, frame->gp_save_offset);
-+
-+      /* .fmask MASK, OFFSET.  */
-+      fprintf (file, "\t.fmask\t0x%08x," HOST_WIDE_INT_PRINT_DEC "\n",
-+             frame->fmask, frame->fp_save_offset);
-+    }
++  ASM_OUTPUT_TYPE_DIRECTIVE (asm_out_file, fnname, "function");
++  assemble_name (asm_out_file, fnname);
++  fputs (":\n", asm_out_file);
 +}
 +
 +/* Implement TARGET_OUTPUT_FUNCTION_EPILOGUE.  */
@@ -7079,18 +6821,10 @@ index 0000000..45dd285
 +mips_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
 +                             HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 +{
-+  const char *fnname;
-+
 +  /* Reinstate the normal $gp.  */
 +  SET_REGNO (pic_offset_table_rtx, GLOBAL_POINTER_REGNUM);
-+
-+  /* Get the function name the same way that toplev.c does before calling
-+     assemble_start_function.  This is needed so that the name used here
-+     exactly matches the name used in ASM_DECLARE_FUNCTION_NAME.  */
-+  fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
-+  mips_end_function_definition (fnname);
 +}
-+\f
++
 +/* Save register REG to MEM.  Make the instruction frame-related.  */
 +
 +static void
@@ -7181,6 +6915,14 @@ index 0000000..45dd285
 +      mips_for_each_saved_gpr_and_fpr (size, mips_save_reg);
 +    }
 +
++  /* Set up the frame pointer, if we're using one.  */
++  if (frame_pointer_needed)
++    {
++      insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
++                            GEN_INT (frame->hard_frame_pointer_offset - size));
++      RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
++    }
++
 +  /* Allocate the rest of the frame.  */
 +  if (size > 0)
 +    {
@@ -7202,13 +6944,6 @@ index 0000000..45dd285
 +      }
 +    }
 +
-+  /* Set up the frame pointer, if we're using one.  */
-+  if (frame_pointer_needed)
-+    {
-+      insn = mips_emit_move (hard_frame_pointer_rtx, stack_pointer_rtx);
-+      RTX_FRAME_RELATED_P (insn) = 1;
-+    }
-+
 +  mips_emit_loadgp ();
 +}
 +\f
@@ -7230,7 +6965,6 @@ index 0000000..45dd285
 +{
 +  const struct mips_frame_info *frame;
 +  HOST_WIDE_INT step1, step2;
-+  rtx base, target;
 +
 +  if (!sibcall_p && mips_can_use_return_insn ())
 +    {
@@ -7250,6 +6984,19 @@ index 0000000..45dd285
 +  step1 = frame->total_size;
 +  step2 = 0;
 +
++  /* Move past any dynamic stack allocations. */
++  if (cfun->calls_alloca)
++    {
++      rtx adjust = GEN_INT (-frame->hard_frame_pointer_offset);
++      if (!SMALL_INT (adjust))
++      {
++        mips_emit_move (MIPS_EPILOGUE_TEMP (Pmode), adjust);
++        adjust = MIPS_EPILOGUE_TEMP (Pmode);
++      }
++
++      emit_insn (gen_add3_insn (stack_pointer_rtx, hard_frame_pointer_rtx, adjust));
++    }
++
 +  /* If we need to restore registers, deallocate as much stack as
 +     possible in the second step without going out of range.  */
 +  if ((frame->mask | frame->fmask) != 0)
@@ -7259,48 +7006,32 @@ index 0000000..45dd285
 +    }
 +
 +  /* Set TARGET to BASE + STEP1.  */
-+  base = frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx;
-+  target = base;
 +  if (step1 > 0)
 +    {
-+      rtx adjust;
-+
 +      /* Get an rtx for STEP1 that we can add to BASE.  */
-+      adjust = GEN_INT (step1);
++      rtx adjust = GEN_INT (step1);
 +      if (!SMALL_OPERAND (step1))
 +      {
 +        mips_emit_move (MIPS_EPILOGUE_TEMP (Pmode), adjust);
 +        adjust = MIPS_EPILOGUE_TEMP (Pmode);
 +      }
 +
-+      /* Normal mode code can copy the result straight into $sp.  */
-+      target = stack_pointer_rtx;
-+
-+      emit_insn (gen_add3_insn (target, base, adjust));
++      emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, adjust));
 +    }
 +
-+  /* Copy TARGET into the stack pointer.  */
-+  if (target != stack_pointer_rtx)
-+    mips_emit_move (stack_pointer_rtx, target);
-+
 +  /* Restore the registers.  */
-+  mips_for_each_saved_gpr_and_fpr (frame->total_size - step2,
-+                     mips_restore_reg);
++  mips_for_each_saved_gpr_and_fpr (frame->total_size - step2, mips_restore_reg);
 +
-+        /* Deallocate the final bit of the frame.  */
++  /* Deallocate the final bit of the frame.  */
 +  if (step2 > 0)
-+    emit_insn (gen_add3_insn (stack_pointer_rtx,
-+                            stack_pointer_rtx,
++    emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
 +                            GEN_INT (step2)));
 +
 +  /* Add in the __builtin_eh_return stack adjustment.  We need to
 +     use a temporary in MIPS16 code.  */
 +  if (crtl->calls_eh_return)
-+    {
-+      emit_insn (gen_add3_insn (stack_pointer_rtx,
-+                              stack_pointer_rtx,
-+                              EH_RETURN_STACKADJ_RTX));
-+    }
++    emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
++                            EH_RETURN_STACKADJ_RTX));
 +
 +  if (!sibcall_p)
 +    emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM)));
@@ -7777,8 +7508,7 @@ index 0000000..45dd285
 +{
 +  switch (mips_tune)
 +    {
-+    case PROCESSOR_ROCKET32:
-+    case PROCESSOR_ROCKET64:
++    case PROCESSOR_ROCKET:
 +      return 1;
 +
 +    default:
@@ -7792,9 +7522,6 @@ index 0000000..45dd285
 +     for more information.  */
 +  enum insn_code icode;
 +
-+  /* The floating-point comparison code to use with ICODE, if any.  */
-+  enum mips_fp_condition cond;
-+
 +  /* The name of the built-in function.  */
 +  const char *name;
 +
@@ -7835,23 +7562,21 @@ index 0000000..45dd285
 +
 +   AVAIL is the name of the availability predicate, without the leading
 +   mips_builtin_avail_.  */
-+#define MIPS_BUILTIN(INSN, COND, NAME, BUILTIN_TYPE,                  \
-+                   FUNCTION_TYPE, AVAIL)                              \
-+  { CODE_FOR_mips_ ## INSN, MIPS_FP_COND_ ## COND,                    \
-+    "__builtin_mips_" NAME, BUILTIN_TYPE, FUNCTION_TYPE,              \
-+    mips_builtin_avail_ ## AVAIL }
++#define MIPS_BUILTIN(INSN, NAME, BUILTIN_TYPE, FUNCTION_TYPE, AVAIL)  \
++  { CODE_FOR_mips_ ## INSN, "__builtin_mips_" NAME,                   \
++    BUILTIN_TYPE, FUNCTION_TYPE, mips_builtin_avail_ ## AVAIL }
 +
 +/* Define __builtin_mips_<INSN>, which is a MIPS_BUILTIN_DIRECT function
 +   mapped to instruction CODE_FOR_mips_<INSN>,  FUNCTION_TYPE and AVAIL
 +   are as for MIPS_BUILTIN.  */
 +#define DIRECT_BUILTIN(INSN, FUNCTION_TYPE, AVAIL)                    \
-+  MIPS_BUILTIN (INSN, f, #INSN, MIPS_BUILTIN_DIRECT, FUNCTION_TYPE, AVAIL)
++  MIPS_BUILTIN (INSN, #INSN, MIPS_BUILTIN_DIRECT, FUNCTION_TYPE, AVAIL)
 +
 +/* Define __builtin_mips_<INSN>, which is a MIPS_BUILTIN_DIRECT_NO_TARGET
 +   function mapped to instruction CODE_FOR_mips_<INSN>,  FUNCTION_TYPE
 +   and AVAIL are as for MIPS_BUILTIN.  */
 +#define DIRECT_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE, AVAIL)          \
-+  MIPS_BUILTIN (INSN, f, #INSN,       MIPS_BUILTIN_DIRECT_NO_TARGET,          \
++  MIPS_BUILTIN (INSN, #INSN, MIPS_BUILTIN_DIRECT_NO_TARGET,           \
 +              FUNCTION_TYPE, AVAIL)
 +
 +static const struct mips_builtin_description mips_builtins[] = {
@@ -8437,17 +8162,9 @@ index 0000000..45dd285
 +mips_set_current_function (tree fndecl)
 +{
 +  bool utfunc = fndecl && (lookup_attribute("utfunc", DECL_ATTRIBUTES(fndecl)) != NULL);
-+
-+  if (!riscv_in_utfunc && utfunc)
-+  {
-+    riscv_in_utfunc = true;
++  if (riscv_in_utfunc != utfunc)
 +    reinit_regs();
-+  }
-+  else if (riscv_in_utfunc && !utfunc)
-+  {
-+    riscv_in_utfunc = false;
-+    reinit_regs();
-+  }
++  riscv_in_utfunc = utfunc;
 +}
 +
 +/* Allocate a chunk of memory for per-function machine-dependent data.  */
@@ -8458,68 +8175,6 @@ index 0000000..45dd285
 +  return ggc_alloc_cleared_machine_function ();
 +}
 +
-+/* Return the processor associated with the given ISA level, or null
-+   if the ISA isn't valid.  */
-+
-+static const struct mips_cpu_info *
-+mips_cpu_info_from_isa (int isa)
-+{
-+  unsigned int i;
-+
-+  for (i = 0; i < ARRAY_SIZE (mips_cpu_info_table); i++)
-+    if (mips_cpu_info_table[i].isa == isa)
-+      return mips_cpu_info_table + i;
-+
-+  return NULL;
-+}
-+
-+/* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL
-+   with a final "000" replaced by "k".  Ignore case.
-+
-+   Note: this function is shared between GCC and GAS.  */
-+
-+static bool
-+mips_strict_matching_cpu_name_p (const char *canonical, const char *given)
-+{
-+  while (*given != 0 && TOLOWER (*given) == TOLOWER (*canonical))
-+    given++, canonical++;
-+
-+  return ((*given == 0 && *canonical == 0)
-+        || (strcmp (canonical, "000") == 0 && strcasecmp (given, "k") == 0));
-+}
-+
-+/* Return true if GIVEN matches CANONICAL, where GIVEN is a user-supplied
-+   CPU name.  We've traditionally allowed a lot of variation here.
-+
-+   Note: this function is shared between GCC and GAS.  */
-+
-+static bool
-+mips_matching_cpu_name_p (const char *canonical, const char *given)
-+{
-+  /* First see if the name matches exactly, or with a final "000"
-+     turned into "k".  */
-+  if (mips_strict_matching_cpu_name_p (canonical, given))
-+    return true;
-+
-+  /* If not, try comparing based on numerical designation alone.
-+     See if GIVEN is an unadorned number, or 'r' followed by a number.  */
-+  if (TOLOWER (*given) == 'r')
-+    given++;
-+  if (!ISDIGIT (*given))
-+    return false;
-+
-+  /* Skip over some well-known prefixes in the canonical name,
-+     hoping to find a number there too.  */
-+  if (TOLOWER (canonical[0]) == 'v' && TOLOWER (canonical[1]) == 'r')
-+    canonical += 2;
-+  else if (TOLOWER (canonical[0]) == 'r' && TOLOWER (canonical[1]) == 'm')
-+    canonical += 2;
-+  else if (TOLOWER (canonical[0]) == 'r')
-+    canonical += 1;
-+
-+  return mips_strict_matching_cpu_name_p (canonical, given);
-+}
-+
 +/* Return the mips_cpu_info entry for the processor or ISA given
 +   by CPU_STRING.  Return null if the string isn't recognized.
 +
@@ -8529,53 +8184,14 @@ index 0000000..45dd285
 +mips_parse_cpu (const char *cpu_string)
 +{
 +  unsigned int i;
-+  const char *s;
-+
-+  /* In the past, we allowed upper-case CPU names, but it doesn't
-+     work well with the multilib machinery.  */
-+  for (s = cpu_string; *s != 0; s++)
-+    if (ISUPPER (*s))
-+      {
-+      warning (0, "CPU names must be lower case");
-+      break;
-+      }
-+
-+  /* 'from-abi' selects the most compatible architecture for the given
-+     ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs.  For the
-+     EABIs, we have to decide whether we're using the 32-bit or 64-bit
-+     version.  */
-+  if (strcasecmp (cpu_string, "from-abi") == 0)
-+    return mips_cpu_info_from_isa (TARGET_64BIT ? ISA_RV32 : ISA_RV64);
 +
 +  for (i = 0; i < ARRAY_SIZE (mips_cpu_info_table); i++)
-+    if (mips_matching_cpu_name_p (mips_cpu_info_table[i].name, cpu_string))
++    if (strcmp (mips_cpu_info_table[i].name, cpu_string) == 0)
 +      return mips_cpu_info_table + i;
 +
 +  return NULL;
 +}
 +
-+/* Set up globals to generate code for the ISA or processor
-+   described by INFO.  */
-+
-+static void
-+mips_set_architecture (const struct mips_cpu_info *info)
-+{
-+  if (info != 0)
-+    {
-+      mips_tune = mips_arch = info->cpu;
-+      mips_isa = info->isa;
-+    }
-+}
-+
-+/* Likewise for tuning.  */
-+
-+static void
-+mips_set_tune (const struct mips_cpu_info *info)
-+{
-+  if (info != 0)
-+    mips_tune = info->cpu;
-+}
-+
 +/* Implement TARGET_HANDLE_OPTION.  */
 +
 +static bool
@@ -8592,7 +8208,6 @@ index 0000000..45dd285
 +      return false;
 +      return true;
 +
-+    case OPT_march_:
 +    case OPT_mtune_:
 +      return mips_parse_cpu (arg) != 0;
 +
@@ -8607,28 +8222,22 @@ index 0000000..45dd285
 +mips_option_override (void)
 +{
 +  int i, start, regno, mode;
-+  const struct mips_cpu_info *info = 0;
++  const struct mips_cpu_info *info;
 +
 +#ifdef SUBTARGET_OVERRIDE_OPTIONS
 +  SUBTARGET_OVERRIDE_OPTIONS;
 +#endif
 +
-+  /* The following code determines the architecture and register size.
-+     Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()).
-+     The GAS and GCC code should be kept in sync as much as possible.  */
-+
-+  if (mips_arch_string != 0)
-+    info = mips_parse_cpu (mips_arch_string);
-+  if (info == 0)
-+    info = mips_parse_cpu (MIPS_CPU_STRING_DEFAULT);
++  info = mips_parse_cpu (MIPS_CPU_STRING_DEFAULT);
 +  gcc_assert (info);
-+  mips_set_architecture (info);
++  mips_tune = info->cpu;
 +
-+  /* Optimize for mips_arch, unless -mtune selects a different processor.  */
 +  if (mips_tune_string != 0)
-+    mips_set_tune (mips_parse_cpu (mips_tune_string));
-+
-+  /* End of code shared with GAS.  */
++    {
++      const struct mips_cpu_info *tune = mips_parse_cpu (mips_tune_string);
++      if (tune)
++      mips_tune = tune->cpu;
++    }
 +
 +  flag_pcc_struct_return = 0;
 +
@@ -9106,9 +8715,6 @@ index 0000000..45dd285
 +#undef TARGET_LEGITIMATE_ADDRESS_P
 +#define TARGET_LEGITIMATE_ADDRESS_P   mips_legitimate_address_p
 +
-+#undef TARGET_FRAME_POINTER_REQUIRED
-+#define TARGET_FRAME_POINTER_REQUIRED mips_frame_pointer_required
-+
 +#undef TARGET_CAN_ELIMINATE
 +#define TARGET_CAN_ELIMINATE mips_can_eliminate
 +
@@ -9129,10 +8735,10 @@ index 0000000..45dd285
 +#include "gt-riscv.h"
 diff --git a/gcc-4.6.1/gcc/config/riscv/riscv.h b/gcc-4.6.1/gcc/config/riscv/riscv.h
 new file mode 100644
-index 0000000..0416dc8
+index 0000000..2c52f88
 --- /dev/null
 +++ gcc-4.6.1/gcc/config/riscv/riscv.h
-@@ -0,0 +1,1758 @@
+@@ -0,0 +1,1721 @@
 +/* Definitions of target machine for GNU compiler.  MIPS version.
 +   Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
 +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
@@ -9187,9 +8793,6 @@ index 0000000..0416dc8
 +     difference between them from GCC's point of view.  */
 +  enum processor cpu;
 +
-+  /* The ISA level that the processor implements.  */
-+  int isa;
-+
 +  /* A mask of PTF_* values.  */
 +  unsigned int tune_flags;
 +};
@@ -9222,9 +8825,6 @@ index 0000000..0416dc8
 +#define TARGET_HARD_FLOAT TARGET_HARD_FLOAT_ABI
 +#define TARGET_SOFT_FLOAT TARGET_SOFT_FLOAT_ABI
 +
-+/* IRIX specific stuff.  */
-+#define TARGET_IRIX6     0
-+
 +/* Target CPU builtins.  */
 +#define TARGET_CPU_CPP_BUILTINS()                                     \
 +  do                                                                  \
@@ -9323,9 +8923,8 @@ index 0000000..0416dc8
 +#define TARGET_ENDIAN_DEFAULT 0
 +#endif
 +
-+/* 'from-abi' makes a good default: you get whatever the ABI requires.  */
 +#ifndef MIPS_CPU_STRING_DEFAULT
-+#define MIPS_CPU_STRING_DEFAULT "from-abi"
++#define MIPS_CPU_STRING_DEFAULT "rocket"
 +#endif
 +
 +#define TARGET_LIBGCC_SDATA_SECTION ".sdata"
@@ -9409,14 +9008,8 @@ index 0000000..0416dc8
 +     |march=octeon|march=xlr: -msoft-float;             \
 +     march=*: -mhard-float}"
 +
-+/* A spec condition that matches 32-bit options.  It only works if
-+   MIPS_ISA_LEVEL_SPEC has been applied.  */
-+
-+#define MIPS_32BIT_OPTION_SPEC \
-+  "mips1|mips2|mips32*|mgp32"
-+
-+#define OPT_ARCH64 "mabi=32|mgp32:;"
-+#define OPT_ARCH32 "mabi=32|mgp32"
++#define OPT_ARCH64 "mabi=32:;"
++#define OPT_ARCH32 "mabi=32"
 +
 +/* Support for a compile-time default CPU, et cetera.  The rules are:
 +   --with-arch is ignored if -march is specified or a -mips is specified
@@ -9484,7 +9077,7 @@ index 0000000..0416dc8
 +%(subtarget_asm_optimizing_spec) \
 +%(subtarget_asm_debugging_spec) \
 +%{mabi=*} %{!mabi=*: %(asm_abi_default_spec)} \
-+%{mgp32} %{mgp64} %{march=*} \
++%{march=*} \
 +%{mshared} %{mno-shared} \
 +%{mtune=*} \
 +%(subtarget_asm_spec)"
@@ -9562,20 +9155,8 @@ index 0000000..0416dc8
 +/* By default, turn on GDB extensions.  */
 +#define DEFAULT_GDB_EXTENSIONS 1
 +
-+/* Local compiler-generated symbols must have a prefix that the assembler
-+   understands.   By default, this is $, although some targets (e.g.,
-+   NetBSD-ELF) need to override this.  */
-+
-+#ifndef LOCAL_LABEL_PREFIX
-+#define LOCAL_LABEL_PREFIX    "$"
-+#endif
-+
-+/* By default on the mips, external symbols do not have an underscore
-+   prepended, but some targets (e.g., NetBSD) require this.  */
-+
-+#ifndef USER_LABEL_PREFIX
++#define LOCAL_LABEL_PREFIX    "."
 +#define USER_LABEL_PREFIX     ""
-+#endif
 +
 +/* On Sun 4, this limit is 2048.  We use 1500 to be safe,
 +   since the length can run past this up to a continuation point.  */
@@ -9591,6 +9172,10 @@ index 0000000..0416dc8
 +/* The DWARF 2 CFA column which tracks the return address.  */
 +#define DWARF_FRAME_RETURN_COLUMN RETURN_ADDR_REGNUM
 +
++/* Don't emit .cfi_sections, as it does not work */
++#undef HAVE_GAS_CFI_SECTIONS_DIRECTIVE
++#define HAVE_GAS_CFI_SECTIONS_DIRECTIVE 0
++
 +/* Before the prologue, RA lives in r31.  */
 +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, RETURN_ADDR_REGNUM)
 +
@@ -10198,19 +9783,9 @@ index 0000000..0416dc8
 +
 +#define STACK_GROWS_DOWNWARD
 +
-+#define FRAME_GROWS_DOWNWARD flag_stack_protect
-+
-+/* Size of the area allocated in the frame to save the GP.  */
-+
-+#define MIPS_GP_SAVE_AREA_SIZE 0
-+
-+/* The offset of the first local variable from the frame pointer.  See
-+   mips_compute_frame_info for details about the frame layout.  */
++#define FRAME_GROWS_DOWNWARD 1
 +
-+#define STARTING_FRAME_OFFSET                         \
-+  (FRAME_GROWS_DOWNWARD                                       \
-+   ? 0                                                        \
-+   : crtl->outgoing_args_size + MIPS_GP_SAVE_AREA_SIZE)
++#define STARTING_FRAME_OFFSET 0
 +
 +#define RETURN_ADDR_RTX mips_return_addr
 +
@@ -10229,7 +9804,7 @@ index 0000000..0416dc8
 + { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}                          \
 +
 +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-+  (OFFSET) = mips_initial_elimination_offset (FROM)
++  (OFFSET) = mips_initial_elimination_offset (FROM, TO)
 +
 +/* Allocate stack space for arguments at the beginning of each function.  */
 +#define ACCUMULATE_OUTGOING_ARGS 1
@@ -10337,10 +9912,8 @@ index 0000000..0416dc8
 +\f
 +#define EPILOGUE_USES(REGNO)  mips_epilogue_uses (REGNO)
 +
-+/* Treat LOC as a byte offset from the stack pointer and round it up
-+   to the next fully-aligned offset.  */
-+#define MIPS_STACK_ALIGN(LOC) \
-+  (TARGET_64BIT ? ((LOC) + 15) & -16 : ((LOC) + 7) & -8)
++/* Even on RV32, provide 8-byte alignment for 64b floats. */
++#define MIPS_STACK_ALIGN(LOC) (((LOC) + 7) & -8)
 +
 +/* No mips port has ever used the profiler counter word, so don't emit it
 +   or the label for it.  */
@@ -10593,10 +10166,6 @@ index 0000000..0416dc8
 +  dbxout_stab_value_internal_label ("LM", &COUNTER);          \
 +} while (0)
 +
-+/* Use .loc directives for SDB line numbers.  */
-+#define SDB_OUTPUT_SOURCE_LINE(STREAM, LINE)                  \
-+  fprintf (STREAM, "\t.loc\t%d %d\n", num_source_filenames, LINE)
-+
 +/* The MIPS implementation uses some labels for its own purpose.  The
 +   following lists what labels are created, and are all formed by the
 +   pattern $L[a-z].*.  The machine independent portion of GCC creates
@@ -10893,10 +10462,10 @@ index 0000000..0416dc8
 +#define SWITCHABLE_TARGET 1
 diff --git a/gcc-4.6.1/gcc/config/riscv/riscv.md b/gcc-4.6.1/gcc/config/riscv/riscv.md
 new file mode 100644
-index 0000000..cd5e619
+index 0000000..216153d
 --- /dev/null
 +++ gcc-4.6.1/gcc/config/riscv/riscv.md
-@@ -0,0 +1,3048 @@
+@@ -0,0 +1,3042 @@
 +;;  Mips.md        Machine Description for MIPS based processors
 +;;  Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
 +;;  1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
@@ -10923,8 +10492,7 @@ index 0000000..cd5e619
 +;; <http://www.gnu.org/licenses/>.
 +
 +(define_enum "processor" [
-+  rocket32
-+  rocket64
++  rocket
 +])
 +
 +(define_c_enum "unspec" [
@@ -11089,7 +10657,7 @@ index 0000000..cd5e619
 +;; imadd      integer multiply-add
 +;; idiv               integer divide 2 operands
 +;; idiv3      integer divide 3 operands
-+;; move               integer register move ({,D}ADD{,U} with rt = 0)
++;; move               integer register move (addi rd, rs1, 0)
 +;; fmove      floating point register move
 +;; fadd               floating point add/subtract
 +;; fmul               floating point multiply
@@ -11301,6 +10869,7 @@ index 0000000..cd5e619
 +
 +;; Likewise the 64-bit truncate-and-shift patterns.
 +(define_mode_iterator SUBDI [QI HI SI])
++(define_mode_iterator HISI [HI SI])
 +
 +;; This mode iterator allows :ANYF to be used wherever a scalar or vector
 +;; floating-point mode is allowed.
@@ -11662,18 +11231,17 @@ index 0000000..cd5e619
 +  [(set_attr "type" "arith")
 +   (set_attr "mode" "SI")])
 +
-+;; this is used for generating HImode constants.
-+;; see comments in mips_move_integer().
-+(define_insn "bullshit_addsihi"
-+  [(set (match_operand:HI 0 "register_operand" "=d")
-+      (plus:HI (match_operand:SI 1 "register_operand" "d")
-+                     (match_operand:SI 2 "const_arith_operand" "I")))]
-+  "0"
-+{
-+  return TARGET_64BIT ? "addw\t%0,%1,%2" : "add\t%0,%1,%2";
-+}
++;; HImode constant generation; see mips_move_integer for details.
++;; si+si->hi without truncation is legal because of TRULY_NOOP_TRUNCATION.
++
++(define_insn "add<mode>hi3"
++  [(set (match_operand:HI 0 "register_operand" "=d,d")
++      (plus:HI (match_operand:HISI 1 "register_operand" "d,d")
++                (match_operand:HISI 2 "arith_operand" "d,Q")))]
++  ""
++  { return TARGET_64BIT ? "addw\t%0,%1,%2" : "add\t%0,%1,%2"; }
 +  [(set_attr "type" "arith")
-+   (set_attr "mode" "SI")])
++   (set_attr "mode" "HI")])
 +
 +;;
 +;;  ....................
@@ -12034,74 +11602,74 @@ index 0000000..cd5e619
 +
 +;; Floating point multiply accumulate instructions.
 +
-+(define_insn "*madd4<mode>"
++(define_insn "fma<mode>4"
 +  [(set (match_operand:ANYF 0 "register_operand" "=f")
-+      (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
-+                            (match_operand:ANYF 2 "register_operand" "f"))
-+                 (match_operand:ANYF 3 "register_operand" "f")))]
-+  "TARGET_HARD_FLOAT
-+   && !HONOR_NANS (<MODE>mode)"
++    (fma:ANYF
++      (match_operand:ANYF 1 "register_operand" "f")
++      (match_operand:ANYF 2 "register_operand" "f")
++      (match_operand:ANYF 3 "register_operand" "f")))]
++  "TARGET_HARD_FLOAT"
 +  "fmadd.<fmt>\t%0,%1,%2,%3"
 +  [(set_attr "type" "fmadd")
 +   (set_attr "mode" "<UNITMODE>")])
 +
-+(define_insn "*msub4<mode>"
++(define_insn "fms<mode>4"
 +  [(set (match_operand:ANYF 0 "register_operand" "=f")
-+      (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
-+                             (match_operand:ANYF 2 "register_operand" "f"))
-+                  (match_operand:ANYF 3 "register_operand" "f")))]
-+  "TARGET_HARD_FLOAT
-+   && !HONOR_NANS (<MODE>mode)"
++    (fma:ANYF
++      (match_operand:ANYF 1 "register_operand" "f")
++      (match_operand:ANYF 2 "register_operand" "f")
++      (neg:ANYF (match_operand:ANYF 3 "register_operand" "f"))))]
++  "TARGET_HARD_FLOAT"
 +  "fmsub.<fmt>\t%0,%1,%2,%3"
 +  [(set_attr "type" "fmadd")
 +   (set_attr "mode" "<UNITMODE>")])
 +
-+(define_insn "*nmadd4<mode>"
++(define_insn "nfma<mode>4"
 +  [(set (match_operand:ANYF 0 "register_operand" "=f")
-+      (neg:ANYF (plus:ANYF
-+                 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
-+                            (match_operand:ANYF 2 "register_operand" "f"))
-+                 (match_operand:ANYF 3 "register_operand" "f"))))]
-+  "TARGET_HARD_FLOAT
-+   && !HONOR_NANS (<MODE>mode)"
++    (neg:ANYF
++      (fma:ANYF
++        (match_operand:ANYF 1 "register_operand" "f")
++        (match_operand:ANYF 2 "register_operand" "f")
++        (match_operand:ANYF 3 "register_operand" "f"))))]
++  "TARGET_HARD_FLOAT"
 +  "fnmadd.<fmt>\t%0,%1,%2,%3"
 +  [(set_attr "type" "fmadd")
 +   (set_attr "mode" "<UNITMODE>")])
 +
-+(define_insn "*nmadd4<mode>_fastmath"
++(define_insn "nfms<mode>4"
 +  [(set (match_operand:ANYF 0 "register_operand" "=f")
-+      (minus:ANYF
-+       (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
-+                  (match_operand:ANYF 2 "register_operand" "f"))
-+       (match_operand:ANYF 3 "register_operand" "f")))]
-+  "TARGET_HARD_FLOAT
-+   && !HONOR_SIGNED_ZEROS (<MODE>mode)
-+   && !HONOR_NANS (<MODE>mode)"
-+  "fnmadd.<fmt>\t%0,%1,%2,%3"
++    (neg:ANYF
++      (fma:ANYF
++        (match_operand:ANYF 1 "register_operand" "f")
++        (match_operand:ANYF 2 "register_operand" "f")
++        (neg:ANYF (match_operand:ANYF 3 "register_operand" "f")))))]
++  "TARGET_HARD_FLOAT"
++  "fnmsub.<fmt>\t%0,%1,%2,%3"
 +  [(set_attr "type" "fmadd")
 +   (set_attr "mode" "<UNITMODE>")])
 +
-+(define_insn "*nmsub4<mode>"
++;; modulo signed zeros, -(a*b+c) == -c-a*b
++(define_insn "*nfma<mode>4_fastmath"
 +  [(set (match_operand:ANYF 0 "register_operand" "=f")
-+      (neg:ANYF (minus:ANYF
-+                 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
-+                            (match_operand:ANYF 3 "register_operand" "f"))
-+                 (match_operand:ANYF 1 "register_operand" "f"))))]
-+  "TARGET_HARD_FLOAT
-+   && !HONOR_NANS (<MODE>mode)"
-+  "fnmsub.<fmt>\t%0,%1,%2,%3"
++    (minus:ANYF
++      (match_operand:ANYF 3 "register_operand" "f")
++      (mult:ANYF
++        (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
++        (match_operand:ANYF 2 "register_operand" "f"))))]
++  "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
++  "fnmadd.<fmt>\t%0,%1,%2,%3"
 +  [(set_attr "type" "fmadd")
 +   (set_attr "mode" "<UNITMODE>")])
 +
-+(define_insn "*nmsub4<mode>_fastmath"
++;; modulo signed zeros, -(a*b-c) == c-a*b
++(define_insn "*nfms<mode>4_fastmath"
 +  [(set (match_operand:ANYF 0 "register_operand" "=f")
-+      (minus:ANYF
-+       (match_operand:ANYF 1 "register_operand" "f")
-+       (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
-+                  (match_operand:ANYF 3 "register_operand" "f"))))]
-+  "TARGET_HARD_FLOAT
-+   && !HONOR_SIGNED_ZEROS (<MODE>mode)
-+   && !HONOR_NANS (<MODE>mode)"
++    (minus:ANYF
++      (match_operand:ANYF 3 "register_operand" "f")
++      (mult:ANYF
++        (match_operand:ANYF 1 "register_operand" "f")
++        (match_operand:ANYF 2 "register_operand" "f"))))]
++  "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
 +  "fnmsub.<fmt>\t%0,%1,%2,%3"
 +  [(set_attr "type" "fmadd")
 +   (set_attr "mode" "<UNITMODE>")])
@@ -12723,7 +12291,7 @@ index 0000000..cd5e619
 +(define_insn_and_split "*xgot_hi<mode>"
 +  [(set (match_operand:P 0 "register_operand" "=d")
 +      (high:P (match_operand:P 1 "got_disp_operand" "")))]
-+  "TARGET_XGOT"
++  ""
 +  "#"
 +  "&& reload_completed"
 +  [(set (match_dup 0) (high:P (match_dup 2)))
@@ -12739,7 +12307,7 @@ index 0000000..cd5e619
 +  [(set (match_operand:P 0 "register_operand" "=d")
 +      (lo_sum:P (match_operand:P 1 "register_operand" "d")
 +                (match_operand:P 2 "got_disp_operand" "")))]
-+  "TARGET_XGOT"
++  ""
 +  "#"
 +  "&& reload_completed"
 +  [(set (match_dup 0)
@@ -12844,13 +12412,13 @@ index 0000000..cd5e619
 +   (set_attr "mode" "DI")])
 +
 +(define_insn "*movdi_64bit"
-+  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*d,*m")
-+      (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*d*J,*m,*f,*f"))]
++  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*f,*f,*d,*m")
++      (match_operand:DI 1 "move_operand" "d,T,m,dJ,*d*J,*m,*f,*f"))]
 +  "TARGET_64BIT
 +   && (register_operand (operands[0], DImode)
 +       || reg_or_0_operand (operands[1], DImode))"
 +  { return mips_output_move (operands[0], operands[1]); }
-+  [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore")
++  [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
 +   (set_attr "mode" "DI")])
 +
 +;; 32-bit Integer moves
@@ -12872,12 +12440,12 @@ index 0000000..cd5e619
 +;; in FP registers (off by default, use -mdebugh to enable).
 +
 +(define_insn "*mov<mode>_internal"
-+  [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*d,*m,*d,*z")
-+      (match_operand:IMOVE32 1 "move_operand" "d,U,T,m,dJ,*d*J,*m,*f,*f,*z,*d"))]
++  [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=d,d,d,m,*f,*f,*d,*m,*d,*z")
++      (match_operand:IMOVE32 1 "move_operand" "d,T,m,dJ,*d*J,*m,*f,*f,*z,*d"))]
 +  "(register_operand (operands[0], <MODE>mode)
 +    || reg_or_0_operand (operands[1], <MODE>mode))"
 +  { return mips_output_move (operands[0], operands[1]); }
-+  [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mfc,mtc")
++  [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore,mfc,mtc")
 +   (set_attr "mode" "SI")])
 +
 +;; 16-bit Integer moves
@@ -12898,7 +12466,7 @@ index 0000000..cd5e619
 +
 +(define_insn "*movhi_internal"
 +  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m")
-+      (match_operand:HI 1 "move_operand"         "d,Z,m,dJ"))]
++      (match_operand:HI 1 "move_operand"         "d,T,m,dJ"))]
 +  "(register_operand (operands[0], HImode)
 +    || reg_or_0_operand (operands[1], HImode))"
 +  { return mips_output_move (operands[0], operands[1]); }
@@ -12907,11 +12475,6 @@ index 0000000..cd5e619
 +
 +;; 8-bit Integer moves
 +
-+;; Unlike most other insns, the move insns can't be split with '
-+;; different predicates, because register spilling and other parts of
-+;; the compiler, have memoized the insn number already.
-+;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
-+
 +(define_expand "movqi"
 +  [(set (match_operand:QI 0 "")
 +      (match_operand:QI 1 ""))]
@@ -13947,10 +13510,10 @@ index 0000000..cd5e619
 +])
 diff --git a/gcc-4.6.1/gcc/config/riscv/riscv.opt b/gcc-4.6.1/gcc/config/riscv/riscv.opt
 new file mode 100644
-index 0000000..dee2dbf
+index 0000000..291fe75
 --- /dev/null
 +++ gcc-4.6.1/gcc/config/riscv/riscv.opt
-@@ -0,0 +1,77 @@
+@@ -0,0 +1,69 @@
 +; Options for the MIPS port of the compiler
 +;
 +; Copyright (C) 2005, 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
@@ -13985,10 +13548,6 @@ index 0000000..dee2dbf
 +Target Report Mask(ABICALLS)
 +Generate code that can be used in SVR4-style dynamic objects
 +
-+march=
-+Target RejectNegative Joined Var(mips_arch_string)
-+-march=ISA    Generate code for the given ISA
-+
 +mbranch-cost=
 +Target RejectNegative Joined UInteger Var(mips_branch_cost)
 +-mbranch-cost=COST    Set the cost of branches to roughly COST instructions
@@ -14024,10 +13583,6 @@ index 0000000..dee2dbf
 +mtune=
 +Target RejectNegative Joined Var(mips_tune_string)
 +-mtune=PROCESSOR      Optimize the output for PROCESSOR
-+
-+mxgot
-+Target Report Var(TARGET_XGOT) Init(1)
-+Lift restrictions on GOT size
 diff --git a/gcc-4.6.1/gcc/config/riscv/ros.h b/gcc-4.6.1/gcc/config/riscv/ros.h
 new file mode 100644
 index 0000000..593fbc5
@@ -14322,6 +13877,26 @@ index 9a81754..773b270 100644
  
        if (VECTOR_MODE_P (to_mode))
        from = simplify_gen_subreg (to_mode, from, GET_MODE (from), 0);
+diff --git a/gcc-4.6.1/gcc/gengtype.c b/gcc-4.6.1/gcc/gengtype.c
+index abf17f8..6c0ca4a 100644
+--- a/gcc-4.6.1/gcc/gengtype.c
++++ gcc-4.6.1/gcc/gengtype.c
+@@ -3594,14 +3594,13 @@ write_field_root (outf_p f, pair_p v, type_p type, const char *name,
+                 int has_length, struct fileloc *line, const char *if_marked,
+                 bool emit_pch, type_p field_type, const char *field_name)
+ {
++  struct pair newv;
+   /* If the field reference is relative to V, rather than to some
+      subcomponent of V, we can mark any subarrays with a single stride.
+      We're effectively treating the field as a global variable in its
+      own right.  */
+   if (v && type == v->type)
+     {
+-      struct pair newv;
+-
+       newv = *v;
+       newv.type = field_type;
+       newv.name = ACONCAT ((v->name, ".", field_name, NULL));
 diff --git a/gcc-4.6.1/gcc/genmodes.c b/gcc-4.6.1/gcc/genmodes.c
 index dae7e38..df3db0e 100644
 --- a/gcc-4.6.1/gcc/genmodes.c
index f088313..1e92876 100644 (file)
@@ -1873,10 +1873,10 @@ index 0000000..4090efe
 +}
 diff --git a/glibc-2.14.1/sysdeps/riscv/dl-machine.h b/glibc-2.14.1/sysdeps/riscv/dl-machine.h
 new file mode 100644
-index 0000000..830c199
+index 0000000..e442496
 --- /dev/null
 +++ glibc-2.14.1/sysdeps/riscv/dl-machine.h
-@@ -0,0 +1,735 @@
+@@ -0,0 +1,733 @@
 +/* Machine-dependent ELF dynamic relocation inline functions.  MIPS version.
 +   Copyright (C) 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007
 +   Free Software Foundation, Inc.
@@ -1916,14 +1916,12 @@ index 0000000..830c199
 +#ifndef _RTLD_PROLOGUE
 +# define _RTLD_PROLOGUE(entry)                                                \
 +      ".globl\t" __STRING(entry) "\n\t"                               \
-+      ".ent\t" __STRING(entry) "\n\t"                                 \
 +      ".type\t" __STRING(entry) ", @function\n"                       \
 +      __STRING(entry) ":\n\t"
 +#endif
 +
 +#ifndef _RTLD_EPILOGUE
 +# define _RTLD_EPILOGUE(entry)                                                \
-+      ".end\t" __STRING(entry) "\n\t"                                 \
 +      ".size\t" __STRING(entry) ", . - " __STRING(entry) "\n\t"
 +#endif
 +
@@ -2669,10 +2667,10 @@ index 0000000..69d3893
 +#define TLS_DTV_UNALLOCATED   ((void *) -1l)
 diff --git a/glibc-2.14.1/sysdeps/riscv/dl-trampoline.c b/glibc-2.14.1/sysdeps/riscv/dl-trampoline.c
 new file mode 100644
-index 0000000..8baad99
+index 0000000..136a116
 --- /dev/null
 +++ glibc-2.14.1/sysdeps/riscv/dl-trampoline.c
-@@ -0,0 +1,295 @@
+@@ -0,0 +1,289 @@
 +/* PLT trampoline.  MIPS version.
 +   Copyright (C) 1996-2001, 2002, 2003, 2004, 2005
 +   Free Software Foundation, Inc.
@@ -2903,9 +2901,7 @@ index 0000000..8baad99
 +      .align  2\n\
 +      .globl  _dl_runtime_resolve\n\
 +      .type   _dl_runtime_resolve,@function\n\
-+      .ent    _dl_runtime_resolve\n\
 +_dl_runtime_resolve:\n\
-+      .frame  sp, " STRINGXP(ELF_DL_FRAME_SIZE) ", ra\n\
 +      " STRINGXV(SETUP_GP64(t4, _dl_runtime_resolve)) "\n\
 +      # Save arguments and sp value in stack.\n\
 +      addi  sp, sp, " STRINGXP(-ELF_DL_FRAME_SIZE) "\n\
@@ -2921,7 +2917,6 @@ index 0000000..8baad99
 +      move    t7, v0\n\
 +      addi    sp, sp, " STRINGXP(ELF_DL_FRAME_SIZE) "\n\
 +      jr      t7\n\
-+      .end    _dl_runtime_resolve\n\
 +      .previous\n\
 +");
 +
@@ -2949,9 +2944,7 @@ index 0000000..8baad99
 +      .align  2\n\
 +      .globl  _dl_runtime_pltresolve\n\
 +      .type   _dl_runtime_pltresolve,@function\n\
-+      .ent    _dl_runtime_pltresolve\n\
 +_dl_runtime_pltresolve:\n\
-+      .frame  sp, " STRINGXP(ELF_DL_PLT_FRAME_SIZE) ", ra\n\
 +      " STRINGXV(SETUP_GP64(t4, _dl_runtime_pltresolve)) "\n\
 +      # Save arguments and sp value in stack.\n\
 +1:    addi    sp, sp, " STRINGXP(-ELF_DL_PLT_FRAME_SIZE) "\n\
@@ -2964,7 +2957,6 @@ index 0000000..8baad99
 +      " ELF_DL_PLT_RESTORE_ARG_REGS "\
 +      addi    sp, sp, " STRINGXP(ELF_DL_PLT_FRAME_SIZE) "\n\
 +      jr      t7\n\
-+      .end    _dl_runtime_pltresolve\n\
 +      .previous\n\
 +");
 +
@@ -7915,10 +7907,10 @@ index 0000000..7a5e3e0
 +#endif        /* stackinfo.h */
 diff --git a/glibc-2.14.1/sysdeps/riscv/sys/asm.h b/glibc-2.14.1/sysdeps/riscv/sys/asm.h
 new file mode 100644
-index 0000000..331a16e
+index 0000000..7d91b86
 --- /dev/null
 +++ glibc-2.14.1/sysdeps/riscv/sys/asm.h
-@@ -0,0 +1,206 @@
+@@ -0,0 +1,199 @@
 +/* Copyright (C) 1997, 1998, 2002, 2003, 2004, 2005
 +   Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
@@ -8025,25 +8017,18 @@ index 0000000..331a16e
 +              .globl  symbol;                         \
 +              .align  2;                              \
 +              .type   symbol,@function;               \
-+              .ent    symbol,0;                       \
 +symbol:
 +
 +/*
 + * NESTED - declare nested routine entry point
 + */
-+#define       NESTED(symbol, framesize, rpc)                  \
-+              .globl  symbol;                         \
-+              .align  2;                              \
-+              .type   symbol,@function;               \
-+              .ent    symbol,0;                       \
-+symbol:               .frame  sp, framesize, rpc
++#define       NESTED(symbol, framesize, rpc) LEAF(symbol)
 +
 +/*
 + * END - mark end of function
 + */
 +#ifndef END
 +# define END(function)                                   \
-+              .end    function;                       \
 +              .size   function,.-function
 +#endif
 +
@@ -8485,10 +8470,10 @@ index 0000000..74e7197
 +}
 diff --git a/glibc-2.14.1/sysdeps/unix/riscv/sysdep.h b/glibc-2.14.1/sysdeps/unix/riscv/sysdep.h
 new file mode 100644
-index 0000000..52e47c4
+index 0000000..15079d8
 --- /dev/null
 +++ glibc-2.14.1/sysdeps/unix/riscv/sysdep.h
-@@ -0,0 +1,73 @@
+@@ -0,0 +1,72 @@
 +/* Copyright (C) 1992, 1995, 1997, 1999, 2000, 2002, 2003, 2004
 +   Free Software Foundation, Inc.
 +   This file is part of the GNU C Library.
@@ -8519,13 +8504,12 @@ index 0000000..52e47c4
 +
 +#undef END
 +#define       END(function)                                   \
-+              .end    function;                       \
 +              .size   function,.-function
 +
 +#define ret   ret
 +
 +#undef PSEUDO_END
-+#define PSEUDO_END(sym) .end sym; .size sym,.-sym
++#define PSEUDO_END(sym) .size sym,.-sym
 +
 +#define PSEUDO_NOERRNO(name, syscall_name, args)      \
 +  .align 2;                                           \
@@ -8534,7 +8518,7 @@ index 0000000..52e47c4
 +  syscall
 +
 +#undef PSEUDO_END_NOERRNO
-+#define PSEUDO_END_NOERRNO(sym) .end sym; .size sym,.-sym
++#define PSEUDO_END_NOERRNO(sym) .size sym,.-sym
 +
 +#define ret_NOERRNO ret
 +
@@ -13130,7 +13114,7 @@ index 0000000..51923be
 +#include <sysdeps/unix/sysv/linux/riscv/vfork.S>
 diff --git a/glibc-2.14.1/sysdeps/unix/sysv/linux/riscv/nptl/sysdep-cancel.h b/glibc-2.14.1/sysdeps/unix/sysv/linux/riscv/nptl/sysdep-cancel.h
 new file mode 100644
-index 0000000..00ea8c2
+index 0000000..8f638f6
 --- /dev/null
 +++ glibc-2.14.1/sysdeps/unix/sysv/linux/riscv/nptl/sysdep-cancel.h
 @@ -0,0 +1,161 @@
@@ -13217,7 +13201,7 @@ index 0000000..00ea8c2
 +
 +
 +  # undef PSEUDO_END
-+  # define PSEUDO_END(sym) cfi_endproc; .end sym; .size sym,.-sym
++  # define PSEUDO_END(sym) cfi_endproc; .size sym,.-sym
 +
 +  #endif
 +