[RFA] e500 PPC port -- GAS

Elena Zannoni ezannoni@redhat.com
Sat Aug 17 20:54:00 GMT 2002



Gas and testsuite changes.

Elena


[gas]

2002-08-17  Elena Zannoni  <ezannoni@redhat.com>

        From matthew green  <mrg@redhat.com>

        * config/tc-ppc.c (PPC_OPCODE_CLASSIC): Enable this everywhere
        PPC_OPCODE_PPC is, except for BookE architectures.
        (md_parse_option): Add support for -mspe.
        (md_show_usage): Add -mspe.
        (md_parse_option): Add support for -me500 and
        -me500x2 to generate code for Motorola e500 core complex.
        (md_show_usage): Add -me500 and -me500x2.

        (PPC_APUINFO_ISEL, PPC_APUINFO_PMR, PPC_APUINFO_RFMCI,
        PPC_APUINFO_CACHELCK, PPC_APUINFO_SPE, PPC_APUINFO_EFS,
        PPC_APUINFO_BRLOCK): New macros.

        (ppc_cleanup): New function.
        (ppc_apuinfo_section_add): New function.
        (APUID): New macro.
        (md_assemble): Collect info and write the APUinfo section.

        * config/tc-ppc.h (md_cleanup): Define.
        (ppc_cleanup): Export.
        (ELF_TC_SPECIAL_SECTIONS): Add .PPC.EMB.apuinfo section.


Index: tc-ppc.c
===================================================================
RCS file: /cvs/uberbaum/gas/config/tc-ppc.c,v
retrieving revision 1.53
diff -u -r1.53 tc-ppc.c
--- tc-ppc.c	6 Aug 2002 02:30:06 -0000	1.53
+++ tc-ppc.c	18 Aug 2002 03:29:59 -0000
@@ -130,6 +130,7 @@
 static void ppc_elf_rdata PARAMS ((int));
 static void ppc_elf_lcomm PARAMS ((int));
 static void ppc_elf_validate_fix PARAMS ((fixS *, segT));
+static void ppc_apuinfo_section_add PARAMS((unsigned int apu, unsigned int version));
 #endif
 
 #ifdef TE_PE
@@ -787,6 +788,20 @@
 
 #ifdef OBJ_ELF
 symbolS *GOT_symbol;		/* Pre-defined "_GLOBAL_OFFSET_TABLE" */
+#define PPC_APUINFO_ISEL	0x40
+#define PPC_APUINFO_PMR		0x41
+#define PPC_APUINFO_RFMCI	0x42
+#define PPC_APUINFO_CACHELCK	0x43
+#define PPC_APUINFO_SPE		0x100
+#define PPC_APUINFO_EFS		0x101
+#define PPC_APUINFO_BRLOCK	0x102
+
+/* 
+ * We keep a list of APUinfo 
+ */
+unsigned long *ppc_apuinfo_list;
+unsigned int ppc_apuinfo_num;
+unsigned int ppc_apuinfo_num_alloc;
 #endif /* OBJ_ELF */
 
 #ifdef OBJ_ELF
@@ -870,43 +885,62 @@
       /* -m601 means to assemble for the PowerPC 601, which includes
 	 instructions that are holdovers from the Power.  */
       else if (strcmp (arg, "601") == 0)
-	ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_601 | PPC_OPCODE_32;
+	ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+	          | PPC_OPCODE_601 | PPC_OPCODE_32;
       /* -mppc, -mppc32, -m603, and -m604 mean to assemble for the
 	 PowerPC 603/604.  */
       else if (strcmp (arg, "ppc") == 0
 	       || strcmp (arg, "ppc32") == 0
 	       || strcmp (arg, "603") == 0
 	       || strcmp (arg, "604") == 0)
-	ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_32;
+	ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
       /* -m403 and -m405 mean to assemble for the PowerPC 403/405.  */
       else if (strcmp (arg, "403") == 0
                || strcmp (arg, "405") == 0)
-	ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_32;
+	ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+                  | PPC_OPCODE_403 | PPC_OPCODE_32;
       else if (strcmp (arg, "7400") == 0
                || strcmp (arg, "7410") == 0
                || strcmp (arg, "7450") == 0
                || strcmp (arg, "7455") == 0)
-	ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC | PPC_OPCODE_32;
+	ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+                  | PPC_OPCODE_ALTIVEC | PPC_OPCODE_32;
       else if (strcmp (arg, "altivec") == 0)
         {
           if (ppc_cpu == 0)
-            ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC;
+            ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC;
           else
             ppc_cpu |= PPC_OPCODE_ALTIVEC;
         }
+      else if (strcmp (arg, "e500") == 0 || strcmp (arg, "e500x2") == 0)
+	{
+	  ppc_cpu = 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;
+        }
+      else if (strcmp (arg, "spe") == 0)
+	{
+	  if (ppc_cpu == 0)
+	    ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_SPE | PPC_OPCODE_EFS;
+	  else
+	    ppc_cpu |= PPC_OPCODE_SPE;
+	}
       /* -mppc64 and -m620 mean to assemble for the 64-bit PowerPC
 	 620.  */
       else if (strcmp (arg, "ppc64") == 0 || strcmp (arg, "620") == 0)
 	{
-	  ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64;
+	  ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
 	}
       else if (strcmp (arg, "ppc64bridge") == 0)
 	{
-	  ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE | PPC_OPCODE_64;
+	  ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+                    | PPC_OPCODE_64_BRIDGE | PPC_OPCODE_64;
 	}
       /* -mbooke/-mbooke32 mean enable 32-bit BookE support.  */
       else if (strcmp (arg, "booke") == 0 || strcmp (arg, "booke32") == 0)
-	ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32;
+	{
+	  ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32;
+	}
       /* -mbooke64 means enable 64-bit BookE support.  */
       else if (strcmp (arg, "booke64") == 0)
 	{
@@ -915,7 +949,8 @@
 	}
       else if (strcmp (arg, "power4") == 0)
 	{
-	  ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4;
+	  ppc_cpu = PPC_OPCODE_PPC| PPC_OPCODE_CLASSIC
+                    | PPC_OPCODE_64 | PPC_OPCODE_POWER4;
 	}
       /* -mcom means assemble for the common intersection between Power
 	 and PowerPC.  At present, we just allow the union, rather
@@ -1037,6 +1072,9 @@
 -many			generate code for any architecture (PWR/PWRX/PPC)\n\
 -mregnames		Allow symbolic names for registers\n\
 -mno-regnames		Do not allow symbolic names for registers\n"));
+  fprintf (stream, _("\
+-me500, -me500x2	generate code for Motorola e500 core complex\n\
+-mspe			generate code for Motorola SPE instructions\n"));
 #ifdef OBJ_ELF
   fprintf (stream, _("\
 -mrelocatable		support for GCC's -mrelocatble option\n\
@@ -1070,12 +1108,12 @@
       else if (strcmp (default_cpu, "rs6000") == 0)
 	ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_32;
       else if (strncmp (default_cpu, "powerpc", 7) == 0)
-	{
-	  if (default_cpu[7] == '6' && default_cpu[8] == '4')
-	    ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64;
-	  else
-	    ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_32;
-	}
+        {
+          if (default_cpu[7] == '6' && default_cpu[8] == '4')
+            ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
+          else
+            ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
+        }
       else
 	as_fatal (_("Unknown default cpu = %s, os = %s"),
 		  default_cpu, default_os);
@@ -1240,6 +1278,64 @@
 #endif
 }
 
+void
+ppc_cleanup ()
+{
+  if (ppc_apuinfo_list == NULL)
+    return;
+
+  /* Ok, so write the section info out.  We have this layout:
+
+  byte	data		what
+  ----	----		----
+  0	8		length of "APUinfo\0"
+  4	(n*4)		number of APU's (4 bytes each)
+  8	2		note type 2
+  12	"APUinfo\0"	name
+  20	APU#1		first APU's info
+  24	APU#2		second APU's info
+  ...	...
+  */
+  {
+    char *p;
+    asection *seg = now_seg;
+    subsegT subseg = now_subseg;
+    asection *apuinfo_secp = (asection *) NULL;
+    int i;
+
+    /* Create the .PPC.EMB.apuinfo section.  */
+    apuinfo_secp = subseg_new (".PPC.EMB.apuinfo", 0);
+    bfd_set_section_flags (stdoutput,
+			   apuinfo_secp,
+			   SEC_HAS_CONTENTS | SEC_READONLY | SEC_MERGE);
+
+    p = frag_more (4);
+    md_number_to_chars (p, (valueT) 8, 4);
+
+    p = frag_more (4);
+    md_number_to_chars (p, (valueT) ppc_apuinfo_num, 4);
+
+    p = frag_more (4);
+    md_number_to_chars (p, (valueT) 2, 4);
+
+    p = frag_more (8);
+    strcpy (p, "APUinfo");
+
+    for (i = 0; i < ppc_apuinfo_num; i++)
+      {
+        p = frag_more (4);
+        md_number_to_chars (p, (valueT) ppc_apuinfo_list[i], 4);
+      }
+
+    frag_align (2, 0, 0);
+
+    /* We probably can't restore the current segment, for there likely
+       isn't one yet...  */
+    if (seg && subseg)
+      subseg_set (seg, subseg);
+  }
+}
+
 /* Insert an operand value into an instruction.  */
 
 static unsigned long
@@ -1837,6 +1933,38 @@
 #endif
 
 
+#define APUID(a,v)	((((a) & 0xffff) << 16) | ((v) & 0xffff))
+static void
+ppc_apuinfo_section_add(apu, version)
+      unsigned int apu, version;
+{
+  unsigned int i;
+
+  /* Check we don't already exist.  */
+  for (i = 0; i < ppc_apuinfo_num; i++)
+    if (ppc_apuinfo_list[i] == APUID(apu, version))
+      return;
+    
+  if (ppc_apuinfo_num == ppc_apuinfo_num_alloc)
+    {
+      if (ppc_apuinfo_num_alloc == 0)
+	{
+	  ppc_apuinfo_num_alloc = 4;
+	  ppc_apuinfo_list = (unsigned long *)
+	      xmalloc (sizeof (unsigned long) * ppc_apuinfo_num_alloc);
+	}
+      else
+	{
+	  ppc_apuinfo_num_alloc += 4;
+	  ppc_apuinfo_list = (unsigned long *) xrealloc (ppc_apuinfo_list,
+	      sizeof (unsigned long) * ppc_apuinfo_num_alloc);
+	}
+    }
+  ppc_apuinfo_list[ppc_apuinfo_num++] = APUID(apu, version);
+}
+#undef APUID
+
+
 /* We need to keep a list of fixups.  We can't simply generate them as
    we go, because that would require us to first create the frag, and
    that would screw up references to ``.''.  */
@@ -1961,7 +2089,6 @@
 	  operand = &powerpc_operands[next_opindex];
 	  next_opindex = 0;
 	}
-
       errmsg = NULL;
 
       /* If this is a fake operand, then we do not expect anything
@@ -2322,6 +2449,29 @@
   if (*str != '\0')
     as_bad (_("junk at end of line: `%s'"), str);
 
+  /* Do we need/want a APUinfo section? */
+  if (ppc_cpu & (PPC_OPCODE_SPE
+   	       | PPC_OPCODE_ISEL | PPC_OPCODE_EFS
+	       | PPC_OPCODE_BRLOCK | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
+	       | PPC_OPCODE_RFMCI))
+    {
+      /* These are all version "1".  */
+      if (opcode->flags & PPC_OPCODE_SPE)
+        ppc_apuinfo_section_add(PPC_APUINFO_SPE, 1);
+      if (opcode->flags & PPC_OPCODE_ISEL)
+        ppc_apuinfo_section_add(PPC_APUINFO_ISEL, 1);
+      if (opcode->flags & PPC_OPCODE_EFS)
+        ppc_apuinfo_section_add(PPC_APUINFO_EFS, 1);
+      if (opcode->flags & PPC_OPCODE_BRLOCK)
+        ppc_apuinfo_section_add(PPC_APUINFO_BRLOCK, 1);
+      if (opcode->flags & PPC_OPCODE_PMR)
+        ppc_apuinfo_section_add(PPC_APUINFO_PMR, 1);
+      if (opcode->flags & PPC_OPCODE_CACHELCK)
+        ppc_apuinfo_section_add(PPC_APUINFO_CACHELCK, 1);
+      if (opcode->flags & PPC_OPCODE_RFMCI)
+        ppc_apuinfo_section_add(PPC_APUINFO_RFMCI, 1);
+    }
+
   /* Write out the instruction.  */
   f = frag_more (4);
   md_number_to_chars (f, insn, 4);
@@ -5221,16 +5371,16 @@
 	  && operand->shift == 0)
 	fixP->fx_r_type = BFD_RELOC_PPC_B26;
       else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
-	  && operand->bits == 16
-	  && operand->shift == 0)
-	{
-	  fixP->fx_r_type = BFD_RELOC_PPC_B16;
+	 && operand->bits == 16
+	 && operand->shift == 0)
+       {
+         fixP->fx_r_type = BFD_RELOC_PPC_B16;
 #ifdef OBJ_XCOFF
-	  fixP->fx_size = 2;
-	  if (target_big_endian)
-	    fixP->fx_where += 2;
+         fixP->fx_size = 2;
+         if (target_big_endian)
+           fixP->fx_where += 2;
 #endif
-	}
+       }
       else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
 	       && operand->bits == 26
 	       && operand->shift == 0)
@@ -5238,14 +5388,14 @@
       else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
 	       && operand->bits == 16
 	       && operand->shift == 0)
-	{
-	  fixP->fx_r_type = BFD_RELOC_PPC_BA16;
+        {
+          fixP->fx_r_type = BFD_RELOC_PPC_BA16;
 #ifdef OBJ_XCOFF
-	  fixP->fx_size = 2;
-	  if (target_big_endian)
-	    fixP->fx_where += 2;
+          fixP->fx_size = 2;
+          if (target_big_endian)
+            fixP->fx_where += 2;
 #endif
-	}
+        }
 #if defined (OBJ_XCOFF) || defined (OBJ_ELF)
       else if ((operand->flags & PPC_OPERAND_PARENS) != 0
 	       && operand->bits == 16
Index: tc-ppc.h
===================================================================
RCS file: /cvs/uberbaum/gas/config/tc-ppc.h,v
retrieving revision 1.18
diff -u -r1.18 tc-ppc.h
--- tc-ppc.h	11 Jul 2002 01:07:49 -0000	1.18
+++ tc-ppc.h	18 Aug 2002 03:29:59 -0000
@@ -248,6 +248,7 @@
   { ".sbss",		SHT_NOBITS,	SHF_ALLOC + SHF_WRITE },	\
   { ".sdata2",		SHT_PROGBITS,	SHF_ALLOC },			\
   { ".sbss2",		SHT_PROGBITS,	SHF_ALLOC },			\
+  { ".PPC.EMB.apuinfo",       SHT_NOTE,       0 }, \
   { ".PPC.EMB.sdata0",	SHT_PROGBITS,	SHF_ALLOC },			\
   { ".PPC.EMB.sbss0",	SHT_PROGBITS,	SHF_ALLOC },			\
   /* Extra sections for 64-bit ELF PPC.  */				\
@@ -285,3 +286,6 @@
 extern int ppc_parse_name PARAMS ((const char *, struct expressionS *));
 
 #define md_operand(x)
+
+#define md_cleanup() ppc_cleanup ()
+ extern void ppc_cleanup PARAMS ((void));




[gas/testsuite]


2002-08-17  Elena Zannoni   <ezannoni@redhat.com>

        From  matthew green  <mrg@redhat.com>

        * e500.s: New tests for e500 instructions.
        * e500.d: Results for new test.
        * ppc.exp: Test e500.s.

Index: ppc.exp
===================================================================
RCS file: /cvs/uberbaum/gas/testsuite/gas/ppc/ppc.exp,v
retrieving revision 1.6
diff -u -r1.6 ppc.exp
--- ppc.exp     21 Feb 2002 03:57:34 -0000      1.6
+++ ppc.exp     18 Aug 2002 03:39:23 -0000
@@ -37,3 +37,7 @@
        run_dump_test "booke"
     }
 }
+
+if { [istarget powerpc*-*-*] } then {
+   run_dump_test "e500"
+}



--- /dev/null   Sat Aug 17 18:49:30 2002
+++ e500.s      Sat Aug 17 17:15:06 2002
@@ -0,0 +1,15 @@
+# Motorola PowerPC e500 tests
+       .section ".text"
+start:
+       isel    2, 3, 4, 23
+       dcblc   4, 5, 6
+       dcbtls  7, 8, 9
+       dcbtstls 10, 11, 12
+       icbtls  13, 14, 15
+       icblc   16, 17, 18
+       mtpmr   201, 4
+       mfpmr   5, 203
+       bblels
+       bbelr
+       mtspefscr       8
+       mfspefscr       9



--- /dev/null   Sat Aug 17 18:49:30 2002
+++ e500.d      Sat Aug 17 17:15:06 2002
@@ -0,0 +1,22 @@
+#as: -mppc -me500
+#objdump: -Dr -Me500
+#name: e500 tests
+
+.*: +file format elf(32)?(64)?-powerpc
+
+Disassembly of section \.text:
+
+0+0000000 <start>:
+   0:  7c 43 25 de     isel    r2,r3,r4,23
+   4:  7c 85 33 0c     dcblc   4,r5,r6
+   8:  7c e8 49 4c     dcbtls  7,r8,r9
+   c:  7d 4b 61 0c     dcbtstls        10,r11,r12
+  10:  7d ae 7b cc     icbtls  13,r14,r15
+  14:  7e 11 91 cc     icblc   16,r17,r18
+  18:  7c 89 43 9c     mtpmr   r41,r4
+  1c:  7c ab 52 9c     mfpmr   r5,r43
+  20:  7c 00 04 0c     bblels
+  24:  7c 00 04 4c     bbelr
+  28:  7d 00 83 a6     mtspefscr       r8
+  2c:  7d 20 82 a6     mfspefscr       r9
+Disassembly of section \.data:



More information about the Binutils mailing list