* 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.
This commit is contained in:
Alan Modra 2003-11-21 15:05:15 +00:00
parent 0234cb7c70
commit 69c040dfe9
2 changed files with 196 additions and 111 deletions

View File

@ -1,3 +1,11 @@
2003-11-22 Alan Modra <amodra@bigpond.net.au>
* 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.
2003-11-20 Kazu Hirata <kazu@cs.umass.edu>
* depend.c: Convert to ISO-C.

View File

@ -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. */