Release 2.21.1 ?

Andreas Krebbel krebbel@linux.vnet.ibm.com
Tue May 17 17:31:00 GMT 2011


> Yes, that's OK.

Here is the backport for 2.21 of:

[PATCH] S/390: Support the .machine pseudo
http://sourceware.org/ml/binutils/2011-04/msg00191.html

the backported patch also includes the trivial change:

[Committed] S/390: gas: Add -march=all
http://sourceware.org/ml/binutils/2011-03/msg00355.html

Ok for 2.21?

Bye,

-Andreas-


2011-05-17  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	Backported from mainline
	2011-03-18  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	* config/tc-s390.c (md_parse_option): Add -march=all option which
	switches to the highest available CPU.

	2011-04-14  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	* config/tc-s390.c (s390_machine): New prototype.
	(md_pseudo_table): New pseudo-op .machine.
	(s390_opcode_hash): Initialize to NULL.
	(s390_parse_cpu): New function.
	(md_parse_option): Use s390_parse_cpu.
	(s390_setup_opcodes): New function.
	(md_begin): Use s390_setup_opcodes.
	(s390_machine): New hook handling the new .machine pseudo.

	* doc/c-s390.texi: Document the new pseudo op .machine.


2011-05-17  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	    Backported from mainline
	    2011-04-14  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	    * gas/s390/zarch-machine.s: New testcase.
	    * gas/s390/zarch-machine.d: New testcase output.
	    * gas/s390/s390.exp: Execute the new testcase.


Index: gas/config/tc-s390.c
===================================================================
--- gas/config/tc-s390.c.orig
+++ gas/config/tc-s390.c
@@ -85,6 +85,7 @@ static void s390_elf_cons (int);
 static void s390_bss (int);
 static void s390_insn (int);
 static void s390_literals (int);
+static void s390_machine (int);
 
 const pseudo_typeS md_pseudo_table[] =
 {
@@ -99,6 +100,7 @@ const pseudo_typeS md_pseudo_table[] =
   { "quad",     s390_elf_cons,  8 },
   { "ltorg",    s390_literals,  0 },
   { "string",   stringer,       8 + 1 },
+  { "machine",  s390_machine,   0 },
   { NULL,	NULL,		0 }
 };
 
@@ -293,7 +295,7 @@ register_name (expressionS *expressionP)
 static struct hash_control *s390_opformat_hash;
 
 /* Opcode hash table.  */
-static struct hash_control *s390_opcode_hash;
+static struct hash_control *s390_opcode_hash = NULL;
 
 /* Flags to set in the elf header */
 static flagword s390_flags = 0;
@@ -350,6 +352,35 @@ s390_target_format (void)
   return s390_arch_size == 64 ? "elf64-s390" : "elf32-s390";
 }
 
+/* Map a CPU string as given with -march= or .machine to the
+   respective enum s390_opcode_cpu_val value.  0xffffffff is returned
+   in case of an error.  */
+
+static unsigned int
+s390_parse_cpu (char *arg)
+{
+  if (strcmp (arg, "g5") == 0)
+    return S390_OPCODE_G5;
+  else if (strcmp (arg, "g6") == 0)
+    return S390_OPCODE_G6;
+  else if (strcmp (arg, "z900") == 0)
+    return S390_OPCODE_Z900;
+  else if (strcmp (arg, "z990") == 0)
+    return S390_OPCODE_Z990;
+  else if (strcmp (arg, "z9-109") == 0)
+    return S390_OPCODE_Z9_109;
+  else if (strcmp (arg, "z9-ec") == 0)
+    return S390_OPCODE_Z9_EC;
+  else if (strcmp (arg, "z10") == 0)
+    return S390_OPCODE_Z10;
+  else if (strcmp (arg, "z196") == 0)
+    return S390_OPCODE_Z196;
+  else if (strcmp (arg, "all") == 0)
+    return S390_OPCODE_MAXCPU - 1;
+  else
+    return -1;
+}
+
 int
 md_parse_option (int c, char *arg)
 {
@@ -382,23 +413,9 @@ md_parse_option (int c, char *arg)
 
       else if (arg != NULL && strncmp (arg, "arch=", 5) == 0)
 	{
-	  if (strcmp (arg + 5, "g5") == 0)
-	    current_cpu = S390_OPCODE_G5;
-	  else if (strcmp (arg + 5, "g6") == 0)
-	    current_cpu = S390_OPCODE_G6;
-	  else if (strcmp (arg + 5, "z900") == 0)
-	    current_cpu = S390_OPCODE_Z900;
-	  else if (strcmp (arg + 5, "z990") == 0)
-	    current_cpu = S390_OPCODE_Z990;
-	  else if (strcmp (arg + 5, "z9-109") == 0)
-	    current_cpu = S390_OPCODE_Z9_109;
-	  else if (strcmp (arg + 5, "z9-ec") == 0)
-	    current_cpu = S390_OPCODE_Z9_EC;
-	  else if (strcmp (arg + 5, "z10") == 0)
-	    current_cpu = S390_OPCODE_Z10;
-	  else if (strcmp (arg + 5, "z196") == 0)
-	    current_cpu = S390_OPCODE_Z196;
-	  else
+	  current_cpu = s390_parse_cpu (arg + 5);
+
+	  if (current_cpu == (unsigned int)-1)
 	    {
 	      as_bad (_("invalid switch -m%s"), arg);
 	      return 0;
@@ -454,42 +471,20 @@ md_show_usage (FILE *stream)
         -Qy, -Qn          ignored\n"));
 }
 
-/* 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.  */
+/* Generate the hash table mapping mnemonics to struct s390_opcode.
+   This table is built at startup and whenever the CPU level is
+   changed using .machine.  */
 
-void
-md_begin (void)
+static void
+s390_setup_opcodes (void)
 {
   register const struct s390_opcode *op;
   const struct s390_opcode *op_end;
   bfd_boolean dup_insn = FALSE;
   const char *retval;
 
-  /* Give a warning if the combination -m64-bit and -Aesa is used.  */
-  if (s390_arch_size == 64 && current_cpu < S390_OPCODE_Z900)
-    as_warn (_("The 64 bit file format is used without esame instructions."));
-
-  s390_cie_data_alignment = -s390_arch_size / 8;
-
-  /* Set the ELF flags if desired.  */
-  if (s390_flags)
-    bfd_set_private_flags (stdoutput, s390_flags);
-
-  /* Insert the opcode formats into a hash table.  */
-  s390_opformat_hash = hash_new ();
-
-  op_end = s390_opformats + s390_num_opformats;
-  for (op = s390_opformats; op < op_end; op++)
-    {
-      retval = hash_insert (s390_opformat_hash, op->name, (void *) op);
-      if (retval != (const char *) NULL)
-	{
-	  as_bad (_("Internal assembler error for instruction format %s"),
-		  op->name);
-	  dup_insn = TRUE;
-	}
-    }
+  if (s390_opcode_hash != NULL)
+    hash_die (s390_opcode_hash);
 
   /* Insert the opcodes into a hash table.  */
   s390_opcode_hash = hash_new ();
@@ -521,11 +516,50 @@ md_begin (void)
 
   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 (void)
+{
+  register const struct s390_opcode *op;
+  const struct s390_opcode *op_end;
+  bfd_boolean dup_insn = FALSE;
+  const char *retval;
+
+  /* Give a warning if the combination -m64-bit and -Aesa is used.  */
+  if (s390_arch_size == 64 && current_cpu < S390_OPCODE_Z900)
+    as_warn (_("The 64 bit file format is used without esame instructions."));
+
+  s390_cie_data_alignment = -s390_arch_size / 8;
+
+  /* Set the ELF flags if desired.  */
+  if (s390_flags)
+    bfd_set_private_flags (stdoutput, s390_flags);
+
+  /* Insert the opcode formats into a hash table.  */
+  s390_opformat_hash = hash_new ();
+
+  op_end = s390_opformats + s390_num_opformats;
+  for (op = s390_opformats; op < op_end; op++)
+    {
+      retval = hash_insert (s390_opformat_hash, op->name, (void *) op);
+      if (retval != (const char *) NULL)
+	{
+	  as_bad (_("Internal assembler error for instruction format %s"),
+		  op->name);
+	  dup_insn = TRUE;
+	}
+    }
+
+  s390_setup_opcodes ();
 
   record_alignment (text_section, 2);
   record_alignment (data_section, 2);
   record_alignment (bss_section, 2);
-
 }
 
 /* Called after all assembly has been done.  */
@@ -1753,6 +1787,72 @@ s390_literals (int ignore ATTRIBUTE_UNUS
   lpe_count = 0;
 }
 
+/* The .machine pseudo op allows to switch to a different CPU level in
+   the asm listing.  The current CPU setting can be stored on a stack
+   with .machine push and restored with .machined pop.  */
+
+static void
+s390_machine (int ignore ATTRIBUTE_UNUSED)
+{
+  char *cpu_string;
+#define MAX_HISTORY 100
+  static unsigned int *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 int old_cpu = current_cpu;
+      unsigned int new_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++] = current_cpu;
+	}
+      else if (strcmp (cpu_string, "pop") == 0)
+	{
+	  if (curr_hist <= 0)
+	    as_bad (_(".machine stack underflow"));
+	  else
+	    current_cpu = cpu_history[--curr_hist];
+	}
+      else if ((new_cpu = s390_parse_cpu (cpu_string)) != (unsigned int)-1)
+	current_cpu = new_cpu;
+      else
+	as_bad (_("invalid machine `%s'"), cpu_string);
+
+      if (current_cpu != old_cpu)
+	s390_setup_opcodes ();
+    }
+
+  demand_empty_rest_of_line ();
+}
+
 char *
 md_atof (int type, char *litp, int *sizep)
 {
Index: gas/doc/c-s390.texi
===================================================================
--- gas/doc/c-s390.texi.orig
+++ gas/doc/c-s390.texi
@@ -851,6 +851,17 @@ ELF extension documentation @samp{ELF Ha
 @item .ltorg
 This directive causes the current contents of the literal pool to be
 dumped to the current location (@ref{s390 Literal Pool Entries}).
+
+@cindex @code{.machine} directive, s390
+@item .machine string
+This directive allows you to change the machine for which code is
+generated.  @code{string} may be any of the @code{-march=} selection
+options (without the -march=), @code{push}, or @code{pop}.
+@code{.machine push} saves the currently selected cpu, which may be
+restored with @code{.machine pop}.  Be aware that the cpu string has
+to be put into double quotes in case it contains characters not
+appropriate for identifiers.  So you have to write @code{"z9-109"}
+instead of just @code{z9-109}.
 @end table
 
 @node s390 Floating Point
Index: gas/testsuite/gas/s390/zarch-machine.d
===================================================================
--- /dev/null
+++ gas/testsuite/gas/s390/zarch-machine.d
@@ -0,0 +1,12 @@
+#name: s390x machine
+#objdump: -dr
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+.* <foo>:
+.*:	e3 95 af ff 00 08 [ 	]*ag	%r9,4095\(%r5,%r10\)
+.*:	eb d6 65 b3 01 6a [ 	]*asi	5555\(%r6\),-42
+.*:	e3 95 af ff 00 18 [ 	]*agf	%r9,4095\(%r5,%r10\)
+.*:	07 07 [ 	]*nopr	%r7
Index: gas/testsuite/gas/s390/zarch-machine.s
===================================================================
--- /dev/null
+++ gas/testsuite/gas/s390/zarch-machine.s
@@ -0,0 +1,8 @@
+.text
+foo:
+	ag	%r9,4095(%r5,%r10)
+.machine push
+.machine z10
+	asi	5555(%r6),-42
+.machine pop
+	agf	%r9,4095(%r5,%r10)
Index: gas/testsuite/gas/s390/s390.exp
===================================================================
--- gas/testsuite/gas/s390/s390.exp.orig
+++ gas/testsuite/gas/s390/s390.exp
@@ -27,4 +27,5 @@ if [expr [istarget "s390-*-*"] ||  [ista
     run_dump_test "zarch-z196" "{as -m64} {as -march=z196}"
     run_dump_test "zarch-reloc" "{as -m64}"
     run_dump_test "zarch-operands" "{as -m64} {as -march=z9-109}"
+    run_dump_test "zarch-machine" "{as -m64} {as -march=z900}"
 }



More information about the Binutils mailing list