Home | History | Annotate | Download | only in config
      1 /* tc-xgate.c -- Assembler code for Freescale XGATE
      2    Copyright (C) 2010-2014 Free Software Foundation, Inc.
      3    Contributed by Sean Keys <skeys (at) ipdatasys.com>
      4 
      5    This file is part of GAS, the GNU Assembler.
      6 
      7    GAS is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3, or (at your option)
     10    any later version.
     11 
     12    GAS is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with GAS; see the file COPYING.  If not, write to
     19    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
     20    Boston, MA 02110-1301, USA.  */
     21 
     22 #include "as.h"
     23 #include "safe-ctype.h"
     24 #include "subsegs.h"
     25 #include "opcode/xgate.h"
     26 #include "dwarf2dbg.h"
     27 #include "elf/xgate.h"
     28 
     29 const char comment_chars[] = ";!";
     30 const char line_comment_chars[] = "#*";
     31 const char line_separator_chars[] = "";
     32 const char EXP_CHARS[] = "eE";
     33 const char FLT_CHARS[] = "dD";
     34 
     35 /* Max opcodes per opcode handle.  */
     36 #define MAX_OPCODES     0x05
     37 
     38 #define SIXTEENTH_BIT		0x8000
     39 #define N_BITS_IN_WORD		16
     40 #define MAX_NUM_OPERANDS	3
     41 
     42 /* #define STATE_CONDITIONAL_BRANCH		(1) */
     43 #define STATE_PC_RELATIVE	(2)
     44 #define REGISTER_P(ptr)		(ptr == 'r')
     45 #define INCREMENT		01
     46 #define DECREMENT		02
     47 #define MAXREGISTER		07
     48 #define MINREGISTER		00
     49 
     50 #define OPTION_MMCU 'm'
     51 
     52 /* This macro has no side-effects.  */
     53 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
     54 
     55 /* Each unique opcode name has a handle.  That handle may
     56    contain pointers to opcodes with the same name but
     57    different address modes.  */
     58 struct xgate_opcode_handle
     59 {
     60   int number_of_modes;
     61   char *name;
     62   struct xgate_opcode *opc0[MAX_OPCODES];
     63 };
     64 
     65 /* XGATE's registers all are 16-bit general purpose.
     66    They are numbered according to the specifications.  */
     67 typedef enum register_id
     68 {
     69   REG_NONE = -1,
     70   REG_R0 = 0,
     71   REG_R1 = 1,
     72   REG_R2 = 2,
     73   REG_R3 = 3,
     74   REG_R4 = 4,
     75   REG_R5 = 5,
     76   REG_R6 = 6,
     77   REG_R7 = 7,
     78   REG_PC = 8,
     79   REG_CCR = 9
     80 } register_id;
     81 
     82 /* Operand Modifiers */
     83 typedef enum op_modifiers
     84 {
     85   MOD_NONE = -1,
     86   MOD_POSTINC = 1,
     87   MOD_PREDEC = 2,
     88   MOD_CONSTANT = 3,
     89   MOD_LOAD_HIGH = 4,
     90   MOD_LOAD_LOW = 5
     91 }op_modifiers;
     92 
     93 typedef struct s_operand
     94 {
     95   expressionS exp;
     96   register_id reg;
     97   op_modifiers mod;
     98 } s_operand;
     99 
    100 
    101 /* Forward declarations.  */
    102 static inline char *skip_whitespace (char *);
    103 static void get_default_target (void);
    104 static char *extract_word (char *, char *, int);
    105 static struct xgate_opcode *xgate_find_match (struct xgate_opcode_handle *,
    106 					      int, s_operand [], unsigned int);
    107 static int cmp_opcode (struct xgate_opcode *, struct xgate_opcode *);
    108 static void xgate_print_table (void);
    109 static unsigned int xgate_get_operands (char *, s_operand []);
    110 static register_id reg_name_search (char *);
    111 static op_modifiers xgate_determine_modifiers(char **);
    112 static void xgate_scan_operands (struct xgate_opcode *opcode, s_operand []);
    113 static unsigned int xgate_parse_operand (struct xgate_opcode *, int *, int,
    114 					 char **, s_operand);
    115 
    116 static struct hash_control *xgate_hash;
    117 
    118 /* Previous opcode.  */
    119 static unsigned int prev = 0;
    120 
    121 static unsigned char fixup_required = 0;
    122 
    123 /* Used to enable clipping of 16 bit operands into 8 bit constraints.  */
    124 static unsigned char autoHiLo = 0;
    125 
    126 static char oper_check;
    127 static char flag_print_insn_syntax = 0;
    128 static char flag_print_opcodes = 0;
    129 
    130 static int current_architecture;
    131 static const char *default_cpu;
    132 
    133 /* ELF flags to set in the output file header.  */
    134 static int elf_flags = E_XGATE_F64;
    135 
    136 /* This table describes how you change sizes for the various types of variable
    137    size expressions.  This version only supports two kinds.  */
    138 
    139 /* The fields are:
    140    How far Forward this mode will reach.
    141    How far Backward this mode will reach.
    142    How many bytes this mode will add to the size of the frag.
    143    Which mode to go to if the offset won't fit in this one.  */
    144 
    145 relax_typeS md_relax_table[] =
    146 {
    147   {1, 1, 0, 0},			/* First entries aren't used.  */
    148   {1, 1, 0, 0},			/* For no good reason except.  */
    149   {1, 1, 0, 0},			/* that the VAX doesn't either.  */
    150   {1, 1, 0, 0},
    151   /* XGATE 9 and 10 bit pc rel todo complete and test */
    152 /*{(511), (-512), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
    153   {(1023), (-1024), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, */
    154   {0, 0, 0, 0}
    155 };
    156 
    157 /* This table describes all the machine specific pseudo-ops the assembler
    158    has to support.  The fields are: pseudo-op name without dot function to
    159    call to execute this pseudo-op Integer arg to pass to the function.  */
    160 const pseudo_typeS md_pseudo_table[] =
    161 {
    162   /* The following pseudo-ops are supported for MRI compatibility.  */
    163   {0, 0, 0}
    164 };
    165 
    166 const char *md_shortopts = "m:";
    167 
    168 struct option md_longopts[] =
    169 {
    170 #define OPTION_PRINT_INSN_SYNTAX  (OPTION_MD_BASE + 0)
    171   { "print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX },
    172 
    173 #define OPTION_PRINT_OPCODES  (OPTION_MD_BASE + 1)
    174   { "print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES },
    175 
    176 #define OPTION_GENERATE_EXAMPLE  (OPTION_MD_BASE + 2)
    177   { "generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE },
    178 
    179 #define OPTION_MSHORT  (OPTION_MD_BASE + 3)
    180   { "mshort", no_argument, NULL, OPTION_MSHORT },
    181 
    182 #define OPTION_MLONG  (OPTION_MD_BASE + 4)
    183   { "mlong", no_argument, NULL, OPTION_MLONG },
    184 
    185 #define OPTION_MSHORT_DOUBLE  (OPTION_MD_BASE + 5)
    186   { "mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE },
    187 
    188 #define OPTION_MLONG_DOUBLE  (OPTION_MD_BASE + 6)
    189   { "mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE },
    190 
    191   { NULL, no_argument, NULL, 0 }
    192 };
    193 
    194 size_t md_longopts_size = sizeof(md_longopts);
    195 
    196 char *
    197 md_atof (int type, char *litP, int *sizeP)
    198 {
    199   return ieee_md_atof (type, litP, sizeP, TRUE);
    200 }
    201 
    202 int
    203 md_parse_option (int c, char *arg)
    204 {
    205   switch (c)
    206     {
    207     case OPTION_MMCU:
    208       if (strcasecmp (arg, "v1") == 0)
    209 	current_architecture = XGATE_V1;
    210       else if (strcasecmp (arg, "v2") == 0)
    211 	current_architecture = XGATE_V2;
    212       else if (strcasecmp (arg, "v3") == 0)
    213 	current_architecture = XGATE_V3;
    214       else
    215 	as_bad (_(" architecture variant invalid"));
    216       break;
    217 
    218     case OPTION_PRINT_INSN_SYNTAX:
    219       flag_print_insn_syntax = 1;
    220       break;
    221 
    222     case OPTION_PRINT_OPCODES:
    223       flag_print_opcodes = 1;
    224       break;
    225 
    226     case OPTION_GENERATE_EXAMPLE:
    227       flag_print_opcodes = 2;
    228       break;
    229 
    230     case OPTION_MSHORT:
    231       elf_flags &= ~E_XGATE_I32;
    232       break;
    233 
    234     case OPTION_MLONG:
    235       elf_flags |= E_XGATE_I32;
    236       break;
    237 
    238     case OPTION_MSHORT_DOUBLE:
    239       elf_flags &= ~E_XGATE_F64;
    240       break;
    241 
    242     case OPTION_MLONG_DOUBLE:
    243       elf_flags |= E_XGATE_F64;
    244       break;
    245 
    246     default:
    247       return 0;
    248     }
    249   return 1;
    250 }
    251 
    252 const char *
    253 xgate_arch_format (void)
    254 {
    255   get_default_target ();
    256 
    257   if (current_architecture & cpuxgate)
    258     return "elf32-xgate";
    259 
    260   return "error";
    261 }
    262 
    263 static void
    264 get_default_target (void)
    265 {
    266   const bfd_target *target;
    267   bfd abfd;
    268 
    269   if (current_architecture != 0)
    270     return;
    271 
    272   default_cpu = "unknown";
    273   target = bfd_find_target (0, &abfd);
    274 
    275   if (target && target->name)
    276     {
    277       if (strcmp (target->name, "elf32-xgate") == 0)
    278 	{
    279 	  current_architecture = cpuxgate;
    280 	  default_cpu = "XGATE V1";
    281 	  return;
    282 	}
    283 
    284       as_bad (_("Default target `%s' is not supported."), target->name);
    285     }
    286 }
    287 
    288 void
    289 md_begin (void)
    290 {
    291   struct xgate_opcode *xgate_opcode_ptr = NULL;
    292   struct xgate_opcode *xgate_op_table = NULL;
    293   struct xgate_opcode_handle *op_handles = 0;
    294   char *prev_op_name = 0;
    295   int handle_enum = 0;
    296   int number_of_op_handles = 0;
    297   int i, j = 0;
    298 
    299   /* Create a local copy of our opcode table
    300      including an extra line for NULL termination.  */
    301   xgate_op_table = (struct xgate_opcode *)
    302     xmalloc ((xgate_num_opcodes) * sizeof (struct xgate_opcode));
    303 
    304   memset (xgate_op_table, 0,
    305 	  sizeof(struct xgate_opcode) * (xgate_num_opcodes));
    306 
    307   for (xgate_opcode_ptr = (struct xgate_opcode*) xgate_opcodes, i = 0;
    308        i < xgate_num_opcodes; i++)
    309     xgate_op_table[i] = xgate_opcode_ptr[i];
    310 
    311   qsort (xgate_op_table, xgate_num_opcodes, sizeof(struct xgate_opcode),
    312 	 (int (*)(const void *, const void *)) cmp_opcode);
    313 
    314   /* Calculate number of handles since this will be
    315      smaller than the raw number of opcodes in the table.  */
    316   prev_op_name = "";
    317   for (xgate_opcode_ptr = xgate_op_table, i = 0;  i < xgate_num_opcodes;
    318        xgate_opcode_ptr++, i++)
    319     {
    320       if (strcmp (prev_op_name, xgate_opcode_ptr->name))
    321 	number_of_op_handles++;
    322       prev_op_name = xgate_opcode_ptr->name;
    323     }
    324 
    325   op_handles = (struct xgate_opcode_handle *)
    326     xmalloc (sizeof(struct xgate_opcode_handle) * (number_of_op_handles));
    327 
    328   /* Insert unique opcode names into hash table, aliasing duplicates.  */
    329   xgate_hash = hash_new ();
    330 
    331   prev_op_name = "";
    332   for (xgate_opcode_ptr = xgate_op_table, i = 0, j = 0; i < xgate_num_opcodes;
    333        i++, xgate_opcode_ptr++)
    334     {
    335       if (!strcmp (prev_op_name, xgate_opcode_ptr->name))
    336 	{
    337 	  handle_enum++;
    338 	  op_handles[j].opc0[handle_enum] = xgate_opcode_ptr;
    339 	}
    340       else
    341 	{
    342 	  handle_enum = 0;
    343 	  if (i)
    344 	    j++;
    345 	  op_handles[j].name = xgate_opcode_ptr->name;
    346 	  op_handles[j].opc0[0] = xgate_opcode_ptr;
    347 	  hash_insert (xgate_hash, (char *) op_handles[j].name,
    348 		       (char *) &(op_handles[j]));
    349 	}
    350       op_handles[j].number_of_modes = handle_enum;
    351       prev_op_name = op_handles[j].name;
    352     }
    353 
    354   if (flag_print_opcodes)
    355     {
    356       xgate_print_table ();
    357       exit (EXIT_SUCCESS);
    358     }
    359 }
    360 
    361 void
    362 xgate_init_after_args (void)
    363 {
    364 }
    365 
    366 void
    367 md_show_usage (FILE * stream)
    368 {
    369   get_default_target ();
    370 
    371   fprintf (stream,
    372 	   _("\
    373 Freescale XGATE co-processor options:\n\
    374   -mshort                 use 16-bit int ABI (default)\n\
    375   -mlong                  use 32-bit int ABI\n\
    376   -mshort-double          use 32-bit double ABI\n\
    377   -mlong-double           use 64-bit double ABI (default)\n\
    378   --mxgate                specify the processor variant[default %s]\n\
    379   --print-insn-syntax     print the syntax of instruction in case of error\n\
    380   --print-opcodes         print the list of instructions with syntax\n\
    381   --generate-example      generate an example of each instruction"),
    382 	   default_cpu);
    383 }
    384 
    385 enum bfd_architecture
    386 xgate_arch (void)
    387 {
    388   get_default_target ();
    389   return bfd_arch_xgate;
    390 }
    391 
    392 int
    393 xgate_mach (void)
    394 {
    395   return 0;
    396 }
    397 
    398 static void
    399 xgate_print_syntax (char *name)
    400 {
    401   int i;
    402 
    403   for (i = 0; i < xgate_num_opcodes; i++)
    404     {
    405       if (!strcmp (xgate_opcodes[i].name, name))
    406 	{
    407 	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IDR))
    408 	    printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
    409 		    xgate_opcodes[i].name);
    410 	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_INH))
    411 	    printf ("\tFormat is %s\n", xgate_opcodes[i].name);
    412 	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_TRI))
    413 	    printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes[i].name);
    414 	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA))
    415 	    printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes[i].name);
    416 	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM3))
    417 	    printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes[i].name);
    418 	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM4))
    419 	    printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes[i].name);
    420 	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM8))
    421 	    printf ("\tFormat is %s\tRx, <8-bit value>\n",
    422 		    xgate_opcodes[i].name);
    423 	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16))
    424 	    printf ("\tFormat is %s\tRx, <16-bit value>\n",
    425 		    xgate_opcodes[i].name);
    426 	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_C))
    427 	    printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes[i].name);
    428 	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_C_R))
    429 	    printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes[i].name);
    430 	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_P))
    431 	    printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes[i].name);
    432 	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16mLDW))
    433 	    printf ("\tFormat is %s\tRx, <16-bit value>\n",
    434 		    xgate_opcodes[i].name);
    435 	}
    436     }
    437 }
    438 
    439 static void
    440 xgate_print_table (void)
    441 {
    442   int i;
    443 
    444   for (i = 0; i < xgate_num_opcodes; i++)
    445     xgate_print_syntax (xgate_opcodes[i].name);
    446 
    447   return;
    448 }
    449 
    450 const char *
    451 xgate_listing_header (void)
    452 {
    453   if (current_architecture & cpuxgate)
    454     return "XGATE GAS ";
    455 
    456   return "ERROR MC9S12X GAS ";
    457 }
    458 
    459 symbolS *
    460 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
    461 {
    462   return 0;
    463 }
    464 
    465 /* GAS will call this function for each section at the end of the assembly,
    466    to permit the CPU backend to adjust the alignment of a section.  */
    467 
    468 valueT
    469 md_section_align (asection * seg, valueT addr)
    470 {
    471   int align = bfd_get_section_alignment (stdoutput, seg);
    472   return ((addr + (1 << align) - 1) & (-1 << align));
    473 }
    474 
    475 void
    476 md_assemble (char *input_line)
    477 {
    478   struct xgate_opcode *opcode = 0;
    479   struct xgate_opcode *macro_opcode = 0;
    480   struct xgate_opcode_handle *opcode_handle = 0;
    481   /* Caller expects it to be returned as it was passed.  */
    482   char *saved_input_line = input_line;
    483   char op_name[9] =  { 0 };
    484   unsigned int operandCount = 0;
    485   char *p = 0;
    486 
    487   s_operand new_operands[MAX_NUM_OPERANDS];
    488 
    489   fixup_required = 0;
    490   oper_check = 0; /* set error flags */
    491   input_line = extract_word (input_line, op_name, sizeof(op_name));
    492 
    493   /* Check to make sure we are not reading a bogus line.  */
    494   if (!op_name[0])
    495     as_bad (_("opcode missing or not found on input line"));
    496 
    497   if (!(opcode_handle = (struct xgate_opcode_handle *) hash_find (xgate_hash,
    498 								  op_name)))
    499     {
    500       as_bad (_("opcode %s not found in opcode hash table"), op_name);
    501     }
    502   else
    503     {
    504       /* Parse operands so we can find the proper opcode bin.  */
    505 
    506       operandCount = xgate_get_operands (input_line, new_operands);
    507 
    508       opcode = xgate_find_match (opcode_handle, opcode_handle->number_of_modes,
    509 				 new_operands, operandCount);
    510 
    511       if (!opcode)
    512 	{
    513 	  as_bad (_("matching operands to opcode "));
    514 	  xgate_print_syntax (opcode_handle->opc0[0]->name);
    515 	}
    516       else if (opcode->size == 2)
    517 	{
    518 	  /* Size is one word - assemble that native insn.  */
    519 	  xgate_scan_operands (opcode, new_operands);
    520 	}
    521       else
    522 	{
    523 	  /* Insn is a simplified instruction - expand it out.  */
    524 	  autoHiLo = 1;
    525 	  unsigned int i;
    526 
    527 	  /* skip past our ';' separator.  */
    528 	  for (i = strlen (opcode->constraints), p = opcode->constraints; i > 0;
    529 	       i--, p++)
    530 	    {
    531 	      if (*p == ';')
    532 		{
    533 		  p++;
    534 		  break;
    535 		}
    536 	    }
    537 	  input_line = skip_whitespace (input_line);
    538 	  char *macro_inline = input_line;
    539 
    540 	  /* Loop though the macro's opcode list and apply operands to
    541 	     each real opcode. */
    542 	  for (i = 0; *p && i < (opcode->size / 2); i++)
    543 	    {
    544 	      /* Loop though macro operand list.  */
    545 	      input_line = macro_inline; /* Rewind.  */
    546 	      p = extract_word (p, op_name, 10);
    547 
    548 	      if (!(opcode_handle = (struct xgate_opcode_handle *)
    549 		    hash_find (xgate_hash, op_name)))
    550 		{
    551 		  as_bad (_(": processing macro, real opcode handle"
    552 			    " not found in hash"));
    553 		  break;
    554 		}
    555 	      else
    556 		{
    557 		  operandCount = xgate_get_operands(input_line, new_operands);
    558 		  macro_opcode = xgate_find_match (opcode_handle,
    559 						   opcode_handle->number_of_modes, new_operands,
    560 					       operandCount);
    561 		  xgate_scan_operands (macro_opcode, new_operands);
    562 		}
    563 	    }
    564 	}
    565     }
    566   autoHiLo = 0;
    567   input_line = saved_input_line;
    568 }
    569 
    570 /* Force truly undefined symbols to their maximum size, and generally set up
    571    the frag list to be relaxed.  */
    572 
    573 int
    574 md_estimate_size_before_relax (fragS *fragp, asection *seg)
    575 {
    576   /* If symbol is undefined or located in a different section,
    577      select the largest supported relocation.  */
    578   relax_substateT subtype;
    579   relax_substateT rlx_state[] = { 0, 2 };
    580 
    581   for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
    582     {
    583       if (fragp->fr_subtype == rlx_state[subtype]
    584 	  && (!S_IS_DEFINED (fragp->fr_symbol)
    585 	      || seg != S_GET_SEGMENT (fragp->fr_symbol)))
    586 	{
    587 	  fragp->fr_subtype = rlx_state[subtype + 1];
    588 	  break;
    589 	}
    590     }
    591 
    592   if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
    593     abort ();
    594 
    595   return md_relax_table[fragp->fr_subtype].rlx_length;
    596 }
    597 
    598 
    599 /* Relocation, relaxation and frag conversions.  */
    600 
    601 /* PC-relative offsets are relative to the start of the
    602    next instruction.  That is, the address of the offset, plus its
    603    size, since the offset is always the last part of the insn.  */
    604 
    605 long
    606 md_pcrel_from (fixS * fixP)
    607 {
    608   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
    609 }
    610 
    611 /* If while processing a fixup, a reloc really needs to be created
    612    then it is done here.  */
    613 
    614 arelent *
    615 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
    616 {
    617   arelent * reloc;
    618 
    619   reloc = (arelent *) xmalloc (sizeof(arelent));
    620   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof(asymbol *));
    621   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
    622   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
    623 
    624   if (fixp->fx_r_type == 0)
    625     reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
    626   else
    627     reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
    628 
    629   if (reloc->howto == (reloc_howto_type *) NULL)
    630     {
    631       as_bad_where (fixp->fx_file, fixp->fx_line, _
    632 		    ("Relocation %d is not supported by object file format."),
    633 		    (int) fixp->fx_r_type);
    634       return NULL;
    635     }
    636 
    637   /* Since we use Rel instead of Rela, encode the vtable entry to be
    638      used in the relocation's section offset.  */
    639   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
    640     reloc->address = fixp->fx_offset;
    641   reloc->addend = 0;
    642   return reloc;
    643 }
    644 
    645 /* Patch the instruction with the resolved operand.  Elf relocation
    646    info will also be generated to take care of linker/loader fixups.
    647    The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
    648    for the support of --gstabs.  */
    649 
    650 void
    651 md_apply_fix (fixS * fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
    652 {
    653   char *where;
    654   long value = *valP;
    655   int opcode = 0;
    656   ldiv_t result;
    657 
    658   /* If the fixup is done mark it done so no further symbol resolution
    659      will take place.  */
    660   if (fixP->fx_addsy == (symbolS *) NULL)
    661     fixP->fx_done = 1;
    662 
    663   /* We don't actually support subtracting a symbol.  */
    664   if (fixP->fx_subsy != (symbolS *) NULL)
    665     as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
    666 
    667   where = fixP->fx_frag->fr_literal + fixP->fx_where;
    668   opcode = bfd_getl16 (where);
    669   int mask = 0;
    670 
    671   switch (fixP->fx_r_type)
    672     {
    673     case R_XGATE_PCREL_9:
    674       if (value < -512 || value > 511)
    675 	as_bad_where (fixP->fx_file, fixP->fx_line,
    676 		      _("Value %ld too large for 9-bit PC-relative branch."),
    677 		      value);
    678       result = ldiv (value, 2); /* from bytes to words */
    679       value = result.quot;
    680       if (result.rem)
    681 	as_bad_where (fixP->fx_file, fixP->fx_line, _
    682 		      ("Value %ld not aligned by 2 for 9-bit"
    683 		       " PC-relative branch."), value);
    684       /* Clip into 8-bit field.
    685 	 FIXME I'm sure there is a more proper place for this.  */
    686       mask = 0x1FF;
    687       value &= mask;
    688       number_to_chars_bigendian (where, (opcode | value), 2);
    689       break;
    690     case R_XGATE_PCREL_10:
    691       if (value < -1024 || value > 1023)
    692 	as_bad_where (fixP->fx_file, fixP->fx_line,
    693 		      _("Value %ld too large for 10-bit PC-relative branch."),
    694 		      value);
    695       result = ldiv (value, 2); /* from bytes to words */
    696       value = result.quot;
    697       if (result.rem)
    698 	as_bad_where (fixP->fx_file, fixP->fx_line, _
    699 		      ("Value %ld not aligned by 2 for 10-bit"
    700 		       " PC-relative branch."), value);
    701       /* Clip into 9-bit field.
    702 	 FIXME I'm sure there is a more proper place for this.  */
    703       mask = 0x3FF;
    704       value &= mask;
    705       number_to_chars_bigendian (where, (opcode | value), 2);
    706       break;
    707     case BFD_RELOC_XGATE_IMM8_HI:
    708       if (value < -65537 || value > 65535)
    709 	as_bad_where (fixP->fx_file, fixP->fx_line,
    710 		      _("Value out of 16-bit range."));
    711       value >>= 8;
    712       value &= 0x00ff;
    713       bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
    714       break;
    715     case BFD_RELOC_XGATE_24:
    716     case BFD_RELOC_XGATE_IMM8_LO:
    717       if (value < -65537 || value > 65535)
    718 	as_bad_where (fixP->fx_file, fixP->fx_line,
    719 		      _("Value out of 16-bit range."));
    720       value &= 0x00ff;
    721       bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
    722       break;
    723     case BFD_RELOC_XGATE_IMM3:
    724       if (value < 0 || value > 7)
    725 	as_bad_where (fixP->fx_file, fixP->fx_line,
    726 		      _("Value out of 3-bit range."));
    727       value <<= 8; /* make big endian */
    728       number_to_chars_bigendian (where, (opcode | value), 2);
    729       break;
    730     case BFD_RELOC_XGATE_IMM4:
    731       if (value < 0 || value > 15)
    732 	as_bad_where (fixP->fx_file, fixP->fx_line,
    733 		      _("Value out of 4-bit range."));
    734       value <<= 4; /* align the operand bits */
    735       number_to_chars_bigendian (where, (opcode | value), 2);
    736       break;
    737     case BFD_RELOC_XGATE_IMM5:
    738       if (value < 0 || value > 31)
    739 	as_bad_where (fixP->fx_file, fixP->fx_line,
    740 		      _("Value out of 5-bit range."));
    741       value <<= 5; /* align the operand bits */
    742       number_to_chars_bigendian (where, (opcode | value), 2);
    743       break;
    744     case BFD_RELOC_8:
    745       ((bfd_byte *) where)[0] = (bfd_byte) value;
    746       break;
    747     case BFD_RELOC_32:
    748       bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
    749       break;
    750     case BFD_RELOC_16:
    751       bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
    752       break;
    753     default:
    754       as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP->fx_line,
    755 		fixP->fx_r_type);
    756       break;
    757     }
    758 }
    759 
    760 /* See whether we need to force a relocation into the output file.  */
    761 
    762 int
    763 tc_xgate_force_relocation (fixS * fixP)
    764 {
    765   if (fixP->fx_r_type == BFD_RELOC_XGATE_RL_GROUP)
    766     return 1;
    767   return generic_force_reloc (fixP);
    768 }
    769 
    770 /* Here we decide which fixups can be adjusted to make them relative
    771    to the beginning of the section instead of the symbol.  Basically
    772    we need to make sure that the linker relaxation is done
    773    correctly, so in some cases we force the original symbol to be
    774    used.  */
    775 
    776 int
    777 tc_xgate_fix_adjustable (fixS * fixP)
    778 {
    779   switch (fixP->fx_r_type)
    780     {
    781       /* For the linker relaxation to work correctly, these relocs
    782 	 need to be on the symbol itself.  */
    783     case BFD_RELOC_16:
    784     case BFD_RELOC_XGATE_RL_JUMP:
    785     case BFD_RELOC_XGATE_RL_GROUP:
    786     case BFD_RELOC_VTABLE_INHERIT:
    787     case BFD_RELOC_VTABLE_ENTRY:
    788     case BFD_RELOC_32:
    789       return 0;
    790     default:
    791       return 1;
    792     }
    793 }
    794 
    795 void
    796 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
    797 		 asection * sec ATTRIBUTE_UNUSED,
    798 		 fragS * fragP ATTRIBUTE_UNUSED)
    799 {
    800   as_bad (("md_convert_frag not implemented yet"));
    801   abort ();
    802 }
    803 
    804 /* Set the ELF specific flags.  */
    805 
    806 void
    807 xgate_elf_final_processing (void)
    808 {
    809   elf_flags |= EF_XGATE_MACH;
    810   elf_elfheader (stdoutput)->e_flags &= ~EF_XGATE_ABI;
    811   elf_elfheader (stdoutput)->e_flags |= elf_flags;
    812 }
    813 
    814 static inline char *
    815 skip_whitespace (char *s)
    816 {
    817   while (*s == ' ' || *s == '\t' || *s == '(' || *s == ')')
    818     s++;
    819 
    820   return s;
    821 }
    822 
    823 /* Extract a word (continuous alpha-numeric chars) from the input line.  */
    824 
    825 static char *
    826 extract_word (char *from, char *to, int limit)
    827 {
    828   char *op_end;
    829   int size = 0;
    830 
    831   /* Drop leading whitespace.  */
    832   from = skip_whitespace (from);
    833   *to = 0;
    834   /* Find the op code end.  */
    835   for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
    836     {
    837       to[size++] = *op_end++;
    838       if (size + 1 >= limit)
    839 	break;
    840     }
    841   to[size] = 0;
    842   return op_end;
    843 }
    844 
    845 static char *
    846 xgate_new_instruction (int size)
    847 {
    848   char *f = frag_more (size);
    849   dwarf2_emit_insn (size);
    850   return f;
    851 }
    852 
    853 static unsigned short
    854 xgate_apply_operand (unsigned short new_mask,
    855 		     unsigned short *availiable_mask_bits,
    856 		     unsigned short mask,
    857 		     unsigned char n_bits)
    858 {
    859   unsigned short n_shifts;
    860   unsigned int n_drop_bits;
    861 
    862   /* Shift until you find an available operand bit "1" and record
    863      the number of shifts.  */
    864   for (n_shifts = 0;
    865        !(*availiable_mask_bits & SIXTEENTH_BIT) && n_shifts < 16;
    866        n_shifts++)
    867     *availiable_mask_bits <<= 1;
    868 
    869   /* Shift for the number of bits your operand requires while bits
    870      are available.  */
    871   for (n_drop_bits = n_bits;
    872        n_drop_bits && (*availiable_mask_bits & SIXTEENTH_BIT);
    873        --n_drop_bits)
    874     *availiable_mask_bits <<= 1;
    875 
    876   if (n_drop_bits)
    877     as_bad (_(":operand has too many bits"));
    878   *availiable_mask_bits >>= n_shifts + n_bits;
    879   if ((n_drop_bits == 0) && (*availiable_mask_bits == 0))
    880     {
    881       oper_check = 1; /* flag operand check as good */
    882     }
    883   new_mask <<= N_BITS_IN_WORD - (n_shifts + n_bits);
    884   mask |= new_mask;
    885   return mask;
    886 }
    887 
    888 /* Parse ordinary expression.  */
    889 
    890 static char *
    891 xgate_parse_exp (char *s, expressionS * op)
    892 {
    893   input_line_pointer = s;
    894   expression(op);
    895   if (op->X_op == O_absent)
    896     as_bad (_("missing operand"));
    897   return input_line_pointer;
    898 }
    899 
    900 static int
    901 cmp_opcode (struct xgate_opcode *op1, struct xgate_opcode *op2)
    902 {
    903   return strcmp (op1->name, op2->name);
    904 }
    905 
    906 static struct xgate_opcode *
    907 xgate_find_match (struct xgate_opcode_handle *opcode_handle,
    908 		  int numberOfModes, s_operand oprs[], unsigned int operandCount)
    909 {
    910   int i;
    911 
    912   if (numberOfModes == 0)
    913     return opcode_handle->opc0[0];
    914 
    915   for (i = 0; i <= numberOfModes; i++)
    916     {
    917       switch (operandCount)
    918         {
    919       case 0:
    920         if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_INH))
    921           return opcode_handle->opc0[i];
    922         break;
    923       case 1:
    924         if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
    925           if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_MON))
    926             return opcode_handle->opc0[i];
    927           if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_DYA_MON))
    928             return opcode_handle->opc0[i];
    929         if (oprs[0].reg == REG_NONE)
    930           if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_IMM3))
    931             return opcode_handle->opc0[i];
    932         break;
    933       case 2:
    934         if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
    935           {
    936             if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
    937               if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_DYA))
    938                 return opcode_handle->opc0[i];
    939             if (oprs[1].reg == REG_CCR)
    940               if (!strcmp(opcode_handle->opc0[i]->constraints,
    941                   XGATE_OP_MON_R_C))
    942                 return opcode_handle->opc0[i];
    943             if (oprs[1].reg == REG_PC)
    944               if (!strcmp(opcode_handle->opc0[i]->constraints,
    945                   XGATE_OP_MON_R_P))
    946                 return opcode_handle->opc0[i];
    947             if (oprs[1].reg == REG_NONE)
    948               if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_IMM16)
    949                   || !strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_IMM8)
    950                   || !strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_IMM4)
    951                   || !strcmp(opcode_handle->opc0[i]->constraints,
    952                       XGATE_OP_IMM16mADD)
    953                   || !strcmp(opcode_handle->opc0[i]->constraints,
    954                       XGATE_OP_IMM16mAND)
    955                   || !strcmp(opcode_handle->opc0[i]->constraints,
    956                       XGATE_OP_IMM16mCPC)
    957                   || !strcmp(opcode_handle->opc0[i]->constraints,
    958                       XGATE_OP_IMM16mSUB)
    959                   || !strcmp(opcode_handle->opc0[i]->constraints,
    960                       XGATE_OP_IMM16mLDW))
    961                 return opcode_handle->opc0[i];
    962           }
    963         if (oprs[0].reg == REG_CCR)
    964           if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_MON_C_R))
    965             return opcode_handle->opc0[i];
    966         break;
    967       case 3:
    968         if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
    969           {
    970             if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
    971               {
    972                 if (oprs[2].reg >= REG_R0 && oprs[2].reg <= REG_R7)
    973                   {
    974                     if (!strcmp(opcode_handle->opc0[i]->constraints,
    975                         XGATE_OP_IDR)
    976                         || !strcmp(opcode_handle->opc0[i]->constraints,
    977                             XGATE_OP_TRI))
    978                       return opcode_handle->opc0[i];
    979                   }
    980 
    981                 if (oprs[2].reg == REG_NONE)
    982                   if (!strcmp(opcode_handle->opc0[i]->constraints,
    983                       XGATE_OP_IDO5))
    984                     return opcode_handle->opc0[i];
    985               }
    986           }
    987         break;
    988       default:
    989         as_bad(_("unknown operand count"));
    990         break;
    991         }
    992     }
    993   return NULL ;
    994 }
    995 
    996 /* Because we are dealing with two different core that view the system
    997    memory with different offsets, we must differentiate what core a
    998    symbol belongs to, in order for the linker to cross-link.  */
    999 
   1000 int
   1001 xgate_frob_symbol (symbolS *sym)
   1002 {
   1003   asymbol *bfdsym;
   1004   elf_symbol_type *elfsym;
   1005 
   1006   bfdsym = symbol_get_bfdsym (sym);
   1007   elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
   1008 
   1009   gas_assert(elfsym);
   1010 
   1011   /* Mark the symbol as being *from XGATE  */
   1012   elfsym->internal_elf_sym.st_target_internal = 1;
   1013 
   1014   return 0;
   1015 }
   1016 
   1017 static unsigned int
   1018 xgate_get_operands (char *line, s_operand oprs[])
   1019 {
   1020   int num_operands;
   1021 
   1022   /* If there are no operands, then it must be inherent.  */
   1023   if (*line == 0 || *line == '\n' || *line == '\r')
   1024     return 0;
   1025 
   1026   for (num_operands = 0; strlen (line) && (num_operands < MAX_NUM_OPERANDS);
   1027        num_operands++)
   1028     {
   1029       line = skip_whitespace (line);
   1030       if (*line == '#')
   1031 	line++;
   1032 
   1033       oprs[num_operands].mod = xgate_determine_modifiers (&line);
   1034 
   1035       if ((oprs[num_operands].reg = reg_name_search (line)) == REG_NONE)
   1036 	line = xgate_parse_exp (line, &oprs[num_operands].exp);
   1037 
   1038       /* skip to next operand */
   1039       while (*line != 0)
   1040 	{
   1041 	  if (*line == ',')
   1042 	    {
   1043 	      line++;
   1044 	      break;
   1045 	    }
   1046 	  line++;
   1047 	}
   1048     }
   1049   if (num_operands > MAX_NUM_OPERANDS)
   1050     return 0;
   1051   return num_operands;
   1052 }
   1053 
   1054 /* reg_name_search() finds the register number given its name.
   1055    Returns the register number or REG_NONE on failure.  */
   1056 static register_id
   1057 reg_name_search (char *name)
   1058 {
   1059   if (strncasecmp (name, "r0", 2) == 0)
   1060     return REG_R0;
   1061   if (strncasecmp (name, "r1", 2) == 0)
   1062     return REG_R1;
   1063   if (strncasecmp (name, "r2", 2) == 0)
   1064     return REG_R2;
   1065   if (strncasecmp (name, "r3", 2) == 0)
   1066     return REG_R3;
   1067   if (strncasecmp (name, "r4", 2) == 0)
   1068     return REG_R4;
   1069   if (strncasecmp (name, "r5", 2) == 0)
   1070     return REG_R5;
   1071   if (strncasecmp (name, "r6", 2) == 0)
   1072     return REG_R6;
   1073   if (strncasecmp (name, "r7", 2) == 0)
   1074     return REG_R7;
   1075   if (strncasecmp (name, "pc", 2) == 0)
   1076     return REG_PC;
   1077   if (strncasecmp (name, "ccr", 3) == 0)
   1078     return REG_CCR;
   1079   return REG_NONE;
   1080 }
   1081 
   1082 /* Parse operand modifiers such as inc/dec/hi/low.  */
   1083 
   1084 static op_modifiers
   1085 xgate_determine_modifiers(char **line)
   1086 {
   1087   char *local_line = line[0];
   1088 
   1089   if (strncasecmp (local_line, "%hi", 3) == 0)
   1090     {
   1091       *line += 3;
   1092       return MOD_LOAD_HIGH;
   1093     }
   1094   if (strncasecmp (local_line, "%lo", 3) == 0)
   1095     {
   1096       *line += 3;
   1097       return MOD_LOAD_LOW;
   1098     }
   1099   if (*(local_line + 2) == '+')
   1100     return MOD_POSTINC;
   1101   if (strncasecmp (local_line, "-r", 2) == 0)
   1102     {
   1103       *line += 1;
   1104       return MOD_PREDEC;
   1105     }
   1106   return MOD_NONE;
   1107 }
   1108 
   1109 /* Parse instruction operands.  */
   1110 
   1111 static void
   1112 xgate_scan_operands (struct xgate_opcode *opcode, s_operand oprs[])
   1113 {
   1114   char *frag = xgate_new_instruction (opcode->size);
   1115   int where = frag - frag_now->fr_literal;
   1116   char *op = opcode->constraints;
   1117   unsigned int bin = (int) opcode->bin_opcode;
   1118   unsigned short oper_mask = 0;
   1119   int operand_bit_length = 0;
   1120   unsigned int operand = 0;
   1121   char n_operand_bits = 0;
   1122   char first_operand_equals_second = 0;
   1123   int i = 0;
   1124   char c = 0;
   1125 
   1126   /* Generate available operand bits mask.  */
   1127   for (i = 0; (c = opcode->format[i]); i++)
   1128     {
   1129       if (ISDIGIT (c) || (c == 's'))
   1130 	{
   1131 	  oper_mask <<= 1;
   1132 	}
   1133       else
   1134 	{
   1135 	  oper_mask <<= 1;
   1136 	  oper_mask += 1;
   1137 	  n_operand_bits++;
   1138 	}
   1139     }
   1140 
   1141   /* Parse first operand.  */
   1142   if (*op)
   1143     {
   1144       if (*op == '=')
   1145 	{
   1146 	  first_operand_equals_second = 1;
   1147 	  ++op;
   1148 	}
   1149       operand = xgate_parse_operand (opcode, &operand_bit_length, where,
   1150 				     &op, oprs[0]);
   1151       ++op;
   1152       bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length);
   1153 
   1154       if(first_operand_equals_second)
   1155 	bin = xgate_apply_operand (operand, &oper_mask, bin,
   1156 				   operand_bit_length);
   1157       /* Parse second operand.  */
   1158       if (*op)
   1159 	{
   1160 	  if (*op == ',')
   1161 	    ++op;
   1162 	  if (first_operand_equals_second)
   1163 	    {
   1164 	      bin = xgate_apply_operand (operand, &oper_mask, bin,
   1165 					 operand_bit_length);
   1166 	      ++op;
   1167 	    }
   1168 	  else
   1169 	    {
   1170 	      operand = xgate_parse_operand (opcode, &operand_bit_length, where,
   1171 					     &op, oprs[1]);
   1172 	      bin = xgate_apply_operand (operand, &oper_mask, bin,
   1173 					 operand_bit_length);
   1174 	      ++op;
   1175 	    }
   1176 	}
   1177       /* Parse the third register.  */
   1178       if (*op)
   1179 	{
   1180 	  if (*op == ',')
   1181 	    ++op;
   1182 	  operand = xgate_parse_operand (opcode, &operand_bit_length, where,
   1183 					 &op, oprs[2]);
   1184 	  bin = xgate_apply_operand (operand, &oper_mask, bin,
   1185 				     operand_bit_length);
   1186 	}
   1187     }
   1188   if (opcode->size == 2 && fixup_required)
   1189     {
   1190       bfd_putl16 (bin, frag);
   1191     }
   1192   else if ( !strcmp (opcode->constraints, XGATE_OP_REL9)
   1193       || !strcmp (opcode->constraints, XGATE_OP_REL10))
   1194     {
   1195       /* Write our data to a frag for further processing.  */
   1196       bfd_putl16 (opcode->bin_opcode, frag);
   1197     }
   1198   else
   1199     {
   1200       /* Apply operand mask(s)to bin opcode and write the output.  */
   1201       /* Since we are done write this frag in xgate BE format.  */
   1202       number_to_chars_bigendian (frag, bin, opcode->size);
   1203     }
   1204   prev = bin;
   1205   return;
   1206 }
   1207 
   1208 static unsigned int
   1209 xgate_parse_operand (struct xgate_opcode *opcode,
   1210 		     int *bit_width,
   1211 		     int where,
   1212 		     char **op_con,
   1213 		     s_operand operand)
   1214 {
   1215   char *op_constraint = *op_con;
   1216   unsigned int op_mask = 0;
   1217   unsigned int pp_fix = 0;
   1218   unsigned short max_size = 0;
   1219   int i;
   1220 
   1221   *bit_width = 0;
   1222   /* Reset.  */
   1223 
   1224   switch (*op_constraint)
   1225     {
   1226     case '+': /* Indexed register operand +/- or plain r.  */
   1227       /* Default to neither inc or dec.  */
   1228       pp_fix = 0;
   1229       *bit_width = 5;
   1230 
   1231       if (operand.reg == REG_NONE)
   1232 	as_bad (_(": expected register name r0-r7 ") );
   1233       op_mask = operand.reg;
   1234       if(operand.mod == MOD_POSTINC)
   1235 	pp_fix = INCREMENT;
   1236       if(operand.mod == MOD_PREDEC)
   1237 	pp_fix = DECREMENT;
   1238       op_mask <<= 2;
   1239       op_mask |= pp_fix;
   1240       break;
   1241 
   1242     case 'r': /* Register operand.  */
   1243       if (operand.reg == REG_NONE)
   1244 	as_bad (_(": expected register name r0-r7 "));
   1245 
   1246       *bit_width = 3;
   1247 
   1248       op_mask = operand.reg;
   1249       break;
   1250 
   1251     case 'i': /* Immediate value or expression expected.  */
   1252       /* Advance the original format pointer.  */
   1253       (*op_con)++;
   1254       op_constraint++;
   1255       if (ISDIGIT (*op_constraint))
   1256 	*bit_width = (int) *op_constraint - '0';
   1257       else if (*op_constraint == 'a')
   1258 	*bit_width = 0x0A;
   1259       else if (*op_constraint == 'f')
   1260 	*bit_width = 0x0F;
   1261 
   1262       /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
   1263       if (operand.exp.X_op == O_constant)
   1264 	{
   1265 	  op_mask = operand.exp.X_add_number;
   1266 	  if (((opcode->name[strlen (opcode->name) - 1] == 'l') && autoHiLo)
   1267 	      || operand.mod == MOD_LOAD_LOW)
   1268 	    op_mask &= 0x00FF;
   1269 	  else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
   1270 		    && autoHiLo) || operand.mod == MOD_LOAD_HIGH)
   1271 	    op_mask >>= 8;
   1272 
   1273 	  /* Make sure it fits.  */
   1274 	  for (i = *bit_width; i; i--)
   1275 	    {
   1276 	      max_size <<= 1;
   1277 	      max_size += 1;
   1278 	    }
   1279 	  if (op_mask > max_size)
   1280 	    as_bad (_(":operand value(%d) too big for constraint"), op_mask);
   1281 	}
   1282       else
   1283 	{
   1284 	  /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
   1285 	     TODO fix.  */
   1286 	  fixup_required = 1;
   1287 	  if (*op_constraint == '8')
   1288 	    {
   1289 	      if (((opcode->name[strlen (opcode->name) - 1] == 'l')
   1290 		   && autoHiLo) || operand.mod == MOD_LOAD_LOW)
   1291 		fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
   1292 			     BFD_RELOC_XGATE_24);
   1293 	      else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
   1294 			&& autoHiLo) || operand.mod == MOD_LOAD_HIGH )
   1295 		fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
   1296 			     BFD_RELOC_XGATE_IMM8_HI);
   1297 	      else
   1298 		as_bad (_("you must use a hi/lo directive or 16-bit macro "
   1299 			  "to load a 16-bit value."));
   1300 	    }
   1301 	  else if (*op_constraint == '5')
   1302 	    fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
   1303 			 BFD_RELOC_XGATE_IMM5);
   1304 	  else if (*op_constraint == '4')
   1305 	    fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
   1306 			 BFD_RELOC_XGATE_IMM4);
   1307 	  else if (*op_constraint == '3')
   1308 	    fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
   1309 			 BFD_RELOC_XGATE_IMM3);
   1310 	  else
   1311 	    as_bad (_(":unknown relocation constraint size"));
   1312 	}
   1313       break;
   1314 
   1315     case 'c': /* CCR register expected.  */
   1316       *bit_width = 0;
   1317       if (operand.reg != REG_CCR)
   1318 	as_bad (_(": expected register name ccr "));
   1319       break;
   1320 
   1321     case 'p': /* PC register expected.  */
   1322       *bit_width = 0;
   1323       if (operand.reg != REG_PC)
   1324 	as_bad (_(": expected register name pc "));
   1325       break;
   1326 
   1327     case 'b': /* Branch expected.  */
   1328       (*op_con)++;
   1329       op_constraint++;
   1330 
   1331       if (operand.exp.X_op != O_register)
   1332 	{
   1333 	  if (*op_constraint == '9')
   1334 	    fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
   1335 			 R_XGATE_PCREL_9);
   1336 	  else if (*op_constraint == 'a')
   1337 	    fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
   1338 			 R_XGATE_PCREL_10);
   1339 	}
   1340       else
   1341 	as_fatal (_("Operand `%x' not recognized in fixup8."),
   1342 		  operand.exp.X_op);
   1343       break;
   1344     case '?':
   1345       break;
   1346 
   1347     default:
   1348       as_bad (_("unknown constraint `%c'"), *op_constraint);
   1349       break;
   1350     }
   1351   return op_mask;
   1352 }
   1353