Home | History | Annotate | Line # | Download | only in gas
cgen.c revision 1.1.1.6
      1 /* GAS interface for targets using CGEN: Cpu tools GENerator.
      2    Copyright (C) 1996-2022 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_code_real_type)
    252 		    ((int) BFD_RELOC_UNUSED
    253 		     + (int) operand->type));
    254   fixP->fx_cgen.insn = insn;
    255   fixP->fx_cgen.opinfo = opinfo;
    256   fixP->fx_cgen.field = NULL;
    257   fixP->fx_cgen.msb_field_p = 0;
    258 
    259   return fixP;
    260 }
    261 
    262 /* Default routine to record a fixup given an expression.
    263    This is a cover function to fix_new_exp.
    264    It exists because we record INSN with the fixup.
    265 
    266    FRAG and WHERE are their respective arguments to fix_new_exp.
    267    LENGTH is in bits.
    268    OPINFO is something the caller chooses to help in reloc determination.
    269 
    270    At this point we do not use a bfd_reloc_code_real_type for
    271    operands residing in the insn, but instead just use the
    272    operand index.  This lets us easily handle fixups for any
    273    operand type.  We pick a BFD reloc type in md_apply_fix.  */
    274 
    275 fixS *
    276 gas_cgen_record_fixup_exp (fragS *frag, int where, const CGEN_INSN *insn,
    277 			   int length, const CGEN_OPERAND *operand, int opinfo,
    278 			   expressionS *exp)
    279 {
    280   fixS *fixP;
    281 
    282   /* It may seem strange to use operand->attrs and not insn->attrs here,
    283      but it is the operand that has a pc relative relocation.  */
    284   fixP = fix_new_exp (frag, where, length / 8, exp,
    285 		      CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
    286 		      (bfd_reloc_code_real_type)
    287 		        ((int) BFD_RELOC_UNUSED
    288 			 + (int) operand->type));
    289   fixP->fx_cgen.insn = insn;
    290   fixP->fx_cgen.opinfo = opinfo;
    291   fixP->fx_cgen.field = NULL;
    292   fixP->fx_cgen.msb_field_p = 0;
    293 
    294   return fixP;
    295 }
    296 
    297 #ifdef OBJ_COMPLEX_RELC
    298 static symbolS *
    299 expr_build_binary (operatorT op, symbolS * s1, symbolS * s2)
    300 {
    301   expressionS e;
    302 
    303   e.X_op = op;
    304   e.X_add_symbol = s1;
    305   e.X_op_symbol = s2;
    306   e.X_add_number = 0;
    307   return make_expr_symbol (& e);
    308 }
    309 #endif
    310 
    311 /* Used for communication between the next two procedures.  */
    312 static jmp_buf expr_jmp_buf;
    313 static int expr_jmp_buf_p;
    314 
    315 /* Callback for cgen interface.  Parse the expression at *STRP.
    316    The result is an error message or NULL for success (in which case
    317    *STRP is advanced past the parsed text).
    318    WANT is an indication of what the caller is looking for.
    319    If WANT == CGEN_ASM_PARSE_INIT the caller is beginning to try to match
    320    a table entry with the insn, reset the queued fixups counter.
    321    An enum cgen_parse_operand_result is stored in RESULTP.
    322    OPINDEX is the operand's table entry index.
    323    OPINFO is something the caller chooses to help in reloc determination.
    324    The resulting value is stored in VALUEP.  */
    325 
    326 const char *
    327 gas_cgen_parse_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
    328 		       	enum cgen_parse_operand_type want, const char **strP,
    329 		       	int opindex, int opinfo,
    330 		       	enum cgen_parse_operand_result *resultP,
    331 		       	bfd_vma *valueP)
    332 {
    333 #ifdef __STDC__
    334   /* These are volatile to survive the setjmp.  */
    335   char * volatile hold;
    336   enum cgen_parse_operand_result * volatile resultP_1;
    337   volatile int opinfo_1;
    338 #else
    339   static char *hold;
    340   static enum cgen_parse_operand_result *resultP_1;
    341   int opinfo_1;
    342 #endif
    343   const char *errmsg;
    344   expressionS exp;
    345 
    346 #ifdef OBJ_COMPLEX_RELC
    347   volatile int              signed_p = 0;
    348   symbolS *                 stmp = NULL;
    349   bfd_reloc_code_real_type  reloc_type;
    350   const CGEN_OPERAND *      operand;
    351   fixS                      dummy_fixup;
    352 #endif
    353   if (want == CGEN_PARSE_OPERAND_INIT)
    354     {
    355       gas_cgen_init_parse ();
    356       return NULL;
    357     }
    358 
    359   resultP_1 = resultP;
    360   hold = input_line_pointer;
    361   input_line_pointer = (char *) *strP;
    362   opinfo_1 = opinfo;
    363 
    364   /* We rely on md_operand to longjmp back to us.
    365      This is done via gas_cgen_md_operand.  */
    366   if (setjmp (expr_jmp_buf) != 0)
    367     {
    368       expr_jmp_buf_p = 0;
    369       input_line_pointer = (char *) hold;
    370       *resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR;
    371       return _("illegal operand");
    372     }
    373 
    374   expr_jmp_buf_p = 1;
    375   expression (&exp);
    376   expr_jmp_buf_p = 0;
    377   errmsg = NULL;
    378 
    379   *strP = input_line_pointer;
    380   input_line_pointer = hold;
    381 
    382 #ifdef TC_CGEN_PARSE_FIX_EXP
    383   opinfo_1 = TC_CGEN_PARSE_FIX_EXP (opinfo_1, & exp);
    384 #endif
    385 
    386   /* FIXME: Need to check `want'.  */
    387 
    388   switch (exp.X_op)
    389     {
    390     case O_illegal:
    391       errmsg = _("illegal operand");
    392       *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
    393       break;
    394     case O_absent:
    395       errmsg = _("missing operand");
    396       *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
    397       break;
    398     case O_constant:
    399       if (want == CGEN_PARSE_OPERAND_SYMBOLIC)
    400 	goto de_fault;
    401       *valueP = exp.X_add_number;
    402       *resultP = CGEN_PARSE_OPERAND_RESULT_NUMBER;
    403       break;
    404     case O_register:
    405       *valueP = exp.X_add_number;
    406       *resultP = CGEN_PARSE_OPERAND_RESULT_REGISTER;
    407       break;
    408     de_fault:
    409     default:
    410 #ifdef OBJ_COMPLEX_RELC
    411       /* Look up operand, check to see if there's an obvious
    412 	 overflow (this helps disambiguate some insn parses).  */
    413       operand = cgen_operand_lookup_by_num (cd, opindex);
    414       errmsg = weak_operand_overflow_check (& exp, operand);
    415 
    416       if (! errmsg)
    417 	{
    418 	  asymbol *bsym;
    419 
    420 	  /* Fragment the expression as necessary, and queue a reloc.  */
    421 	  memset (& dummy_fixup, 0, sizeof (fixS));
    422 
    423 	  reloc_type = md_cgen_lookup_reloc (0, operand, & dummy_fixup);
    424 
    425 	  if (exp.X_op == O_symbol
    426 	      && reloc_type == BFD_RELOC_RELC
    427 	      && symbol_constant_p (exp.X_add_symbol)
    428 	      && (!symbol_symbolS (exp.X_add_symbol)
    429 		  || (bsym = symbol_get_bfdsym (exp.X_add_symbol)) == NULL
    430 		  || (bsym->section != expr_section
    431 		      && bsym->section != absolute_section
    432 		      && bsym->section != undefined_section)))
    433 	    {
    434 	      /* Local labels will have been (eagerly) turned into constants
    435 		 by now, due to the inappropriately deep insight of the
    436 		 expression parser.  Unfortunately make_expr_symbol
    437 		 prematurely dives into the symbol evaluator, and in this
    438 		 case it gets a bad answer, so we manually create the
    439 		 expression symbol we want here.  */
    440 	      stmp = symbol_create (FAKE_LABEL_NAME, expr_section,
    441 				    &zero_address_frag, 0);
    442 	      symbol_set_value_expression (stmp, & exp);
    443 	    }
    444 	  else
    445 	    stmp = make_expr_symbol (& exp);
    446 
    447 	  /* If this is a pc-relative RELC operand, we
    448 	     need to subtract "." from the expression.  */
    449  	  if (reloc_type == BFD_RELOC_RELC
    450 	      && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR))
    451  	    stmp = expr_build_binary (O_subtract, stmp, expr_build_dot ());
    452 
    453 	  /* FIXME: this is not a perfect heuristic for figuring out
    454 	     whether an operand is signed: it only works when the operand
    455 	     is an immediate. it's not terribly likely that any other
    456 	     values will be signed relocs, but it's possible. */
    457 	  if (operand && (operand->hw_type == HW_H_SINT))
    458 	    signed_p = 1;
    459 
    460 	  if (symbol_symbolS (stmp)
    461 	      && (bsym = symbol_get_bfdsym (stmp)) != NULL
    462 	      && bsym->section == expr_section
    463 	      && ! S_IS_LOCAL (stmp))
    464 	    {
    465 	      if (signed_p)
    466 		bsym->flags |= BSF_SRELC;
    467 	      else
    468 		bsym->flags |= BSF_RELC;
    469 	    }
    470 
    471 	  /* Now package it all up for the fixup emitter.  */
    472 	  exp.X_op = O_symbol;
    473 	  exp.X_op_symbol = 0;
    474 	  exp.X_add_symbol = stmp;
    475 	  exp.X_add_number = 0;
    476 
    477 	  /* Re-init rightshift quantity, just in case.  */
    478 	  rightshift = operand->length;
    479 	  queue_fixup_recursively (opindex, opinfo_1, & exp,
    480 				   (reloc_type == BFD_RELOC_RELC) ?
    481 				   & (operand->index_fields) : 0,
    482 				   signed_p, -1);
    483 	}
    484       * resultP = errmsg
    485 	? CGEN_PARSE_OPERAND_RESULT_ERROR
    486 	: CGEN_PARSE_OPERAND_RESULT_QUEUED;
    487       *valueP = 0;
    488 #else
    489       queue_fixup (opindex, opinfo_1, &exp);
    490       *valueP = 0;
    491       *resultP = CGEN_PARSE_OPERAND_RESULT_QUEUED;
    492 #endif
    493       break;
    494     }
    495 
    496   return errmsg;
    497 }
    498 
    499 /* md_operand handler to catch unrecognized expressions and halt the
    500    parsing process so the next entry can be tried.
    501 
    502    ??? This could be done differently by adding code to `expression'.  */
    503 
    504 void
    505 gas_cgen_md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
    506 {
    507   /* Don't longjmp if we're not called from within cgen_parse_operand().  */
    508   if (expr_jmp_buf_p)
    509     longjmp (expr_jmp_buf, 1);
    510 }
    511 
    512 /* Finish assembling instruction INSN.
    513    BUF contains what we've built up so far.
    514    LENGTH is the size of the insn in bits.
    515    RELAX_P is non-zero if relaxable insns should be emitted as such.
    516    Otherwise they're emitted in non-relaxable forms.
    517    The "result" is stored in RESULT if non-NULL.  */
    518 
    519 void
    520 gas_cgen_finish_insn (const CGEN_INSN *insn, CGEN_INSN_BYTES_PTR buf,
    521 		      unsigned int length, int relax_p, finished_insnS *result)
    522 {
    523   int i;
    524   int relax_operand;
    525   char *f;
    526   unsigned int byte_len = length / 8;
    527 
    528   /* ??? Target foo issues various warnings here, so one might want to provide
    529      a hook here.  However, our caller is defined in tc-foo.c so there
    530      shouldn't be a need for a hook.  */
    531 
    532   /* Write out the instruction.
    533      It is important to fetch enough space in one call to `frag_more'.
    534      We use (f - frag_now->fr_literal) to compute where we are and we
    535      don't want frag_now to change between calls.
    536 
    537      Relaxable instructions: We need to ensure we allocate enough
    538      space for the largest insn.  */
    539 
    540   if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
    541     /* These currently shouldn't get here.  */
    542     abort ();
    543 
    544   /* Is there a relaxable insn with the relaxable operand needing a fixup?  */
    545 
    546   relax_operand = -1;
    547   if (relax_p && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE))
    548     {
    549       /* Scan the fixups for the operand affected by relaxing
    550 	 (i.e. the branch address).  */
    551 
    552       for (i = 0; i < num_fixups; ++i)
    553 	{
    554 	  if (CGEN_OPERAND_ATTR_VALUE (cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex),
    555 				       CGEN_OPERAND_RELAX))
    556 	    {
    557 	      relax_operand = i;
    558 	      break;
    559 	    }
    560 	}
    561     }
    562 
    563   if (relax_operand != -1)
    564     {
    565       int max_len;
    566       fragS *old_frag;
    567       expressionS *exp;
    568       symbolS *sym;
    569       offsetT off;
    570 
    571 #ifdef TC_CGEN_MAX_RELAX
    572       max_len = TC_CGEN_MAX_RELAX (insn, byte_len);
    573 #else
    574       max_len = CGEN_MAX_INSN_SIZE;
    575 #endif
    576       /* Ensure variable part and fixed part are in same fragment.  */
    577       /* FIXME: Having to do this seems like a hack.  */
    578       frag_grow (max_len);
    579 
    580       /* Allocate space for the fixed part.  */
    581       f = frag_more (byte_len);
    582 
    583       /* Create a relaxable fragment for this instruction.  */
    584       old_frag = frag_now;
    585 
    586       exp = &fixups[relax_operand].exp;
    587       sym = exp->X_add_symbol;
    588       off = exp->X_add_number;
    589       if (exp->X_op != O_constant && exp->X_op != O_symbol)
    590 	{
    591 	  /* Handle complex expressions.  */
    592 	  sym = make_expr_symbol (exp);
    593 	  off = 0;
    594 	}
    595 
    596       frag_var (rs_machine_dependent,
    597 		max_len - byte_len /* max chars */,
    598 		0 /* variable part already allocated */,
    599 		/* FIXME: When we machine generate the relax table,
    600 		   machine generate a macro to compute subtype.  */
    601 		1 /* subtype */,
    602 		sym,
    603 		off,
    604 		f);
    605 
    606       /* Record the operand number with the fragment so md_convert_frag
    607 	 can use gas_cgen_md_record_fixup to record the appropriate reloc.  */
    608       old_frag->fr_cgen.insn    = insn;
    609       old_frag->fr_cgen.opindex = fixups[relax_operand].opindex;
    610       old_frag->fr_cgen.opinfo  = fixups[relax_operand].opinfo;
    611       if (result)
    612 	result->frag = old_frag;
    613     }
    614   else
    615     {
    616       f = frag_more (byte_len);
    617       if (result)
    618 	result->frag = frag_now;
    619     }
    620 
    621   /* If we're recording insns as numbers (rather than a string of bytes),
    622      target byte order handling is deferred until now.  */
    623 #if CGEN_INT_INSN_P
    624   cgen_put_insn_value (gas_cgen_cpu_desc, (unsigned char *) f, length, *buf,
    625                        gas_cgen_cpu_desc->insn_endian);
    626 #else
    627   memcpy (f, buf, byte_len);
    628 #endif
    629 
    630   /* Emit DWARF2 debugging information.  */
    631   dwarf2_emit_insn (byte_len);
    632 
    633   /* Create any fixups.  */
    634   for (i = 0; i < num_fixups; ++i)
    635     {
    636       fixS *fixP;
    637       const CGEN_OPERAND *operand =
    638 	cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex);
    639 
    640       /* Don't create fixups for these.  That's done during relaxation.
    641 	 We don't need to test for CGEN_INSN_RELAXED as they can't get here
    642 	 (see above).  */
    643       if (relax_p
    644 	  && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE)
    645 	  && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_RELAX))
    646 	continue;
    647 
    648 #ifndef md_cgen_record_fixup_exp
    649 #define md_cgen_record_fixup_exp gas_cgen_record_fixup_exp
    650 #endif
    651 
    652       fixP = md_cgen_record_fixup_exp (frag_now, f - frag_now->fr_literal,
    653 				       insn, length, operand,
    654 				       fixups[i].opinfo,
    655 				       &fixups[i].exp);
    656       fixP->fx_cgen.field = fixups[i].field;
    657       fixP->fx_cgen.msb_field_p = fixups[i].msb_field_p;
    658       if (result)
    659 	result->fixups[i] = fixP;
    660     }
    661 
    662   if (result)
    663     {
    664       result->num_fixups = num_fixups;
    665       result->addr = f;
    666     }
    667 }
    668 
    669 #ifdef OBJ_COMPLEX_RELC
    670 /* Queue many fixups, recursively. If the field is a multi-ifield,
    671    repeatedly queue its sub-parts, right shifted to fit into the field (we
    672    assume here multi-fields represent a left-to-right, MSB0-LSB0
    673    reading). */
    674 
    675 static void
    676 queue_fixup_recursively (const int                      opindex,
    677 			 const int                      opinfo,
    678 			 expressionS *                  expP,
    679 			 const CGEN_MAYBE_MULTI_IFLD *  field,
    680 			 const int                      signed_p,
    681 			 const int                      part_of_multi)
    682 {
    683   if (field && field->count)
    684     {
    685       int i;
    686 
    687       for (i = 0; i < field->count; ++ i)
    688 	queue_fixup_recursively (opindex, opinfo, expP,
    689 				 & (field->val.multi[i]), signed_p, i);
    690     }
    691   else
    692     {
    693       expressionS * new_exp = expP;
    694 
    695 #ifdef DEBUG
    696       printf ("queueing fixup for field %s\n",
    697 	      (field ? field->val.leaf->name : "??"));
    698       print_symbol_value (expP->X_add_symbol);
    699 #endif
    700       if (field && part_of_multi != -1)
    701 	{
    702 	  rightshift -= field->val.leaf->length;
    703 
    704 	  /* Shift reloc value by number of bits remaining after this
    705 	     field.  */
    706 	  if (rightshift)
    707 	    new_exp = make_right_shifted_expr (expP, rightshift, signed_p);
    708 	}
    709 
    710       /* Truncate reloc values to length, *after* leftmost one.  */
    711       fixups[num_fixups].msb_field_p = (part_of_multi <= 0);
    712       fixups[num_fixups].field = (CGEN_MAYBE_MULTI_IFLD *) field;
    713 
    714       queue_fixup (opindex, opinfo, new_exp);
    715     }
    716 }
    717 
    718 /* Encode the self-describing RELC reloc format's addend.  */
    719 
    720 static unsigned long
    721 gas_cgen_encode_addend (const unsigned long start,    /* in bits */
    722 			const unsigned long len,      /* in bits */
    723 			const unsigned long oplen,    /* in bits */
    724 			const unsigned long wordsz,   /* in bytes */
    725 			const unsigned long chunksz,  /* in bytes */
    726 			const unsigned long signed_p,
    727 			const unsigned long trunc_p)
    728 {
    729   unsigned long res = 0L;
    730 
    731   res |= start    & 0x3F;
    732   res |= (oplen   & 0x3F) << 6;
    733   res |= (len     & 0x3F) << 12;
    734   res |= (wordsz  & 0xF)  << 18;
    735   res |= (chunksz & 0xF)  << 22;
    736   res |= (CGEN_INSN_LSB0_P ? 1 : 0) << 27;
    737   res |= signed_p << 28;
    738   res |= trunc_p << 29;
    739 
    740   return res;
    741 }
    742 
    743 /* Purpose: make a weak check that the expression doesn't overflow the
    744    operand it's to be inserted into.
    745 
    746    Rationale: some insns used to use %operators to disambiguate during a
    747    parse. when these %operators are translated to expressions by the macro
    748    expander, the ambiguity returns. we attempt to disambiguate by field
    749    size.
    750 
    751    Method: check to see if the expression's top node is an O_and operator,
    752    and the mask is larger than the operand length. This would be an
    753    overflow, so signal it by returning an error string. Any other case is
    754    ambiguous, so we assume it's OK and return NULL.  */
    755 
    756 static const char *
    757 weak_operand_overflow_check (const expressionS *  exp,
    758 			     const CGEN_OPERAND * operand)
    759 {
    760   const unsigned long len = operand->length;
    761   unsigned long mask;
    762   unsigned long opmask = len == 0 ? 0 : (1UL << (len - 1) << 1) - 1;
    763 
    764   if (!exp)
    765     return NULL;
    766 
    767   if (exp->X_op != O_bit_and)
    768     {
    769       /* Check for implicit overflow flag.  */
    770       if (CGEN_OPERAND_ATTR_VALUE
    771 	  (operand, CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW))
    772 	return _("a reloc on this operand implies an overflow");
    773       return NULL;
    774     }
    775 
    776   mask = exp->X_add_number;
    777 
    778   if (exp->X_add_symbol
    779       && symbol_constant_p (exp->X_add_symbol))
    780     mask |= *symbol_X_add_number (exp->X_add_symbol);
    781 
    782   if (exp->X_op_symbol
    783       && symbol_constant_p (exp->X_op_symbol))
    784     mask |= *symbol_X_add_number (exp->X_op_symbol);
    785 
    786   /* Want to know if mask covers more bits than opmask.
    787      this is the same as asking if mask has any bits not in opmask,
    788      or whether (mask & ~opmask) is nonzero.  */
    789   if (mask && (mask & ~opmask))
    790     {
    791 #ifdef DEBUG
    792       printf ("overflow: (mask = %8.8x, ~opmask = %8.8x, AND = %8.8x)\n",
    793 	      mask, ~opmask, (mask & ~opmask));
    794 #endif
    795       return _("operand mask overflow");
    796     }
    797 
    798   return NULL;
    799 }
    800 
    801 static expressionS *
    802 make_right_shifted_expr (expressionS * exp,
    803 			 const int     amount,
    804 			 const int     signed_p)
    805 {
    806   symbolS * stmp = 0;
    807   expressionS * new_exp;
    808   asymbol *bsym;
    809 
    810   stmp = expr_build_binary (O_right_shift,
    811 			    make_expr_symbol (exp),
    812 			    expr_build_uconstant (amount));
    813   bsym = symbol_get_bfdsym (stmp);
    814 
    815   if (signed_p)
    816     bsym->flags |= BSF_SRELC;
    817   else
    818     bsym->flags |= BSF_RELC;
    819 
    820   /* Then wrap that in a "symbol expr" for good measure.  */
    821   new_exp = XNEW (expressionS);
    822   memset (new_exp, 0, sizeof (expressionS));
    823   new_exp->X_op = O_symbol;
    824   new_exp->X_op_symbol = 0;
    825   new_exp->X_add_symbol = stmp;
    826   new_exp->X_add_number = 0;
    827 
    828   return new_exp;
    829 }
    830 
    831 #endif
    832 
    833 /* Apply a fixup to the object code.  This is called for all the
    834    fixups we generated by the call to fix_new_exp, above.  In the call
    835    above we used a reloc code which was the largest legal reloc code
    836    plus the operand index.  Here we undo that to recover the operand
    837    index.  At this point all symbol values should be fully resolved,
    838    and we attempt to completely resolve the reloc.  If we can not do
    839    that, we determine the correct reloc code and put it back in the fixup.  */
    840 
    841 /* FIXME: This function handles some of the fixups and bfd_install_relocation
    842    handles the rest.  bfd_install_relocation (or some other bfd function)
    843    should handle them all.  */
    844 
    845 void
    846 gas_cgen_md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
    847 {
    848   char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
    849   valueT value = * valP;
    850   /* Canonical name, since used a lot.  */
    851   CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
    852 
    853   if (fixP->fx_addsy == (symbolS *) NULL)
    854     fixP->fx_done = 1;
    855 
    856   /* We don't actually support subtracting a symbol.  */
    857   if (fixP->fx_subsy != (symbolS *) NULL)
    858     as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
    859 
    860   if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
    861     {
    862       int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
    863       const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (cd, opindex);
    864       const char *errmsg;
    865       bfd_reloc_code_real_type reloc_type;
    866       const CGEN_INSN *insn = fixP->fx_cgen.insn;
    867 #ifdef OBJ_COMPLEX_RELC
    868       int start;
    869       int length;
    870       int signed_p = 0;
    871 
    872       if (fixP->fx_cgen.field)
    873 	{
    874 	  /* Use the twisty little pointer path
    875 	     back to the ifield if it exists.  */
    876 	  start = fixP->fx_cgen.field->val.leaf->start;
    877 	  length = fixP->fx_cgen.field->val.leaf->length;
    878 	}
    879       else
    880 	{
    881 	  /* Or the far less useful operand-size guesstimate.  */
    882 	  start = operand->start;
    883 	  length = operand->length;
    884 	}
    885 
    886       /* FIXME: this is not a perfect heuristic for figuring out
    887          whether an operand is signed: it only works when the operand
    888          is an immediate. it's not terribly likely that any other
    889          values will be signed relocs, but it's possible. */
    890       if (operand && (operand->hw_type == HW_H_SINT))
    891         signed_p = 1;
    892 #endif
    893 
    894       /* If the reloc has been fully resolved finish the operand here.  */
    895       /* FIXME: This duplicates the capabilities of code in BFD.  */
    896       if (fixP->fx_done
    897 	  /* FIXME: If partial_inplace isn't set bfd_install_relocation won't
    898 	     finish the job.  Testing for pcrel is a temporary hack.  */
    899 	  || fixP->fx_pcrel)
    900 	{
    901 	  CGEN_FIELDS *fields = xmalloc (CGEN_CPU_SIZEOF_FIELDS (cd));
    902 
    903 	  CGEN_CPU_SET_FIELDS_BITSIZE (cd) (fields, CGEN_INSN_BITSIZE (insn));
    904 	  CGEN_CPU_SET_VMA_OPERAND (cd) (cd, opindex, fields, (bfd_vma) value);
    905 
    906 #if CGEN_INT_INSN_P
    907 	  {
    908 	    CGEN_INSN_INT insn_value =
    909 	      cgen_get_insn_value (cd, (unsigned char *) where,
    910 				   CGEN_INSN_BITSIZE (insn),
    911                                    cd->insn_endian);
    912 
    913 	    /* ??? 0 is passed for `pc'.  */
    914 	    errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
    915 						   &insn_value, (bfd_vma) 0);
    916 	    cgen_put_insn_value (cd, (unsigned char *) where,
    917 				 CGEN_INSN_BITSIZE (insn), insn_value,
    918                                  cd->insn_endian);
    919 	  }
    920 #else
    921 	  /* ??? 0 is passed for `pc'.  */
    922 	  errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
    923 						 (unsigned char *) where,
    924 						 (bfd_vma) 0);
    925 #endif
    926 	  if (errmsg)
    927 	    as_bad_where (fixP->fx_file, fixP->fx_line, "%s", errmsg);
    928 
    929 	  free (fields);
    930 	}
    931 
    932       if (fixP->fx_done)
    933 	return;
    934 
    935       /* The operand isn't fully resolved.  Determine a BFD reloc value
    936 	 based on the operand information and leave it to
    937 	 bfd_install_relocation.  Note that this doesn't work when
    938 	 partial_inplace == false.  */
    939 
    940       reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
    941 #ifdef OBJ_COMPLEX_RELC
    942       if (reloc_type == BFD_RELOC_RELC)
    943 	{
    944 	  /* Change addend to "self-describing" form,
    945 	     for BFD to handle in the linker.  */
    946 	  value = gas_cgen_encode_addend (start, operand->length,
    947 					  length, fixP->fx_size,
    948 					  cd->insn_chunk_bitsize / 8,
    949 					  signed_p,
    950 					  ! (fixP->fx_cgen.msb_field_p));
    951 	}
    952 #endif
    953 
    954       if (reloc_type != BFD_RELOC_NONE)
    955 	fixP->fx_r_type = reloc_type;
    956       else
    957 	{
    958 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    959 			_("unresolved expression that must be resolved"));
    960 	  fixP->fx_done = 1;
    961 	  return;
    962 	}
    963     }
    964   else if (fixP->fx_done)
    965     {
    966       /* We're finished with this fixup.  Install it because
    967 	 bfd_install_relocation won't be called to do it.  */
    968       switch (fixP->fx_r_type)
    969 	{
    970 	case BFD_RELOC_8:
    971 	  md_number_to_chars (where, value, 1);
    972 	  break;
    973 	case BFD_RELOC_16:
    974 	  md_number_to_chars (where, value, 2);
    975 	  break;
    976 	case BFD_RELOC_32:
    977 	  md_number_to_chars (where, value, 4);
    978 	  break;
    979 	case BFD_RELOC_64:
    980 	  md_number_to_chars (where, value, 8);
    981 	  break;
    982 	default:
    983 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    984 			_("internal error: can't install fix for reloc type %d (`%s')"),
    985 			fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
    986 	  break;
    987 	}
    988     }
    989   /* else
    990      bfd_install_relocation will be called to finish things up.  */
    991 
    992   /* Tuck `value' away for use by tc_gen_reloc.
    993      See the comment describing fx_addnumber in write.h.
    994      This field is misnamed (or misused :-).  */
    995   fixP->fx_addnumber = value;
    996 }
    997 
    998 bfd_reloc_code_real_type
    999 gas_cgen_pcrel_r_type (bfd_reloc_code_real_type r)
   1000 {
   1001   switch (r)
   1002     {
   1003     case BFD_RELOC_8:  r = BFD_RELOC_8_PCREL;  break;
   1004     case BFD_RELOC_16: r = BFD_RELOC_16_PCREL; break;
   1005     case BFD_RELOC_24: r = BFD_RELOC_24_PCREL; break;
   1006     case BFD_RELOC_32: r = BFD_RELOC_32_PCREL; break;
   1007     case BFD_RELOC_64: r = BFD_RELOC_64_PCREL; break;
   1008     default:
   1009       break;
   1010     }
   1011   return r;
   1012 }
   1013 
   1014 /* Translate internal representation of relocation info to BFD target format.
   1015 
   1016    FIXME: To what extent can we get all relevant targets to use this?  */
   1017 
   1018 arelent *
   1019 gas_cgen_tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
   1020 {
   1021   bfd_reloc_code_real_type r_type = fixP->fx_r_type;
   1022   arelent *reloc;
   1023 
   1024   reloc = XNEW (arelent);
   1025 
   1026 #ifdef GAS_CGEN_PCREL_R_TYPE
   1027   if (fixP->fx_pcrel)
   1028     r_type = GAS_CGEN_PCREL_R_TYPE (r_type);
   1029 #endif
   1030   reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type);
   1031 
   1032   if (reloc->howto == (reloc_howto_type *) NULL)
   1033     {
   1034       as_bad_where (fixP->fx_file, fixP->fx_line,
   1035 		    _("relocation is not supported"));
   1036       return NULL;
   1037     }
   1038 
   1039   gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
   1040 
   1041   reloc->sym_ptr_ptr = XNEW (asymbol *);
   1042   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   1043 
   1044   /* Use fx_offset for these cases.  */
   1045   if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
   1046       || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
   1047     reloc->addend = fixP->fx_offset;
   1048   else
   1049     reloc->addend = fixP->fx_addnumber;
   1050 
   1051   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
   1052   return reloc;
   1053 }
   1054 
   1055 /* Perform any cgen specific initialisation.
   1056    Called after gas_cgen_cpu_desc has been created.  */
   1057 
   1058 void
   1059 gas_cgen_begin (void)
   1060 {
   1061   if (flag_signed_overflow_ok)
   1062     cgen_set_signed_overflow_ok (gas_cgen_cpu_desc);
   1063   else
   1064     cgen_clear_signed_overflow_ok (gas_cgen_cpu_desc);
   1065 }
   1066