aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2003-11-21 15:05:15 +0000
committerAlan Modra <amodra@gmail.com>2003-11-21 15:05:15 +0000
commit69c040dfe9f43c9145f787e1652738030690f5d9 (patch)
treecd8391aa28ce042cdd1d9239af168fc42cf2c806 /gas/config/tc-ppc.c
parent0234cb7c70cd672825ac5760714792f64581ea22 (diff)
downloadgdb-69c040dfe9f43c9145f787e1652738030690f5d9.zip
gdb-69c040dfe9f43c9145f787e1652738030690f5d9.tar.gz
gdb-69c040dfe9f43c9145f787e1652738030690f5d9.tar.bz2
* 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.
Diffstat (limited to 'gas/config/tc-ppc.c')
-rw-r--r--gas/config/tc-ppc.c299
1 files changed, 188 insertions, 111 deletions
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 5849654..c806f01 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -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. */