public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Re: [PATCH] PowerPC VLE changes
@ 2017-03-24 15:32 Александр Федотов
  2017-03-27 14:32 ` Andrew Jenner
  0 siblings, 1 reply; 20+ messages in thread
From: Александр Федотов @ 2017-03-24 15:32 UTC (permalink / raw)
  To: binutils

Hi all

I have question in continuation of
https://sourceware.org/ml/binutils/2016-07/msg00342.html

Why do you need to have "e_cmpwi" etc in vle_opcodes table ? It seems
they are just alias names because of the same opcodes and objdump
never show them.
Why don't to use powerpc_macros instead ?

And it seems that following instructions must be marked as E200Z4 also
respectively to MPC5748G Reference Manual:

lbdx
lhdx
lwdx
stbdx
sthdx
stwdx



Alexander

^ permalink raw reply	[flat|nested] 20+ messages in thread
* Re: [PATCH] PowerPC VLE changes
@ 2017-06-23 20:52 Alexander Fedotov
  2017-06-23 20:55 ` Alexander Fedotov
  2017-06-24 13:11 ` Alan Modra
  0 siblings, 2 replies; 20+ messages in thread
From: Alexander Fedotov @ 2017-06-23 20:52 UTC (permalink / raw)
  To: Alan Modra, binutils; +Cc: Edmar Wienskoski

[-- Attachment #1: Type: text/plain, Size: 144 bytes --]

Hello Alan

We want to upstream our changes for VLE, LSP, SPE2 and other stuff.
All of them are based on 2.28 release.

Best regards,
Alexander

[-- Attachment #2: 2.28-vle.patch --]
[-- Type: text/x-patch, Size: 18120 bytes --]

diff -ruN binutils-2.28/bfd/elf32-ppc.c binutils-2.28-vle/bfd/elf32-ppc.c
--- binutils-2.28/bfd/elf32-ppc.c	2017-03-02 11:23:53.000000000 +0300
+++ binutils-2.28-vle/bfd/elf32-ppc.c	2017-06-23 22:01:57.953766000 +0300
@@ -171,6 +171,9 @@
 #define NOP		0x60000000
 #define SUB_11_11_12	0x7d6c5850
 
+/* VLE some instructions */
+#define E_B		0x78000000
+
 /* Offset of tp and dtp pointers from start of TLS block.  */
 #define TP_OFFSET	0x7000
 #define DTP_OFFSET	0x8000
@@ -1444,6 +1447,21 @@
 	 0x1fffffe,		/* dst_mask */
 	 TRUE),			/* pcrel_offset */
 
+  /* A relative 24 bit branch.  */
+  HOWTO (R_PPC_VLE_PLTREL24,	/* type */
+	 1,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 24,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 1,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 ppc_elf_unhandled_reloc, /* special_function */
+	 "R_PPC_VLE_PLTREL24",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0x1fffffe,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
   /* The 16 LSBS in split16a format.  */
   HOWTO (R_PPC_VLE_LO16A,	/* type */
 	 0,			/* rightshift */
@@ -1656,6 +1674,21 @@
 	 0x3e007ff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
 
+  /* e_li split20 format.  */
+  HOWTO (R_PPC_VLE_ADDR20,	/* type */
+	 16,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 20,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_PPC_VLE_ADDR20",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0x1f07ff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+ 
   HOWTO (R_PPC_IRELATIVE,	/* type */
 	 0,			/* rightshift */
 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
@@ -2463,6 +2496,14 @@
   return 0;
 }
 
+static bfd_boolean
+ppc_elf_section_flags (flagword *flags, const Elf_Internal_Shdr * hdr)
+{
+  if (hdr->sh_flags & SHF_PPC_VLE)
+    *flags |= SEC_PPC_VLE;
+  return TRUE;
+}
+
 /* Return address for Ith PLT stub in section PLT, for relocation REL
    or (bfd_vma) -1 if it should not be included.  */
 
@@ -2511,6 +2552,8 @@
 {
   if ((asect->flags & SEC_SORT_ENTRIES) != 0)
     shdr->sh_type = SHT_ORDERED;
+  if ((asect->flags & SEC_PPC_VLE) != 0)
+    shdr->sh_flags |= SHF_PPC_VLE;
 
   return TRUE;
 }
@@ -4247,6 +4290,7 @@
 	case R_PPC_VLE_HI16D:
 	case R_PPC_VLE_HA16A:
 	case R_PPC_VLE_HA16D:
+	case R_PPC_VLE_ADDR20:
 	  break;
 
 	case R_PPC_EMB_SDA2REL:
@@ -4294,6 +4338,7 @@
 	  break;
 
 	case R_PPC_PLTREL24:
+	case R_PPC_VLE_PLTREL24:
 	  if (h == NULL)
 	    break;
 	  /* Fall through */
@@ -4365,6 +4410,7 @@
 	case R_PPC_NONE:
 	case R_PPC_max:
 	case R_PPC_RELAX:
+	case R_PPC_VLE_RELAX:
 	case R_PPC_RELAX_PLT:
 	case R_PPC_RELAX_PLTREL24:
 	case R_PPC_16DX_HA:
@@ -4965,6 +5011,23 @@
   insn |= value & 0x7ff;
   bfd_put_32 (input_bfd, insn, loc);
 }
+
+static void
+ppc_elf_vle_split20 (bfd *output_bfd, bfd_byte *loc, bfd_vma value)
+{
+  unsigned int insn;
+
+  insn = bfd_get_32 (output_bfd, loc);
+  /* We have an li20 field, bits 17..20, 11..15, 21..31.  */
+  /* Top 4 bits of value to 17..20.  */
+  insn |= (value & 0xf0000) >> 5;
+  /* Next 5 bits of the value to 11..15.  */
+  insn |= (value & 0xf800) << 5;
+  /* And the final 11 bits of the value to bits 21 to 31.  */
+  insn |= value & 0x7ff;
+  bfd_put_32 (output_bfd, insn, loc);
+}
+
 \f
 /* Choose which PLT scheme to use, and set .plt flags appropriately.
    Returns -1 on error, 0 for old PLT, 1 for new PLT.  */
@@ -6907,6 +6970,13 @@
     0x4e800420, /* bctr */
   };
 
+typedef enum ppc_target_stub_entry_type
+  {
+    stub_entry_type_ppc = 0,
+    stub_entry_type_vle
+  }
+ppc_target_stub_entry_type;
+
 static const int stub_entry[] =
   {
     0x3d800000, /* lis 12,xxx@ha */
@@ -6915,6 +6985,15 @@
     0x4e800420, /* bctr */
   };
 
+/* Keep the same size as stub_entry */
+static const int stub_entry_vle[] =
+  {
+    0x7180e000, /* e_lis 12,xxx@ha */
+    0x1d8c0000, /* e_add16i 12,12,xxx@l */
+    0x7d8903a6, /* mtctr 12 */
+    0x00064400, /* se_bctr, se_nop (size padding) */
+  };
+
 struct ppc_elf_relax_info
 {
   unsigned int workaround_size;
@@ -6955,6 +7034,7 @@
   bfd_size_type trampbase, trampoff, newsize, picfixup_size;
   asection *got2;
   bfd_boolean maybe_pasted;
+  ppc_target_stub_entry_type target_stub_type = 0;
 
   *again = FALSE;
 
@@ -7035,21 +7115,43 @@
 	  struct elf_link_hash_entry *h;
 	  struct plt_entry **plist;
 	  unsigned char sym_type;
+	  reloc_howto_type *current_howto;
+	  current_howto = NULL;
 
 	  switch (r_type)
 	    {
 	    case R_PPC_REL24:
 	    case R_PPC_LOCAL24PC:
 	    case R_PPC_PLTREL24:
+	      target_stub_type = stub_entry_type_ppc;
 	      max_branch_offset = 1 << 25;
 	      break;
 
 	    case R_PPC_REL14:
 	    case R_PPC_REL14_BRTAKEN:
 	    case R_PPC_REL14_BRNTAKEN:
+	      target_stub_type = stub_entry_type_ppc;
 	      max_branch_offset = 1 << 15;
 	      break;
 
+	    case R_PPC_VLE_REL24:
+	      target_stub_type = stub_entry_type_vle;
+	      max_branch_offset = 1 << 25;
+	      current_howto = ppc_elf_howto_table[r_type];
+	      break;
+
+	    case R_PPC_VLE_REL15:
+	      target_stub_type = stub_entry_type_vle;
+	      max_branch_offset = 1 << 16;
+	      current_howto = ppc_elf_howto_table[r_type];
+	      break;
+
+	    case R_PPC_VLE_REL8:
+	      target_stub_type = stub_entry_type_vle;
+	      max_branch_offset = 1 << 9;
+	      current_howto = ppc_elf_howto_table[r_type];
+	      break;
+
 	    case R_PPC_ADDR16_HA:
 	      if (htab->params->pic_fixup > 0)
 		break;
@@ -7297,9 +7399,25 @@
 
 	      symaddr = tsec->output_section->vma + tsec->output_offset + toff;
 	      reladdr = isec->output_section->vma + isec->output_offset + roff;
-	      if (symaddr - reladdr + max_branch_offset
-		  < 2 * max_branch_offset)
-		continue;
+
+	      /* I don't trust the relocation check using ' ... < (2 * max_branch_offset)'
+	       * Check for overflow using the bfd API first.
+	       */
+	      if (current_howto) /* current_howto is not necessarily defined for
+				    all reloc types above, but use it if it is defined */
+		{
+		  if (bfd_check_overflow (current_howto->complain_on_overflow,
+					  current_howto->bitsize,
+					  current_howto->rightshift,
+					  bfd_arch_bits_per_address(abfd),
+					  (symaddr-reladdr)) == bfd_reloc_ok )
+		    continue;
+		}
+	      else
+		{
+		  if (((symaddr - reladdr) + max_branch_offset) < (2 * max_branch_offset))
+		    continue;
+		}
 	    }
 
 	  /* Look for an existing fixup to this address.  */
@@ -7328,7 +7446,7 @@
 		  size = 4 * ARRAY_SIZE (stub_entry);
 		  insn_offset = 0;
 		}
-	      stub_rtype = R_PPC_RELAX;
+	      stub_rtype = (target_stub_type == stub_entry_type_vle) ? R_PPC_VLE_RELAX : R_PPC_RELAX;
 	      if (tsec == htab->elf.splt
 		  || tsec == htab->glink)
 		{
@@ -7385,10 +7503,21 @@
 	    case R_PPC_REL24:
 	    case R_PPC_LOCAL24PC:
 	    case R_PPC_PLTREL24:
-	      t0 = bfd_get_32 (abfd, hit_addr);
-	      t0 &= ~0x3fffffc;
-	      t0 |= val & 0x3fffffc;
-	      bfd_put_32 (abfd, t0, hit_addr);
+	      if (r_type == R_PPC_PLTREL24
+		  && (elf_section_flags (isec) & SHF_PPC_VLE) != 0)
+		{
+		  t0 = bfd_get_32 (abfd, hit_addr);
+		  t0 &= ~0x01fffffe;
+		  t0 |= val & 0x01fffffe;
+		  bfd_put_32 (abfd, t0, hit_addr);
+		}
+	      else
+		{
+		  t0 = bfd_get_32 (abfd, hit_addr);
+		  t0 &= ~0x3fffffc;
+		  t0 |= val & 0x3fffffc;
+		  bfd_put_32 (abfd, t0, hit_addr);
+		}
 	      break;
 
 	    case R_PPC_REL14:
@@ -7399,6 +7528,27 @@
 	      t0 |= val & 0xfffc;
 	      bfd_put_32 (abfd, t0, hit_addr);
 	      break;
+
+	    case R_PPC_VLE_REL24:
+	      t0 = bfd_get_32 (abfd, hit_addr);
+	      t0 &= ~0x01fffffe;
+	      t0 |= val & 0x01fffffe;
+	      bfd_put_32 (abfd, t0, hit_addr);
+	      break;
+
+	    case R_PPC_VLE_REL15:
+	      t0 = bfd_get_32 (abfd, hit_addr);
+	      t0 &= ~0xfffe;
+	      t0 |= val & 0xfffe;
+	      bfd_put_32 (abfd, t0, hit_addr);
+	      break;
+
+	    case R_PPC_VLE_REL8:
+	      t0 = bfd_get_32 (abfd, hit_addr);
+	      t0 &= ~0xff;
+	      t0 |= val & 0xff;
+	      bfd_put_32 (abfd, t0, hit_addr);
+	      break;
 	    }
 	}
 
@@ -9043,6 +9193,7 @@
 	  /* Fall through.  */
 
 	case R_PPC_RELAX:
+	case R_PPC_VLE_RELAX:
 	  {
 	    const int *stub;
 	    size_t size;
@@ -9063,8 +9214,8 @@
 	      }
 	    else
 	      {
-		stub = stub_entry;
-		size = ARRAY_SIZE (stub_entry);
+		stub = (r_type == R_PPC_VLE_RELAX) ? stub_entry_vle : stub_entry;
+		size = ARRAY_SIZE (stub_entry); /* stub_entry and stub_entry_vle must be same size */
 	      }
 
 	    relocation += addend;
@@ -9072,10 +9223,23 @@
 	      relocation = 0;
 
 	    /* First insn is HA, second is LO.  */
-	    insn = *stub++;
-	    insn |= ((relocation + 0x8000) >> 16) & 0xffff;
-	    bfd_put_32 (input_bfd, insn, contents + insn_offset);
-	    insn_offset += 4;
+	    if (r_type == R_PPC_VLE_RELAX)
+	      {
+		/* Write e_lis insn is @ha type relocation */
+		unsigned ha_val;
+		insn = *stub++;
+		ha_val = ((relocation + 0x8000) >> 16) & 0xffff;
+		insn |= (((ha_val & 0xf800) << 5) | (ha_val&0x7ff));
+		bfd_put_32 (input_bfd, insn, contents + insn_offset);
+		insn_offset += 4;
+	      }
+	    else
+	      {
+		insn = *stub++;
+		insn |= ((relocation + 0x8000) >> 16) & 0xffff;
+		bfd_put_32 (input_bfd, insn, contents + insn_offset);
+		insn_offset += 4;
+	      }
 
 	    insn = *stub++;
 	    insn |= relocation & 0xffff;
@@ -9482,6 +9646,10 @@
 	  }
 	  goto copy_reloc;
 
+	case R_PPC_VLE_ADDR20:
+	  ppc_elf_vle_split20 (output_bfd, contents + rel->r_offset, relocation);
+	  continue;
+
 	  /* Relocate against the beginning of the section.  */
 	case R_PPC_SECTOFF:
 	case R_PPC_SECTOFF_LO:
@@ -9759,8 +9927,15 @@
       && (strcmp (input_section->output_section->name, ".init") == 0
 	  || strcmp (input_section->output_section->name, ".fini") == 0))
     {
+      unsigned int insn;
+
+      if ((elf_section_flags (input_section) & SHF_PPC_VLE) == 0)
+        insn = B;
+      else
+        insn = E_B;
+      
       /* Branch around the trampolines.  */
-      unsigned int insn = B + input_section->size - input_section->rawsize;
+      insn += input_section->size - input_section->rawsize;
       bfd_put_32 (input_bfd, insn, contents + input_section->rawsize);
     }
 
@@ -10949,6 +11124,7 @@
 #define elf_backend_action_discarded		ppc_elf_action_discarded
 #define elf_backend_init_index_section		_bfd_elf_init_1_index_section
 #define elf_backend_lookup_section_flags_hook	ppc_elf_lookup_section_flags
+#define elf_backend_section_flags		ppc_elf_section_flags
 
 #include "elf32-target.h"
 
diff -ruN binutils-2.28/binutils/objdump.c binutils-2.28-vle/binutils/objdump.c
--- binutils-2.28/binutils/objdump.c	2017-03-02 11:23:53.000000000 +0300
+++ binutils-2.28-vle/binutils/objdump.c	2017-06-23 17:25:21.641299056 +0300
@@ -481,6 +481,10 @@
   PF (SEC_NEVER_LOAD, "NEVER_LOAD");
   PF (SEC_EXCLUDE, "EXCLUDE");
   PF (SEC_SORT_ENTRIES, "SORT_ENTRIES");
+  if (bfd_get_arch(abfd) == bfd_arch_powerpc || bfd_get_arch (abfd) == bfd_mach_ppc_vle)
+    {
+      PF (SEC_TIC54X_BLOCK, "VLE"); /* hack, would have to include ppc.h */
+    }
   if (bfd_get_arch (abfd) == bfd_arch_tic54x)
     {
       PF (SEC_TIC54X_BLOCK, "BLOCK");
diff -ruN binutils-2.28/binutils/readelf.c binutils-2.28-vle/binutils/readelf.c
--- binutils-2.28/binutils/readelf.c	2017-03-02 11:23:53.000000000 +0300
+++ binutils-2.28-vle/binutils/readelf.c	2017-06-23 21:51:24.753324000 +0300
@@ -5491,7 +5491,9 @@
       /* ARM specific.  */
       /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
       /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
-      /* 23 */ { STRING_COMMA_LEN ("COMDEF") }
+      /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
+      /* VLE specific.  */
+      /* 24 */ { STRING_COMMA_LEN ("VLE") }
     };
 
   if (do_section_details)
@@ -5524,6 +5526,7 @@
 	    case SHF_TLS:		sindex = 9; break;
 	    case SHF_EXCLUDE:		sindex = 18; break;
 	    case SHF_COMPRESSED:	sindex = 20; break;
+	    case SHF_PPC_VLE:		sindex = 24; break;
 
 	    default:
 	      sindex = -1;
@@ -5617,6 +5620,7 @@
 	    case SHF_TLS:		*p = 'T'; break;
 	    case SHF_EXCLUDE:		*p = 'E'; break;
 	    case SHF_COMPRESSED:	*p = 'C'; break;
+	    case SHF_PPC_VLE:		*p = 'V'; break;
 
 	    default:
 	      if ((elf_header.e_machine == EM_X86_64
@@ -6333,6 +6337,8 @@
 	printf (_("l (large), "));
       else if (elf_header.e_machine == EM_ARM)
 	printf (_("y (purecode), "));
+      else if (elf_header.e_machine == EM_PPC)
+	printf (_("V (VLE), "));      
       printf ("p (processor specific)\n");
     }
 
diff -ruN binutils-2.28/gas/config/obj-elf.c binutils-2.28-vle/gas/config/obj-elf.c
--- binutils-2.28/gas/config/obj-elf.c	2017-03-02 11:23:53.000000000 +0300
+++ binutils-2.28-vle/gas/config/obj-elf.c	2017-06-23 17:26:08.784859055 +0300
@@ -677,6 +677,11 @@
 	    /* RX init/fini arrays can and should have the "awx" attributes set.  */
 	    ;
 #endif
+#ifdef TC_PPC
+	  /* A section on powerpc-vle may have SHF_PPC_VLE.  */
+	  else if ((attr & ~ssect->attr) == SHF_PPC_VLE)
+	    override = TRUE;
+#endif
 	  else
 	    {
 	      if (group_name == NULL)
diff -ruN binutils-2.28/gas/config/tc-ppc.c binutils-2.28-vle/gas/config/tc-ppc.c
--- binutils-2.28/gas/config/tc-ppc.c	2017-03-02 11:23:53.000000000 +0300
+++ binutils-2.28-vle/gas/config/tc-ppc.c	2017-06-23 17:48:51.463401055 +0300
@@ -1153,6 +1153,16 @@
 	    }
 	}
 
+      else if (strcmp (arg, "no-vle") == 0)
+        {
+        sticky &= ~PPC_OPCODE_VLE;
+
+        new_cpu = ppc_parse_cpu (ppc_cpu, &sticky, "booke");
+        new_cpu &= ~PPC_OPCODE_VLE;
+
+        ppc_cpu = new_cpu;
+        }
+
       else if (strcmp (arg, "regnames") == 0)
 	reg_names_p = TRUE;
 
@@ -3562,13 +3572,26 @@
 }
 
 int
-ppc_section_flags (flagword flags, bfd_vma attr ATTRIBUTE_UNUSED, int type)
+ppc_section_flags (flagword flags, bfd_vma attr, int type)
 {
   if (type == SHT_ORDERED)
     flags |= SEC_ALLOC | SEC_LOAD | SEC_SORT_ENTRIES;
 
+  if (attr == SHF_PPC_VLE)
+    flags |= SEC_PPC_VLE;
+
   return flags;
 }
+
+bfd_vma
+ppc_elf_section_letter (int letter, const char **ptrmsg)
+{
+  if (letter == 'v')
+    return SHF_PPC_VLE;
+
+  *ptrmsg = _("bad .section directive: want a,e,v,w,x,M,S,G,T in string");
+  return -1;
+}
 #endif /* OBJ_ELF */
 
 \f
diff -ruN binutils-2.28/gas/config/tc-ppc.h binutils-2.28-vle/gas/config/tc-ppc.h
--- binutils-2.28/gas/config/tc-ppc.h	2017-03-02 11:23:53.000000000 +0300
+++ binutils-2.28-vle/gas/config/tc-ppc.h	2017-06-23 17:28:07.396135056 +0300
@@ -226,6 +226,9 @@
 #define tc_comment_chars ppc_comment_chars
 extern const char *ppc_comment_chars;
 
+#define md_elf_section_letter ppc_elf_section_letter
+extern bfd_vma ppc_elf_section_letter (int, const char **);
+
 /* Keep relocations relative to the GOT, or non-PC relative.  */
 #define tc_fix_adjustable(FIX) ppc_fix_adjustable (FIX)
 extern int ppc_fix_adjustable (struct fix *);
diff -ruN binutils-2.28/gas/doc/as.texinfo binutils-2.28-vle/gas/doc/as.texinfo
--- binutils-2.28/gas/doc/as.texinfo	2017-03-02 11:23:53.000000000 +0300
+++ binutils-2.28-vle/gas/doc/as.texinfo	2017-06-23 17:29:31.519652342 +0300
@@ -6495,6 +6495,8 @@
 section is allocatable
 @item e
 section is excluded from executable and shared library.
+@item v
+section contains PowerPC VLE code (sets the SHF_PPC_VLE flag bit)
 @item w
 section is writable
 @item x
diff -ruN binutils-2.28/include/elf/ppc.h binutils-2.28-vle/include/elf/ppc.h
--- binutils-2.28/include/elf/ppc.h	2017-03-02 11:23:54.000000000 +0300
+++ binutils-2.28-vle/include/elf/ppc.h	2017-06-23 17:34:20.838930833 +0300
@@ -79,8 +79,10 @@
   RELOC_NUMBER (R_PPC_RELAX,		 48)
   RELOC_NUMBER (R_PPC_RELAX_PLT,	 49)
   RELOC_NUMBER (R_PPC_RELAX_PLTREL24,	 50)
+  RELOC_NUMBER (R_PPC_VLE_RELAX,	 51)
 /* Reloc only used internally by gas.  As above, value is unimportant.  */
-  RELOC_NUMBER (R_PPC_16DX_HA,		 51)
+  RELOC_NUMBER (R_PPC_16DX_HA,		 52)
+  RELOC_NUMBER (R_PPC_VLE_PLTREL24,	 53)
 #endif
 
   /* Relocs added to support TLS.  */
@@ -152,6 +154,7 @@
   RELOC_NUMBER (R_PPC_VLE_SDAREL_HI16D,	230)
   RELOC_NUMBER (R_PPC_VLE_SDAREL_HA16A,	231)
   RELOC_NUMBER (R_PPC_VLE_SDAREL_HA16D,	232)
+  RELOC_NUMBER (R_PPC_VLE_ADDR20,	233)
 
 /* Power9 split rel16 for addpcis.  */
   RELOC_NUMBER (R_PPC_REL16DX_HA,	246)
@@ -198,6 +201,9 @@
 /* Processor specific section headers, sh_flags field.  */
 #define SHF_PPC_VLE		0x10000000	/* PowerPC VLE text section.  */
 
+/* BFD section headers flag.  */
+#define SEC_PPC_VLE		SEC_TIC54X_BLOCK
+
 /* Processor specific section headers, sh_type field.  */
 
 #define SHT_ORDERED		SHT_HIPROC	/* Link editor is to sort the \
diff -ruN binutils-2.28/opcodes/ppc-dis.c binutils-2.28-vle/opcodes/ppc-dis.c
--- binutils-2.28/opcodes/ppc-dis.c	2017-03-02 11:23:54.000000000 +0300
+++ binutils-2.28-vle/opcodes/ppc-dis.c	2017-06-23 17:16:54.219715056 +0300
@@ -108,8 +108,8 @@
   { "e200z4",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE| PPC_OPCODE_SPE
 		| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
-		| PPC_OPCODE_E500 | PPC_OPCODE_E200Z4),
-    PPC_OPCODE_VLE },
+		| PPC_OPCODE_E500 | PPC_OPCODE_E200Z4 | PPC_OPCODE_VLE),
+    0 },
   { "e300",    PPC_OPCODE_PPC | PPC_OPCODE_E300,
     0 },
   { "e500",    (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
@@ -235,12 +235,13 @@
   dialect = POWERPC_DIALECT (info);
 
   /* Disassemble according to the section headers flags for VLE-mode.  */
-  if (dialect & PPC_OPCODE_VLE
-      && info->section != NULL && info->section->owner != NULL
+  if (dialect & PPC_OPCODE_VLE)
+    return dialect;
+  else if (info->section != NULL && info->section->owner != NULL
       && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour
       && elf_object_id (info->section->owner) == PPC32_ELF_DATA
       && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)
-    return dialect;
+    return PPC_OPCODE_VLE;
   else
     return dialect & ~ PPC_OPCODE_VLE;
 }

^ permalink raw reply	[flat|nested] 20+ messages in thread
* [PATCH] PowerPC VLE changes
@ 2016-07-26 16:41 Andrew Jenner
  2016-07-26 23:26 ` Alan Modra
  0 siblings, 1 reply; 20+ messages in thread
From: Andrew Jenner @ 2016-07-26 16:41 UTC (permalink / raw)
  To: binutils, Kwok Cheung Yeung

[-- Attachment #1: Type: text/plain, Size: 880 bytes --]

I'm in the process of preparing patches to add PowerPC VLE support to 
GCC. This patch is a prerequisite for that, fixing some BFD issues and 
adding some instructions:
* Volatile Context Save/Restore APU instructions as documented in 
http://www.nxp.com/files/32bit/doc/ref_manual/e200z3RM.pdf .
* E200z4 decorated load and store instructions as documented in 
http://www.nxp.com/files/32bit/doc/ref_manual/MPC5748GRM.pdf .

Okay to commit?

Thanks,

Andrew

---
bfd/ChangeLog:

     * elf32-ppc.c (is_branch_reloc): Recognise VLE branch relocations.
     (ppc_elf_howto_raw): Fix dst_mask of R_PPC_VLE_REL15.
     (ppc_elf_vle_split16): Clear field before inserting.

opcodes/ChangeLog:

     * ppc-opc.c (vle_opcodes): Alias 'e_cmpwi' to 'e_cmpi' and
     'e_cmplwi' to 'e_cmpli' instead.
     (OPVUPRT, OPVUPRT_MASK): Define.
     (powerpc_opcodes, vle_opcodes): Add entries.

[-- Attachment #2: binutils_vle.patch --]
[-- Type: text/x-patch, Size: 8003 bytes --]

diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 81b3d84..8d5131a 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -1425,7 +1425,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
 	 "R_PPC_VLE_REL15",	/* name */
 	 FALSE,			/* partial_inplace */
 	 0,			/* src_mask */
-	 0xfe,			/* dst_mask */
+	 0xfffe,		/* dst_mask */
 	 TRUE),			/* pcrel_offset */

   /* A relative 24 bit branch.  */
@@ -3948,7 +3948,8 @@ is_branch_reloc (enum elf_ppc_reloc_type r_type)
 	  || r_type == R_PPC_ADDR24
 	  || r_type == R_PPC_ADDR14
 	  || r_type == R_PPC_ADDR14_BRTAKEN
-	  || r_type == R_PPC_ADDR14_BRNTAKEN);
+	  || r_type == R_PPC_ADDR14_BRNTAKEN
+	  || r_type == R_PPC_VLE_REL24);
 }

 static void
@@ -4899,6 +4900,7 @@ ppc_elf_vle_split16 (bfd *output_bfd, bfd_byte *loc,
   insn = bfd_get_32 (output_bfd, loc);
   top5 = value & 0xf800;
   top5 = top5 << (split16_format == split16a_type ? 9 : 5);
+  insn &= (split16_format == split16a_type ? ~0x1f007ff : ~0x1f07ff);
   insn |= top5;
   insn |= value & 0x7ff;
   bfd_put_32 (output_bfd, insn, loc);
diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h
index 628a7a1..d9f973d 100644
--- a/include/opcode/ppc.h
+++ b/include/opcode/ppc.h
@@ -214,6 +214,9 @@ extern const int vle_num_opcodes;
 /* Opcode is supported by Vector-Scalar (VSX) Unit from ISA 2.08.  */
 #define PPC_OPCODE_VSX3       0x40000000000ull

+  /* Opcode is supported by e200z4.  */
+#define PPC_OPCODE_E200Z4     0x80000000000ull
+
 /* A macro to extract the major opcode from an instruction.  */
 #define PPC_OP(i) (((i) >> 26) & 0x3f)

diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c
index 77a2a60..da1301e 100644
--- a/opcodes/ppc-dis.c
+++ b/opcodes/ppc-dis.c
@@ -105,6 +105,11 @@ struct ppc_mopt ppc_opts[] = {
     0 },
   { "com",     PPC_OPCODE_COMMON,
     0 },
+  { "e200z4",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE| PPC_OPCODE_SPE
+		| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
+		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+		| PPC_OPCODE_E500 | PPC_OPCODE_E200Z4),
+    PPC_OPCODE_VLE },
   { "e300",    PPC_OPCODE_PPC | PPC_OPCODE_E300,
     0 },
   { "e500",    (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
index 8106ab7..d4fc7c0 100644
--- a/opcodes/ppc-opc.c
+++ b/opcodes/ppc-opc.c
@@ -2374,6 +2374,12 @@ extract_vleil (unsigned long insn,
 #define OPVUP(x,vup) (OP (x) | ((((unsigned long)(vup)) & 0xff) << 8))
 #define OPVUP_MASK OPVUP (0x3f,  0xff)

+/* The main opcode combined with an update code and the RT fields specified in
+   D form instruction.  Used for VLE volatile context save/restore
+   instructions.  */
+#define OPVUPRT(x,vup,rt) (OPVUP (x, vup) | ((((unsigned long)(rt)) & 0x1f) << 21))
+#define OPVUPRT_MASK OPVUPRT (0x3f, 0xff, 0x1f)
+
 /* An A form instruction.  */
 #define A(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1) | (((unsigned long)(rc)) & 1))
 #define A_MASK A (0x3f, 0x1f, 1)
@@ -3055,6 +3061,7 @@ extract_vleil (unsigned long insn,
 #define E6500	PPC_OPCODE_E6500
 #define PPCVLE  PPC_OPCODE_VLE
 #define PPCHTM  PPC_OPCODE_HTM
+#define E200Z4  PPC_OPCODE_E200Z4
 /* The list of embedded processors that use the embedded operand ordering
    for the 3 operand dcbt and dcbtst instructions.  */
 #define DCBT_EO	(PPC_OPCODE_E500 | PPC_OPCODE_E500MC | PPC_OPCODE_476 \
@@ -5815,6 +5822,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {

 {"mcrxr",	X(31,512),	XBFRARB_MASK, COM,	POWER7,		{BF}},

+{"lbdcbx",	X(31,514),	X_MASK,      E200Z4,	0,		{RT, RA, RB}},
 {"lbdx",	X(31,515),	X_MASK,	     E500MC,	0,		{RT, RA, RB}},

 {"bblels",	X(31,518),	X_MASK,	     PPCBRLK,	0,		{0}},
@@ -5865,6 +5873,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 {"maskir",	XRC(31,541,0),	X_MASK,	     M601,	0,		{RA, RS, RB}},
 {"maskir.",	XRC(31,541,1),	X_MASK,	     M601,	0,		{RA, RS, RB}},

+{"lhdcbx",	X(31,546),	X_MASK,      E200Z4,	0,		{RT, RA, RB}},
 {"lhdx",	X(31,547),	X_MASK,	     E500MC,	0,		{RT, RA, RB}},

 {"lvtrx",	X(31,549),	X_MASK,	     PPCVEC2,	0,		{VD, RA0, RB}},
@@ -5888,6 +5897,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {

 {"mcrxrx",	X(31,576),     XBFRARB_MASK, POWER9,	0,		{BF}},

+{"lwdcbx",	X(31,578),	X_MASK,      E200Z4,	0,		{RT, RA, RB}},
 {"lwdx",	X(31,579),	X_MASK,	     E500MC,	0,		{RT, RA, RB}},

 {"lvtlx",	X(31,581),	X_MASK,	     PPCVEC2,	0,		{VD, RA0, RB}},
@@ -5938,6 +5948,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {

 {"lfdux",	X(31,631),	X_MASK,	     COM,	PPCEFS,		{FRT, RAS, RB}},

+{"stbdcbx",	X(31,642),	X_MASK,      E200Z4,	0,		{RS, RA, RB}},
 {"stbdx",	X(31,643),	X_MASK,	     E500MC,	0,		{RS, RA, RB}},

 {"stvlx",	X(31,647),	X_MASK,	     CELL,	0,		{VS, RA0, RB}},
@@ -5975,6 +5986,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 {"sre",		XRC(31,665,0),	X_MASK,	     M601,	0,		{RA, RS, RB}},
 {"sre.",	XRC(31,665,1),	X_MASK,	     M601,	0,		{RA, RS, RB}},

+{"sthdcbx",	X(31,674),	X_MASK,      E200Z4,	0,		{RS, RA, RB}},
 {"sthdx",	X(31,675),	X_MASK,	     E500MC,	0,		{RS, RA, RB}},

 {"stvfrx",	X(31,677),	X_MASK,	     PPCVEC2,	0,		{VS, RA0, RB}},
@@ -5992,6 +6004,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 {"sriq",	XRC(31,696,0),	X_MASK,	     M601,	0,		{RA, RS, SH}},
 {"sriq.",	XRC(31,696,1),	X_MASK,	     M601,	0,		{RA, RS, SH}},

+{"stwdcbx",	X(31,706),	X_MASK,	     E200Z4,	0,		{RS, RA, RB}},
 {"stwdx",	X(31,707),	X_MASK,	     E500MC,	0,		{RS, RA, RB}},

 {"stvflx",	X(31,709),	X_MASK,	     PPCVEC2,	0,		{VS, RA0, RB}},
@@ -7070,7 +7083,9 @@ const struct powerpc_opcode vle_opcodes[] = {
 {"se_cmphl",	SE_RR(3,3),	SE_RR_MASK,	PPCVLE,	0,		{RX, RY}},

 {"e_cmpi",	SCI8BF(6,0,21),	SCI8BF_MASK,	PPCVLE,	0,		{CRD32, RA, SCLSCI8}},
+{"e_cmpwi",	SCI8BF(6,0,21),	SCI8BF_MASK,	PPCVLE,	0,		{CRD32, RA, SCLSCI8}},
 {"e_cmpli",	SCI8BF(6,1,21),	SCI8BF_MASK,	PPCVLE,	0,		{CRD32, RA, SCLSCI8}},
+{"e_cmplwi",	SCI8BF(6,1,21),	SCI8BF_MASK,	PPCVLE,	0,		{CRD32, RA, SCLSCI8}},
 {"e_addi",	SCI8(6,16),	SCI8_MASK,	PPCVLE,	0,		{RT, RA, SCLSCI8}},
 {"e_subi",	SCI8(6,16),	SCI8_MASK,	PPCVLE,	0,		{RT, RA, SCLSCI8N}},
 {"e_addi.",	SCI8(6,17),	SCI8_MASK,	PPCVLE,	0,		{RT, RA, SCLSCI8}},
@@ -7097,6 +7112,16 @@ const struct powerpc_opcode vle_opcodes[] = {
 {"e_sthu",	OPVUP(6,5),	OPVUP_MASK,	PPCVLE,	0,		{RT, D8, RA0}},
 {"e_stwu",	OPVUP(6,6),	OPVUP_MASK,	PPCVLE,	0,		{RT, D8, RA0}},
 {"e_stmw",	OPVUP(6,9),	OPVUP_MASK,	PPCVLE,	0,		{RT, D8, RA0}},
+{"e_ldmvgprw",	OPVUPRT(6,16,0),OPVUPRT_MASK,	PPCVLE,	0,		{D8, RA0}},
+{"e_stmvgprw",	OPVUPRT(6,17,0),OPVUPRT_MASK,	PPCVLE,	0,		{D8, RA0}},
+{"e_ldmvsprw",	OPVUPRT(6,16,1),OPVUPRT_MASK,	PPCVLE,	0,		{D8, RA0}},
+{"e_stmvsprw",	OPVUPRT(6,17,1),OPVUPRT_MASK,	PPCVLE,	0,		{D8, RA0}},
+{"e_ldmvsrrw",	OPVUPRT(6,16,4),OPVUPRT_MASK,	PPCVLE,	0,		{D8, RA0}},
+{"e_stmvsrrw",	OPVUPRT(6,17,4),OPVUPRT_MASK,	PPCVLE,	0,		{D8, RA0}},
+{"e_ldmvcsrrw",	OPVUPRT(6,16,5),OPVUPRT_MASK,	PPCVLE,	0,		{D8, RA0}},
+{"e_stmvcsrrw",	OPVUPRT(6,17,5),OPVUPRT_MASK,	PPCVLE,	0,		{D8, RA0}},
+{"e_ldmvdsrrw",	OPVUPRT(6,16,6),OPVUPRT_MASK,	PPCVLE,	0,		{D8, RA0}},
+{"e_stmvdsrrw",	OPVUPRT(6,17,6),OPVUPRT_MASK,	PPCVLE,	0,		{D8, RA0}},
 {"e_add16i",	OP(7),		OP_MASK,	PPCVLE,	0,		{RT, RA, SI}},
 {"e_la",	OP(7),		OP_MASK,	PPCVLE,	0,		{RT, D, RA0}},
 {"e_sub16i",	OP(7),		OP_MASK,	PPCVLE,	0,		{RT, RA, NSI}},
@@ -7144,10 +7169,8 @@ const struct powerpc_opcode vle_opcodes[] = {
 {"e_cmphl16i",	IA16(28,23),	IA16_MASK,	PPCVLE,	0,		{RA, VLEUIMM}},
 {"e_cmph16i",	IA16(28,22),	IA16_MASK,	PPCVLE,	0,		{RA, VLESIMM}},
 {"e_cmpl16i",	I16A(28,21),	I16A_MASK,	PPCVLE,	0,		{RA, VLEUIMM}},
-{"e_cmplwi",	I16A(28,21),	I16A_MASK,	PPCVLE,	0,		{RA, VLESIMM}},
 {"e_mull2i",	I16A(28,20),	I16A_MASK,	PPCVLE,	0,		{RA, VLESIMM}},
 {"e_cmp16i",	IA16(28,19),	IA16_MASK,	PPCVLE,	0,		{RA, VLESIMM}},
-{"e_cmpwi",	IA16(28,19),	IA16_MASK,	PPCVLE,	0,		{RA, VLESIMM}},
 {"e_sub2is",	I16A(28,18),	I16A_MASK,	PPCVLE,	0,		{RA, VLENSIMM}},
 {"e_add2is",	I16A(28,18),	I16A_MASK,	PPCVLE,	0,		{RA, VLESIMM}},
 {"e_sub2i.",	I16A(28,17),	I16A_MASK,	PPCVLE,	0,		{RA, VLENSIMM}},

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2017-06-24 13:22 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-24 15:32 [PATCH] PowerPC VLE changes Александр Федотов
2017-03-27 14:32 ` Andrew Jenner
2017-03-28 14:14   ` Александр Федотов
2017-03-28 23:33   ` Alan Modra
2017-03-29 19:36     ` Alexander Fedotov
2017-04-04  1:29       ` Alan Modra
2017-04-04 10:23         ` Alexander Fedotov
2017-04-04 10:33           ` Alexander Fedotov
2017-04-22  8:51             ` Alan Modra
  -- strict thread matches above, loose matches on Subject: below --
2017-06-23 20:52 Alexander Fedotov
2017-06-23 20:55 ` Alexander Fedotov
2017-06-23 20:56   ` Alexander Fedotov
2017-06-23 21:34     ` Alexander Fedotov
2017-06-24 13:22       ` Alan Modra
2017-06-24 13:21     ` Alan Modra
2017-06-24 13:18   ` Alan Modra
2017-06-24 13:11 ` Alan Modra
2016-07-26 16:41 Andrew Jenner
2016-07-26 23:26 ` Alan Modra
2016-08-01 16:43   ` Andrew Jenner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).