This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

.machine pseudo op for ppc


I was going to do this using .cpu, but .machine is apparently already
used on other ppc assemblers.

gas/ChangeLog
	* config/tc-ppc.c (parse_cpu): New function, broken out from..
	(md_parse_option): ..here.
	(ppc_setup_opcodes): New function, broken out from..
	(md_begin): ..here.
	(ppc_machine): Implement .machine pseudo op.

gas/testsuite/ChangeLog
	* gas/ppc/machine.s: New.
	* gas/ppc/machine.d: New.
	* gas/ppc/ppc.exp: Run it.

Index: gas/config/tc-ppc.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-ppc.c,v
retrieving revision 1.82
diff -u -p -r1.82 tc-ppc.c
--- gas/config/tc-ppc.c	4 Sep 2003 01:52:18 -0000	1.82
+++ gas/config/tc-ppc.c	21 Nov 2003 15:00:35 -0000
@@ -819,6 +819,107 @@ const struct option md_longopts[] = {
 };
 const size_t md_longopts_size = sizeof (md_longopts);
 
+
+/* Handle -m options that set cpu type, and .machine arg.  */
+
+static int
+parse_cpu (const char *arg)
+{
+  /* -mpwrx and -mpwr2 mean to assemble for the IBM POWER/2
+     (RIOS2).  */
+  if (strcmp (arg, "pwrx") == 0 || strcmp (arg, "pwr2") == 0)
+    ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_32;
+  /* -mpwr means to assemble for the IBM POWER (RIOS1).  */
+  else if (strcmp (arg, "pwr") == 0)
+    ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_32;
+  /* -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_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_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_CLASSIC
+	       | PPC_OPCODE_403 | PPC_OPCODE_32);
+  else if (strcmp (arg, "440") == 0)
+    ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32
+	       | PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI);
+  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_CLASSIC
+	       | PPC_OPCODE_ALTIVEC | PPC_OPCODE_32);
+  else if (strcmp (arg, "altivec") == 0)
+    {
+      if (ppc_cpu == 0)
+	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_CLASSIC | PPC_OPCODE_64;
+    }
+  else if (strcmp (arg, "ppc64bridge") == 0)
+    {
+      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;
+    }
+  /* -mbooke64 means enable 64-bit BookE support.  */
+  else if (strcmp (arg, "booke64") == 0)
+    {
+      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE
+		 | PPC_OPCODE_BOOKE64 | PPC_OPCODE_64);
+    }
+  else if (strcmp (arg, "power4") == 0)
+    {
+      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
+     than the intersection.  */
+  else if (strcmp (arg, "com") == 0)
+    ppc_cpu = PPC_OPCODE_COMMON | PPC_OPCODE_32;
+  /* -many means to assemble for any architecture (PWR/PWRX/PPC).  */
+  else if (strcmp (arg, "any") == 0)
+    ppc_cpu |= PPC_OPCODE_ANY;
+  else
+    return 0;
+
+  return 1;
+}
+
 int
 md_parse_option (c, arg)
      int c;
@@ -886,95 +987,8 @@ md_parse_option (c, arg)
       break;
 
     case 'm':
-      /* -mpwrx and -mpwr2 mean to assemble for the IBM POWER/2
-	 (RIOS2).  */
-      if (strcmp (arg, "pwrx") == 0 || strcmp (arg, "pwr2") == 0)
-	ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_32;
-      /* -mpwr means to assemble for the IBM POWER (RIOS1).  */
-      else if (strcmp (arg, "pwr") == 0)
-	ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_32;
-      /* -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_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_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_CLASSIC
-		   | PPC_OPCODE_403 | PPC_OPCODE_32);
-      else if (strcmp (arg, "440") == 0)
-	ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32
-		   | PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI);
-      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_CLASSIC
-		   | PPC_OPCODE_ALTIVEC | PPC_OPCODE_32);
-      else if (strcmp (arg, "altivec") == 0)
-	{
-	  if (ppc_cpu == 0)
-	    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_CLASSIC | PPC_OPCODE_64;
-	}
-      else if (strcmp (arg, "ppc64bridge") == 0)
-	{
-	  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;
-	}
-      /* -mbooke64 means enable 64-bit BookE support.  */
-      else if (strcmp (arg, "booke64") == 0)
-	{
-	  ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE
-		     | PPC_OPCODE_BOOKE64 | PPC_OPCODE_64);
-	}
-      else if (strcmp (arg, "power4") == 0)
-	{
-	  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
-	 than the intersection.  */
-      else if (strcmp (arg, "com") == 0)
-	ppc_cpu = PPC_OPCODE_COMMON | PPC_OPCODE_32;
-      /* -many means to assemble for any architecture (PWR/PWRX/PPC).  */
-      else if (strcmp (arg, "any") == 0)
-	ppc_cpu |= PPC_OPCODE_ANY;
+      if (parse_cpu (arg))
+	;
 
       else if (strcmp (arg, "regnames") == 0)
 	reg_names_p = TRUE;
@@ -1200,12 +1214,11 @@ ppc_target_format ()
 #endif
 }
 
-/* This function is called when the assembler starts up.  It is called
-   after the options have been parsed and the output file has been
-   opened.  */
+/* Insert opcodes and macros into hash tables.  Called at startup and
+   for .cpu pseudo.  */
 
-void
-md_begin ()
+static void
+ppc_setup_opcodes (void)
 {
   register const struct powerpc_opcode *op;
   const struct powerpc_opcode *op_end;
@@ -1213,15 +1226,10 @@ md_begin ()
   const struct powerpc_macro *macro_end;
   bfd_boolean dup_insn = FALSE;
 
-  ppc_set_cpu ();
-
-  ppc_cie_data_alignment = ppc_obj64 ? -8 : -4;
-
-#ifdef OBJ_ELF
-  /* Set the ELF flags if desired.  */
-  if (ppc_flags && !msolaris)
-    bfd_set_private_flags (stdoutput, ppc_flags);
-#endif
+  if (ppc_hash != NULL)
+    hash_die (ppc_hash);
+  if (ppc_macro_hash != NULL)
+    hash_die (ppc_macro_hash);
 
   /* Insert the opcodes into a hash table.  */
   ppc_hash = hash_new ();
@@ -1251,7 +1259,7 @@ md_begin ()
 	  const char *retval;
 
 	  retval = hash_insert (ppc_hash, op->name, (PTR) op);
-	  if (retval != (const char *) NULL)
+	  if (retval != NULL)
 	    {
 	      /* Ignore Power duplicates for -m601.  */
 	      if ((ppc_cpu & PPC_OPCODE_601) != 0
@@ -1290,6 +1298,26 @@ md_begin ()
 
   if (dup_insn)
     abort ();
+}
+
+/* This function is called when the assembler starts up.  It is called
+   after the options have been parsed and the output file has been
+   opened.  */
+
+void
+md_begin ()
+{
+  ppc_set_cpu ();
+
+  ppc_cie_data_alignment = ppc_obj64 ? -8 : -4;
+
+#ifdef OBJ_ELF
+  /* Set the ELF flags if desired.  */
+  if (ppc_flags && !msolaris)
+    bfd_set_private_flags (stdoutput, ppc_flags);
+#endif
+
+  ppc_setup_opcodes ();
 
   /* Tell the main code what the endianness is if it is not overidden
      by the user.  */
@@ -3967,18 +3995,67 @@ ppc_tc (ignore)
 }
 
 /* Pseudo-op .machine.  */
-/* FIXME: `.machine' is a nop for the moment.  It would be nice to
-   accept this directive on the first line of input and set ppc_obj64
-   and the target format accordingly.  Unfortunately, the target
-   format is selected in output-file.c:output_file_create before we
-   even get to md_begin, so it's not possible without changing
-   as.c:main.  */
 
 static void
 ppc_machine (ignore)
      int ignore ATTRIBUTE_UNUSED;
 {
-  discard_rest_of_line ();
+  char *cpu_string;
+#define MAX_HISTORY 100
+  static unsigned long *cpu_history;
+  static int curr_hist;
+
+  SKIP_WHITESPACE ();
+
+  if (*input_line_pointer == '"')
+    {
+      int len;
+      cpu_string = demand_copy_C_string (&len);
+    }
+  else
+    {
+      char c;
+      cpu_string = input_line_pointer;
+      c = get_symbol_end ();
+      cpu_string = xstrdup (cpu_string);
+      *input_line_pointer = c;
+    }
+
+  if (cpu_string != NULL)
+    {
+      unsigned long old_cpu = ppc_cpu;
+      char *p;
+
+      for (p = cpu_string; *p != 0; p++)
+	*p = TOLOWER (*p);
+
+      if (strcmp (cpu_string, "push") == 0)
+	{
+	  if (cpu_history == NULL)
+	    cpu_history = xmalloc (MAX_HISTORY * sizeof (*cpu_history));
+
+	  if (curr_hist >= MAX_HISTORY)
+	    as_bad (_(".machine stack overflow"));
+	  else
+	    cpu_history[curr_hist++] = ppc_cpu;
+	}
+      else if (strcmp (cpu_string, "pop") == 0)
+	{
+	  if (curr_hist <= 0)
+	    as_bad (_(".machine stack underflow"));
+	  else
+	    ppc_cpu = cpu_history[--curr_hist];
+	}
+      else if (parse_cpu (cpu_string))
+	;
+      else
+	as_bad (_("invalid machine `%s'"), cpu_string);
+
+      if (ppc_cpu != old_cpu)
+	ppc_setup_opcodes ();
+    }
+
+  demand_empty_rest_of_line ();
 }
 
 /* See whether a symbol is in the TOC section.  */
Index: gas/testsuite/gas/ppc/ppc.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/ppc/ppc.exp,v
retrieving revision 1.10
diff -u -p -r1.10 ppc.exp
--- gas/testsuite/gas/ppc/ppc.exp	4 Jul 2003 13:35:35 -0000	1.10
+++ gas/testsuite/gas/ppc/ppc.exp	21 Nov 2003 14:30:45 -0000
@@ -26,7 +26,8 @@ if { [istarget powerpc64*-*-*] || [istar
 }
 
 if { [istarget powerpc*-*-*] } then {
-   run_dump_test "simpshft"
+    run_dump_test "simpshft"
+    run_dump_test "machine"
 
     if { [istarget powerpc-*-*aix*] } then {
 	run_dump_test "altivec_xcoff"
Index: gas/testsuite/gas/ppc/machine.d
===================================================================
RCS file: gas/testsuite/gas/ppc/machine.d
diff -N gas/testsuite/gas/ppc/machine.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/ppc/machine.d	21 Nov 2003 14:36:53 -0000
@@ -0,0 +1,9 @@
+#objdump: -s -j .text
+#name: PowerPC .machine test
+
+.*
+
+Contents of section \.text:
+ 0000 7c11eba6 7c100ba6 4c000066 00000200 .*
+ 0010 44000002 4c0000a4 7c000224 4e800020 .*
+ 0020 7c11eba6 .*
Index: gas/testsuite/gas/ppc/machine.s
===================================================================
RCS file: gas/testsuite/gas/ppc/machine.s
diff -N gas/testsuite/gas/ppc/machine.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/ppc/machine.s	21 Nov 2003 14:36:53 -0000
@@ -0,0 +1,15 @@
+	.machine "403"
+	.text
+	mtpid 0
+	.machine push
+	.machine "booke"
+	mtpid 0
+	.machine Any
+	rfci
+	attn
+	sc
+	rfsvc
+	tlbiel 0
+	blr
+	.machine pop
+	mtpid 0

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]