12159047fSniklas /* tc-a29k.c -- Assemble for the AMD 29000.
2*c074d1c9Sdrahn Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1998, 2000, 2001, 2002
3b305b0f1Sespie Free Software Foundation, Inc.
42159047fSniklas
52159047fSniklas This file is part of GAS, the GNU Assembler.
62159047fSniklas
72159047fSniklas GAS is free software; you can redistribute it and/or modify
82159047fSniklas it under the terms of the GNU General Public License as published by
92159047fSniklas the Free Software Foundation; either version 2, or (at your option)
102159047fSniklas any later version.
112159047fSniklas
122159047fSniklas GAS is distributed in the hope that it will be useful,
132159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
142159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
152159047fSniklas GNU General Public License for more details.
162159047fSniklas
172159047fSniklas You should have received a copy of the GNU General Public License
18b305b0f1Sespie along with GAS; see the file COPYING. If not, write to the Free
19b305b0f1Sespie Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20b305b0f1Sespie 02111-1307, USA. */
212159047fSniklas
222159047fSniklas /* John Gilmore has reorganized this module somewhat, to make it easier
232159047fSniklas to convert it to new machines' assemblers as desired. There was too
242159047fSniklas much bloody rewriting required before. There still probably is. */
252159047fSniklas
262159047fSniklas #include "as.h"
27*c074d1c9Sdrahn #include "safe-ctype.h"
282159047fSniklas
292159047fSniklas #include "opcode/a29k.h"
302159047fSniklas
312159047fSniklas /* Make it easier to clone this machine desc into another one. */
322159047fSniklas #define machine_opcode a29k_opcode
332159047fSniklas #define machine_opcodes a29k_opcodes
342159047fSniklas #define machine_ip a29k_ip
352159047fSniklas #define machine_it a29k_it
362159047fSniklas
372159047fSniklas #define IMMEDIATE_BIT 0x01000000 /* Turns RB into Immediate */
382159047fSniklas #define ABSOLUTE_BIT 0x01000000 /* Turns PC-relative to Absolute */
392159047fSniklas #define CE_BIT 0x00800000 /* Coprocessor enable in LOAD */
402159047fSniklas #define UI_BIT 0x00000080 /* Unsigned integer in CONVERT */
412159047fSniklas
422159047fSniklas /* handle of the OPCODE hash table */
432159047fSniklas static struct hash_control *op_hash = NULL;
442159047fSniklas
452159047fSniklas struct machine_it
462159047fSniklas {
472159047fSniklas char *error;
482159047fSniklas unsigned long opcode;
492159047fSniklas struct nlist *nlistp;
502159047fSniklas expressionS exp;
512159047fSniklas int pcrel;
522159047fSniklas int reloc_offset; /* Offset of reloc within insn */
532159047fSniklas
542159047fSniklas int reloc;
552159047fSniklas }
562159047fSniklas the_insn;
572159047fSniklas
582159047fSniklas static void machine_ip PARAMS ((char *str));
592159047fSniklas /* static void print_insn PARAMS ((struct machine_it *insn)); */
602159047fSniklas #ifndef OBJ_COFF
612159047fSniklas static void s_data1 PARAMS ((void));
622159047fSniklas static void s_use PARAMS ((int));
632159047fSniklas #endif
64*c074d1c9Sdrahn static void insert_sreg PARAMS ((char *, int));
65*c074d1c9Sdrahn static void define_some_regs PARAMS ((void));
66*c074d1c9Sdrahn static char *parse_operand PARAMS ((char *, expressionS *, int));
672159047fSniklas
682159047fSniklas const pseudo_typeS
692159047fSniklas md_pseudo_table[] =
702159047fSniklas {
712159047fSniklas {"align", s_align_bytes, 4},
722159047fSniklas {"block", s_space, 0},
732159047fSniklas {"cputype", s_ignore, 0}, /* CPU as 29000 or 29050 */
742159047fSniklas {"reg", s_lsym, 0}, /* Register equate, same as equ */
752159047fSniklas {"space", s_ignore, 0}, /* Listing control */
762159047fSniklas {"sect", s_ignore, 0}, /* Creation of coff sections */
772159047fSniklas #ifndef OBJ_COFF
782159047fSniklas /* We can do this right with coff. */
792159047fSniklas {"use", s_use, 0},
802159047fSniklas #endif
812159047fSniklas {"word", cons, 4},
822159047fSniklas {NULL, 0, 0},
832159047fSniklas };
842159047fSniklas
852159047fSniklas #if defined(BFD_HEADERS)
862159047fSniklas #ifdef RELSZ
872159047fSniklas const int md_reloc_size = RELSZ; /* Coff headers */
882159047fSniklas #else
892159047fSniklas const int md_reloc_size = 12; /* something else headers */
902159047fSniklas #endif
912159047fSniklas #else
922159047fSniklas const int md_reloc_size = 12; /* Not bfdized*/
932159047fSniklas #endif
942159047fSniklas
952159047fSniklas /* This array holds the chars that always start a comment. If the
962159047fSniklas pre-processor is disabled, these aren't very useful */
972159047fSniklas const char comment_chars[] = ";";
982159047fSniklas
992159047fSniklas /* This array holds the chars that only start a comment at the beginning of
1002159047fSniklas a line. If the line seems to have the form '# 123 filename'
1012159047fSniklas .line and .file directives will appear in the pre-processed output */
1022159047fSniklas /* Note that input_file.c hand checks for '#' at the beginning of the
1032159047fSniklas first line of the input file. This is because the compiler outputs
1042159047fSniklas #NO_APP at the beginning of its output. */
1052159047fSniklas /* Also note that comments like this one will always work */
1062159047fSniklas const char line_comment_chars[] = "#";
1072159047fSniklas
1082159047fSniklas /* We needed an unused char for line separation to work around the
1092159047fSniklas lack of macros, using sed and such. */
1102159047fSniklas const char line_separator_chars[] = "@";
1112159047fSniklas
1122159047fSniklas /* Chars that can be used to separate mant from exp in floating point nums */
1132159047fSniklas const char EXP_CHARS[] = "eE";
1142159047fSniklas
1152159047fSniklas /* Chars that mean this number is a floating point constant */
1162159047fSniklas /* As in 0f12.456 */
1172159047fSniklas /* or 0d1.2345e12 */
1182159047fSniklas const char FLT_CHARS[] = "rRsSfFdDxXpP";
1192159047fSniklas
1202159047fSniklas /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
1212159047fSniklas changed in read.c. Ideally it shouldn't have to know about it at
1222159047fSniklas all, but nothing is ideal around here. */
1232159047fSniklas
1242159047fSniklas /*
1252159047fSniklas * anull bit - causes the branch delay slot instructions to not be executed
1262159047fSniklas */
1272159047fSniklas #define ANNUL (1 << 29)
1282159047fSniklas
1292159047fSniklas #ifndef OBJ_COFF
1302159047fSniklas
1312159047fSniklas static void
s_use(ignore)1322159047fSniklas s_use (ignore)
1332159047fSniklas int ignore;
1342159047fSniklas {
1352159047fSniklas if (strncmp (input_line_pointer, ".text", 5) == 0)
1362159047fSniklas {
1372159047fSniklas input_line_pointer += 5;
1382159047fSniklas s_text (0);
1392159047fSniklas return;
1402159047fSniklas }
1412159047fSniklas if (strncmp (input_line_pointer, ".data", 5) == 0)
1422159047fSniklas {
1432159047fSniklas input_line_pointer += 5;
1442159047fSniklas s_data (0);
1452159047fSniklas return;
1462159047fSniklas }
1472159047fSniklas if (strncmp (input_line_pointer, ".data1", 6) == 0)
1482159047fSniklas {
1492159047fSniklas input_line_pointer += 6;
1502159047fSniklas s_data1 ();
1512159047fSniklas return;
1522159047fSniklas }
1532159047fSniklas /* Literals can't go in the text segment because you can't read from
1542159047fSniklas instruction memory on some 29k's. So, into initialized data. */
1552159047fSniklas if (strncmp (input_line_pointer, ".lit", 4) == 0)
1562159047fSniklas {
1572159047fSniklas input_line_pointer += 4;
1582159047fSniklas subseg_set (SEG_DATA, 200);
1592159047fSniklas demand_empty_rest_of_line ();
1602159047fSniklas return;
1612159047fSniklas }
1622159047fSniklas
163b305b0f1Sespie as_bad (_("Unknown segment type"));
1642159047fSniklas demand_empty_rest_of_line ();
1652159047fSniklas }
1662159047fSniklas
1672159047fSniklas static void
s_data1()1682159047fSniklas s_data1 ()
1692159047fSniklas {
1702159047fSniklas subseg_set (SEG_DATA, 1);
1712159047fSniklas demand_empty_rest_of_line ();
1722159047fSniklas }
1732159047fSniklas
1742159047fSniklas #endif /* OBJ_COFF */
1752159047fSniklas
1762159047fSniklas /* Install symbol definition that maps REGNAME to REGNO.
1772159047fSniklas FIXME-SOON: These are not recognized in mixed case. */
1782159047fSniklas
1792159047fSniklas static void
insert_sreg(regname,regnum)1802159047fSniklas insert_sreg (regname, regnum)
1812159047fSniklas char *regname;
1822159047fSniklas int regnum;
1832159047fSniklas {
1842159047fSniklas /* FIXME-SOON, put something in these syms so they won't be output
1852159047fSniklas to the symbol table of the resulting object file. */
1862159047fSniklas
1872159047fSniklas /* Must be large enough to hold the names of the special registers. */
1882159047fSniklas char buf[80];
1892159047fSniklas int i;
1902159047fSniklas
1912159047fSniklas symbol_table_insert (symbol_new (regname, SEG_REGISTER, (valueT) regnum,
1922159047fSniklas &zero_address_frag));
1932159047fSniklas for (i = 0; regname[i]; i++)
194*c074d1c9Sdrahn buf[i] = TOUPPER (regname[i]);
1952159047fSniklas buf[i] = '\0';
1962159047fSniklas
1972159047fSniklas symbol_table_insert (symbol_new (buf, SEG_REGISTER, (valueT) regnum,
1982159047fSniklas &zero_address_frag));
1992159047fSniklas }
2002159047fSniklas
2012159047fSniklas /* Install symbol definitions for assorted special registers.
2022159047fSniklas See ASM29K Ref page 2-9. */
2032159047fSniklas
204*c074d1c9Sdrahn static void
define_some_regs()2052159047fSniklas define_some_regs ()
2062159047fSniklas {
2072159047fSniklas #define SREG 256
2082159047fSniklas
2092159047fSniklas /* Protected special-purpose register names */
2102159047fSniklas insert_sreg ("vab", SREG + 0);
2112159047fSniklas insert_sreg ("ops", SREG + 1);
2122159047fSniklas insert_sreg ("cps", SREG + 2);
2132159047fSniklas insert_sreg ("cfg", SREG + 3);
2142159047fSniklas insert_sreg ("cha", SREG + 4);
2152159047fSniklas insert_sreg ("chd", SREG + 5);
2162159047fSniklas insert_sreg ("chc", SREG + 6);
2172159047fSniklas insert_sreg ("rbp", SREG + 7);
2182159047fSniklas insert_sreg ("tmc", SREG + 8);
2192159047fSniklas insert_sreg ("tmr", SREG + 9);
2202159047fSniklas insert_sreg ("pc0", SREG + 10);
2212159047fSniklas insert_sreg ("pc1", SREG + 11);
2222159047fSniklas insert_sreg ("pc2", SREG + 12);
2232159047fSniklas insert_sreg ("mmu", SREG + 13);
2242159047fSniklas insert_sreg ("lru", SREG + 14);
2252159047fSniklas
2262159047fSniklas /* Additional protected special-purpose registers for the 29050 */
2272159047fSniklas insert_sreg ("rsn", SREG + 15);
2282159047fSniklas insert_sreg ("rma0", SREG + 16);
2292159047fSniklas insert_sreg ("rmc0", SREG + 17);
2302159047fSniklas insert_sreg ("rma1", SREG + 18);
2312159047fSniklas insert_sreg ("rmc1", SREG + 19);
2322159047fSniklas insert_sreg ("spc0", SREG + 20);
2332159047fSniklas insert_sreg ("spc1", SREG + 21);
2342159047fSniklas insert_sreg ("spc2", SREG + 22);
2352159047fSniklas insert_sreg ("iba0", SREG + 23);
2362159047fSniklas insert_sreg ("ibc0", SREG + 24);
2372159047fSniklas insert_sreg ("iba1", SREG + 25);
2382159047fSniklas insert_sreg ("ibc1", SREG + 26);
2392159047fSniklas
2402159047fSniklas /* Additional registers for the 29040. */
2412159047fSniklas insert_sreg ("dba", SREG + 27);
2422159047fSniklas insert_sreg ("dbc", SREG + 28);
2432159047fSniklas insert_sreg ("cir", SREG + 29);
2442159047fSniklas insert_sreg ("cdr", SREG + 30);
2452159047fSniklas
2462159047fSniklas /* Unprotected special-purpose register names */
2472159047fSniklas insert_sreg ("ipc", SREG + 128);
2482159047fSniklas insert_sreg ("ipa", SREG + 129);
2492159047fSniklas insert_sreg ("ipb", SREG + 130);
2502159047fSniklas insert_sreg ("q", SREG + 131);
2512159047fSniklas insert_sreg ("alu", SREG + 132);
2522159047fSniklas insert_sreg ("bp", SREG + 133);
2532159047fSniklas insert_sreg ("fc", SREG + 134);
2542159047fSniklas insert_sreg ("cr", SREG + 135);
2552159047fSniklas insert_sreg ("fpe", SREG + 160);
2562159047fSniklas insert_sreg ("inte", SREG + 161);
2572159047fSniklas insert_sreg ("fps", SREG + 162);
2582159047fSniklas /* "", SREG+163); Reserved */
2592159047fSniklas insert_sreg ("exop", SREG + 164);
2602159047fSniklas }
2612159047fSniklas
2622159047fSniklas /* This function is called once, at assembler startup time. It should
2632159047fSniklas set up all the tables, etc., that the MD part of the assembler will
2642159047fSniklas need. */
2652159047fSniklas void
md_begin()2662159047fSniklas md_begin ()
2672159047fSniklas {
2682159047fSniklas register const char *retval = NULL;
2692159047fSniklas int lose = 0;
2702159047fSniklas register int skipnext = 0;
2712159047fSniklas register unsigned int i;
2722159047fSniklas register char *strend, *strend2;
2732159047fSniklas
2742159047fSniklas /* Hash up all the opcodes for fast use later. */
2752159047fSniklas
2762159047fSniklas op_hash = hash_new ();
2772159047fSniklas
2782159047fSniklas for (i = 0; i < num_opcodes; i++)
2792159047fSniklas {
2802159047fSniklas const char *name = machine_opcodes[i].name;
2812159047fSniklas
2822159047fSniklas if (skipnext)
2832159047fSniklas {
2842159047fSniklas skipnext = 0;
2852159047fSniklas continue;
2862159047fSniklas }
2872159047fSniklas
2882159047fSniklas /* Hack to avoid multiple opcode entries. We pre-locate all the
2892159047fSniklas variations (b/i field and P/A field) and handle them. */
2902159047fSniklas
2912159047fSniklas if (!strcmp (name, machine_opcodes[i + 1].name))
2922159047fSniklas {
2932159047fSniklas if ((machine_opcodes[i].opcode & 0x01000000) != 0
2942159047fSniklas || (machine_opcodes[i + 1].opcode & 0x01000000) == 0
2952159047fSniklas || ((machine_opcodes[i].opcode | 0x01000000)
2962159047fSniklas != machine_opcodes[i + 1].opcode))
2972159047fSniklas goto bad_table;
2982159047fSniklas strend = machine_opcodes[i].args + strlen (machine_opcodes[i].args) - 1;
2992159047fSniklas strend2 = machine_opcodes[i + 1].args + strlen (machine_opcodes[i + 1].args) - 1;
3002159047fSniklas switch (*strend)
3012159047fSniklas {
3022159047fSniklas case 'b':
3032159047fSniklas if (*strend2 != 'i')
3042159047fSniklas goto bad_table;
3052159047fSniklas break;
3062159047fSniklas case 'P':
3072159047fSniklas if (*strend2 != 'A')
3082159047fSniklas goto bad_table;
3092159047fSniklas break;
3102159047fSniklas default:
3112159047fSniklas bad_table:
3122159047fSniklas fprintf (stderr, "internal error: can't handle opcode %s\n",
3132159047fSniklas name);
3142159047fSniklas lose = 1;
3152159047fSniklas }
3162159047fSniklas
3172159047fSniklas /* OK, this is an i/b or A/P pair. We skip the
3182159047fSniklas higher-valued one, and let the code for operand checking
3192159047fSniklas handle OR-ing in the bit. */
3202159047fSniklas skipnext = 1;
3212159047fSniklas }
3222159047fSniklas
3232159047fSniklas retval = hash_insert (op_hash, name, (PTR) &machine_opcodes[i]);
3242159047fSniklas if (retval != NULL)
3252159047fSniklas {
3262159047fSniklas fprintf (stderr, "internal error: can't hash `%s': %s\n",
3272159047fSniklas machine_opcodes[i].name, retval);
3282159047fSniklas lose = 1;
3292159047fSniklas }
3302159047fSniklas }
3312159047fSniklas
3322159047fSniklas if (lose)
333b305b0f1Sespie as_fatal (_("Broken assembler. No assembly attempted."));
3342159047fSniklas
3352159047fSniklas define_some_regs ();
3362159047fSniklas }
3372159047fSniklas
3382159047fSniklas /* Assemble a single instruction. Its label has already been handled
3392159047fSniklas by the generic front end. We just parse opcode and operands, and
3402159047fSniklas produce the bytes of data and relocation. */
3412159047fSniklas
3422159047fSniklas void
md_assemble(str)3432159047fSniklas md_assemble (str)
3442159047fSniklas char *str;
3452159047fSniklas {
3462159047fSniklas char *toP;
3472159047fSniklas
3482159047fSniklas know (str);
3492159047fSniklas machine_ip (str);
3502159047fSniklas toP = frag_more (4);
3512159047fSniklas /* put out the opcode */
3522159047fSniklas md_number_to_chars (toP, the_insn.opcode, 4);
3532159047fSniklas
3542159047fSniklas /* put out the symbol-dependent stuff */
3552159047fSniklas if (the_insn.reloc != NO_RELOC)
3562159047fSniklas {
3572159047fSniklas fix_new_exp (frag_now,
3582159047fSniklas (toP - frag_now->fr_literal + the_insn.reloc_offset),
3592159047fSniklas 4, /* size */
3602159047fSniklas &the_insn.exp,
3612159047fSniklas the_insn.pcrel,
3622159047fSniklas the_insn.reloc);
3632159047fSniklas }
3642159047fSniklas }
3652159047fSniklas
366*c074d1c9Sdrahn static char *
parse_operand(s,operandp,opt)3672159047fSniklas parse_operand (s, operandp, opt)
3682159047fSniklas char *s;
3692159047fSniklas expressionS *operandp;
3702159047fSniklas int opt;
3712159047fSniklas {
3722159047fSniklas char *save = input_line_pointer;
3732159047fSniklas char *new;
3742159047fSniklas
3752159047fSniklas input_line_pointer = s;
3762159047fSniklas expression (operandp);
3772159047fSniklas if (operandp->X_op == O_absent && ! opt)
378b305b0f1Sespie as_bad (_("missing operand"));
3792159047fSniklas new = input_line_pointer;
3802159047fSniklas input_line_pointer = save;
3812159047fSniklas return new;
3822159047fSniklas }
3832159047fSniklas
3842159047fSniklas /* Instruction parsing. Takes a string containing the opcode.
3852159047fSniklas Operands are at input_line_pointer. Output is in the_insn.
3862159047fSniklas Warnings or errors are generated. */
3872159047fSniklas
3882159047fSniklas static void
machine_ip(str)3892159047fSniklas machine_ip (str)
3902159047fSniklas char *str;
3912159047fSniklas {
3922159047fSniklas char *s;
3932159047fSniklas const char *args;
3942159047fSniklas struct machine_opcode *insn;
3952159047fSniklas char *argsStart;
3962159047fSniklas unsigned long opcode;
3972159047fSniklas expressionS the_operand;
3982159047fSniklas expressionS *operand = &the_operand;
3992159047fSniklas unsigned int reg;
4002159047fSniklas
4012159047fSniklas /* Must handle `div0' opcode. */
4022159047fSniklas s = str;
403*c074d1c9Sdrahn if (ISALPHA (*s))
404*c074d1c9Sdrahn for (; ISALNUM (*s); ++s)
405*c074d1c9Sdrahn *s = TOLOWER (*s);
4062159047fSniklas
4072159047fSniklas switch (*s)
4082159047fSniklas {
4092159047fSniklas case '\0':
4102159047fSniklas break;
4112159047fSniklas
4122159047fSniklas case ' ': /* FIXME-SOMEDAY more whitespace */
4132159047fSniklas *s++ = '\0';
4142159047fSniklas break;
4152159047fSniklas
4162159047fSniklas default:
417b305b0f1Sespie as_bad (_("Unknown opcode: `%s'"), str);
4182159047fSniklas return;
4192159047fSniklas }
4202159047fSniklas if ((insn = (struct machine_opcode *) hash_find (op_hash, str)) == NULL)
4212159047fSniklas {
422b305b0f1Sespie as_bad (_("Unknown opcode `%s'."), str);
4232159047fSniklas return;
4242159047fSniklas }
4252159047fSniklas argsStart = s;
4262159047fSniklas opcode = insn->opcode;
4272159047fSniklas memset (&the_insn, '\0', sizeof (the_insn));
4282159047fSniklas the_insn.reloc = NO_RELOC;
4292159047fSniklas
4302159047fSniklas /* Build the opcode, checking as we go to make sure that the
4312159047fSniklas operands match.
4322159047fSniklas
4332159047fSniklas If an operand matches, we modify the_insn or opcode appropriately,
4342159047fSniklas and do a "continue". If an operand fails to match, we "break". */
4352159047fSniklas
4362159047fSniklas if (insn->args[0] != '\0')
4372159047fSniklas {
4382159047fSniklas /* Prime the pump. */
4392159047fSniklas s = parse_operand (s, operand, insn->args[0] == 'I');
4402159047fSniklas }
4412159047fSniklas
4422159047fSniklas for (args = insn->args;; ++args)
4432159047fSniklas {
4442159047fSniklas switch (*args)
4452159047fSniklas {
4462159047fSniklas
4472159047fSniklas case '\0': /* end of args */
4482159047fSniklas if (*s == '\0')
4492159047fSniklas {
4502159047fSniklas /* We are truly done. */
4512159047fSniklas the_insn.opcode = opcode;
4522159047fSniklas return;
4532159047fSniklas }
454b305b0f1Sespie as_bad (_("Too many operands: %s"), s);
4552159047fSniklas break;
4562159047fSniklas
4572159047fSniklas case ',': /* Must match a comma */
4582159047fSniklas if (*s++ == ',')
4592159047fSniklas {
4602159047fSniklas /* Parse next operand. */
4612159047fSniklas s = parse_operand (s, operand, args[1] == 'I');
4622159047fSniklas continue;
4632159047fSniklas }
4642159047fSniklas break;
4652159047fSniklas
4662159047fSniklas case 'v': /* Trap numbers (immediate field) */
4672159047fSniklas if (operand->X_op == O_constant)
4682159047fSniklas {
4692159047fSniklas if (operand->X_add_number < 256)
4702159047fSniklas {
4712159047fSniklas opcode |= (operand->X_add_number << 16);
4722159047fSniklas continue;
4732159047fSniklas }
4742159047fSniklas else
4752159047fSniklas {
476b305b0f1Sespie as_bad (_("Immediate value of %ld is too large"),
4772159047fSniklas (long) operand->X_add_number);
4782159047fSniklas continue;
4792159047fSniklas }
4802159047fSniklas }
4812159047fSniklas the_insn.reloc = RELOC_8;
4822159047fSniklas the_insn.reloc_offset = 1; /* BIG-ENDIAN Byte 1 of insn */
4832159047fSniklas the_insn.exp = *operand;
4842159047fSniklas continue;
4852159047fSniklas
4862159047fSniklas case 'b': /* A general register or 8-bit immediate */
4872159047fSniklas case 'i':
4882159047fSniklas /* We treat the two cases identically since we mashed
4892159047fSniklas them together in the opcode table. */
4902159047fSniklas if (operand->X_op == O_register)
4912159047fSniklas goto general_reg;
4922159047fSniklas
4932159047fSniklas /* Make sure the 'i' case really exists. */
4942159047fSniklas if ((insn->opcode | IMMEDIATE_BIT) != (insn + 1)->opcode)
4952159047fSniklas break;
4962159047fSniklas
4972159047fSniklas opcode |= IMMEDIATE_BIT;
4982159047fSniklas if (operand->X_op == O_constant)
4992159047fSniklas {
5002159047fSniklas if (operand->X_add_number < 256)
5012159047fSniklas {
5022159047fSniklas opcode |= operand->X_add_number;
5032159047fSniklas continue;
5042159047fSniklas }
5052159047fSniklas else
5062159047fSniklas {
507b305b0f1Sespie as_bad (_("Immediate value of %ld is too large"),
5082159047fSniklas (long) operand->X_add_number);
5092159047fSniklas continue;
5102159047fSniklas }
5112159047fSniklas }
5122159047fSniklas the_insn.reloc = RELOC_8;
5132159047fSniklas the_insn.reloc_offset = 3; /* BIG-ENDIAN Byte 3 of insn */
5142159047fSniklas the_insn.exp = *operand;
5152159047fSniklas continue;
5162159047fSniklas
5172159047fSniklas case 'a': /* next operand must be a register */
5182159047fSniklas case 'c':
5192159047fSniklas general_reg:
5202159047fSniklas /* lrNNN or grNNN or %%expr or a user-def register name */
5212159047fSniklas if (operand->X_op != O_register)
5222159047fSniklas break; /* Only registers */
5232159047fSniklas know (operand->X_add_symbol == 0);
5242159047fSniklas know (operand->X_op_symbol == 0);
5252159047fSniklas reg = operand->X_add_number;
5262159047fSniklas if (reg >= SREG)
5272159047fSniklas break; /* No special registers */
5282159047fSniklas
5292159047fSniklas /* Got the register, now figure out where it goes in the
5302159047fSniklas opcode. */
5312159047fSniklas switch (*args)
5322159047fSniklas {
5332159047fSniklas case 'a':
5342159047fSniklas opcode |= reg << 8;
5352159047fSniklas continue;
5362159047fSniklas
5372159047fSniklas case 'b':
5382159047fSniklas case 'i':
5392159047fSniklas opcode |= reg;
5402159047fSniklas continue;
5412159047fSniklas
5422159047fSniklas case 'c':
5432159047fSniklas opcode |= reg << 16;
5442159047fSniklas continue;
5452159047fSniklas }
546b305b0f1Sespie as_fatal (_("failed sanity check."));
5472159047fSniklas break;
5482159047fSniklas
5492159047fSniklas case 'x': /* 16 bit constant, zero-extended */
5502159047fSniklas case 'X': /* 16 bit constant, one-extended */
5512159047fSniklas if (operand->X_op == O_constant)
5522159047fSniklas {
5532159047fSniklas opcode |= (operand->X_add_number & 0xFF) << 0 |
5542159047fSniklas ((operand->X_add_number & 0xFF00) << 8);
5552159047fSniklas continue;
5562159047fSniklas }
5572159047fSniklas the_insn.reloc = RELOC_CONST;
5582159047fSniklas the_insn.exp = *operand;
5592159047fSniklas continue;
5602159047fSniklas
5612159047fSniklas case 'h':
5622159047fSniklas if (operand->X_op == O_constant)
5632159047fSniklas {
5642159047fSniklas opcode |= (operand->X_add_number & 0x00FF0000) >> 16 |
5652159047fSniklas (((unsigned long) operand->X_add_number
5662159047fSniklas /* avoid sign ext */ & 0xFF000000) >> 8);
5672159047fSniklas continue;
5682159047fSniklas }
5692159047fSniklas the_insn.reloc = RELOC_CONSTH;
5702159047fSniklas the_insn.exp = *operand;
5712159047fSniklas continue;
5722159047fSniklas
5732159047fSniklas case 'P': /* PC-relative jump address */
5742159047fSniklas case 'A': /* Absolute jump address */
5752159047fSniklas /* These two are treated together since we folded the
5762159047fSniklas opcode table entries together. */
5772159047fSniklas if (operand->X_op == O_constant)
5782159047fSniklas {
5792159047fSniklas /* Make sure the 'A' case really exists. */
5802159047fSniklas if ((insn->opcode | ABSOLUTE_BIT) != (insn + 1)->opcode)
5812159047fSniklas break;
5822159047fSniklas {
5832159047fSniklas bfd_vma v, mask;
5842159047fSniklas mask = 0x1ffff;
5852159047fSniklas v = operand->X_add_number & ~ mask;
5862159047fSniklas if (v)
5872159047fSniklas as_bad ("call/jmp target out of range");
5882159047fSniklas }
5892159047fSniklas opcode |= ABSOLUTE_BIT |
5902159047fSniklas (operand->X_add_number & 0x0003FC00) << 6 |
5912159047fSniklas ((operand->X_add_number & 0x000003FC) >> 2);
5922159047fSniklas continue;
5932159047fSniklas }
5942159047fSniklas the_insn.reloc = RELOC_JUMPTARG;
5952159047fSniklas the_insn.exp = *operand;
5962159047fSniklas the_insn.pcrel = 1; /* Assume PC-relative jump */
5972159047fSniklas /* FIXME-SOON, Do we figure out whether abs later, after
5982159047fSniklas know sym val? */
5992159047fSniklas continue;
6002159047fSniklas
6012159047fSniklas case 'e': /* Coprocessor enable bit for LOAD/STORE insn */
6022159047fSniklas if (operand->X_op == O_constant)
6032159047fSniklas {
6042159047fSniklas if (operand->X_add_number == 0)
6052159047fSniklas continue;
6062159047fSniklas if (operand->X_add_number == 1)
6072159047fSniklas {
6082159047fSniklas opcode |= CE_BIT;
6092159047fSniklas continue;
6102159047fSniklas }
6112159047fSniklas }
6122159047fSniklas break;
6132159047fSniklas
6142159047fSniklas case 'n': /* Control bits for LOAD/STORE instructions */
6152159047fSniklas if (operand->X_op == O_constant &&
6162159047fSniklas operand->X_add_number < 128)
6172159047fSniklas {
6182159047fSniklas opcode |= (operand->X_add_number << 16);
6192159047fSniklas continue;
6202159047fSniklas }
6212159047fSniklas break;
6222159047fSniklas
6232159047fSniklas case 's': /* Special register number */
6242159047fSniklas if (operand->X_op != O_register)
6252159047fSniklas break; /* Only registers */
6262159047fSniklas if (operand->X_add_number < SREG)
6272159047fSniklas break; /* Not a special register */
6282159047fSniklas opcode |= (operand->X_add_number & 0xFF) << 8;
6292159047fSniklas continue;
6302159047fSniklas
6312159047fSniklas case 'u': /* UI bit of CONVERT */
6322159047fSniklas if (operand->X_op == O_constant)
6332159047fSniklas {
6342159047fSniklas if (operand->X_add_number == 0)
6352159047fSniklas continue;
6362159047fSniklas if (operand->X_add_number == 1)
6372159047fSniklas {
6382159047fSniklas opcode |= UI_BIT;
6392159047fSniklas continue;
6402159047fSniklas }
6412159047fSniklas }
6422159047fSniklas break;
6432159047fSniklas
6442159047fSniklas case 'r': /* RND bits of CONVERT */
6452159047fSniklas if (operand->X_op == O_constant &&
6462159047fSniklas operand->X_add_number < 8)
6472159047fSniklas {
6482159047fSniklas opcode |= operand->X_add_number << 4;
6492159047fSniklas continue;
6502159047fSniklas }
6512159047fSniklas break;
6522159047fSniklas
6532159047fSniklas case 'I': /* ID bits of INV and IRETINV. */
6542159047fSniklas /* This operand is optional. */
6552159047fSniklas if (operand->X_op == O_absent)
6562159047fSniklas continue;
6572159047fSniklas else if (operand->X_op == O_constant
6582159047fSniklas && operand->X_add_number < 4)
6592159047fSniklas {
6602159047fSniklas opcode |= operand->X_add_number << 16;
6612159047fSniklas continue;
6622159047fSniklas }
6632159047fSniklas break;
6642159047fSniklas
6652159047fSniklas case 'd': /* FD bits of CONVERT */
6662159047fSniklas if (operand->X_op == O_constant &&
6672159047fSniklas operand->X_add_number < 4)
6682159047fSniklas {
6692159047fSniklas opcode |= operand->X_add_number << 2;
6702159047fSniklas continue;
6712159047fSniklas }
6722159047fSniklas break;
6732159047fSniklas
6742159047fSniklas case 'f': /* FS bits of CONVERT */
6752159047fSniklas if (operand->X_op == O_constant &&
6762159047fSniklas operand->X_add_number < 4)
6772159047fSniklas {
6782159047fSniklas opcode |= operand->X_add_number << 0;
6792159047fSniklas continue;
6802159047fSniklas }
6812159047fSniklas break;
6822159047fSniklas
6832159047fSniklas case 'C':
6842159047fSniklas if (operand->X_op == O_constant &&
6852159047fSniklas operand->X_add_number < 4)
6862159047fSniklas {
6872159047fSniklas opcode |= operand->X_add_number << 16;
6882159047fSniklas continue;
6892159047fSniklas }
6902159047fSniklas break;
6912159047fSniklas
6922159047fSniklas case 'F':
6932159047fSniklas if (operand->X_op == O_constant &&
6942159047fSniklas operand->X_add_number < 16)
6952159047fSniklas {
6962159047fSniklas opcode |= operand->X_add_number << 18;
6972159047fSniklas continue;
6982159047fSniklas }
6992159047fSniklas break;
7002159047fSniklas
7012159047fSniklas default:
7022159047fSniklas BAD_CASE (*args);
7032159047fSniklas }
7042159047fSniklas /* Types or values of args don't match. */
7052159047fSniklas as_bad ("Invalid operands");
7062159047fSniklas return;
7072159047fSniklas }
7082159047fSniklas }
7092159047fSniklas
7102159047fSniklas /* This is identical to the md_atof in m68k.c. I think this is right,
7112159047fSniklas but I'm not sure.
7122159047fSniklas
7132159047fSniklas Turn a string in input_line_pointer into a floating point constant
714b55d4692Sfgsch of type TYPE, and store the appropriate bytes in *LITP. The number
715b55d4692Sfgsch of LITTLENUMS emitted is stored in *SIZEP. An error message is
7162159047fSniklas returned, or NULL on OK. */
7172159047fSniklas
7182159047fSniklas /* Equal to MAX_PRECISION in atof-ieee.c */
7192159047fSniklas #define MAX_LITTLENUMS 6
7202159047fSniklas
7212159047fSniklas char *
md_atof(type,litP,sizeP)7222159047fSniklas md_atof (type, litP, sizeP)
7232159047fSniklas char type;
7242159047fSniklas char *litP;
7252159047fSniklas int *sizeP;
7262159047fSniklas {
7272159047fSniklas int prec;
7282159047fSniklas LITTLENUM_TYPE words[MAX_LITTLENUMS];
7292159047fSniklas LITTLENUM_TYPE *wordP;
7302159047fSniklas char *t;
7312159047fSniklas
7322159047fSniklas switch (type)
7332159047fSniklas {
7342159047fSniklas
7352159047fSniklas case 'f':
7362159047fSniklas case 'F':
7372159047fSniklas case 's':
7382159047fSniklas case 'S':
7392159047fSniklas prec = 2;
7402159047fSniklas break;
7412159047fSniklas
7422159047fSniklas case 'd':
7432159047fSniklas case 'D':
7442159047fSniklas case 'r':
7452159047fSniklas case 'R':
7462159047fSniklas prec = 4;
7472159047fSniklas break;
7482159047fSniklas
7492159047fSniklas case 'x':
7502159047fSniklas case 'X':
7512159047fSniklas prec = 6;
7522159047fSniklas break;
7532159047fSniklas
7542159047fSniklas case 'p':
7552159047fSniklas case 'P':
7562159047fSniklas prec = 6;
7572159047fSniklas break;
7582159047fSniklas
7592159047fSniklas default:
7602159047fSniklas *sizeP = 0;
7612159047fSniklas return "Bad call to MD_ATOF()";
7622159047fSniklas }
7632159047fSniklas t = atof_ieee (input_line_pointer, type, words);
7642159047fSniklas if (t)
7652159047fSniklas input_line_pointer = t;
7662159047fSniklas *sizeP = prec * sizeof (LITTLENUM_TYPE);
7672159047fSniklas for (wordP = words; prec--;)
7682159047fSniklas {
7692159047fSniklas md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
7702159047fSniklas litP += sizeof (LITTLENUM_TYPE);
7712159047fSniklas }
7722159047fSniklas return 0;
7732159047fSniklas }
7742159047fSniklas
7752159047fSniklas /*
7762159047fSniklas * Write out big-endian.
7772159047fSniklas */
7782159047fSniklas void
md_number_to_chars(buf,val,n)7792159047fSniklas md_number_to_chars (buf, val, n)
7802159047fSniklas char *buf;
7812159047fSniklas valueT val;
7822159047fSniklas int n;
7832159047fSniklas {
7842159047fSniklas number_to_chars_bigendian (buf, val, n);
7852159047fSniklas }
7862159047fSniklas
7872159047fSniklas void
md_apply_fix3(fixP,valP,seg)788*c074d1c9Sdrahn md_apply_fix3 (fixP, valP, seg)
7892159047fSniklas fixS *fixP;
790*c074d1c9Sdrahn valueT * valP;
791*c074d1c9Sdrahn segT seg ATTRIBUTE_UNUSED;
7922159047fSniklas {
793*c074d1c9Sdrahn long val = *valP;
7942159047fSniklas char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
7952159047fSniklas
796*c074d1c9Sdrahn fixP->fx_addnumber = val; /* Remember value for emit_reloc. */
7972159047fSniklas
7982159047fSniklas know (fixP->fx_size == 4);
7992159047fSniklas know (fixP->fx_r_type < NO_RELOC);
8002159047fSniklas
8012159047fSniklas /* This is a hack. There should be a better way to handle this. */
8022159047fSniklas if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy)
8032159047fSniklas val += fixP->fx_where + fixP->fx_frag->fr_address;
8042159047fSniklas
8052159047fSniklas switch (fixP->fx_r_type)
8062159047fSniklas {
8072159047fSniklas case RELOC_32:
8082159047fSniklas buf[0] = val >> 24;
8092159047fSniklas buf[1] = val >> 16;
8102159047fSniklas buf[2] = val >> 8;
8112159047fSniklas buf[3] = val;
8122159047fSniklas break;
8132159047fSniklas
8142159047fSniklas case RELOC_8:
8152159047fSniklas buf[0] = val;
8162159047fSniklas break;
8172159047fSniklas
8182159047fSniklas case RELOC_WDISP30:
819*c074d1c9Sdrahn val = (val >> 2) + 1;
8202159047fSniklas buf[0] |= (val >> 24) & 0x3f;
8212159047fSniklas buf[1] = (val >> 16);
8222159047fSniklas buf[2] = val >> 8;
8232159047fSniklas buf[3] = val;
8242159047fSniklas break;
8252159047fSniklas
8262159047fSniklas case RELOC_HI22:
8272159047fSniklas buf[1] |= (val >> 26) & 0x3f;
8282159047fSniklas buf[2] = val >> 18;
8292159047fSniklas buf[3] = val >> 10;
8302159047fSniklas break;
8312159047fSniklas
8322159047fSniklas case RELOC_LO10:
8332159047fSniklas buf[2] |= (val >> 8) & 0x03;
8342159047fSniklas buf[3] = val;
8352159047fSniklas break;
8362159047fSniklas
8372159047fSniklas case RELOC_BASE13:
8382159047fSniklas buf[2] |= (val >> 8) & 0x1f;
8392159047fSniklas buf[3] = val;
8402159047fSniklas break;
8412159047fSniklas
8422159047fSniklas case RELOC_WDISP22:
843*c074d1c9Sdrahn val = (val >> 2) + 1;
8442159047fSniklas /* FALLTHROUGH */
8452159047fSniklas case RELOC_BASE22:
8462159047fSniklas buf[1] |= (val >> 16) & 0x3f;
8472159047fSniklas buf[2] = val >> 8;
8482159047fSniklas buf[3] = val;
8492159047fSniklas break;
8502159047fSniklas
8512159047fSniklas case RELOC_JUMPTARG: /* 00XX00XX pattern in a word */
8522159047fSniklas if (!fixP->fx_done)
8532159047fSniklas {
8542159047fSniklas /* The linker tries to support both AMD and old GNU style
8552159047fSniklas R_IREL relocs. That means that if the addend is exactly
8562159047fSniklas the negative of the address within the section, the
8572159047fSniklas linker will not handle it correctly. */
8582159047fSniklas if (fixP->fx_pcrel
8592159047fSniklas && val != 0
8602159047fSniklas && val == - (fixP->fx_frag->fr_address + fixP->fx_where))
8612159047fSniklas as_bad_where
8622159047fSniklas (fixP->fx_file, fixP->fx_line,
8632159047fSniklas "the linker will not handle this relocation correctly");
8642159047fSniklas }
8652159047fSniklas else if (fixP->fx_pcrel)
8662159047fSniklas {
8672159047fSniklas long v = val >> 17;
868*c074d1c9Sdrahn
8692159047fSniklas if (v != 0 && v != -1)
8702159047fSniklas as_bad_where (fixP->fx_file, fixP->fx_line,
8712159047fSniklas "call/jmp target out of range");
8722159047fSniklas }
8732159047fSniklas else
874*c074d1c9Sdrahn /* This case was supposed to be handled in machine_ip. */
8752159047fSniklas abort ();
8762159047fSniklas buf[1] = val >> 10; /* Holds bits 0003FFFC of address */
8772159047fSniklas buf[3] = val >> 2;
8782159047fSniklas break;
8792159047fSniklas
8802159047fSniklas case RELOC_CONST: /* 00XX00XX pattern in a word */
8812159047fSniklas buf[1] = val >> 8; /* Holds bits 0000XXXX */
8822159047fSniklas buf[3] = val;
8832159047fSniklas break;
8842159047fSniklas
8852159047fSniklas case RELOC_CONSTH: /* 00XX00XX pattern in a word */
8862159047fSniklas buf[1] = val >> 24; /* Holds bits XXXX0000 */
8872159047fSniklas buf[3] = val >> 16;
8882159047fSniklas break;
8892159047fSniklas
8902159047fSniklas case NO_RELOC:
8912159047fSniklas default:
892b305b0f1Sespie as_bad (_("bad relocation type: 0x%02x"), fixP->fx_r_type);
8932159047fSniklas break;
8942159047fSniklas }
895*c074d1c9Sdrahn
896*c074d1c9Sdrahn if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
897*c074d1c9Sdrahn fixP->fx_done = 1;
8982159047fSniklas }
8992159047fSniklas
9002159047fSniklas #ifdef OBJ_COFF
9012159047fSniklas short
tc_coff_fix2rtype(fixP)9022159047fSniklas tc_coff_fix2rtype (fixP)
9032159047fSniklas fixS *fixP;
9042159047fSniklas {
9052159047fSniklas
9062159047fSniklas switch (fixP->fx_r_type)
9072159047fSniklas {
9082159047fSniklas case RELOC_32:
9092159047fSniklas return (R_WORD);
9102159047fSniklas case RELOC_8:
9112159047fSniklas return (R_BYTE);
9122159047fSniklas case RELOC_CONST:
9132159047fSniklas return (R_ILOHALF);
9142159047fSniklas case RELOC_CONSTH:
9152159047fSniklas return (R_IHIHALF);
9162159047fSniklas case RELOC_JUMPTARG:
9172159047fSniklas return (R_IREL);
9182159047fSniklas default:
919b305b0f1Sespie printf (_("need %o3\n"), fixP->fx_r_type);
9202159047fSniklas abort ();
9212159047fSniklas } /* switch on type */
9222159047fSniklas
9232159047fSniklas return (0);
9242159047fSniklas }
9252159047fSniklas
9262159047fSniklas #endif /* OBJ_COFF */
9272159047fSniklas
9282159047fSniklas /* should never be called for 29k */
9292159047fSniklas void
md_convert_frag(headers,seg,fragP)9302159047fSniklas md_convert_frag (headers, seg, fragP)
931*c074d1c9Sdrahn object_headers *headers ATTRIBUTE_UNUSED;
932*c074d1c9Sdrahn segT seg ATTRIBUTE_UNUSED;
933*c074d1c9Sdrahn register fragS *fragP ATTRIBUTE_UNUSED;
9342159047fSniklas {
935b305b0f1Sespie as_fatal (_("a29k_convert_frag\n"));
9362159047fSniklas }
9372159047fSniklas
9382159047fSniklas /* should never be called for a29k */
9392159047fSniklas int
md_estimate_size_before_relax(fragP,segtype)9402159047fSniklas md_estimate_size_before_relax (fragP, segtype)
941*c074d1c9Sdrahn register fragS *fragP ATTRIBUTE_UNUSED;
942*c074d1c9Sdrahn segT segtype ATTRIBUTE_UNUSED;
9432159047fSniklas {
944b305b0f1Sespie as_fatal (_("a29k_estimate_size_before_relax\n"));
9452159047fSniklas return 0;
9462159047fSniklas }
9472159047fSniklas
9482159047fSniklas #if 0
9492159047fSniklas /* for debugging only */
9502159047fSniklas static void
9512159047fSniklas print_insn (insn)
9522159047fSniklas struct machine_it *insn;
9532159047fSniklas {
9542159047fSniklas char *Reloc[] =
9552159047fSniklas {
9562159047fSniklas "RELOC_8",
9572159047fSniklas "RELOC_16",
9582159047fSniklas "RELOC_32",
9592159047fSniklas "RELOC_DISP8",
9602159047fSniklas "RELOC_DISP16",
9612159047fSniklas "RELOC_DISP32",
9622159047fSniklas "RELOC_WDISP30",
9632159047fSniklas "RELOC_WDISP22",
9642159047fSniklas "RELOC_HI22",
9652159047fSniklas "RELOC_22",
9662159047fSniklas "RELOC_13",
9672159047fSniklas "RELOC_LO10",
9682159047fSniklas "RELOC_SFA_BASE",
9692159047fSniklas "RELOC_SFA_OFF13",
9702159047fSniklas "RELOC_BASE10",
9712159047fSniklas "RELOC_BASE13",
9722159047fSniklas "RELOC_BASE22",
9732159047fSniklas "RELOC_PC10",
9742159047fSniklas "RELOC_PC22",
9752159047fSniklas "RELOC_JMP_TBL",
9762159047fSniklas "RELOC_SEGOFF16",
9772159047fSniklas "RELOC_GLOB_DAT",
9782159047fSniklas "RELOC_JMP_SLOT",
9792159047fSniklas "RELOC_RELATIVE",
9802159047fSniklas "NO_RELOC"
9812159047fSniklas };
9822159047fSniklas
9832159047fSniklas if (insn->error)
9842159047fSniklas {
9852159047fSniklas fprintf (stderr, "ERROR: %s\n");
9862159047fSniklas }
9872159047fSniklas fprintf (stderr, "opcode=0x%08x\n", insn->opcode);
9882159047fSniklas fprintf (stderr, "reloc = %s\n", Reloc[insn->reloc]);
9892159047fSniklas fprintf (stderr, "exp = {\n");
9902159047fSniklas fprintf (stderr, "\t\tX_add_symbol = %s\n",
9912159047fSniklas insn->exp.X_add_symbol ?
9922159047fSniklas (S_GET_NAME (insn->exp.X_add_symbol) ?
9932159047fSniklas S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0");
9942159047fSniklas fprintf (stderr, "\t\tX_op_symbol = %s\n",
9952159047fSniklas insn->exp.X_op_symbol ?
9962159047fSniklas (S_GET_NAME (insn->exp.X_op_symbol) ?
9972159047fSniklas S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0");
9982159047fSniklas fprintf (stderr, "\t\tX_add_number = %d\n",
9992159047fSniklas insn->exp.X_add_number);
10002159047fSniklas fprintf (stderr, "}\n");
10012159047fSniklas }
10022159047fSniklas
10032159047fSniklas #endif
10042159047fSniklas
10052159047fSniklas /* Translate internal representation of relocation info to target format.
10062159047fSniklas
10072159047fSniklas On sparc/29k: first 4 bytes are normal unsigned long address, next three
10082159047fSniklas bytes are index, most sig. byte first. Byte 7 is broken up with
10092159047fSniklas bit 7 as external, bits 6 & 5 unused, and the lower
10102159047fSniklas five bits as relocation type. Next 4 bytes are long addend. */
10112159047fSniklas /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
10122159047fSniklas
10132159047fSniklas #ifdef OBJ_AOUT
10142159047fSniklas
10152159047fSniklas void
tc_aout_fix_to_chars(where,fixP,segment_address_in_file)10162159047fSniklas tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
10172159047fSniklas char *where;
10182159047fSniklas fixS *fixP;
10192159047fSniklas relax_addressT segment_address_in_file;
10202159047fSniklas {
10212159047fSniklas long r_symbolnum;
10222159047fSniklas
10232159047fSniklas know (fixP->fx_r_type < NO_RELOC);
10242159047fSniklas know (fixP->fx_addsy != NULL);
10252159047fSniklas
10262159047fSniklas md_number_to_chars (where,
10272159047fSniklas fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
10282159047fSniklas 4);
10292159047fSniklas
10302159047fSniklas r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
10312159047fSniklas ? S_GET_TYPE (fixP->fx_addsy)
10322159047fSniklas : fixP->fx_addsy->sy_number);
10332159047fSniklas
10342159047fSniklas where[4] = (r_symbolnum >> 16) & 0x0ff;
10352159047fSniklas where[5] = (r_symbolnum >> 8) & 0x0ff;
10362159047fSniklas where[6] = r_symbolnum & 0x0ff;
10372159047fSniklas where[7] = (((!S_IS_DEFINED (fixP->fx_addsy)) << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F);
10382159047fSniklas /* Also easy */
10392159047fSniklas md_number_to_chars (&where[8], fixP->fx_addnumber, 4);
10402159047fSniklas }
10412159047fSniklas
10422159047fSniklas #endif /* OBJ_AOUT */
10432159047fSniklas
1044*c074d1c9Sdrahn const char *md_shortopts = "";
10452159047fSniklas struct option md_longopts[] = {
10462159047fSniklas {NULL, no_argument, NULL, 0}
10472159047fSniklas };
10482159047fSniklas size_t md_longopts_size = sizeof (md_longopts);
10492159047fSniklas
10502159047fSniklas int
md_parse_option(c,arg)10512159047fSniklas md_parse_option (c, arg)
1052*c074d1c9Sdrahn int c ATTRIBUTE_UNUSED;
1053*c074d1c9Sdrahn char *arg ATTRIBUTE_UNUSED;
10542159047fSniklas {
10552159047fSniklas return 0;
10562159047fSniklas }
10572159047fSniklas
10582159047fSniklas void
md_show_usage(stream)10592159047fSniklas md_show_usage (stream)
1060*c074d1c9Sdrahn FILE *stream ATTRIBUTE_UNUSED;
10612159047fSniklas {
10622159047fSniklas }
10632159047fSniklas
1064191aa565Sniklas /* This is called when a line is unrecognized. This is used to handle
1065191aa565Sniklas definitions of a29k style local labels. */
1066191aa565Sniklas
1067191aa565Sniklas int
a29k_unrecognized_line(c)1068191aa565Sniklas a29k_unrecognized_line (c)
1069191aa565Sniklas int c;
1070191aa565Sniklas {
1071191aa565Sniklas int lab;
1072191aa565Sniklas char *s;
1073191aa565Sniklas
1074191aa565Sniklas if (c != '$'
1075*c074d1c9Sdrahn || ! ISDIGIT (input_line_pointer[0]))
1076191aa565Sniklas return 0;
1077191aa565Sniklas
1078191aa565Sniklas s = input_line_pointer;
1079191aa565Sniklas
1080191aa565Sniklas lab = 0;
1081*c074d1c9Sdrahn while (ISDIGIT (*s))
1082191aa565Sniklas {
1083191aa565Sniklas lab = lab * 10 + *s - '0';
1084191aa565Sniklas ++s;
1085191aa565Sniklas }
1086191aa565Sniklas
1087191aa565Sniklas if (*s != ':')
1088191aa565Sniklas {
1089191aa565Sniklas /* Not a label definition. */
1090191aa565Sniklas return 0;
1091191aa565Sniklas }
1092191aa565Sniklas
1093191aa565Sniklas if (dollar_label_defined (lab))
1094191aa565Sniklas {
1095b305b0f1Sespie as_bad (_("label \"$%d\" redefined"), lab);
1096191aa565Sniklas return 0;
1097191aa565Sniklas }
1098191aa565Sniklas
1099191aa565Sniklas define_dollar_label (lab);
1100191aa565Sniklas colon (dollar_label_name (lab, 0));
1101191aa565Sniklas input_line_pointer = s + 1;
1102191aa565Sniklas
1103191aa565Sniklas return 1;
1104191aa565Sniklas }
1105191aa565Sniklas
11062159047fSniklas /* Default the values of symbols known that should be "predefined". We
11072159047fSniklas don't bother to predefine them unless you actually use one, since there
11082159047fSniklas are a lot of them. */
11092159047fSniklas
11102159047fSniklas symbolS *
md_undefined_symbol(name)11112159047fSniklas md_undefined_symbol (name)
11122159047fSniklas char *name;
11132159047fSniklas {
11142159047fSniklas long regnum;
11152159047fSniklas char testbuf[5 + /*SLOP*/ 5];
11162159047fSniklas
11172159047fSniklas if (name[0] == 'g' || name[0] == 'G'
11182159047fSniklas || name[0] == 'l' || name[0] == 'L'
11192159047fSniklas || name[0] == 's' || name[0] == 'S')
11202159047fSniklas {
11212159047fSniklas /* Perhaps a global or local register name */
11222159047fSniklas if (name[1] == 'r' || name[1] == 'R')
11232159047fSniklas {
11242159047fSniklas long maxreg;
11252159047fSniklas
11262159047fSniklas /* Parse the number, make sure it has no extra zeroes or
11272159047fSniklas trailing chars. */
11282159047fSniklas regnum = atol (&name[2]);
11292159047fSniklas
11302159047fSniklas if (name[0] == 's' || name[0] == 'S')
11312159047fSniklas maxreg = 255;
11322159047fSniklas else
11332159047fSniklas maxreg = 127;
11342159047fSniklas if (regnum > maxreg)
11352159047fSniklas return NULL;
11362159047fSniklas
11372159047fSniklas sprintf (testbuf, "%ld", regnum);
11382159047fSniklas if (strcmp (testbuf, &name[2]) != 0)
11392159047fSniklas return NULL; /* gr007 or lr7foo or whatever */
11402159047fSniklas
11412159047fSniklas /* We have a wiener! Define and return a new symbol for it. */
11422159047fSniklas if (name[0] == 'l' || name[0] == 'L')
11432159047fSniklas regnum += 128;
11442159047fSniklas else if (name[0] == 's' || name[0] == 'S')
11452159047fSniklas regnum += SREG;
11462159047fSniklas return (symbol_new (name, SEG_REGISTER, (valueT) regnum,
11472159047fSniklas &zero_address_frag));
11482159047fSniklas }
11492159047fSniklas }
11502159047fSniklas
11512159047fSniklas return NULL;
11522159047fSniklas }
11532159047fSniklas
11542159047fSniklas /* Parse an operand that is machine-specific. */
11552159047fSniklas
11562159047fSniklas void
md_operand(expressionP)11572159047fSniklas md_operand (expressionP)
11582159047fSniklas expressionS *expressionP;
11592159047fSniklas {
11602159047fSniklas
11612159047fSniklas if (input_line_pointer[0] == '%' && input_line_pointer[1] == '%')
11622159047fSniklas {
11632159047fSniklas /* We have a numeric register expression. No biggy. */
11642159047fSniklas input_line_pointer += 2; /* Skip %% */
11652159047fSniklas (void) expression (expressionP);
11662159047fSniklas if (expressionP->X_op != O_constant
11672159047fSniklas || expressionP->X_add_number > 255)
1168b305b0f1Sespie as_bad (_("Invalid expression after %%%%\n"));
11692159047fSniklas expressionP->X_op = O_register;
11702159047fSniklas }
11712159047fSniklas else if (input_line_pointer[0] == '&')
11722159047fSniklas {
11732159047fSniklas /* We are taking the 'address' of a register...this one is not
11742159047fSniklas in the manual, but it *is* in traps/fpsymbol.h! What they
11752159047fSniklas seem to want is the register number, as an absolute number. */
11762159047fSniklas input_line_pointer++; /* Skip & */
11772159047fSniklas (void) expression (expressionP);
11782159047fSniklas if (expressionP->X_op != O_register)
1179b305b0f1Sespie as_bad (_("Invalid register in & expression"));
11802159047fSniklas else
11812159047fSniklas expressionP->X_op = O_constant;
11822159047fSniklas }
1183191aa565Sniklas else if (input_line_pointer[0] == '$'
1184*c074d1c9Sdrahn && ISDIGIT (input_line_pointer[1]))
1185191aa565Sniklas {
1186191aa565Sniklas long lab;
1187191aa565Sniklas char *name;
1188191aa565Sniklas symbolS *sym;
1189191aa565Sniklas
1190191aa565Sniklas /* This is a local label. */
1191191aa565Sniklas ++input_line_pointer;
1192191aa565Sniklas lab = (long) get_absolute_expression ();
1193191aa565Sniklas if (dollar_label_defined (lab))
1194191aa565Sniklas {
1195191aa565Sniklas name = dollar_label_name (lab, 0);
1196191aa565Sniklas sym = symbol_find (name);
1197191aa565Sniklas }
1198191aa565Sniklas else
1199191aa565Sniklas {
1200191aa565Sniklas name = dollar_label_name (lab, 1);
1201191aa565Sniklas sym = symbol_find_or_make (name);
1202191aa565Sniklas }
1203191aa565Sniklas
1204191aa565Sniklas expressionP->X_op = O_symbol;
1205191aa565Sniklas expressionP->X_add_symbol = sym;
1206191aa565Sniklas expressionP->X_add_number = 0;
1207191aa565Sniklas }
12082159047fSniklas else if (input_line_pointer[0] == '$')
12092159047fSniklas {
12102159047fSniklas char *s;
12112159047fSniklas char type;
12122159047fSniklas int fieldnum, fieldlimit;
12132159047fSniklas LITTLENUM_TYPE floatbuf[8];
12142159047fSniklas
12152159047fSniklas /* $float(), $doubleN(), or $extendN() convert floating values
12162159047fSniklas to integers. */
12172159047fSniklas
12182159047fSniklas s = input_line_pointer;
12192159047fSniklas
12202159047fSniklas ++s;
12212159047fSniklas
12222159047fSniklas fieldnum = 0;
12232159047fSniklas if (strncmp (s, "double", sizeof "double" - 1) == 0)
12242159047fSniklas {
12252159047fSniklas s += sizeof "double" - 1;
12262159047fSniklas type = 'd';
12272159047fSniklas fieldlimit = 2;
12282159047fSniklas }
12292159047fSniklas else if (strncmp (s, "float", sizeof "float" - 1) == 0)
12302159047fSniklas {
12312159047fSniklas s += sizeof "float" - 1;
12322159047fSniklas type = 'f';
12332159047fSniklas fieldlimit = 1;
12342159047fSniklas }
12352159047fSniklas else if (strncmp (s, "extend", sizeof "extend" - 1) == 0)
12362159047fSniklas {
12372159047fSniklas s += sizeof "extend" - 1;
12382159047fSniklas type = 'x';
12392159047fSniklas fieldlimit = 4;
12402159047fSniklas }
12412159047fSniklas else
12422159047fSniklas {
12432159047fSniklas return;
12442159047fSniklas }
12452159047fSniklas
1246*c074d1c9Sdrahn if (ISDIGIT (*s))
12472159047fSniklas {
12482159047fSniklas fieldnum = *s - '0';
12492159047fSniklas ++s;
12502159047fSniklas }
12512159047fSniklas if (fieldnum >= fieldlimit)
12522159047fSniklas return;
12532159047fSniklas
12542159047fSniklas SKIP_WHITESPACE ();
12552159047fSniklas if (*s != '(')
12562159047fSniklas return;
12572159047fSniklas ++s;
12582159047fSniklas SKIP_WHITESPACE ();
12592159047fSniklas
12602159047fSniklas s = atof_ieee (s, type, floatbuf);
12612159047fSniklas if (s == NULL)
12622159047fSniklas return;
12632159047fSniklas s = s;
12642159047fSniklas
12652159047fSniklas SKIP_WHITESPACE ();
12662159047fSniklas if (*s != ')')
12672159047fSniklas return;
12682159047fSniklas ++s;
12692159047fSniklas SKIP_WHITESPACE ();
12702159047fSniklas
12712159047fSniklas input_line_pointer = s;
12722159047fSniklas expressionP->X_op = O_constant;
12732159047fSniklas expressionP->X_unsigned = 1;
12742159047fSniklas expressionP->X_add_number = ((floatbuf[fieldnum * 2]
12752159047fSniklas << LITTLENUM_NUMBER_OF_BITS)
12762159047fSniklas + floatbuf[fieldnum * 2 + 1]);
12772159047fSniklas }
12782159047fSniklas }
12792159047fSniklas
12802159047fSniklas /* Round up a section size to the appropriate boundary. */
12812159047fSniklas valueT
md_section_align(segment,size)12822159047fSniklas md_section_align (segment, size)
1283*c074d1c9Sdrahn segT segment ATTRIBUTE_UNUSED;
12842159047fSniklas valueT size;
12852159047fSniklas {
12862159047fSniklas return size; /* Byte alignment is fine */
12872159047fSniklas }
12882159047fSniklas
12892159047fSniklas /* Exactly what point is a PC-relative offset relative TO?
12902159047fSniklas On the 29000, they're relative to the address of the instruction,
12912159047fSniklas which we have set up as the address of the fixup too. */
12922159047fSniklas long
md_pcrel_from(fixP)12932159047fSniklas md_pcrel_from (fixP)
12942159047fSniklas fixS *fixP;
12952159047fSniklas {
12962159047fSniklas return fixP->fx_where + fixP->fx_frag->fr_address;
12972159047fSniklas }
1298