Little endian fix
authorMichael Meissner <gnu@the-meissners.org>
Tue, 16 May 1995 23:30:21 +0000 (23:30 +0000)
committerMichael Meissner <gnu@the-meissners.org>
Tue, 16 May 1995 23:30:21 +0000 (23:30 +0000)
gas/ChangeLog
gas/config/tc-ppc.c

index 2808236a00371e00af57d129b6af66ea858572ff..090f7d32d13e7766d3c102025fce7591fd21eeda 100644 (file)
@@ -1,3 +1,9 @@
+Wed May 17 00:59:12 1995  Andrew Cagney - aka Noid  <cagney@highland.com.au>
+
+       * config/tc-ppc.c (md_begin): Was assuming that an instruction was
+       bigendian and hence 16bit relocs withing instructions would
+        ALWAYS be at addresses i+2-i+3.  In LE mode it is i+0-i+1.
+
 Tue May 16 16:29:58 1995  Ken Raeburn  <raeburn@cujo.cygnus.com>
 
        * config/obj-multi.h (obj_frob_symbol, obj_frob_file, S_GET_SIZE,
index 09c997bd10e67e76f55cc27c3ab972efa7f9449e..ee03182a45c5dca99be986027d237b2258dc591f 100644 (file)
@@ -62,7 +62,7 @@ static void ppc_toc PARAMS ((int));
 #ifdef OBJ_ELF
 static bfd_reloc_code_real_type ppc_elf_suffix PARAMS ((char **));
 static void ppc_elf_cons PARAMS ((int));
-static void ppc_elf_validate_fix (fixS *, segT);
+static void ppc_elf_validate_fix PARAMS ((fixS *, segT));
 #endif
 \f
 /* Generic assembler global variables which must be defined by all
@@ -138,9 +138,6 @@ static int ppc_cpu = 0;
    PPC_OPCODE_32 or PPC_OPCODE_64.  */
 static int ppc_size = PPC_OPCODE_32;
 
-/* The endianness we are using.  */
-static int ppc_big_endian = PPC_BIG_ENDIAN;
-
 /* Opcode hash table.  */
 static struct hash_control *ppc_hash;
 
@@ -266,14 +263,22 @@ md_parse_option (c, arg)
       /* -many means to assemble for any architecture (PWR/PWRX/PPC).  */
       else if (strcmp (arg, "any") == 0)
        ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_PPC;
+
 #ifdef OBJ_ELF
       /* -mrelocatable -- warn about initializations that require relocation */
       else if (strcmp (arg, "relocatable") == 0)
        mrelocatable = true;
+
+      /* -mlittle/-mbig set the endianess */
+      else if (strcmp (arg, "little") == 0 || strcmp (arg, "little-endian") == 0)
+       target_big_endian = 0;
+
+      else if (strcmp (arg, "big") == 0 || strcmp (arg, "big-endian") == 0)
+       target_big_endian = 1;
 #endif
       else
        {
-         as_bad ("invalid architecture -m%s", arg);
+         as_bad ("invalid switch -m%s", arg);
          return 0;
        }
       break;
@@ -304,15 +309,19 @@ md_show_usage (stream)
   fprintf(stream, "\
 PowerPC options:\n\
 -u                     ignored\n\
--mpwrx                 generate code for IBM POWER/2 (RIOS2)\n\
+-mpwrx, -mpwr2         generate code for IBM POWER/2 (RIOS2)\n\
 -mpwr                  generate code for IBM POWER (RIOS1)\n\
 -m601                  generate code for Motorola PowerPC 601\n\
 -mppc, -mppc32, -m403, -m603, -m604\n\
                        generate code for Motorola PowerPC 603/604\n\
+-mppc64, -m620         generate code for Motorola PowerPC 620\n\
 -many                  generate code for any architecture (PWR/PWRX/PPC)\n");
 #ifdef OBJ_ELF
   fprintf(stream, "\
--mrelocatable          warn incompatible with GCC's -mrelocatble option\n\
+-mrelocatable          support for GCC's -mrelocatble option\n\
+-mlittle, -mlittle-endian\n\
+                       generate code for a little endian machine\n
+-mbig, -mbig-endian    generate code for a big endian machine\n
 -V                     print assembler version number\n\
 -Qy, -Qn               ignored\n");
 #endif
@@ -329,10 +338,11 @@ ppc_set_cpu ()
     {
       if (strcmp (default_cpu, "rs6000") == 0)
        ppc_cpu = PPC_OPCODE_POWER;
-      else if (strcmp (default_cpu, "powerpc") == 0)
+      else if (strcmp (default_cpu, "powerpc") == 0
+              || strcmp (default_cpu, "powerpcle") == 0)
        ppc_cpu = PPC_OPCODE_PPC;
       else
-       abort ();
+       as_fatal ("Unknown default cpu = %s", default_cpu);
     }
 }
 
@@ -348,7 +358,7 @@ ppc_arch ()
   else if ((ppc_cpu & PPC_OPCODE_POWER) != 0)
     return bfd_arch_rs6000;
   else
-    abort ();
+    as_fatal ("Neither Power nor PowerPC opcodes were selected.");
 }
 
 /* This function is called when the assembler starts up.  It is called
@@ -427,7 +437,7 @@ md_begin ()
     }
 
   /* Tell the main code what the endianness is.  */
-  target_big_endian = ppc_big_endian;
+  target_big_endian = PPC_BIG_ENDIAN;
 
 #ifdef OBJ_COFF
   ppc_coff_debug_section = coff_section_from_bfd_index (stdoutput, N_DEBUG);
@@ -586,7 +596,9 @@ ppc_elf_cons (nbytes)
 
 /* Validate any relocations emitted for -mrelocatable */
 static void
-ppc_elf_validate_fix (fixS *fixp, segT seg)
+ppc_elf_validate_fix (fixp, seg)
+     fixS *fixp;
+     segT seg;
 {
   if (mrelocatable
       && !fixp->fx_done
@@ -831,10 +843,11 @@ md_assemble (str)
   md_number_to_chars (f, insn, 4);
 
   /* Create any fixups.  At this point we do not use a
-     bfd_reloc_code_real_type, but instead just use the operand index.
-     This lets us easily handle fixups for any operand type, although
-     that is admittedly not a very exciting feature.  We pick a BFD
-     reloc type in md_apply_fix.  */
+     bfd_reloc_code_real_type, but instead just use the
+     BFD_RELOC_UNUSED plus the operand index.  This lets us easily
+     handle fixups for any operand type, although that is admittedly
+     not a very exciting feature.  We pick a BFD reloc type in
+     md_apply_fix.  */
   for (i = 0; i < fc; i++)
     {
       const struct powerpc_operand *operand;
@@ -843,12 +856,13 @@ md_assemble (str)
       if (fixups[i].reloc != BFD_RELOC_UNUSED)
        {
          reloc_howto_type *reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
-         int offset = (!reloc_howto) ? 0 : (4 - bfd_get_reloc_size (reloc_howto));
+         int size = (!reloc_howto) ? 0 : bfd_get_reloc_size (reloc_howto);
+         int offset = target_big_endian ? (4 - size) : 0;
 
-         if (offset < 0)
-           offset = 0;
+         if (size > 4)
+           abort();
 
-         fix_new_exp (frag_now, f - frag_now->fr_literal + offset, 4 - offset,
+         fix_new_exp (frag_now, f - frag_now->fr_literal + offset, size,
                       &fixups[i].exp, (reloc_howto && reloc_howto->pc_relative),
                       fixups[i].reloc);
        }
@@ -2317,7 +2331,7 @@ md_atof (type, litp, sizep)
 
   *sizep = prec * 2;
 
-  if (ppc_big_endian)
+  if (target_big_endian)
     {
       for (i = 0; i < prec; i++)
        {
@@ -2346,7 +2360,7 @@ md_number_to_chars (buf, val, n)
      valueT val;
      int n;
 {
-  if (ppc_big_endian)
+  if (target_big_endian)
     number_to_chars_bigendian (buf, val, n);
   else
     number_to_chars_littleendian (buf, val, n);
@@ -2609,13 +2623,13 @@ md_apply_fix3 (fixp, valuep, seg)
       /* Fetch the instruction, insert the fully resolved operand
         value, and stuff the instruction back again.  */
       where = fixp->fx_frag->fr_literal + fixp->fx_where;
-      if (ppc_big_endian)
+      if (target_big_endian)
        insn = bfd_getb32 ((unsigned char *) where);
       else
        insn = bfd_getl32 ((unsigned char *) where);
       insn = ppc_insert_operand (insn, operand, (offsetT) value,
                                 fixp->fx_file, fixp->fx_line);
-      if (ppc_big_endian)
+      if (target_big_endian)
        bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
       else
        bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
@@ -2649,7 +2663,7 @@ md_apply_fix3 (fixp, valuep, seg)
               && ppc_is_toc_sym (fixp->fx_addsy))
        {
          fixp->fx_size = 2;
-         if (ppc_big_endian)
+         if (target_big_endian)
            fixp->fx_where += 2;
          fixp->fx_r_type = BFD_RELOC_PPC_TOC16;
        }