示例#1
0
void
frag_append_1_char (int datum)
{
  frag_alloc_check (&frchain_now->frch_obstack);
  if (obstack_room (&frchain_now->frch_obstack) <= 1)
    {
      frag_wane (frag_now);
      frag_new (0);
    }
  obstack_1grow (&frchain_now->frch_obstack, datum);
}
示例#2
0
void
frag_grow (unsigned int nchars)
{
  if (obstack_room (&frchain_now->frch_obstack) < nchars)
    {
      long oldc;
      long newc;

      /* Try to allocate a bit more than needed right now.  But don't do
         this if we would waste too much memory.  Especially necessary
         for extremely big (like 2GB initialized) frags.  */
      if (nchars < 0x10000)
        newc = 2 * nchars;
      else
        newc = nchars + 0x10000;
      newc += SIZEOF_STRUCT_FRAG;

      /* Check for possible overflow.  */
      if (newc < 0)
        as_fatal (_("can't extend frag %u chars"), nchars);

      /* Force to allocate at least NEWC bytes, but not less than the
         default.  */
      oldc = obstack_chunk_size (&frchain_now->frch_obstack);
      if (newc > oldc)
	obstack_chunk_size (&frchain_now->frch_obstack) = newc;

      while (obstack_room (&frchain_now->frch_obstack) < nchars)
        {
          /* Not enough room in this frag.  Close it and start a new one.
             This must be done in a loop because the created frag may not
             be big enough if the current obstack chunk is used.  */
          frag_wane (frag_now);
          frag_new (0);
        }

      /* Restore the old chunk size.  */
      obstack_chunk_size (&frchain_now->frch_obstack) = oldc;
    }
}
示例#3
0
static void
frag_var_init (relax_stateT type, int max_chars, int var,
               relax_substateT subtype, symbolS *symbol, offsetT offset,
               char *opcode)
{
  frag_now->fr_var = var;
  frag_now->fr_type = type;
  frag_now->fr_subtype = subtype;
  frag_now->fr_symbol = symbol;
  frag_now->fr_offset = offset;
  frag_now->fr_opcode = opcode;
#ifdef USING_CGEN
  frag_now->fr_cgen.insn = 0;
  frag_now->fr_cgen.opindex = 0;
  frag_now->fr_cgen.opinfo = 0;
#endif
#ifdef TC_FRAG_INIT
  TC_FRAG_INIT (frag_now);
#endif
  as_where (&frag_now->fr_file, &frag_now->fr_line);

  frag_new (max_chars);
}
示例#4
0
文件: frags.c 项目: hollylee/xchain
/*
 *			frag_var()
 *
 * Start a new frag unless we have max_chars more chars of room in the current frag.
 * Close off the old frag with a .fill 0.
 *
 * Set up a machine_dependent relaxable frag, then start a new frag.
 * Return the address of the 1st char of the var part of the old frag
 * to write into.
 */
char *
frag_var(
    relax_stateT type,
    int max_chars,
    int var,
    relax_substateT subtype,
    symbolS *symbol,
    long offset,
    char *opcode)
{
    register char  *retval;

    frag_grow (max_chars);
    retval = obstack_next_free (&frags);
    obstack_blank_fast (&frags, max_chars);
    frag_now->fr_var = var;
    frag_now->fr_type = type;
    frag_now->fr_subtype = subtype;
    frag_now->fr_symbol = symbol;
    frag_now->fr_offset = offset;
    frag_now->fr_opcode = opcode;
    frag_new (max_chars);
    return (retval);
}				/* frag_var() */
示例#5
0
void
md_assemble (char *str)
{
  frv_insn insn;
  char *errmsg;
  int packing_constraint;
  finished_insnS  finished_insn;
  fragS *double_nop_frag = NULL;
  fragS *single_nop_frag = NULL;
  struct vliw_insn_list *vliw_insn_list_entry = NULL;

  /* Initialize GAS's cgen interface for a new instruction.  */
  gas_cgen_init_parse ();

  memset (&insn, 0, sizeof (insn));

  insn.insn = frv_cgen_assemble_insn
    (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, &errmsg);
  
  if (!insn.insn)
    {
      as_bad ("%s", errmsg);
      return;
    }
  
  /* If the cpu is tomcat, then we need to insert nops to workaround
     hardware limitations.  We need to keep track of each vliw unit
     and examine the length of the unit and the individual insns
     within the unit to determine the number and location of the
     required nops.  */
  if (frv_mach == bfd_mach_frvtomcat)
    {
      /* If we've just finished a VLIW insn OR this is a branch,
	 then start up a new frag.  Fill it with nops.  We will get rid
	 of those that are not required after we've seen all of the 
	 instructions but before we start resolving fixups.  */
      if ( !FRV_IS_NOP (insn)
	  && (frv_is_branch_insn (insn.insn) || insn.fields.f_pack))
	{
	  char *buffer;

	  frag_wane (frag_now);
	  frag_new (0);
	  double_nop_frag = frag_now;
	  buffer = frag_var (rs_machine_dependent, 8, 8, NOP_DELETE, NULL, 0, 0);
	  md_number_to_chars (buffer, FRV_NOP_PACK, 4);
	  md_number_to_chars (buffer+4, FRV_NOP_NOPACK, 4);

	  frag_wane (frag_now);
	  frag_new (0);
	  single_nop_frag = frag_now;
	  buffer = frag_var (rs_machine_dependent, 4, 4, NOP_DELETE, NULL, 0, 0);
	  md_number_to_chars (buffer, FRV_NOP_NOPACK, 4);
	}

      vliw_insn_list_entry = frv_insert_vliw_insn (DO_COUNT);
      vliw_insn_list_entry->insn   = insn.insn;
      if (frv_is_branch_insn (insn.insn))
	vliw_insn_list_entry->type = VLIW_BRANCH_TYPE;

      if ( !FRV_IS_NOP (insn)
	  && (frv_is_branch_insn (insn.insn) || insn.fields.f_pack))
	{
	  vliw_insn_list_entry->snop_frag = single_nop_frag;
	  vliw_insn_list_entry->dnop_frag = double_nop_frag;
	}
    }

  /* Make sure that this insn does not violate the VLIW packing constraints.  */
  /* -mno-pack disallows any packing whatsoever.  */
  if (frv_flags & EF_FRV_NOPACK)
    {
      if (! insn.fields.f_pack)
	{
	  as_bad (_("VLIW packing used for -mno-pack"));
	  return;
	}
    }
  /* -mcpu=FRV is an idealized FR-V implementation that supports all of the
     instructions, don't do vliw checking.  */
  else if (frv_mach != bfd_mach_frv)
    {
      if (!target_implements_insn_p (insn.insn))
	{
	  as_bad (_("Instruction not supported by this architecture"));
	  return;
	}
      packing_constraint = frv_vliw_add_insn (& vliw, insn.insn);
      if (frv_mach == bfd_mach_fr550 && ! packing_constraint)
	packing_constraint = fr550_check_acc_range (& vliw, & insn);
      if (insn.fields.f_pack)
	frv_vliw_reset (& vliw, frv_mach, frv_flags);
      if (packing_constraint)
	{
	  as_bad (_("VLIW packing constraint violation"));
	  return;
	}
    }

  /* Doesn't really matter what we pass for RELAX_P here.  */
  gas_cgen_finish_insn (insn.insn, insn.buffer,
			CGEN_FIELDS_BITSIZE (& insn.fields), 1, &finished_insn);


  /* If the cpu is tomcat, then we need to insert nops to workaround
     hardware limitations.  We need to keep track of each vliw unit
     and examine the length of the unit and the individual insns
     within the unit to determine the number and location of the
     required nops.  */
  if (frv_mach == bfd_mach_frvtomcat)
    {
      if (vliw_insn_list_entry)
        vliw_insn_list_entry->address = finished_insn.addr;
      else
	abort();

      if (insn.fields.f_pack)
	{
	  /* We've completed a VLIW insn.  */
	  previous_vliw_chain = current_vliw_chain;
	  current_vliw_chain = NULL;
	  current_vliw_insn  = NULL;
        } 
    }
}
示例#6
0
文件: listing.c 项目: CromFr/gdb
static void
new_frag (void)
{
  frag_wane (frag_now);
  frag_new (0);
}