xref: /openbsd-src/gnu/usr.bin/binutils/gas/config/tc-a29k.c (revision c074d1c999f3e07019cd5e9a2f190b057ef3b935)
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