Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Functions | Variables
tc-dlx.c File Reference
#include "safe-ctype.h"
#include "as.h"
#include "tc-dlx.h"
#include "opcode/dlx.h"

Go to the source code of this file.

Classes

struct  machine_it

Defines

#define machine_opcode   dlx_opcode
#define machine_opcodes   dlx_opcodes
#define machine_ip   dlx_ip
#define machine_it   dlx_it
#define NO_RELOC   BFD_RELOC_NONE
#define RELOC_DLX_REL26   BFD_RELOC_DLX_JMP26
#define RELOC_DLX_16   BFD_RELOC_16
#define RELOC_DLX_REL16   BFD_RELOC_16_PCREL_S2
#define RELOC_DLX_HI16   BFD_RELOC_HI16_S
#define RELOC_DLX_LO16   BFD_RELOC_LO16
#define RELOC_DLX_VTINHERIT   BFD_RELOC_VTABLE_INHERIT
#define RELOC_DLX_VTENTRY   BFD_RELOC_VTABLE_ENTRY
#define MAX_REG_NO   35
#define READ_OP   0x100
#define WRITE_OP   0x200
#define MAX_LITTLENUMS   6

Functions

static void insert_sreg (char *regname, int regnum)
static void define_some_regs (void)
static int match_sft_register (char *name)
static int is_ldst_registers (char *name)
static void s_proc (int end_p)
void md_begin (void)
static char * dlx_parse_loadop (char *str)
static char * dlx_parse_storeop (char *str)
static char * fix_ld_st_operand (unsigned long opcode, char *str)
static int hilo_modifier_ok (char *s)
static char * parse_operand (char *s, expressionS *operandp)
static void machine_ip (char *str)
void md_assemble (char *str)
char * md_atof (int type, char *litP, int *sizeP)
void md_number_to_chars (char *buf, valueT val, int n)
bfd_boolean md_dlx_fix_adjustable (fixS *fixP)
void md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
int md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
void md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
int dlx_unrecognized_line (int c)
symbolS * md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
void md_operand (expressionS *expressionP)
valueT md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
long md_pcrel_from (fixS *fixP)
arelenttc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
void dlx_pop_insert (void)

Variables

static struct hash_controlop_hash = NULL
struct machine_it the_insn
const char comment_chars [] = ";"
const char line_comment_chars [] = "#"
const char line_separator_chars [] = "@"
const char EXP_CHARS [] = "eE"
const char FLT_CHARS [] = "rRsSfFdDxXpP"
static char iBuf [81]
const char * md_shortopts = ""
size_t md_longopts_size = sizeof (md_longopts)
const pseudo_typeS dlx_pseudo_table []

Class Documentation

struct machine_it

Definition at line 46 of file tc-dlx.c.

Collaboration diagram for machine_it:
Class Members
char * error
expressionS exp
int HI
int LO
struct nlist * nlistp
unsigned long opcode
int pcrel
int reloc
int reloc_offset
int size

Define Documentation

#define machine_ip   dlx_ip

Definition at line 31 of file tc-dlx.c.

#define machine_it   dlx_it

Definition at line 32 of file tc-dlx.c.

#define machine_opcode   dlx_opcode

Definition at line 29 of file tc-dlx.c.

#define machine_opcodes   dlx_opcodes

Definition at line 30 of file tc-dlx.c.

#define MAX_LITTLENUMS   6

Definition at line 987 of file tc-dlx.c.

#define MAX_REG_NO   35
#define NO_RELOC   BFD_RELOC_NONE

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

#define READ_OP   0x100

Definition at line 306 of file tc-dlx.c.

#define RELOC_DLX_16   BFD_RELOC_16

Definition at line 36 of file tc-dlx.c.

Definition at line 38 of file tc-dlx.c.

Definition at line 39 of file tc-dlx.c.

Definition at line 37 of file tc-dlx.c.

Definition at line 35 of file tc-dlx.c.

Definition at line 41 of file tc-dlx.c.

Definition at line 40 of file tc-dlx.c.

#define WRITE_OP   0x200

Definition at line 307 of file tc-dlx.c.


Function Documentation

static void define_some_regs ( void  ) [static]

Definition at line 107 of file tc-dlx.c.

{
  /* Software representation.  */
  insert_sreg ("zero",  0);
  insert_sreg ("at",    1);
  insert_sreg ("v0",    2);
  insert_sreg ("v1",    3);
  insert_sreg ("a0",    4);
  insert_sreg ("a1",    5);
  insert_sreg ("a2",    6);
  insert_sreg ("a3",    7);
  insert_sreg ("t0",    8);
  insert_sreg ("t1",    9);
  insert_sreg ("t2",    10);
  insert_sreg ("t3",    11);
  insert_sreg ("t4",    12);
  insert_sreg ("t5",    13);
  insert_sreg ("t6",    14);
  insert_sreg ("t7",    15);
  insert_sreg ("s0",    16);
  insert_sreg ("s1",    17);
  insert_sreg ("s2",    18);
  insert_sreg ("s3",    19);
  insert_sreg ("s4",    20);
  insert_sreg ("s5",    21);
  insert_sreg ("s6",    22);
  insert_sreg ("s7",    23);
  insert_sreg ("t8",    24);
  insert_sreg ("t9",    25);
  insert_sreg ("k0",    26);
  insert_sreg ("k1",    27);
  insert_sreg ("gp",    28);
  insert_sreg ("sp",    29);
  insert_sreg ("fp",    30);
  insert_sreg ("ra",    31);
  /* Special registers.  */
  insert_sreg ("pc",    0);
  insert_sreg ("npc",   1);
  insert_sreg ("iad",   2);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* dlx_parse_loadop ( char *  str) [static]

Definition at line 311 of file tc-dlx.c.

{
  char *ptr = str;
  int   idx = 0;

  /* The last pair of ()/[] is the register, all other are the
     reloc displacement, and if there is a register then it ought
     to have a pair of ()/[]
     This is not necessarily true, what if the load instruction come
     without the register and with %hi/%lo modifier?  */
  for (idx = 0; idx < 72 && ptr[idx] != '\0'; idx++)
    ;

  if (idx == 72)
    {
    badoperand_load:
      as_bad (_("Bad operand for a load instruction: <%s>"), str);
      return NULL;
    }
  else
    {
      int i, pb = 0;
      int m2 = 0;
      char rs1[7], rd[7], endm, match = '0';
      char imm[72];

      idx -= 1;
      switch (str[idx])
       {
       case ')':
         match = '(';
         endm  = ')';
         break;
       case ']':
         match = '[';
         endm  = ']';
         break;
       default:
         /* No register indicated, fill in zero.  */
         rs1[0] = 'r';
         rs1[1] = '0';
         rs1[2] = '\0';
         match  = 0;
         endm = 0;
         m2 = 1;
       }

      if (!m2)
       {
         /* Searching for (/[ which will match the ]/).  */
         for (pb = idx - 1; str[pb] != match; pb -= 1)
           /* Match can only be either '[' or '(', if it is
              '(' then this can be a normal expression, we'll treat
              it as an operand.  */
           if (str[pb] == endm || pb < (idx - 5))
             goto load_no_rs1;
         pb += 1;

         for (i = 0; (pb + i) < idx; i++)
           rs1[i] = str[pb+i];

         rs1[i] = '\0';

         if (is_ldst_registers (& rs1[0]))
           /* Point to the last character of the imm.  */
           pb -= 1;
         else
           {
           load_no_rs1:
             if (match == '[')
              goto badoperand_load;
             /* No register indicated, fill in zero and restore the imm.  */
             rs1[0] = 'r';
             rs1[1] = '0';
             rs1[2] = '\0';
             m2 = 1;
           }
       }

      /* Duplicate the first register.  */
      for (i = 0; i < 7 && str[i] != ','; i++)
       rd[i] = ptr[i];

      if (str[i] != ',')
       goto badoperand_load;
      else
       rd[i] = '\0';

      /* Copy the immd.  */
      if (m2)
       /* Put the '\0' back in.  */
       pb = idx + 1;

      for (i++, m2 = 0; i < pb; m2++,i++)
       imm[m2] = ptr[i];

      imm[m2] = '\0';

      /* Assemble the instruction to gas internal format.  */
      for (i = 0; rd[i] != '\0'; i++)
       iBuf[i] = rd[i];

      iBuf[i++] = ',';

      for (pb = 0 ; rs1[pb] != '\0'; i++, pb++)
       iBuf[i] = rs1[pb];

      iBuf[i++] = ',';

      for (pb = 0; imm[pb] != '\0'; i++, pb++)
       iBuf[i] = imm[pb];

      iBuf[i] = '\0';
      return iBuf;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* dlx_parse_storeop ( char *  str) [static]

Definition at line 429 of file tc-dlx.c.

{
  char *ptr = str;
  int   idx = 0;

  /* Search for the ','.  */
  for (idx = 0; idx < 72 && ptr[idx] != ','; idx++)
    ;

  if (idx == 72)
    {
    badoperand_store:
      as_bad (_("Bad operand for a store instruction: <%s>"), str);
      return NULL;
    }
  else
    {
      /* idx now points to the ','.  */
      int i, pb = 0;
      int comma = idx;
      int m2 = 0;
      char rs1[7], rd[7], endm, match = '0';
      char imm[72];

      /* Now parse the '(' and ')', and make idx point to ')'.  */
      idx -= 1;
      switch (str[idx])
       {
       case ')':
         match = '(';
         endm  = ')';
         break;
       case ']':
         match = '[';
         endm  = ']';
         break;
       default:
         /* No register indicated, fill in zero.  */
         rs1[0] = 'r';
         rs1[1] = '0';
         rs1[2] = '\0';
         match  = 0;
         endm = 0;
         m2 = 1;
       }

      if (!m2)
       {
         /* Searching for (/[ which will match the ]/).  */
         for (pb = idx - 1; str[pb] != match; pb -= 1)
           if (pb < (idx - 5) || str[pb] == endm)
             goto store_no_rs1;
         pb += 1;

         for (i = 0; (pb + i) < idx; i++)
           rs1[i] = str[pb + i];

         rs1[i] = '\0';

         if (is_ldst_registers (& rs1[0]))
           /* Point to the last character of the imm.  */
           pb -= 1;
         else
           {
           store_no_rs1:
             if (match == '[')
              goto badoperand_store;

             /* No register indicated, fill in zero and restore the imm.  */
             rs1[0] = 'r';
             rs1[1] = '0';
             rs1[2] = '\0';
             pb = comma;
           }
       }
      else
       /* No register was specified.  */
       pb = comma;

      /* Duplicate the first register.  */
      for (i = comma + 1; (str[i] == ' ' || str[i] == '\t'); i++)
       ;

      for (m2 = 0; (m2 < 7 && str[i] != '\0'); i++, m2++)
       {
         if (str[i] != ' ' && str[i] != '\t')
           rd[m2] = str[i];
         else
           goto badoperand_store;
       }

      if (str[i] != '\0')
       goto badoperand_store;
      else
       rd[m2] = '\0';

      /* Copy the immd.  */
      for (i = 0; i < pb; i++)
       imm[i] = ptr[i];

      imm[i] = '\0';

      /* Assemble the instruction to gas internal format.  */
      for (i = 0; rd[i] != '\0'; i++)
       iBuf[i] = rd[i];
      iBuf[i++] = ',';
      for (pb = 0 ; rs1[pb] != '\0'; i++, pb++)
       iBuf[i] = rs1[pb];
      iBuf[i++] = ',';
      for (pb = 0; imm[pb] != '\0'; i++, pb++)
       iBuf[i] = imm[pb];
      iBuf[i] = '\0';
      return iBuf;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void dlx_pop_insert ( void  )

Definition at line 1289 of file tc-dlx.c.

{
  pop_insert (dlx_pseudo_table);
  return ;
}

Here is the call graph for this function:

Definition at line 1152 of file tc-dlx.c.

{
  int lab;
  char *s;

  if (c != '$' || ! ISDIGIT ((unsigned char) input_line_pointer[0]))
    return 0;

  s = input_line_pointer;

  lab = 0;
  while (ISDIGIT ((unsigned char) *s))
    {
      lab = lab * 10 + *s - '0';
      ++s;
    }

  if (*s != ':')
    /* Not a label definition.  */
    return 0;

  if (dollar_label_defined (lab))
    {
      as_bad (_("label \"$%d\" redefined"), lab);
      return 0;
    }

  define_dollar_label (lab);
  colon (dollar_label_name (lab, 0));
  input_line_pointer = s + 1;

  return 1;
}

Here is the call graph for this function:

static char* fix_ld_st_operand ( unsigned long  opcode,
char *  str 
) [static]

Definition at line 546 of file tc-dlx.c.

{
  /* Check the opcode.  */
  switch ((int) opcode)
    {
    case  LBOP:
    case  LBUOP:
    case  LSBUOP:
    case  LHOP:
    case  LHUOP:
    case  LSHUOP:
    case  LWOP:
    case  LSWOP:
      return dlx_parse_loadop (str);
    case  SBOP:
    case  SHOP:
    case  SWOP:
      return dlx_parse_storeop (str);
    default:
      return str;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int hilo_modifier_ok ( char *  s) [static]

Definition at line 570 of file tc-dlx.c.

{
  char *ptr = s;
  int   idx, count = 1;

  if (*ptr != '(')
    return 1;

  for (idx = 1; ptr[idx] != '\0' && ptr[idx] != '[' && idx < 73; idx += 1)
    {
      if (count == 0)
       return count;

      if (ptr[idx] == '(')
       count += 1;

      if (ptr[idx] == ')')
       count -= 1;
    }

  return (count == 0) ? 1:0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void insert_sreg ( char *  regname,
int  regnum 
) [static]

Definition at line 87 of file tc-dlx.c.

{
  /* Must be large enough to hold the names of the special registers.  */
  char buf[80];
  int i;

  symbol_table_insert (symbol_new (regname, reg_section, (valueT) regnum,
                               &zero_address_frag));
  for (i = 0; regname[i]; i++)
    buf[i] = ISLOWER (regname[i]) ? TOUPPER (regname[i]) : regname[i];
  buf[i] = '\0';

  symbol_table_insert (symbol_new (buf, reg_section, (valueT) regnum,
                               &zero_address_frag));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int is_ldst_registers ( char *  name) [static]

Definition at line 182 of file tc-dlx.c.

{
  char *ptr = name;

  /* The first character of the register name got to be either %, $, r of R.  */
  if ((ptr[0] == '%' || ptr[0] == '$' || ptr[0] == 'r' || ptr[0] == 'R')
      && ISDIGIT ((unsigned char) ptr[1]))
    return 1;

  /* Now check the software register representation.  */
  return match_sft_register (ptr);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void machine_ip ( char *  str) [static]

Definition at line 654 of file tc-dlx.c.

{
  char *s;
  const char *args;
  struct machine_opcode *insn;
  char *argsStart;
  unsigned long opcode;
  expressionS the_operand;
  expressionS *operand = &the_operand;
  unsigned int reg, reg_shift = 0;

  /* Fixup the opcode string to all lower cases, and also
     allow numerical digits.  */
  s = str;

  if (ISALPHA (*s))
    for (; ISALNUM (*s); ++s)
      if (ISUPPER (*s))
       *s = TOLOWER (*s);

  switch (*s)
    {
    case '\0':
      break;

      /* FIXME-SOMEDAY more whitespace.  */
    case ' ':
      *s++ = '\0';
      break;

    default:
      as_bad (_("Unknown opcode: `%s'"), str);
      return;
    }

  /* Hash the opcode, insn will have the string from opcode table.
     also initialized the_insn struct.  */
  if ((insn = (struct machine_opcode *) hash_find (op_hash, str)) == NULL)
    {
      /* Handle the ret and return macro here.  */
      if ((strcmp (str, "ret") == 0) || (strcmp (str, "return") == 0))
       {
         memset (&the_insn, '\0', sizeof (the_insn));
         the_insn.reloc = NO_RELOC;
         the_insn.pcrel = 0;
         the_insn.opcode =
           (unsigned long)(JROP | 0x03e00000);    /* 0x03e00000 = r31 << 21 */
       }
      else
       as_bad (_("Unknown opcode `%s'."), str);

      return;
    }

  argsStart = s;
  opcode = insn->opcode;
  memset (&the_insn, '\0', sizeof (the_insn));
  the_insn.reloc = NO_RELOC;
  the_insn.pcrel = 0;

  /* Set the sip reloc HI16 flag.  */
  if (!set_dlx_skip_hi16_flag (1))
    as_bad (_("Can not set dlx_skip_hi16_flag"));

  /* Fix the operand string if it is one of load store instructions.  */
  s = fix_ld_st_operand (opcode, s);

  /* Build the opcode, checking as we go to make sure that the
     operands match.
     If an operand matches, we modify the_insn or opcode appropriately,
     and do a "continue".  If an operand fails to match, we "break".  */
  if (insn->args[0] != '\0' && insn->args[0] != 'N')
    {
      /* Prime the pump.  */
      if (*s == '\0')
       {
         as_bad (_("Missing arguments for opcode <%s>."), str);
         return;
       }
      else
       s = parse_operand (s, operand);
    }
  else if (insn->args[0] == 'N')
    {
      /* Clean up the insn and done!  */
      the_insn.opcode = opcode;
      return;
    }

  /* Parse through the args (this is from opcode table), *s point to
     the current character of the instruction stream.  */
  for (args = insn->args;; ++args)
    {
      switch (*args)
       {
         /* End of Line.  */
       case '\0':
         /* End of args.  */
         if (*s == '\0')
           {
             /* We are truly done.  */
             the_insn.opcode = opcode;
             /* Clean up the HI and LO mark.  */
             the_insn.HI = 0;
             the_insn.LO = 0;
             return;
           }

         the_insn.HI = 0;
         the_insn.LO = 0;
         as_bad (_("Too many operands: %s"), s);
         break;

         /* ',' Args separator */
       case ',':
         /* Must match a comma.  */
         if (*s++ == ',')
           {
             /* Parse next operand.  */
             s = parse_operand (s, operand);
             continue;
           }
         break;

         /* It can be a 'a' register or 'i' operand.  */
       case 'P':
         /* Macro move operand/reg.  */
         if (operand->X_op == O_register)
           {
             /* Its a register.  */
             reg_shift = 21;
             goto general_reg;
           }

         /* The immediate 16 bits literal, bit 0-15.  */
       case 'i':
         /* offset, unsigned.  */
       case 'I':
         /* offset, signed.  */
         if (operand->X_op == O_constant)
           {
             if (the_insn.HI)
              operand->X_add_number >>= 16;

             opcode |= operand->X_add_number & 0xFFFF;

             if (the_insn.HI && the_insn.LO)
              as_bad (_("Both the_insn.HI and the_insn.LO are set : %s"), s);
             else
              {
                the_insn.HI = 0;
                the_insn.LO = 0;
              }
             continue;
           }

         the_insn.reloc        = (the_insn.HI) ? RELOC_DLX_HI16 
           : (the_insn.LO ? RELOC_DLX_LO16 : RELOC_DLX_16);
         the_insn.reloc_offset = 2;
         the_insn.size         = 2;
         the_insn.pcrel        = 0;
         the_insn.exp          = * operand;
         the_insn.HI           = 0;
         the_insn.LO           = 0;
         continue;

       case 'd':
         /* offset, signed.  */
         if (operand->X_op == O_constant)
           {
             opcode |= operand->X_add_number & 0xFFFF;
             continue;
           }
         the_insn.reloc        = RELOC_DLX_REL16;
         the_insn.reloc_offset = 0;    /* BIG-ENDIAN Byte 3 of insn.  */
         the_insn.size         = 4;
         the_insn.pcrel        = 1;
         the_insn.exp          = *operand;
         continue;

         /* The immediate 26 bits literal, bit 0-25.  */
       case 'D':
         /* offset, signed.  */
         if (operand->X_op == O_constant)
           {
             opcode |= operand->X_add_number & 0x3FFFFFF;
             continue;
           }
         the_insn.reloc = RELOC_DLX_REL26;
         the_insn.reloc_offset = 0;    /* BIG-ENDIAN Byte 3 of insn.  */
         the_insn.size  = 4;
         the_insn.pcrel = 1;
         the_insn.exp = *operand;
         continue;

         /* Type 'a' Register.  */
       case 'a':
         /* A general register at bits 21-25, rs1.  */
         reg_shift = 21;
         goto general_reg;

         /* Type 'b' Register.  */
       case 'b':
         /* A general register at bits 16-20, rs2/rd.  */
         reg_shift = 16;
         goto general_reg;

         /* Type 'c' Register.  */
       case 'c':
         /* A general register at bits 11-15, rd.  */
         reg_shift = 11;

       general_reg:
         know (operand->X_add_symbol == 0);
         know (operand->X_op_symbol == 0);
         reg = operand->X_add_number;
         if (reg & 0xffffffe0)
           as_fatal (_("failed regnum sanity check."));
         else
           /* Got the register, now figure out where it goes in the opcode.  */
           opcode |= reg << reg_shift;

         switch (*args)
           {
           case 'a':
           case 'b':
           case 'c':
           case 'P':
             continue;
           }
         as_fatal (_("failed general register sanity check."));
         break;

       default:
         BAD_CASE (*args);
       }

      /* Types or values of args don't match.  */
      as_bad ("Invalid operands");
      return;
    }
}

Here is the call graph for this function:

static int match_sft_register ( char *  name) [static]

Definition at line 151 of file tc-dlx.c.

{
#define MAX_REG_NO  35
/* Currently we have 35 software registers defined -
   we borrowed from MIPS.   */
  static char *soft_reg[] =
    {
      "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9",
      "s0", "s1", "s2", "s3", "s4", "s5", "s7", "k0", "k1",
      "gp", "sp", "fp", "ra", "pc", "npc", "iad",
      "EndofTab"  /* End of the Table indicator */
    };
  char low_name[21], *ptr;
  int idx;

  for (ptr = name,idx = 0; *ptr != '\0'; ptr++)
    low_name[idx++] = TOLOWER (*ptr);

  low_name[idx] = '\0';
  idx = 0;

  while (idx < MAX_REG_NO && strcmp (soft_reg[idx], & low_name [0]))
    idx += 1;

  return idx < MAX_REG_NO;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void md_apply_fix ( fixS *  fixP,
valueT valP,
segT seg  ATTRIBUTE_UNUSED 
)

Definition at line 1059 of file tc-dlx.c.

{
  long val = *valP;
  char *place = fixP->fx_where + fixP->fx_frag->fr_literal;

  switch (fixP->fx_r_type)
    {
    case RELOC_DLX_LO16:
    case RELOC_DLX_REL16:
      if (fixP->fx_bit_fixP != NULL)
       {
         val = (val & 0x0000FFFF) | fixP->fx_bit_fixP->fx_bit_base;
         free (fixP->fx_bit_fixP);
         fixP->fx_bit_fixP = NULL;
       }
#ifdef DEBUG
      else
       know ((fixP->fx_bit_fixP != NULL));
#endif
      break;

    case RELOC_DLX_HI16:
      if (fixP->fx_bit_fixP != NULL)
       {
         val = (val >> 16) | fixP->fx_bit_fixP->fx_bit_base;
         free (fixP->fx_bit_fixP);
         fixP->fx_bit_fixP = NULL;
       }
#ifdef DEBUG
      else
       know ((fixP->fx_bit_fixP != NULL));
#endif
      break;

    case RELOC_DLX_REL26:
      if (fixP->fx_bit_fixP != NULL)
       {
         val = (val & 0x03FFFFFF) | fixP->fx_bit_fixP->fx_bit_base;
         free (fixP->fx_bit_fixP);
         fixP->fx_bit_fixP = NULL;
       }
#ifdef DEBUG
      else
       know ((fixP->fx_bit_fixP != NULL));
#endif
      break;

    case BFD_RELOC_VTABLE_INHERIT:
      /* This borrowed from tc-ppc.c on a whim.  */
      fixP->fx_done = 0;
      if (fixP->fx_addsy
         && !S_IS_DEFINED (fixP->fx_addsy)
         && !S_IS_WEAK (fixP->fx_addsy))
       S_SET_WEAK (fixP->fx_addsy);
      return;

    case BFD_RELOC_VTABLE_ENTRY:
      fixP->fx_done = 0;
      return;

    default:
      break;
    }

  number_to_chars_bigendian (place, val, fixP->fx_size);
  if (fixP->fx_addsy == NULL)
    fixP->fx_done = 1;
}

Here is the call graph for this function:

void md_assemble ( char *  str)

Definition at line 902 of file tc-dlx.c.

{
  char *toP;
  fixS *fixP;
  bit_fixS *bitP;

  know (str);
  machine_ip (str);
  toP = frag_more (4);
  /* Put out the opcode.  */
  md_number_to_chars (toP, the_insn.opcode, 4);

  /* Put out the symbol-dependent stuff.  */
  if (the_insn.reloc != NO_RELOC)
    {
      fixP = fix_new_exp (frag_now,
                       (toP - frag_now->fr_literal + the_insn.reloc_offset),
                       the_insn.size, & the_insn.exp, the_insn.pcrel,
                       the_insn.reloc);

      /* Turn off complaints that the addend is
        too large for things like foo+100000@ha.  */
      switch (the_insn.reloc)
       {
       case RELOC_DLX_HI16:
       case RELOC_DLX_LO16:
         fixP->fx_no_overflow = 1;
         break;
       default:
         break;
       }

      switch (fixP->fx_r_type)
       {
       case RELOC_DLX_REL26:
         bitP = malloc (sizeof (bit_fixS));
         bitP->fx_bit_size = 26;
         bitP->fx_bit_offset = 25;
         bitP->fx_bit_base = the_insn.opcode & 0xFC000000;
         bitP->fx_bit_base_adj = 0;
         bitP->fx_bit_max = 0;
         bitP->fx_bit_min = 0;
         bitP->fx_bit_add = 0x03FFFFFF;
         fixP->fx_bit_fixP = bitP;
         break;
       case RELOC_DLX_LO16:
       case RELOC_DLX_REL16:
         bitP = malloc (sizeof (bit_fixS));
         bitP->fx_bit_size = 16;
         bitP->fx_bit_offset = 15;
         bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000;
         bitP->fx_bit_base_adj = 0;
         bitP->fx_bit_max = 0;
         bitP->fx_bit_min = 0;
         bitP->fx_bit_add = 0x0000FFFF;
         fixP->fx_bit_fixP = bitP;
         break;
       case RELOC_DLX_HI16:
         bitP = malloc (sizeof (bit_fixS));
         bitP->fx_bit_size = 16;
         bitP->fx_bit_offset = 15;
         bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000;
         bitP->fx_bit_base_adj = 0;
         bitP->fx_bit_max = 0;
         bitP->fx_bit_min = 0;
         bitP->fx_bit_add = 0x0000FFFF;
         fixP->fx_bit_fixP = bitP;
         break;
       default:
         fixP->fx_bit_fixP = NULL;
         break;
       }
    }
}

Here is the call graph for this function:

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

Definition at line 990 of file tc-dlx.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;

    case 'x':
    case 'X':
      prec = 6;
      break;

    case 'p':
    case 'P':
      prec = 6;
      break;

    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);

  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 272 of file tc-dlx.c.

{
  const char *retval = NULL;
  int lose = 0;
  unsigned int i;

  /* Create a new hash table.  */
  op_hash = hash_new ();

  /* Hash up all the opcodes for fast use later.  */
  for (i = 0; i < num_dlx_opcodes; i++)
    {
      const char *name = machine_opcodes[i].name;

      retval = hash_insert (op_hash, name, (void *) &machine_opcodes[i]);

      if (retval != NULL)
       {
         fprintf (stderr, "internal error: can't hash `%s': %s\n",
                 machine_opcodes[i].name, retval);
         lose = 1;
       }
    }

  if (lose)
    as_fatal (_("Broken assembler.  No assembly attempted."));

  define_some_regs ();
}

Here is the call graph for this function:

Definition at line 1051 of file tc-dlx.c.

{
  /* We need the symbol name for the VTABLE entries.  */
  return (fixP->fx_r_type != BFD_RELOC_VTABLE_INHERIT
          && fixP->fx_r_type != BFD_RELOC_VTABLE_ENTRY);
}
void md_number_to_chars ( char *  buf,
valueT  val,
int  n 
)

Definition at line 1045 of file tc-dlx.c.

Here is the call graph for this function:

void md_operand ( expressionS expressionP)

Definition at line 1201 of file tc-dlx.c.

{
  /* Check for the #number representation    */
  if (input_line_pointer[0] == '#' &&
      ISDIGIT ((unsigned char) input_line_pointer[1]))
    {
      /* We have a numeric number expression.  No biggy.  */
      input_line_pointer += 1;     /* Skip # */

      (void) expression (expressionP);

      if (expressionP->X_op != O_constant)
       as_bad (_("Invalid expression after # number\n"));
    }

  return;
}

Here is the call graph for this function:

int md_parse_option ( int c  ATTRIBUTE_UNUSED,
char *arg  ATTRIBUTE_UNUSED 
)

Definition at line 1138 of file tc-dlx.c.

{
  return 0;
}
long md_pcrel_from ( fixS *  fixP)

Definition at line 1234 of file tc-dlx.c.

{
  return 4 + fixP->fx_where + fixP->fx_frag->fr_address;
}
valueT md_section_align ( segT segment  ATTRIBUTE_UNUSED,
valueT size   
)

Definition at line 1222 of file tc-dlx.c.

{
  /* Byte alignment is fine.  */
  return size;
}
void md_show_usage ( FILE *stream  ATTRIBUTE_UNUSED)

Definition at line 1145 of file tc-dlx.c.

{
}
symbolS* md_undefined_symbol ( char *name  ATTRIBUTE_UNUSED)

Definition at line 1191 of file tc-dlx.c.

{
  return NULL;
}
static char* parse_operand ( char *  s,
expressionS operandp 
) [static]

Definition at line 594 of file tc-dlx.c.

{
  char *save = input_line_pointer;
  char *new;

  the_insn.HI = the_insn.LO = 0;

  /* Search for %hi and %lo, make a mark and skip it.  */
  if (strncmp (s, "%hi", 3) == 0)
    {
      s += 3;
      the_insn.HI = 1;
    }
  else
    {
      if (strncmp (s, "%lo", 3) == 0)
       {
         s += 3;
         the_insn.LO = 1;
       }
      else
       the_insn.LO = 0;
    }

  if (the_insn.HI || the_insn.LO)
    {
      if (!hilo_modifier_ok (s))
       as_bad (_("Expression Error for operand modifier %%hi/%%lo\n"));
    }

  /* Check for the % and $ register representation    */
  if ((s[0] == '%' || s[0] == '$' || s[0] == 'r' || s[0] == 'R')
      && ISDIGIT ((unsigned char) s[1]))
    {
      /* We have a numeric register expression.  No biggy.  */
      s += 1;
      input_line_pointer = s;
      (void) expression (operandp);
      if (operandp->X_op != O_constant
         || operandp->X_add_number > 31)
       as_bad (_("Invalid expression after %%%%\n"));
      operandp->X_op = O_register;
    }
  else
    {
      /* Normal operand parsing.  */
      input_line_pointer = s;
      (void) expression (operandp);
    }

  new = input_line_pointer;
  input_line_pointer = save;
  return new;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void s_proc ( int  end_p) [static]

Definition at line 199 of file tc-dlx.c.

{
  /* Record the current function so that we can issue an error message for
     misplaced .func,.endfunc, and also so that .endfunc needs no
     arguments.  */
  static char *current_name;
  static char *current_label;

  if (end_p)
    {
      if (current_name == NULL)
       {
         as_bad (_("missing .proc"));
         ignore_rest_of_line ();
         return;
       }

      current_name = current_label = NULL;
      SKIP_WHITESPACE ();
      while (!is_end_of_line[(unsigned char) *input_line_pointer])
        input_line_pointer++;
    }
  else
    {
      char *name, *label;
      char delim1, delim2;

      if (current_name != NULL)
       {
         as_bad (_(".endfunc missing for previous .proc"));
         ignore_rest_of_line ();
         return;
       }

      name = input_line_pointer;
      delim1 = get_symbol_end ();
      name = xstrdup (name);
      *input_line_pointer = delim1;
      SKIP_WHITESPACE ();

      if (*input_line_pointer != ',')
       {
         char leading_char = 0;

         leading_char = bfd_get_symbol_leading_char (stdoutput);
         /* Missing entry point, use function's name with the leading
            char prepended.  */
         if (leading_char)
           asprintf (&label, "%c%s", leading_char, name);
         else
           label = name;
       }
      else
       {
         ++input_line_pointer;
         SKIP_WHITESPACE ();
         label = input_line_pointer;
         delim2 = get_symbol_end ();
         label = xstrdup (label);
         *input_line_pointer = delim2;
       }

      current_name = name;
      current_label = label;
    }
  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

arelent* tc_gen_reloc ( asection *section  ATTRIBUTE_UNUSED,
fixS *  fixP 
)

Definition at line 1245 of file tc-dlx.c.

{
  arelent * reloc;

  reloc = xmalloc (sizeof (arelent));
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);

  if (reloc->howto == NULL)
    {
      as_bad_where (fixP->fx_file, fixP->fx_line,
                  "internal error: can't export reloc type %d (`%s')",
                  fixP->fx_r_type,
                  bfd_get_reloc_code_name (fixP->fx_r_type));
      return NULL;
    }

  assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);

  reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
  reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;

  if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
    reloc->address = fixP->fx_offset;
  reloc->addend = 0;

  return reloc;
}

Here is the call graph for this function:


Variable Documentation

const char comment_chars[] = ";"

Definition at line 63 of file tc-dlx.c.

const pseudo_typeS dlx_pseudo_table[]
Initial value:
{
  
  {"asciiz", stringer, 1},
  {"half", cons, 2},
  {"dword", cons, 8},
  {"word", cons, 4},
  {"proc", s_proc, 0},
  {"endproc", s_proc, 1},
  {NULL, NULL, 0}
}

Definition at line 1276 of file tc-dlx.c.

const char EXP_CHARS[] = "eE"

Definition at line 79 of file tc-dlx.c.

const char FLT_CHARS[] = "rRsSfFdDxXpP"

Definition at line 84 of file tc-dlx.c.

char iBuf[81] [static]

Definition at line 308 of file tc-dlx.c.

const char line_comment_chars[] = "#"

Definition at line 72 of file tc-dlx.c.

Definition at line 76 of file tc-dlx.c.

size_t md_longopts_size = sizeof (md_longopts)

Definition at line 1135 of file tc-dlx.c.

const char* md_shortopts = ""

Definition at line 1128 of file tc-dlx.c.

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