OSDN Git Service

Add CRX insns: pushx, popx
authorNick Clifton <nickc@redhat.com>
Tue, 27 Jul 2004 11:37:12 +0000 (11:37 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 27 Jul 2004 11:37:12 +0000 (11:37 +0000)
Add support to GAS for expressions which are the difference of two symbols

bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf32-crx.c
bfd/reloc.c
include/elf/ChangeLog
include/elf/crx.h
opcodes/ChangeLog
opcodes/crx-opc.c

index 3b7a2d5..9ea9258 100644 (file)
@@ -1,3 +1,11 @@
+2004-07-27  Tomer Levi  <Tomer.Levi@nsc.com>
+
+       * reloc.c: Add BFD_RELOC_CRX_SWITCH8, BFD_RELOC_CRX_SWITCH16,
+       BFD_RELOC_CRX_SWITCH32.
+       * bfd-in2.h: Regenerate.
+       * elf32-crx.c: Support relocation/relaxation of
+       BFD_RELOC_CRX_SWITCH* types.
+
 2004-07-27  Alan Modra  <amodra@bigpond.net.au>
 
        * elf64-ppc.c: Correct "Linker stubs" comment.
index f661889..b6d14ff 100644 (file)
@@ -3463,6 +3463,9 @@ This is the 5 bits of a value.  */
   BFD_RELOC_CRX_NUM32,
   BFD_RELOC_CRX_IMM16,
   BFD_RELOC_CRX_IMM32,
+  BFD_RELOC_CRX_SWITCH8,
+  BFD_RELOC_CRX_SWITCH16,
+  BFD_RELOC_CRX_SWITCH32,
 
 /* These relocs are only used within the CRIS assembler.  They are not
 (at present) written to any object files.  */
index 03575f2..79b9c64 100644 (file)
@@ -77,7 +77,10 @@ static const struct crx_reloc_map crx_reloc_map[R_CRX_MAX] =
   {BFD_RELOC_CRX_NUM16,            R_CRX_NUM16},
   {BFD_RELOC_CRX_NUM32,            R_CRX_NUM32},
   {BFD_RELOC_CRX_IMM16,            R_CRX_IMM16},
-  {BFD_RELOC_CRX_IMM32,            R_CRX_IMM32}
+  {BFD_RELOC_CRX_IMM32,            R_CRX_IMM32},
+  {BFD_RELOC_CRX_SWITCH8,   R_CRX_SWITCH8},
+  {BFD_RELOC_CRX_SWITCH16,  R_CRX_SWITCH16},
+  {BFD_RELOC_CRX_SWITCH32,  R_CRX_SWITCH32}
 };
 
 static reloc_howto_type crx_elf_howto_table[] =
@@ -332,7 +335,58 @@ static reloc_howto_type crx_elf_howto_table[] =
         FALSE,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE)                 /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
+  /* An 8 bit switch table entry.  This is generated for an expression
+     such as ``.byte L1 - L2''.  The offset holds the difference
+     between the reloc address and L2.  */
+  HOWTO (R_CRX_SWITCH8,                /* type */
+        0,                     /* rightshift */
+        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        8,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_SWITCH8",       /* name */
+        FALSE,                 /* partial_inplace */
+        0xff,                  /* src_mask */
+        0xff,                  /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+
+  /* A 16 bit switch table entry.  This is generated for an expression
+     such as ``.word L1 - L2''.  The offset holds the difference
+     between the reloc address and L2.  */
+  HOWTO (R_CRX_SWITCH16,       /* type */
+        0,                     /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_SWITCH16",      /* name */
+        FALSE,                 /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+
+  /* A 32 bit switch table entry.  This is generated for an expression
+     such as ``.long L1 - L2''.  The offset holds the difference
+     between the reloc address and L2.  */
+  HOWTO (R_CRX_SWITCH32,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_SWITCH32",      /* name */
+        FALSE,                 /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        TRUE)                  /* pcrel_offset */
 };
 
 /* Retrieve a howto ptr using a BFD reloc_code.  */
@@ -406,6 +460,13 @@ crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
        return bfd_reloc_ok;
        break;
 
+     case R_CRX_SWITCH8:
+     case R_CRX_SWITCH16:
+     case R_CRX_SWITCH32:
+       /* We only care about the addend, where the difference between 
+         expressions is kept.  */
+       Rvalue = 0;
+       
      default:
        break;
     }
@@ -483,7 +544,7 @@ crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
         Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) |
                      bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask);
 
-       if (r_type == R_CRX_NUM32)
+       if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32)
         /* Relocation on DATA is purely little-endian, that is, for a
            multi-byte datum, the lowest address in memory contains the
            little end of the datum, that is, the least significant byte.
@@ -562,7 +623,40 @@ elf32_crx_relax_delete_bytes (bfd *abfd, asection *sec,
       if (isym->st_shndx == sec_shndx
          && isym->st_value > addr
          && isym->st_value < toaddr)
-       isym->st_value -= count;
+       {
+         /* Adjust the addend of SWITCH relocations in this section, 
+            which reference this local symbol.  */
+         for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+           {
+             unsigned long r_symndx;
+             Elf_Internal_Sym *rsym;
+             bfd_vma addsym, subsym;
+
+             /* Skip if not a SWITCH relocation.  */
+             if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8
+                 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16
+                 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32)
+                 continue;
+
+             r_symndx = ELF32_R_SYM (irel->r_info);
+             rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
+
+             /* Skip if not the local adjusted symbol.  */
+             if (rsym != isym)
+               continue;
+
+             addsym = isym->st_value;
+             subsym = addsym - irel->r_addend;
+
+             /* Fix the addend only when -->> (addsym > addr >= subsym).  */
+             if (subsym <= addr)
+               irel->r_addend -= count;
+             else
+               continue;
+           }
+
+         isym->st_value -= count;
+       }
     }
 
   /* Now adjust the global symbols defined in this section.  */
index e8279d2..b997437 100644 (file)
@@ -3888,6 +3888,12 @@ ENUMX
   BFD_RELOC_CRX_IMM16
 ENUMX
   BFD_RELOC_CRX_IMM32
+ENUMX
+  BFD_RELOC_CRX_SWITCH8
+ENUMX
+  BFD_RELOC_CRX_SWITCH16
+ENUMX
+  BFD_RELOC_CRX_SWITCH32
 ENUMDOC 
   NS CRX Relocations.
 
index 5563ddb..4080885 100644 (file)
@@ -1,3 +1,8 @@
+2004-07-27  Tomer Levi  <Tomer.Levi@nsc.com>
+
+       * crx.h: Add BFD_RELOC_CRX_SWITCH8, BFD_RELOC_CRX_SWITCH16,
+       BFD_RELOC_CRX_SWITCH32.
+
 2004-07-06  Tomer Levi  <Tomer.Levi@nsc.com>
 
        * common.h (EM_CRX): Define.
index 755a610..33ba005 100644 (file)
@@ -45,6 +45,9 @@ START_RELOC_NUMBERS(elf_crx_reloc_type)
   RELOC_NUMBER (R_CRX_NUM32,          15)
   RELOC_NUMBER (R_CRX_IMM16,         16)
   RELOC_NUMBER (R_CRX_IMM32,         17)
+  RELOC_NUMBER (R_CRX_SWITCH8,       18)
+  RELOC_NUMBER (R_CRX_SWITCH16,              19)
+  RELOC_NUMBER (R_CRX_SWITCH32,              20)
 END_RELOC_NUMBERS(R_CRX_MAX)
        
 #endif /* _ELF_CRX_H */
index 159f6d0..5cdcfc8 100644 (file)
@@ -1,3 +1,7 @@
+2004-07-27  Tomer Levi  <Tomer.Levi@nsc.com>
+
+       * crx-opc.c: Add popx,pushx insns. Indent code, fix comments.
+
 2004-07-22  Nick Clifton  <nickc@redhat.com>
 
        PR/280
index da1e322..1a6b313 100644 (file)
@@ -357,7 +357,7 @@ const inst crx_instruction[] =
   /* opc12 r rbase ridx scl2 disps22 */                                                         \
   {NAME,  3, 0x33C+OPC1,  20, LD_STOR_INS | REVERSE_MATCH, {{rbase_ridx_scl2_dispu22,0}, {regr,16}}}
 
-  LD_REG_INST ("loadb", 0x0, 0x0,   DISPUB4),
+  LD_REG_INST ("loadb", 0x0, 0x0, DISPUB4),
   LD_REG_INST ("loadw", 0x1, 0x1, DISPUW4),
   LD_REG_INST ("loadd", 0x2, 0x2, DISPUD4),
 
@@ -439,42 +439,44 @@ const inst crx_instruction[] =
   CSTBIT_INST ("cbitw", i4, 0x382, 0x10, 20, 0xBD),
   CSTBIT_INST ("cbitd", i5, 0x1C3, 0x8,  21, 0x7B),
   {"cbitd",   2, 0x300838,  8, CSTBIT_INS, {{regr,4}, {regr,0}}},
-  {"cbitd",   2, 0x18047B,  9, CSTBIT_INS, {{i5,4},     {regr,0}}},
+  {"cbitd",   2, 0x18047B,  9, CSTBIT_INS, {{i5,4}, {regr,0}}},
 
   CSTBIT_INST ("sbitb", i3, 0x701, 0x20, 19, 0x1FD),
   CSTBIT_INST ("sbitw", i4, 0x383, 0x10, 20, 0xBE),
   CSTBIT_INST ("sbitd", i5, 0x1C4, 0x8,  21, 0x7C),
   {"sbitd",   2, 0x300839,  8, CSTBIT_INS, {{regr,4}, {regr,0}}},
-  {"sbitd",   2, 0x18047C,  9, CSTBIT_INS, {{i5,4},     {regr,0}}},
+  {"sbitd",   2, 0x18047C,  9, CSTBIT_INS, {{i5,4}, {regr,0}}},
 
   CSTBIT_INST ("tbitb", i3, 0x702, 0x20, 19, 0x1FE),
   CSTBIT_INST ("tbitw", i4, 0x384, 0x10, 20, 0xBF),
   CSTBIT_INST ("tbitd", i5, 0x1C5, 0x8,  21, 0x7D),
   {"tbitd",   2, 0x30083A,  8, CSTBIT_INS, {{regr,4}, {regr,0}}},
-  {"tbitd",   2, 0x18047D,  9, CSTBIT_INS, {{i5,4},     {regr,0}}},
+  {"tbitd",   2, 0x18047D,  9, CSTBIT_INS, {{i5,4}, {regr,0}}},
 
 /* Instructions including a register list (opcode is represented as a mask).  */
 #define  REGLIST_INST(NAME, OPC) \
   /* opc12 r mask16 */                                   \
   {NAME,  2, OPC, 20, REG_LIST, {{regr,16}, {i16,0}}}
 
-  REG1_INST ("getrfid",         0xFF9),
-  REG1_INST ("setrfid",   0xFFA),
+  REG1_INST ("getrfid",        0xFF9),
+  REG1_INST ("setrfid",        0xFFA),
 
   REGLIST_INST ("push",         0x346),
   REG1_INST ("push",    0xFFB),
+  REGLIST_INST ("pushx", 0x347),
 
   REGLIST_INST ("pop",  0x324),
   REG1_INST ("pop",     0xFFC),
+  REGLIST_INST ("popx",         0x327),
 
   REGLIST_INST ("popret", 0x326),
   REG1_INST ("popret",    0xFFD),
 
-  REGLIST_INST ("loadm",        0x324),
+  REGLIST_INST ("loadm", 0x324),
   REGLIST_INST ("loadma", 0x325),
-  REGLIST_INST ("popma",        0x325),
+  REGLIST_INST ("popma", 0x325),
 
-  REGLIST_INST ("storm",        0x344),
+  REGLIST_INST ("storm", 0x344),
   REGLIST_INST ("storma", 0x345),
   REGLIST_INST ("pushma", 0x345),
 
@@ -560,7 +562,7 @@ const reg_entry crx_regtab[] =
   REG(ra, 0xe, CRX_R_REGTYPE),
   REG(sp, 0xf, CRX_R_REGTYPE),
 
-/* Build a user register ur<N>.  */
+/* Build a user register u<N>.  */
 #define REG_U(N)    REG(CONCAT2(u,N), 0x80 + N, CRX_U_REGTYPE)
 
   REG_U(0),  REG_U(1),  REG_U(2),  REG_U(3),
@@ -607,7 +609,7 @@ const reg_entry crx_copregtab[] =
   REG_C(8),  REG_C(9), REG_C(10), REG_C(11),
   REG_C(12), REG_C(13), REG_C(14), REG_C(15),
 
-/* Build a Coprocessor Special register c<N>.  */
+/* Build a Coprocessor Special register cs<N>.  */
 #define REG_CS(N)    REG(CONCAT2(cs,N), N, CRX_CS_REGTYPE)
 
   REG_CS(0),  REG_CS(1),  REG_CS(2),  REG_CS(3),