Home | History | Annotate | Line # | Download | only in gas
cgen.c revision 1.1.1.8
      1 /* GAS interface for targets using CGEN: Cpu tools GENerator.
      2    Copyright (C) 1996-2025 Free Software Foundation, Inc.
      3 
      4    This file is part of GAS, the GNU Assembler.
      5 
      6    GAS is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3, or (at your option)
      9    any later version.
     10 
     11    GAS is distributed in the hope that it will be useful, but WITHOUT
     12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     14    License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with GAS; see the file COPYING.  If not, write to the Free Software
     18    Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
     19 
     20 #include "as.h"
     21 #include <setjmp.h>
     22 #include "symcat.h"
     23 #include "cgen-desc.h"
     24 #include "subsegs.h"
     25 #include "cgen.h"
     26 #include "dwarf2dbg.h"
     27 
     28 #include "symbols.h"
     29 
     30 #ifdef OBJ_COMPLEX_RELC
     31 static expressionS * make_right_shifted_expr
     32   (expressionS *, const int, const int);
     33 
     34 static unsigned long gas_cgen_encode_addend
     35   (const unsigned long, const unsigned long, const unsigned long, \
     36    const unsigned long, const unsigned long, const unsigned long, \
     37    const unsigned long);
     38 
     39 static const char * weak_operand_overflow_check
     40   (const expressionS *, const CGEN_OPERAND *);
     41 
     42 static void queue_fixup_recursively
     43   (const int, const int, expressionS *, \
     44    const CGEN_MAYBE_MULTI_IFLD *, const int, const int);
     45 
     46 static int rightshift = 0;
     47 #endif
     48 static void queue_fixup (int, int, expressionS *);
     49 
     50 /* Opcode table descriptor, must be set by md_begin.  */
     51 
     52 CGEN_CPU_DESC gas_cgen_cpu_desc;
     53 
     54 /* Callback to insert a register into the symbol table.
     55    A target may choose to let GAS parse the registers.
     56    ??? Not currently used.  */
     57 
     58 void
     59 cgen_asm_record_register (char *name, int number)
     60 {
     61   /* Use symbol_create here instead of symbol_new so we don't try to
     62      output registers into the object file's symbol table.  */
     63   symbol_table_insert (symbol_create (name, reg_section,
     64 				      &zero_address_frag, number));
     65 }
     66 
     67 /* We need to keep a list of fixups.  We can't simply generate them as
     68    we go, because that would require us to first create the frag, and
     69    that would screw up references to ``.''.
     70 
     71    This is used by cpu's with simple operands.  It keeps knowledge of what
     72    an `expressionS' is and what a `fixup' is out of CGEN which for the time
     73    being is preferable.
     74 
     75    OPINDEX is the index in the operand table.
     76    OPINFO is something the caller chooses to help in reloc determination.  */
     77 
     78 struct fixup
     79 {
     80   int opindex;
     81   int opinfo;
     82   expressionS exp;
     83   struct cgen_maybe_multi_ifield * field;
     84   int msb_field_p;
     85 };
     86 
     87 static struct fixup fixups[GAS_CGEN_MAX_FIXUPS];
     88 static int num_fixups;
     89 
     90 /* Prepare to parse an instruction.
     91    ??? May wish to make this static and delete calls in md_assemble.  */
     92 
     93 void
     94 gas_cgen_init_parse (void)
     95 {
     96   num_fixups = 0;
     97 }
     98 
     99 /* Queue a fixup.  */
    100 
    101 static void
    102 queue_fixup (int opindex, int opinfo, expressionS *expP)
    103 {
    104   /* We need to generate a fixup for this expression.  */
    105   if (num_fixups >= GAS_CGEN_MAX_FIXUPS)
    106     as_fatal (_("too many fixups"));
    107   fixups[num_fixups].exp     = *expP;
    108   fixups[num_fixups].opindex = opindex;
    109   fixups[num_fixups].opinfo  = opinfo;
    110   ++ num_fixups;
    111 }
    112 
    113 /* The following functions allow fixup chains to be stored, retrieved,
    114    and swapped.  They are a generalization of a pre-existing scheme
    115    for storing, restoring and swapping fixup chains that was used by
    116    the m32r port.  The functionality is essentially the same, only
    117    instead of only being able to store a single fixup chain, an entire
    118    array of fixup chains can be stored.  It is the user's responsibility
    119    to keep track of how many fixup chains have been stored and which
    120    elements of the array they are in.
    121 
    122    The algorithms used are the same as in the old scheme.  Other than the
    123    "array-ness" of the whole thing, the functionality is identical to the
    124    old scheme.
    125 
    126    gas_cgen_initialize_saved_fixups_array():
    127       Sets num_fixups_in_chain to 0 for each element. Call this from
    128       md_begin() if you plan to use these functions and you want the
    129       fixup count in each element to be set to 0 initially.  This is
    130       not necessary, but it's included just in case.  It performs
    131       the same function for each element in the array of fixup chains
    132       that gas_init_parse() performs for the current fixups.
    133 
    134    gas_cgen_save_fixups (element):
    135       element - element number of the array you wish to store the fixups
    136                 to.  No mechanism is built in for tracking what element
    137                 was last stored to.
    138 
    139    gas_cgen_restore_fixups (element):
    140       element - element number of the array you wish to restore the fixups
    141                 from.
    142 
    143    gas_cgen_swap_fixups(int element):
    144        element - swap the current fixups with those in this element number.
    145 */
    146 
    147 struct saved_fixups
    148 {
    149   struct fixup fixup_chain[GAS_CGEN_MAX_FIXUPS];
    150   int num_fixups_in_chain;
    151 };
    152 
    153 static struct saved_fixups stored_fixups[MAX_SAVED_FIXUP_CHAINS];
    154 
    155 void
    156 gas_cgen_initialize_saved_fixups_array (void)
    157 {
    158   int i = 0;
    159 
    160   while (i < MAX_SAVED_FIXUP_CHAINS)
    161     stored_fixups[i++].num_fixups_in_chain = 0;
    162 }
    163 
    164 void
    165 gas_cgen_save_fixups (int i)
    166 {
    167   if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
    168     {
    169       as_fatal ("index into stored_fixups[] out of bounds");
    170       return;
    171     }
    172 
    173   stored_fixups[i].num_fixups_in_chain = num_fixups;
    174   memcpy (stored_fixups[i].fixup_chain, fixups,
    175 	  sizeof (fixups[0]) * num_fixups);
    176   num_fixups = 0;
    177 }
    178 
    179 void
    180 gas_cgen_restore_fixups (int i)
    181 {
    182   if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
    183     {
    184       as_fatal ("index into stored_fixups[] out of bounds");
    185       return;
    186     }
    187 
    188   num_fixups = stored_fixups[i].num_fixups_in_chain;
    189   memcpy (fixups, stored_fixups[i].fixup_chain,
    190 	  (sizeof (stored_fixups[i].fixup_chain[0])) * num_fixups);
    191   stored_fixups[i].num_fixups_in_chain = 0;
    192 }
    193 
    194 void
    195 gas_cgen_swap_fixups (int i)
    196 {
    197   if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
    198     {
    199       as_fatal ("index into stored_fixups[] out of bounds");
    200       return;
    201     }
    202 
    203   if (num_fixups == 0)
    204     gas_cgen_restore_fixups (i);
    205 
    206   else if (stored_fixups[i].num_fixups_in_chain == 0)
    207     gas_cgen_save_fixups (i);
    208 
    209   else
    210     {
    211       int tmp;
    212       struct fixup tmp_fixup;
    213 
    214       tmp = stored_fixups[i].num_fixups_in_chain;
    215       stored_fixups[i].num_fixups_in_chain = num_fixups;
    216       num_fixups = tmp;
    217 
    218       for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;)
    219 	{
    220 	  tmp_fixup = stored_fixups[i].fixup_chain [tmp];
    221 	  stored_fixups[i].fixup_chain[tmp] = fixups [tmp];
    222 	  fixups [tmp] = tmp_fixup;
    223 	}
    224     }
    225 }
    226 
    227 /* Default routine to record a fixup.
    228    This is a cover function to fix_new.
    229    It exists because we record INSN with the fixup.
    230 
    231    FRAG and WHERE are their respective arguments to fix_new_exp.
    232    LENGTH is in bits.
    233    OPINFO is something the caller chooses to help in reloc determination.
    234 
    235    At this point we do not use a bfd_reloc_code_real_type for
    236    operands residing in the insn, but instead just use the
    237    operand index.  This lets us easily handle fixups for any
    238    operand type.  We pick a BFD reloc type in md_apply_fix.  */
    239 
    240 fixS *
    241 gas_cgen_record_fixup (fragS *frag, int where, const CGEN_INSN *insn,
    242 		       int length, const CGEN_OPERAND *operand, int opinfo,
    243 		       symbolS *symbol, offsetT offset)
    244 {
    245   fixS *fixP;
    246 
    247   /* It may seem strange to use operand->attrs and not insn->attrs here,
    248      but it is the operand that has a pc relative relocation.  */
    249   fixP = fix_new (frag, where, length / 8, symbol, offset,
    250 		  CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
    251 		  BFD_RELOC_UNUSED + operand->type);
    252   fixP->fx_cgen.insn = insn;
    253   fixP->fx_cgen.opinfo = opinfo;
    254   fixP->fx_cgen.field = NULL;
    255   fixP->fx_cgen.msb_field_p = 0;
    256 
    257   return fixP;
    258 }
    259 
    260 /* Default routine to record a fixup given an expression.
    261    This is a cover function to fix_new_exp.
    262    It exists because we record INSN with the fixup.
    263 
    264    FRAG and WHERE are their respective arguments to fix_new_exp.
    265    LENGTH is in bits.
    266    OPINFO is something the caller chooses to help in reloc determination.
    267 
    268    At this point we do not use a bfd_reloc_code_real_type for
    269    operands residing in the insn, but instead just use the
    270    operand index.  This lets us easily handle fixups for any
    271    operand type.  We pick a BFD reloc type in md_apply_fix.  */
    272 
    273 fixS *
    274 gas_cgen_record_fixup_exp (fragS *frag, int where, const CGEN_INSN *insn,
    275 			   int length, const CGEN_OPERAND *operand, int opinfo,
    276 			   expressionS *exp)
    277 {
    278   fixS *fixP;
    279 
    280   /* It may seem strange to use operand->attrs and not insn->attrs here,
    281      but it is the operand that has a pc relative relocation.  */
    282   fixP = fix_new_exp (frag, where, length / 8, exp,
    283 		      CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
    284 		      BFD_RELOC_UNUSED + operand->type);
    285   fixP->fx_cgen.insn = insn;
    286   fixP->fx_cgen.opinfo = opinfo;
    287   fixP->fx_cgen.field = NULL;
    288   fixP->fx_cgen.msb_field_p = 0;
    289 
    290   return fixP;
    291 }
    292 
    293 #ifdef OBJ_COMPLEX_RELC
    294 static symbolS *
    295 expr_build_binary (operatorT op, symbolS * s1, symbolS * s2)
    296 {
    297   expressionS e;
    298 
    299   e.X_op = op;
    300   e.X_add_symbol = s1;
    301   e.X_op_symbol = s2;
    302   e.X_add_number = 0;
    303   return make_expr_symbol (& e);
    304 }
    305 #endif
    306 
    307 /* Used for communication between the next two procedures.  */
    308 static jmp_buf expr_jmp_buf;
    309 static int expr_jmp_buf_p;
    310 
    311 /* Callback for cgen interface.  Parse the expression at *STRP.
    312    The result is an error message or NULL for success (in which case
    313    *STRP is advanced past the parsed text).
    314    WANT is an indication of what the caller is looking for.
    315    If WANT == CGEN_ASM_PARSE_INIT the caller is beginning to try to match
    316    a table entry with the insn, reset the queued fixups counter.
    317    An enum cgen_parse_operand_result is stored in RESULTP.
    318    OPINDEX is the operand's table entry index.
    319    OPINFO is something the caller chooses to help in reloc determination.
    320    The resulting value is stored in VALUEP.  */
    321 
    322 const char *
    323 gas_cgen_parse_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
    324 		       	enum cgen_parse_operand_type want, const char **strP,
    325 		       	int opindex, int opinfo,
    326 		       	enum cgen_parse_operand_result *resultP,
    327 		       	bfd_vma *valueP)
    328 {
    329 #ifdef __STDC__
    330   /* These are volatile to survive the setjmp.  */
    331   char * volatile hold;
    332   enum cgen_parse_operand_result * volatile resultP_1;
    333   volatile int opinfo_1;
    334 #else
    335   static char *hold;
    336   static enum cgen_parse_operand_result *resultP_1;
    337   int opinfo_1;
    338 #endif
    339   const char *errmsg;
    340   expressionS exp;
    341 
    342 #ifdef OBJ_COMPLEX_RELC
    343   volatile int              signed_p = 0;
    344   symbolS *                 stmp = NULL;
    345   bfd_reloc_code_real_type  reloc_type;
    346   const CGEN_OPERAND *      operand;
    347   fixS                      dummy_fixup;
    348 #endif
    349   if (want == CGEN_PARSE_OPERAND_INIT)
    350     {
    351       gas_cgen_init_parse ();
    352       return NULL;
    353     }
    354 
    355   resultP_1 = resultP;
    356   hold = input_line_pointer;
    357   input_line_pointer = (char *) *strP;
    358   opinfo_1 = opinfo;
    359 
    360   /* We rely on md_operand to longjmp back to us.
    361      This is done via gas_cgen_md_operand.  */
    362   if (setjmp (expr_jmp_buf) != 0)
    363     {
    364       expr_jmp_buf_p = 0;
    365       input_line_pointer = (char *) hold;
    366       *resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR;
    367       return _("illegal operand");
    368     }
    369 
    370   expr_jmp_buf_p = 1;
    371   expression (&exp);
    372   expr_jmp_buf_p = 0;
    373   errmsg = NULL;
    374 
    375   *strP = input_line_pointer;
    376   input_line_pointer = hold;
    377 
    378 #ifdef TC_CGEN_PARSE_FIX_EXP
    379   opinfo_1 = TC_CGEN_PARSE_FIX_EXP (opinfo_1, & exp);
    380 #endif
    381 
    382   /* FIXME: Need to check `want'.  */
    383 
    384   resolve_register (&exp);
    385 
    386   switch (exp.X_op)
    387     {
    388     case O_illegal:
    389       errmsg = _("illegal operand");
    390       *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
    391       break;
    392     case O_absent:
    393       errmsg = _("missing operand");
    394       *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
    395       break;
    396     case O_constant:
    397       if (want == CGEN_PARSE_OPERAND_SYMBOLIC)
    398 	goto de_fault;
    399       *valueP = exp.X_add_number;
    400       *resultP = CGEN_PARSE_OPERAND_RESULT_NUMBER;
    401       break;
    402     case O_register:
    403       *valueP = exp.X_add_number;
    404       *resultP = CGEN_PARSE_OPERAND_RESULT_REGISTER;
    405       break;
    406     de_fault:
    407     default:
    408 #ifdef OBJ_COMPLEX_RELC
    409       /* Look up operand, check to see if there's an obvious
    410 	 overflow (this helps disambiguate some insn parses).  */
    411       operand = cgen_operand_lookup_by_num (cd, opindex);
    412       errmsg = weak_operand_overflow_check (& exp, operand);
    413 
    414       if (! errmsg)
    415 	{
    416 	  asymbol *bsym;
    417 
    418 	  /* Fragment the expression as necessary, and queue a reloc.  */
    419 	  memset (& dummy_fixup, 0, sizeof (fixS));
    420 
    421 	  reloc_type = md_cgen_lookup_reloc (0, operand, & dummy_fixup);
    422 
    423 	  if (exp.X_op == O_symbol
    424 	      && reloc_type == BFD_RELOC_RELC
    425 	      && symbol_constant_p (exp.X_add_symbol)
    426 	      && (!symbol_symbolS (exp.X_add_symbol)
    427 		  || (bsym = symbol_get_bfdsym (exp.X_add_symbol)) == NULL
    428 		  || (bsym->section != expr_section
    429 		      && bsym->section != absolute_section
    430 		      && bsym->section != undefined_section)))
    431 	    {
    432 	      /* Local labels will have been (eagerly) turned into constants
    433 		 by now, due to the inappropriately deep insight of the
    434 		 expression parser.  Unfortunately make_expr_symbol
    435 		 prematurely dives into the symbol evaluator, and in this
    436 		 case it gets a bad answer, so we manually create the
    437 		 expression symbol we want here.  */
    438 	      stmp = symbol_create (FAKE_LABEL_NAME, expr_section,
    439 				    &zero_address_frag, 0);
    440 	      symbol_set_value_expression (stmp, & exp);
    441 	    }
    442 	  else
    443 	    stmp = make_expr_symbol (& exp);
    444 
    445 	  /* If this is a pc-relative RELC operand, we
    446 	     need to subtract "." from the expression.  */
    447  	  if (reloc_type == BFD_RELOC_RELC
    448 	      && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR))
    449  	    stmp = expr_build_binary (O_subtract, stmp, expr_build_dot ());
    450 
    451 	  /* FIXME: this is not a perfect heuristic for figuring out
    452 	     whether an operand is signed: it only works when the operand
    453 	     is an immediate. it's not terribly likely that any other
    454 	     values will be signed relocs, but it's possible. */
    455 	  if (operand && (operand->hw_type == HW_H_SINT))
    456 	    signed_p = 1;
    457 
    458 	  if (symbol_symbolS (stmp)
    459 	      && (bsym = symbol_get_bfdsym (stmp)) != NULL
    460 	      && bsym->section == expr_section
    461 	      && ! S_IS_LOCAL (stmp))
    462 	    {
    463 	      if (signed_p)
    464 		bsym->flags |= BSF_SRELC;
    465 	      else
    466 		bsym->flags |= BSF_RELC;
    467 	    }
    468 
    469 	  /* Now package it all up for the fixup emitter.  */
    470 	  exp.X_op = O_symbol;
    471 	  exp.X_op_symbol = 0;
    472 	  exp.X_add_symbol = stmp;
    473 	  exp.X_add_number = 0;
    474 
    475 	  /* Re-init rightshift quantity, just in case.  */
    476 	  rightshift = operand->length;
    477 	  queue_fixup_recursively (opindex, opinfo_1, & exp,
    478 				   (reloc_type == BFD_RELOC_RELC
    479 				    ? &operand->index_fields : 0),
    480 				   signed_p, -1);
    481 	}
    482       *resultP = (errmsg
    483 		  ? CGEN_PARSE_OPERAND_RESULT_ERROR
    484 		  : CGEN_PARSE_OPERAND_RESULT_QUEUED);
    485       *valueP = 0;
    486 #else
    487       queue_fixup (opindex, opinfo_1, &exp);
    488       *valueP = 0;
    489       *resultP = CGEN_PARSE_OPERAND_RESULT_QUEUED;
    490 #endif
    491       break;
    492     }
    493 
    494   return errmsg;
    495 }
    496 
    497 /* md_operand handler to catch unrecognized expressions and halt the
    498    parsing process so the next entry can be tried.
    499 
    500    ??? This could be done differently by adding code to `expression'.  */
    501 
    502 void
    503 gas_cgen_md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
    504 {
    505   /* Don't longjmp if we're not called from within cgen_parse_operand().  */
    506   if (expr_jmp_buf_p)
    507     longjmp (expr_jmp_buf, 1);
    508 }
    509 
    510 /* Finish assembling instruction INSN.
    511    BUF contains what we've built up so far.
    512    LENGTH is the size of the insn in bits.
    513    RELAX_P is non-zero if relaxable insns should be emitted as such.
    514    Otherwise they're emitted in non-relaxable forms.
    515    The "result" is stored in RESULT if non-NULL.  */
    516 
    517 void
    518 gas_cgen_finish_insn (const CGEN_INSN *insn, CGEN_INSN_BYTES_PTR buf,
    519 		      unsigned int length, int relax_p, finished_insnS *result)
    520 {
    521   int i;
    522   int relax_operand;
    523   char *f;
    524   unsigned int byte_len = length / 8;
    525 
    526   /* ??? Target foo issues various warnings here, so one might want to provide
    527      a hook here.  However, our caller is defined in tc-foo.c so there
    528      shouldn't be a need for a hook.  */
    529 
    530   /* Write out the instruction.
    531      It is important to fetch enough space in one call to `frag_more'.
    532      We use (f - frag_now->fr_literal) to compute where we are and we
    533      don't want frag_now to change between calls.
    534 
    535      Relaxable instructions: We need to ensure we allocate enough
    536      space for the largest insn.  */
    537 
    538   if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
    539     /* These currently shouldn't get here.  */
    540     abort ();
    541 
    542   /* Is there a relaxable insn with the relaxable operand needing a fixup?  */
    543 
    544   relax_operand = -1;
    545   if (relax_p && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE))
    546     {
    547       /* Scan the fixups for the operand affected by relaxing
    548 	 (i.e. the branch address).  */
    549 
    550       for (i = 0; i < num_fixups; ++i)
    551 	{
    552 	  if (CGEN_OPERAND_ATTR_VALUE (cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex),
    553 				       CGEN_OPERAND_RELAX))
    554 	    {
    555 	      relax_operand = i;
    556 	      break;
    557 	    }
    558 	}
    559     }
    560 
    561   if (relax_operand != -1)
    562     {
    563       int max_len;
    564       fragS *old_frag;
    565       expressionS *exp;
    566       symbolS *sym;
    567       offsetT off;
    568 
    569 #ifdef TC_CGEN_MAX_RELAX
    570       max_len = TC_CGEN_MAX_RELAX (insn, byte_len);
    571 #else
    572       max_len = CGEN_MAX_INSN_SIZE;
    573 #endif
    574       /* Ensure variable part and fixed part are in same fragment.  */
    575       /* FIXME: Having to do this seems like a hack.  */
    576       frag_grow (max_len);
    577 
    578       /* Allocate space for the fixed part.  */
    579       f = frag_more (byte_len);
    580 
    581       /* Create a relaxable fragment for this instruction.  */
    582       old_frag = frag_now;
    583 
    584       exp = &fixups[relax_operand].exp;
    585       sym = exp->X_add_symbol;
    586       off = exp->X_add_number;
    587       if (exp->X_op != O_constant && exp->X_op != O_symbol)
    588 	{
    589 	  /* Handle complex expressions.  */
    590 	  sym = make_expr_symbol (exp);
    591 	  off = 0;
    592 	}
    593 
    594       frag_var (rs_machine_dependent,
    595 		max_len - byte_len /* max chars */,
    596 		0 /* variable part already allocated */,
    597 		/* FIXME: When we machine generate the relax table,
    598 		   machine generate a macro to compute subtype.  */
    599 		1 /* subtype */,
    600 		sym,
    601 		off,
    602 		f);
    603 
    604       /* Record the operand number with the fragment so md_convert_frag
    605 	 can use gas_cgen_md_record_fixup to record the appropriate reloc.  */
    606       old_frag->fr_cgen.insn    = insn;
    607       old_frag->fr_cgen.opindex = fixups[relax_operand].opindex;
    608       old_frag->fr_cgen.opinfo  = fixups[relax_operand].opinfo;
    609       if (result)
    610 	result->frag = old_frag;
    611     }
    612   else
    613     {
    614       f = frag_more (byte_len);
    615       if (result)
    616 	result->frag = frag_now;
    617     }
    618 
    619   /* If we're recording insns as numbers (rather than a string of bytes),
    620      target byte order handling is deferred until now.  */
    621 #if CGEN_INT_INSN_P
    622   cgen_put_insn_value (gas_cgen_cpu_desc, (unsigned char *) f, length, *buf,
    623                        gas_cgen_cpu_desc->insn_endian);
    624 #else
    625   memcpy (f, buf, byte_len);
    626 #endif
    627 
    628   /* Emit DWARF2 debugging information.  */
    629   dwarf2_emit_insn (byte_len);
    630 
    631   /* Create any fixups.  */
    632   for (i = 0; i < num_fixups; ++i)
    633     {
    634       fixS *fixP;
    635       const CGEN_OPERAND *operand =
    636 	cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex);
    637 
    638       /* Don't create fixups for these.  That's done during relaxation.
    639 	 We don't need to test for CGEN_INSN_RELAXED as they can't get here
    640 	 (see above).  */
    641       if (relax_p
    642 	  && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE)
    643 	  && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_RELAX))
    644 	continue;
    645 
    646 #ifndef md_cgen_record_fixup_exp
    647 #define md_cgen_record_fixup_exp gas_cgen_record_fixup_exp
    648 #endif
    649 
    650       fixP = md_cgen_record_fixup_exp (frag_now, f - frag_now->fr_literal,
    651 				       insn, length, operand,
    652 				       fixups[i].opinfo,
    653 				       &fixups[i].exp);
    654       fixP->fx_cgen.field = fixups[i].field;
    655       fixP->fx_cgen.msb_field_p = fixups[i].msb_field_p;
    656       if (result)
    657 	result->fixups[i] = fixP;
    658     }
    659 
    660   if (result)
    661     {
    662       result->num_fixups = num_fixups;
    663       result->addr = f;
    664     }
    665 }
    666 
    667 #ifdef OBJ_COMPLEX_RELC
    668 /* Queue many fixups, recursively. If the field is a multi-ifield,
    669    repeatedly queue its sub-parts, right shifted to fit into the field (we
    670    assume here multi-fields represent a left-to-right, MSB0-LSB0
    671    reading). */
    672 
    673 static void
    674 queue_fixup_recursively (const int                      opindex,
    675 			 const int                      opinfo,
    676 			 expressionS *                  expP,
    677 			 const CGEN_MAYBE_MULTI_IFLD *  field,
    678 			 const int                      signed_p,
    679 			 const int                      part_of_multi)
    680 {
    681   if (field && field->count)
    682     {
    683       int i;
    684 
    685       for (i = 0; i < field->count; ++ i)
    686 	queue_fixup_recursively (opindex, opinfo, expP,
    687 				 & (field->val.multi[i]), signed_p, i);
    688     }
    689   else
    690     {
    691       expressionS * new_exp = expP;
    692 
    693 #ifdef DEBUG
    694       printf ("queueing fixup for field %s\n",
    695 	      (field ? field->val.leaf->name : "??"));
    696       print_symbol_value (expP->X_add_symbol);
    697 #endif
    698       if (field && part_of_multi != -1)
    699 	{
    700 	  rightshift -= field->val.leaf->length;
    701 
    702 	  /* Shift reloc value by number of bits remaining after this
    703 	     field.  */
    704 	  if (rightshift)
    705 	    new_exp = make_right_shifted_expr (expP, rightshift, signed_p);
    706 	}
    707 
    708       /* Truncate reloc values to length, *after* leftmost one.  */
    709       fixups[num_fixups].msb_field_p = (part_of_multi <= 0);
    710       fixups[num_fixups].field = (CGEN_MAYBE_MULTI_IFLD *) field;
    711 
    712       queue_fixup (opindex, opinfo, new_exp);
    713     }
    714 }
    715 
    716 /* Encode the self-describing RELC reloc format's addend.  */
    717 
    718 static unsigned long
    719 gas_cgen_encode_addend (const unsigned long start,    /* in bits */
    720 			const unsigned long len,      /* in bits */
    721 			const unsigned long oplen,    /* in bits */
    722 			const unsigned long wordsz,   /* in bytes */
    723 			const unsigned long chunksz,  /* in bytes */
    724 			const unsigned long signed_p,
    725 			const unsigned long trunc_p)
    726 {
    727   unsigned long res = 0L;
    728 
    729   res |= start    & 0x3F;
    730   res |= (oplen   & 0x3F) << 6;
    731   res |= (len     & 0x3F) << 12;
    732   res |= (wordsz  & 0xF)  << 18;
    733   res |= (chunksz & 0xF)  << 22;
    734   res |= (CGEN_INSN_LSB0_P ? 1 : 0) << 27;
    735   res |= signed_p << 28;
    736   res |= trunc_p << 29;
    737 
    738   return res;
    739 }
    740 
    741 /* Purpose: make a weak check that the expression doesn't overflow the
    742    operand it's to be inserted into.
    743 
    744    Rationale: some insns used to use %operators to disambiguate during a
    745    parse. when these %operators are translated to expressions by the macro
    746    expander, the ambiguity returns. we attempt to disambiguate by field
    747    size.
    748 
    749    Method: check to see if the expression's top node is an O_and operator,
    750    and the mask is larger than the operand length. This would be an
    751    overflow, so signal it by returning an error string. Any other case is
    752    ambiguous, so we assume it's OK and return NULL.  */
    753 
    754 static const char *
    755 weak_operand_overflow_check (const expressionS *  exp,
    756 			     const CGEN_OPERAND * operand)
    757 {
    758   const unsigned long len = operand->length;
    759   unsigned long mask;
    760   unsigned long opmask = len == 0 ? 0 : (1UL << (len - 1) << 1) - 1;
    761 
    762   if (!exp)
    763     return NULL;
    764 
    765   if (exp->X_op != O_bit_and)
    766     {
    767       /* Check for implicit overflow flag.  */
    768       if (CGEN_OPERAND_ATTR_VALUE
    769 	  (operand, CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW))
    770 	return _("a reloc on this operand implies an overflow");
    771       return NULL;
    772     }
    773 
    774   mask = exp->X_add_number;
    775 
    776   if (exp->X_add_symbol
    777       && symbol_constant_p (exp->X_add_symbol))
    778     mask |= *symbol_X_add_number (exp->X_add_symbol);
    779 
    780   if (exp->X_op_symbol
    781       && symbol_constant_p (exp->X_op_symbol))
    782     mask |= *symbol_X_add_number (exp->X_op_symbol);
    783 
    784   /* Want to know if mask covers more bits than opmask.
    785      this is the same as asking if mask has any bits not in opmask,
    786      or whether (mask & ~opmask) is nonzero.  */
    787   if (mask && (mask & ~opmask))
    788     {
    789 #ifdef DEBUG
    790       printf ("overflow: (mask = %8.8x, ~opmask = %8.8x, AND = %8.8x)\n",
    791 	      mask, ~opmask, (mask & ~opmask));
    792 #endif
    793       return _("operand mask overflow");
    794     }
    795 
    796   return NULL;
    797 }
    798 
    799 static expressionS *
    800 make_right_shifted_expr (expressionS * exp,
    801 			 const int     amount,
    802 			 const int     signed_p)
    803 {
    804   symbolS * stmp = 0;
    805   expressionS * new_exp;
    806   asymbol *bsym;
    807 
    808   stmp = expr_build_binary (O_right_shift,
    809 			    make_expr_symbol (exp),
    810 			    expr_build_uconstant (amount));
    811   bsym = symbol_get_bfdsym (stmp);
    812 
    813   if (signed_p)
    814     bsym->flags |= BSF_SRELC;
    815   else
    816     bsym->flags |= BSF_RELC;
    817 
    818   /* Then wrap that in a "symbol expr" for good measure.  */
    819   new_exp = XNEW (expressionS);
    820   memset (new_exp, 0, sizeof (expressionS));
    821   new_exp->X_op = O_symbol;
    822   new_exp->X_op_symbol = 0;
    823   new_exp->X_add_symbol = stmp;
    824   new_exp->X_add_number = 0;
    825 
    826   return new_exp;
    827 }
    828 
    829 #endif
    830 
    831 /* Apply a fixup to the object code.  This is called for all the
    832    fixups we generated by the call to fix_new_exp, above.  In the call
    833    above we used a reloc code which was the largest legal reloc code
    834    plus the operand index.  Here we undo that to recover the operand
    835    index.  At this point all symbol values should be fully resolved,
    836    and we attempt to completely resolve the reloc.  If we can not do
    837    that, we determine the correct reloc code and put it back in the fixup.  */
    838 
    839 /* FIXME: This function handles some of the fixups and bfd_install_relocation
    840    handles the rest.  bfd_install_relocation (or some other bfd function)
    841    should handle them all.  */
    842 
    843 void
    844 gas_cgen_md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
    845 {
    846   char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
    847   valueT value = * valP;
    848   /* Canonical name, since used a lot.  */
    849   CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
    850 
    851   if (fixP->fx_addsy == NULL)
    852     fixP->fx_done = 1;
    853 
    854   /* We don't actually support subtracting a symbol.  */
    855   if (fixP->fx_subsy != NULL)
    856     as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
    857 
    858   if (fixP->fx_r_type >= BFD_RELOC_UNUSED)
    859     {
    860       int opindex = fixP->fx_r_type - BFD_RELOC_UNUSED;
    861       const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (cd, opindex);
    862       const char *errmsg;
    863       bfd_reloc_code_real_type reloc_type;
    864       const CGEN_INSN *insn = fixP->fx_cgen.insn;
    865 #ifdef OBJ_COMPLEX_RELC
    866       int start;
    867       int length;
    868       int signed_p = 0;
    869 
    870       if (fixP->fx_cgen.field)
    871 	{
    872 	  /* Use the twisty little pointer path
    873 	     back to the ifield if it exists.  */
    874 	  start = fixP->fx_cgen.field->val.leaf->start;
    875 	  length = fixP->fx_cgen.field->val.leaf->length;
    876 	}
    877       else
    878 	{
    879 	  /* Or the far less useful operand-size guesstimate.  */
    880 	  start = operand->start;
    881 	  length = operand->length;
    882 	}
    883 
    884       /* FIXME: this is not a perfect heuristic for figuring out
    885          whether an operand is signed: it only works when the operand
    886          is an immediate. it's not terribly likely that any other
    887          values will be signed relocs, but it's possible. */
    888       if (operand && (operand->hw_type == HW_H_SINT))
    889         signed_p = 1;
    890 #endif
    891 
    892       /* If the reloc has been fully resolved finish the operand here.  */
    893       /* FIXME: This duplicates the capabilities of code in BFD.  */
    894       if (fixP->fx_done
    895 	  /* FIXME: If partial_inplace isn't set bfd_install_relocation won't
    896 	     finish the job.  Testing for pcrel is a temporary hack.  */
    897 	  || fixP->fx_pcrel)
    898 	{
    899 	  CGEN_FIELDS *fields = xmalloc (CGEN_CPU_SIZEOF_FIELDS (cd));
    900 
    901 	  CGEN_CPU_SET_FIELDS_BITSIZE (cd) (fields, CGEN_INSN_BITSIZE (insn));
    902 	  CGEN_CPU_SET_VMA_OPERAND (cd) (cd, opindex, fields, (bfd_vma) value);
    903 
    904 #if CGEN_INT_INSN_P
    905 	  {
    906 	    CGEN_INSN_INT insn_value =
    907 	      cgen_get_insn_value (cd, (unsigned char *) where,
    908 				   CGEN_INSN_BITSIZE (insn),
    909                                    cd->insn_endian);
    910 
    911 	    /* ??? 0 is passed for `pc'.  */
    912 	    errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
    913 						   &insn_value, 0);
    914 	    cgen_put_insn_value (cd, (unsigned char *) where,
    915 				 CGEN_INSN_BITSIZE (insn), insn_value,
    916                                  cd->insn_endian);
    917 	  }
    918 #else
    919 	  /* ??? 0 is passed for `pc'.  */
    920 	  errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
    921 						 (unsigned char *) where, 0);
    922 #endif
    923 	  if (errmsg)
    924 	    as_bad_where (fixP->fx_file, fixP->fx_line, "%s", errmsg);
    925 
    926 	  free (fields);
    927 	}
    928 
    929       if (fixP->fx_done)
    930 	return;
    931 
    932       /* The operand isn't fully resolved.  Determine a BFD reloc value
    933 	 based on the operand information and leave it to
    934 	 bfd_install_relocation.  Note that this doesn't work when
    935 	 partial_inplace == false.  */
    936 
    937       reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
    938 #ifdef OBJ_COMPLEX_RELC
    939       if (reloc_type == BFD_RELOC_RELC)
    940 	{
    941 	  /* Change addend to "self-describing" form,
    942 	     for BFD to handle in the linker.  */
    943 	  value = gas_cgen_encode_addend (start, operand->length,
    944 					  length, fixP->fx_size,
    945 					  cd->insn_chunk_bitsize / 8,
    946 					  signed_p,
    947 					  ! (fixP->fx_cgen.msb_field_p));
    948 	}
    949 #endif
    950 
    951       if (reloc_type != BFD_RELOC_NONE)
    952 	fixP->fx_r_type = reloc_type;
    953       else
    954 	{
    955 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    956 			_("unresolved expression that must be resolved"));
    957 	  fixP->fx_done = 1;
    958 	  return;
    959 	}
    960     }
    961   else if (fixP->fx_done)
    962     {
    963       /* We're finished with this fixup.  Install it because
    964 	 bfd_install_relocation won't be called to do it.  */
    965       switch (fixP->fx_r_type)
    966 	{
    967 	case BFD_RELOC_8:
    968 	  md_number_to_chars (where, value, 1);
    969 	  break;
    970 	case BFD_RELOC_16:
    971 	  md_number_to_chars (where, value, 2);
    972 	  break;
    973 	case BFD_RELOC_32:
    974 	  md_number_to_chars (where, value, 4);
    975 	  break;
    976 	case BFD_RELOC_64:
    977 	  md_number_to_chars (where, value, 8);
    978 	  break;
    979 	default:
    980 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    981 			_("internal error: can't install fix for reloc type %d (`%s')"),
    982 			fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
    983 	  break;
    984 	}
    985     }
    986   /* else
    987      bfd_install_relocation will be called to finish things up.  */
    988 
    989   /* Tuck `value' away for use by tc_gen_reloc.
    990      See the comment describing fx_addnumber in write.h.
    991      This field is misnamed (or misused :-).  */
    992   fixP->fx_addnumber = value;
    993 }
    994 
    995 bfd_reloc_code_real_type
    996 gas_cgen_pcrel_r_type (bfd_reloc_code_real_type r)
    997 {
    998   switch (r)
    999     {
   1000     case BFD_RELOC_8:  r = BFD_RELOC_8_PCREL;  break;
   1001     case BFD_RELOC_16: r = BFD_RELOC_16_PCREL; break;
   1002     case BFD_RELOC_24: r = BFD_RELOC_24_PCREL; break;
   1003     case BFD_RELOC_32: r = BFD_RELOC_32_PCREL; break;
   1004     case BFD_RELOC_64: r = BFD_RELOC_64_PCREL; break;
   1005     default:
   1006       break;
   1007     }
   1008   return r;
   1009 }
   1010 
   1011 /* Translate internal representation of relocation info to BFD target format.
   1012 
   1013    FIXME: To what extent can we get all relevant targets to use this?  */
   1014 
   1015 arelent *
   1016 gas_cgen_tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
   1017 {
   1018   bfd_reloc_code_real_type r_type = fixP->fx_r_type;
   1019   arelent *reloc;
   1020 
   1021   reloc = notes_alloc (sizeof (arelent));
   1022   reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
   1023   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   1024 
   1025 #ifdef GAS_CGEN_PCREL_R_TYPE
   1026   if (fixP->fx_pcrel)
   1027     r_type = GAS_CGEN_PCREL_R_TYPE (r_type);
   1028 #endif
   1029   reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type);
   1030 
   1031   if (reloc->howto == NULL)
   1032     {
   1033       as_bad_where (fixP->fx_file, fixP->fx_line,
   1034 		    _("relocation is not supported"));
   1035       return NULL;
   1036     }
   1037 
   1038   gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
   1039 
   1040   /* Use fx_offset for these cases.  */
   1041   if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
   1042       || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
   1043     reloc->addend = fixP->fx_offset;
   1044   else
   1045     reloc->addend = fixP->fx_addnumber;
   1046 
   1047   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
   1048   return reloc;
   1049 }
   1050 
   1051 /* Perform any cgen specific initialisation.
   1052    Called after gas_cgen_cpu_desc has been created.  */
   1053 
   1054 void
   1055 gas_cgen_begin (void)
   1056 {
   1057   if (flag_signed_overflow_ok)
   1058     cgen_set_signed_overflow_ok (gas_cgen_cpu_desc);
   1059   else
   1060     cgen_clear_signed_overflow_ok (gas_cgen_cpu_desc);
   1061 }
   1062