forked from pool/binutils
dc97cafffe
- Backport s390 .machinemode pseudo insn OBS-URL: https://build.opensuse.org/request/show/145903 OBS-URL: https://build.opensuse.org/package/show/devel:gcc/binutils?expand=0&rev=121
204 lines
6.5 KiB
Diff
204 lines
6.5 KiB
Diff
binutils:e593ec3bee996af0d129eb53b2039d409e6e1d42
|
|
|
|
2012-09-06 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
|
|
|
|
* config/tc-s390.c (set_highgprs_p): New variable.
|
|
(s390_machinemode): New function.
|
|
(md_pseudo_table): Add new pseudo command machinemode.
|
|
(md_parse_option): Set set_highgprs_p to TRUE if -mzarch was
|
|
specified on command line.
|
|
(s390_elf_final_processing): Set the highgprs flag in the ELF
|
|
header depending on set_highgprs_p.
|
|
|
|
* doc/c-s390.texi: Document new pseudo machinemode.
|
|
|
|
diff --git a/gas/config/tc-s390.c b/gas/config/tc-s390.c
|
|
index 9bc582f..47ec175 100644
|
|
--- a/gas/config/tc-s390.c
|
|
+++ b/gas/config/tc-s390.c
|
|
@@ -44,6 +44,10 @@ static int s390_arch_size = 0;
|
|
static unsigned int current_cpu = S390_OPCODE_MAXCPU - 1;
|
|
static unsigned int current_mode_mask = 0;
|
|
|
|
+/* Set to TRUE if the highgprs flag in the ELF header needs to be set
|
|
+ for the output file. */
|
|
+static bfd_boolean set_highgprs_p = FALSE;
|
|
+
|
|
/* Whether to use user friendly register names. Default is TRUE. */
|
|
#ifndef TARGET_REG_NAMES_P
|
|
#define TARGET_REG_NAMES_P TRUE
|
|
@@ -86,22 +90,24 @@ static void s390_bss (int);
|
|
static void s390_insn (int);
|
|
static void s390_literals (int);
|
|
static void s390_machine (int);
|
|
+static void s390_machinemode (int);
|
|
|
|
const pseudo_typeS md_pseudo_table[] =
|
|
{
|
|
- { "align", s_align_bytes, 0 },
|
|
+ { "align", s_align_bytes, 0 },
|
|
/* Pseudo-ops which must be defined. */
|
|
- { "bss", s390_bss, 0 },
|
|
- { "insn", s390_insn, 0 },
|
|
+ { "bss", s390_bss, 0 },
|
|
+ { "insn", s390_insn, 0 },
|
|
/* Pseudo-ops which must be overridden. */
|
|
- { "byte", s390_byte, 0 },
|
|
- { "short", s390_elf_cons, 2 },
|
|
- { "long", s390_elf_cons, 4 },
|
|
- { "quad", s390_elf_cons, 8 },
|
|
- { "ltorg", s390_literals, 0 },
|
|
- { "string", stringer, 8 + 1 },
|
|
- { "machine", s390_machine, 0 },
|
|
- { NULL, NULL, 0 }
|
|
+ { "byte", s390_byte, 0 },
|
|
+ { "short", s390_elf_cons, 2 },
|
|
+ { "long", s390_elf_cons, 4 },
|
|
+ { "quad", s390_elf_cons, 8 },
|
|
+ { "ltorg", s390_literals, 0 },
|
|
+ { "string", stringer, 8 + 1 },
|
|
+ { "machine", s390_machine, 0 },
|
|
+ { "machinemode", s390_machinemode, 0 },
|
|
+ { NULL, NULL, 0 }
|
|
};
|
|
|
|
|
|
@@ -409,7 +415,11 @@ md_parse_option (int c, char *arg)
|
|
current_mode_mask = 1 << S390_OPCODE_ESA;
|
|
|
|
else if (arg != NULL && strcmp (arg, "zarch") == 0)
|
|
- current_mode_mask = 1 << S390_OPCODE_ZARCH;
|
|
+ {
|
|
+ if (s390_arch_size == 32)
|
|
+ set_highgprs_p = TRUE;
|
|
+ current_mode_mask = 1 << S390_OPCODE_ZARCH;
|
|
+ }
|
|
|
|
else if (arg != NULL && strncmp (arg, "arch=", 5) == 0)
|
|
{
|
|
@@ -1799,7 +1809,7 @@ s390_literals (int ignore ATTRIBUTE_UNUSED)
|
|
|
|
/* 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. */
|
|
+ with .machine push and restored with .machine pop. */
|
|
|
|
static void
|
|
s390_machine (int ignore ATTRIBUTE_UNUSED)
|
|
@@ -1863,6 +1873,83 @@ s390_machine (int ignore ATTRIBUTE_UNUSED)
|
|
demand_empty_rest_of_line ();
|
|
}
|
|
|
|
+/* The .machinemode pseudo op allows to switch to a different
|
|
+ architecture mode in the asm listing. The current architecture
|
|
+ mode setting can be stored on a stack with .machinemode push and
|
|
+ restored with .machinemode pop. */
|
|
+
|
|
+static void
|
|
+s390_machinemode (int ignore ATTRIBUTE_UNUSED)
|
|
+{
|
|
+ char *mode_string;
|
|
+#define MAX_HISTORY 100
|
|
+ static unsigned int *mode_history;
|
|
+ static int curr_hist;
|
|
+
|
|
+ SKIP_WHITESPACE ();
|
|
+
|
|
+ if (*input_line_pointer == '"')
|
|
+ {
|
|
+ int len;
|
|
+ mode_string = demand_copy_C_string (&len);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ char c;
|
|
+ mode_string = input_line_pointer;
|
|
+ c = get_symbol_end ();
|
|
+ mode_string = xstrdup (mode_string);
|
|
+ *input_line_pointer = c;
|
|
+ }
|
|
+
|
|
+ if (mode_string != NULL)
|
|
+ {
|
|
+ unsigned int old_mode_mask = current_mode_mask;
|
|
+ char *p;
|
|
+
|
|
+ for (p = mode_string; *p != 0; p++)
|
|
+ *p = TOLOWER (*p);
|
|
+
|
|
+ if (strcmp (mode_string, "push") == 0)
|
|
+ {
|
|
+ if (mode_history == NULL)
|
|
+ mode_history = xmalloc (MAX_HISTORY * sizeof (*mode_history));
|
|
+
|
|
+ if (curr_hist >= MAX_HISTORY)
|
|
+ as_bad (_(".machinemode stack overflow"));
|
|
+ else
|
|
+ mode_history[curr_hist++] = current_mode_mask;
|
|
+ }
|
|
+ else if (strcmp (mode_string, "pop") == 0)
|
|
+ {
|
|
+ if (curr_hist <= 0)
|
|
+ as_bad (_(".machinemode stack underflow"));
|
|
+ else
|
|
+ current_mode_mask = mode_history[--curr_hist];
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ if (strcmp (mode_string, "esa") == 0)
|
|
+ current_mode_mask = 1 << S390_OPCODE_ESA;
|
|
+ else if (strcmp (mode_string, "zarch") == 0)
|
|
+ {
|
|
+ if (s390_arch_size == 32)
|
|
+ set_highgprs_p = TRUE;
|
|
+ current_mode_mask = 1 << S390_OPCODE_ZARCH;
|
|
+ }
|
|
+ else if (strcmp (mode_string, "zarch_nohighgprs") == 0)
|
|
+ current_mode_mask = 1 << S390_OPCODE_ZARCH;
|
|
+ else
|
|
+ as_bad (_("invalid machine `%s'"), mode_string);
|
|
+ }
|
|
+
|
|
+ if (current_mode_mask != old_mode_mask)
|
|
+ s390_setup_opcodes ();
|
|
+ }
|
|
+
|
|
+ demand_empty_rest_of_line ();
|
|
+}
|
|
+
|
|
char *
|
|
md_atof (int type, char *litp, int *sizep)
|
|
{
|
|
@@ -2381,6 +2468,6 @@ tc_s390_regname_to_dw2regnum (char *regname)
|
|
void
|
|
s390_elf_final_processing (void)
|
|
{
|
|
- if (s390_arch_size == 32 && (current_mode_mask & (1 << S390_OPCODE_ZARCH)))
|
|
+ if (set_highgprs_p)
|
|
elf_elfheader (stdoutput)->e_flags |= EF_S390_HIGH_GPRS;
|
|
}
|
|
diff --git a/gas/doc/c-s390.texi b/gas/doc/c-s390.texi
|
|
index 7971327..76dc144 100644
|
|
--- a/gas/doc/c-s390.texi
|
|
+++ b/gas/doc/c-s390.texi
|
|
@@ -873,6 +873,19 @@ 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}.
|
|
+
|
|
+@cindex @code{.machinemode} directive, s390
|
|
+@item .machinemode string
|
|
+This directive allows to change the architecture mode for which code
|
|
+is being generated. @code{string} may be @code{esa}, @code{zarch},
|
|
+@code{zarch_nohighgprs}, @code{push}, or @code{pop}.
|
|
+@code{.machinemode zarch_nohighgprs} can be used to prevent the
|
|
+@code{highgprs} flag from being set in the ELF header of the output
|
|
+file. This is useful in situations where the code is gated with a
|
|
+runtime check which makes sure that the code is only executed on
|
|
+kernels providing the @code{highgprs} feature.
|
|
+@code{.machinemode push} saves the currently selected mode, which may
|
|
+be restored with @code{.machinemode pop}.
|
|
@end table
|
|
|
|
@node s390 Floating Point
|