diff options
author | Alan Modra <amodra@gmail.com> | 2003-11-21 15:05:15 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2003-11-21 15:05:15 +0000 |
commit | 69c040dfe9f43c9145f787e1652738030690f5d9 (patch) | |
tree | cd8391aa28ce042cdd1d9239af168fc42cf2c806 /gas/config/tc-ppc.c | |
parent | 0234cb7c70cd672825ac5760714792f64581ea22 (diff) | |
download | gdb-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.c | 299 |
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. */ |