Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Enumerations | Functions | Variables
tc-mt.c File Reference
#include "as.h"
#include "dwarf2dbg.h"
#include "subsegs.h"
#include "symcat.h"
#include "opcodes/mt-desc.h"
#include "opcodes/mt-opc.h"
#include "cgen.h"
#include "elf/common.h"
#include "elf/mt.h"
#include "libbfd.h"

Go to the source code of this file.

Classes

struct  mt_insn

Defines

#define INSN_VALUE(buf)   (buf)
#define OPTION_NO_SCHED_REST   (OPTION_MD_BASE)
#define OPTION_MARCH   (OPTION_MD_BASE + 1)
#define MAX_LITTLENUMS   6

Enumerations

enum  mt_architectures { ms1_64_001, ms1_16_002, ms1_16_003, ms2 }

Functions

static enum mt_architectures int md_parse_option (int c ATTRIBUTE_UNUSED, char *arg)
void md_show_usage (FILE *stream)
void md_begin (void)
void md_assemble (char *str)
valueT md_section_align (segT segment, valueT size)
symbolS * md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
int md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
void md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, fragS *fragP ATTRIBUTE_UNUSED)
long md_pcrel_from_section (fixS *fixP, segT sec)
bfd_reloc_code_real_type md_cgen_lookup_reloc (const CGEN_INSN *insn ATTRIBUTE_UNUSED, const CGEN_OPERAND *operand, fixS *fixP ATTRIBUTE_UNUSED)
void md_number_to_chars (char *buf, valueT val, int n)
char * md_atof (char type, char *litP, int *sizeP)
int mt_force_relocation (fixS *fixp ATTRIBUTE_UNUSED)
void mt_apply_fix (fixS *fixP, valueT *valueP, segT seg)
bfd_boolean mt_fix_adjustable (fixS *fixP)

Variables

const char comment_chars [] = ";"
const char line_comment_chars [] = "#"
const char line_separator_chars [] = ""
const char EXP_CHARS [] = "eE"
const char FLT_CHARS [] = "dD"
const pseudo_typeS md_pseudo_table []
static int no_scheduling_restrictions = 0
size_t md_longopts_size = sizeof (md_longopts)
const char * md_shortopts = ""
static int mt_mach = bfd_mach_ms1
static unsigned mt_mach_bitmask = 1 << MACH_MS1
static flagword mt_flags = EF_MT_CPU_MRISC

Class Documentation

struct mt_insn

Definition at line 34 of file tc-mt.c.

Class Members
char * addr
unsigned char buffer
CGEN_FIELDS fields
fixS * fixups
fragS * frag
int indices
const CGEN_INSN * insn
int num_fixups
const CGEN_INSN * orig_insn

Define Documentation

#define INSN_VALUE (   buf)    (buf)

Definition at line 44 of file tc-mt.c.

#define MAX_LITTLENUMS   6

Definition at line 440 of file tc-mt.c.

#define OPTION_MARCH   (OPTION_MD_BASE + 1)

Enumeration Type Documentation

Enumerator:
ms1_64_001 
ms1_16_002 
ms1_16_003 
ms2 

Definition at line 92 of file tc-mt.c.


Function Documentation

void md_assemble ( char *  str)

Definition at line 184 of file tc-mt.c.

{
  static long delayed_load_register = 0;
  static long prev_delayed_load_register = 0;
  static int last_insn_had_delay_slot = 0;
  static int last_insn_in_noncond_delay_slot = 0;
  static int last_insn_has_load_delay = 0;
  static int last_insn_was_memory_access = 0;
  static int last_insn_was_io_insn = 0;
  static int last_insn_was_arithmetic_or_logic = 0;
  static int last_insn_was_branch_insn = 0;
  static int last_insn_was_conditional_branch_insn = 0;

  mt_insn insn;
  char * errmsg;

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

  insn.insn = mt_cgen_assemble_insn
      (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);

  if (!insn.insn)
    {
      as_bad ("%s", errmsg);
      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, NULL);


  /* Handle Scheduling Restrictions.  */
  if (!no_scheduling_restrictions)
    {
      /* Detect consecutive Memory Accesses.  */
      if (last_insn_was_memory_access
         && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MEMORY_ACCESS)
         && mt_mach == ms1_64_001)
       as_warn (_("instruction %s may not follow another memory access instruction."),
               CGEN_INSN_NAME (insn.insn));

      /* Detect consecutive I/O Instructions.  */
      else if (last_insn_was_io_insn
              && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_IO_INSN))
       as_warn (_("instruction %s may not follow another I/O instruction."),
               CGEN_INSN_NAME (insn.insn));

      /* Detect consecutive branch instructions.  */
      else if (last_insn_was_branch_insn
              && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN))
       as_warn (_("%s may not occupy the delay slot of another branch insn."),
               CGEN_INSN_NAME (insn.insn));

      /* Detect data dependencies on delayed loads: memory and input insns.  */
      if (last_insn_has_load_delay && delayed_load_register)
       {
         if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
             && insn.fields.f_sr1 == delayed_load_register)
           as_warn (_("operand references R%ld of previous load."),
                   insn.fields.f_sr1);

         if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
             && insn.fields.f_sr2 == delayed_load_register)
           as_warn (_("operand references R%ld of previous load."),
                   insn.fields.f_sr2);
       }

      /* Detect JAL/RETI hazard */
      if (mt_mach == ms2
         && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_JAL_HAZARD))
       {
         if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
              && insn.fields.f_sr1 == delayed_load_register)
             || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
                && insn.fields.f_sr2 == delayed_load_register))
           as_warn (_("operand references R%ld of previous instrutcion."),
                   delayed_load_register);
         else if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
                  && insn.fields.f_sr1 == prev_delayed_load_register)
                 || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
                     && insn.fields.f_sr2 == prev_delayed_load_register))
           as_warn (_("operand references R%ld of instructcion before previous."),
                   prev_delayed_load_register);
       }
      
      /* Detect data dependency between conditional branch instruction
         and an immediately preceding arithmetic or logical instruction.  */
      if (last_insn_was_arithmetic_or_logic
         && !last_insn_in_noncond_delay_slot
         && (delayed_load_register != 0)
         && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN)
         && mt_arch == ms1_64_001)
       {
         if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
             && insn.fields.f_sr1 == delayed_load_register)
           as_warn (_("conditional branch or jal insn's operand references R%ld of previous arithmetic or logic insn."),
                   insn.fields.f_sr1);

         if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
             && insn.fields.f_sr2 == delayed_load_register)
           as_warn (_("conditional branch or jal insn's operand references R%ld of previous arithmetic or logic insn."),
                   insn.fields.f_sr2);
       }
    }

  /* Keep track of details of this insn for processing next insn.  */
  last_insn_in_noncond_delay_slot = last_insn_was_branch_insn
    && !last_insn_was_conditional_branch_insn;

  last_insn_had_delay_slot =
    CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);

  last_insn_has_load_delay =
    CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_LOAD_DELAY);

  last_insn_was_memory_access =
    CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MEMORY_ACCESS);

  last_insn_was_io_insn =
    CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_IO_INSN);

  last_insn_was_arithmetic_or_logic =
    CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_AL_INSN);

  last_insn_was_branch_insn =
    CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN);
  
  last_insn_was_conditional_branch_insn =
  CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN)
    && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2);
  
  prev_delayed_load_register = delayed_load_register;
  
  if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRDR))
     delayed_load_register = insn.fields.f_dr; 
  else if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRDRRR))
     delayed_load_register = insn.fields.f_drrr; 
  else  /* Insns has no destination register.  */
     delayed_load_register = 0; 

  /* Generate dwarf2 line numbers.  */
  dwarf2_emit_insn (4); 
}

Here is the call graph for this function:

char* md_atof ( char type  ,
char *  litP,
int sizeP 
)

Definition at line 443 of file tc-mt.c.

{
  int              prec;
  LITTLENUM_TYPE   words [MAX_LITTLENUMS];
  LITTLENUM_TYPE * wordP;
  char *           t;

  switch (type)
    {
    case 'f':
    case 'F':
    case 's':
    case 'S':
      prec = 2;
      break;

    case 'd':
    case 'D':
    case 'r':
    case 'R':
      prec = 4;
      break;

   /* FIXME: Some targets allow other format chars for bigger sizes here.  */

    default:
      * sizeP = 0;
      return _("Bad call to md_atof()");
    }

  t = atof_ieee (input_line_pointer, type, words);
  if (t)
    input_line_pointer = t;
  * sizeP = prec * sizeof (LITTLENUM_TYPE);

  /* This loops outputs the LITTLENUMs in REVERSE order;
     in accord with the mt endianness.  */
  for (wordP = words; prec--;)
    {
      md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
      litP += sizeof (LITTLENUM_TYPE);
    }
     
  return 0;
}

Here is the call graph for this function:

void md_begin ( void  )

Definition at line 161 of file tc-mt.c.

{
  /* Initialize the `cgen' interface.  */
  
  /* Set the machine number and endian.  */
  gas_cgen_cpu_desc = mt_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, mt_mach_bitmask,
                                   CGEN_CPU_OPEN_ENDIAN,
                                   CGEN_ENDIAN_BIG,
                                   CGEN_CPU_OPEN_END);
  mt_cgen_init_asm (gas_cgen_cpu_desc);

  /* This is a callback from cgen to gas to parse operands.  */
  cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);

  /* Set the ELF flags if desired. */
  if (mt_flags)
    bfd_set_private_flags (stdoutput, mt_flags);

  /* Set the machine type.  */
  bfd_default_set_arch_mach (stdoutput, bfd_arch_mt, mt_mach);
}

Here is the call graph for this function:

bfd_reloc_code_real_type md_cgen_lookup_reloc ( const CGEN_INSN *insn  ATTRIBUTE_UNUSED,
const CGEN_OPERAND operand,
fixS *fixP  ATTRIBUTE_UNUSED 
)

Definition at line 391 of file tc-mt.c.

{
  bfd_reloc_code_real_type result;

  result = BFD_RELOC_NONE;

  switch (operand->type)
    {
    case MT_OPERAND_IMM16O:
      result = BFD_RELOC_16_PCREL;
      fixP->fx_pcrel = 1;
      /* fixP->fx_no_overflow = 1; */
      break;
    case MT_OPERAND_IMM16:
    case MT_OPERAND_IMM16Z:
      /* These may have been processed at parse time.  */
      if (fixP->fx_cgen.opinfo != 0)
        result = fixP->fx_cgen.opinfo;
      fixP->fx_no_overflow = 1;
      break;
    case MT_OPERAND_LOOPSIZE:
      result = BFD_RELOC_MT_PCINSN8;
      fixP->fx_pcrel = 1;
      /* Adjust for the delay slot, which is not part of the loop  */
      fixP->fx_offset -= 8;
      break;
    default:
      result = BFD_RELOC_NONE;
      break;
    }

  return result;
}
void md_convert_frag ( bfd *abfd  ATTRIBUTE_UNUSED,
segT sec  ATTRIBUTE_UNUSED,
fragS *fragP  ATTRIBUTE_UNUSED 
)

Definition at line 360 of file tc-mt.c.

{
}
int md_estimate_size_before_relax ( fragS *fragP  ATTRIBUTE_UNUSED,
segT segment  ATTRIBUTE_UNUSED 
)

Definition at line 345 of file tc-mt.c.

{
  as_fatal (_("md_estimate_size_before_relax\n"));
  return 1;
} 

Here is the call graph for this function:

void md_number_to_chars ( char *  buf,
valueT  val,
int  n 
)

Definition at line 430 of file tc-mt.c.

Here is the call graph for this function:

static enum mt_architectures int md_parse_option ( int c  ATTRIBUTE_UNUSED,
char *  arg 
) [abstract]

Definition at line 104 of file tc-mt.c.

{
  switch (c)
    {
    case OPTION_MARCH:
      if (strcmp (arg, "ms1-64-001") == 0)
       {
         mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MRISC;
         mt_mach = bfd_mach_ms1;
         mt_mach_bitmask = 1 << MACH_MS1;
         mt_arch = ms1_64_001;
       }
      else if (strcmp (arg, "ms1-16-002") == 0)
       {
         mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MRISC;
         mt_mach = bfd_mach_ms1;
         mt_mach_bitmask = 1 << MACH_MS1;
         mt_arch = ms1_16_002;
       }
      else if (strcmp (arg, "ms1-16-003") == 0)
       {
         mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MRISC2;
         mt_mach = bfd_mach_mrisc2;
         mt_mach_bitmask = 1 << MACH_MS1_003;
         mt_arch = ms1_16_003;
       }
      else if (strcmp (arg, "ms2") == 0)
       {
         mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MS2;
         mt_mach = bfd_mach_mrisc2;
         mt_mach_bitmask = 1 << MACH_MS2;
         mt_arch = ms2;
       }
    case OPTION_NO_SCHED_REST:
      no_scheduling_restrictions = 1;
      break;
    default:
      return 0;
    }

  return 1;
}

Here is the call graph for this function:

long md_pcrel_from_section ( fixS *  fixP,
segT sec   
)

Definition at line 370 of file tc-mt.c.

{
  if (fixP->fx_addsy != (symbolS *) NULL
      && (!S_IS_DEFINED (fixP->fx_addsy)
         || S_GET_SEGMENT (fixP->fx_addsy) != sec))
    /* The symbol is undefined (or is defined but not in this section).
       Let the linker figure it out.  */
    return 0;

  /* Return the address of the opcode - cgen adjusts for opcode size
     itself, to be consistent with the disassembler, which must do
     so.  */
  return fixP->fx_where + fixP->fx_frag->fr_address;
}

Here is the call graph for this function:

valueT md_section_align ( segT segment  ,
valueT size   
)

Definition at line 331 of file tc-mt.c.

{
  int align = bfd_get_section_alignment (stdoutput, segment);

  return ((size + (1 << align) - 1) & (-1 << align));
}

Here is the call graph for this function:

void md_show_usage ( FILE *  stream)

Definition at line 149 of file tc-mt.c.

{
  fprintf (stream, _("MT specific command line options:\n"));
  fprintf (stream, _("  -march=ms1-64-001         allow ms1-64-001 instructions\n"));
  fprintf (stream, _("  -march=ms1-16-002         allow ms1-16-002 instructions (default)\n"));
  fprintf (stream, _("  -march=ms1-16-003         allow ms1-16-003 instructions\n"));
  fprintf (stream, _("  -march=ms2                allow ms2 instructions \n"));
  fprintf (stream, _("  -nosched                  disable scheduling restrictions\n"));
}

Here is the call graph for this function:

symbolS* md_undefined_symbol ( char *name  ATTRIBUTE_UNUSED)

Definition at line 339 of file tc-mt.c.

{
    return NULL;
}
void mt_apply_fix ( fixS *  fixP,
valueT valueP,
segT  seg 
)

Definition at line 501 of file tc-mt.c.

{
  if ((fixP->fx_pcrel != 0) && (fixP->fx_r_type == BFD_RELOC_32))
    fixP->fx_r_type = BFD_RELOC_32_PCREL;

  gas_cgen_md_apply_fix (fixP, valueP, seg);
}

Here is the call graph for this function:

bfd_boolean mt_fix_adjustable ( fixS *  fixP)

Definition at line 510 of file tc-mt.c.

{
  bfd_reloc_code_real_type reloc_type;

  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
    {
      const CGEN_INSN *insn = NULL;
      int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
      const CGEN_OPERAND *operand;

      operand = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
      reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
    }
  else
    reloc_type = fixP->fx_r_type;

  if (fixP->fx_addsy == NULL)
    return TRUE;
  
  /* Prevent all adjustments to global symbols.  */
  if (S_IS_EXTERNAL (fixP->fx_addsy))
    return FALSE;
  
  if (S_IS_WEAK (fixP->fx_addsy))
    return FALSE;
  
  return 1;
}

Here is the call graph for this function:

int mt_force_relocation ( fixS *fixp  ATTRIBUTE_UNUSED)

Definition at line 495 of file tc-mt.c.

{
  return 0;
}

Variable Documentation

const char comment_chars[] = ";"

Definition at line 55 of file tc-mt.c.

const char EXP_CHARS[] = "eE"

Definition at line 58 of file tc-mt.c.

const char FLT_CHARS[] = "dD"

Definition at line 59 of file tc-mt.c.

const char line_comment_chars[] = "#"

Definition at line 56 of file tc-mt.c.

Definition at line 57 of file tc-mt.c.

size_t md_longopts_size = sizeof (md_longopts)

Definition at line 80 of file tc-mt.c.

const pseudo_typeS md_pseudo_table[]
Initial value:
{
    { "word",   cons,                   4 }, 
    { NULL,   NULL,                0 }
}

Definition at line 62 of file tc-mt.c.

const char* md_shortopts = ""

Definition at line 82 of file tc-mt.c.

Definition at line 89 of file tc-mt.c.

int mt_mach = bfd_mach_ms1 [static]

Definition at line 85 of file tc-mt.c.

Definition at line 86 of file tc-mt.c.

Definition at line 70 of file tc-mt.c.