Back to index

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

Go to the source code of this file.

Classes

union  _maxq20_op
struct  _maxq20_insn

Defines

#define MAXQ10S   1
#define DEFAULT_ARCH   "MAXQ20"
#define PFX0   0x0b
#define LONG_PREFIX   MAXQ_LONGJUMP /* BFD_RELOC_16 */
#define SHORT_PREFIX   MAXQ_SHORTJUMP /* BFD_RELOC_16_PCREL_S2 */
#define ABSOLUTE_ADDR_FOR_DATA   MAXQ_INTERSEGMENT
#define NO_PREFIX   0
#define EXPLICT_LONG_PREFIX   14
#define OPTION_EB   (OPTION_MD_BASE + 0)
#define OPTION_EL   (OPTION_MD_BASE + 1)
#define MAXQ_10   (OPTION_MD_BASE + 2)
#define MAXQ_20   (OPTION_MD_BASE + 3)
#define MAX_LITTLENUMS   6
#define is_mnemonic_char(x)   (mnemonic_chars[(unsigned char)(x)])
#define is_register_char(x)   (register_chars[(unsigned char)(x)])
#define is_operand_char(x)   (operand_chars[(unsigned char)(x)])
#define is_space_char(x)   (x==' ')
#define is_identifier_char(x)   (identifier_chars[(unsigned char)(x)])
#define is_digit_char(x)   (identifier_chars[(unsigned char)(x)])
#define END_STRING_AND_SAVE(s)
#define RESTORE_END_STRING(s)
#define SET_PFX_ARG(x)   (PFX_INSN[1] = x)

Typedefs

typedef union _maxq20_op
typedef struct _maxq20_insn maxq20_insn

Functions

symbolS * md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
static void maxq_target (int target)
int md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
void md_show_usage (FILE *stream)
unsigned long maxq20_mach (void)
arelenttc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
int md_estimate_size_before_relax (fragS *fragP, segT segment)
char * md_atof (int type, char *litP, int *sizeP)
void maxq20_cons_fix_new (fragS *frag, unsigned int off, unsigned int len, expressionS *exp)
void md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED, fragS *fragP)
long md_pcrel_from (fixS *fixP)
void maxq_number_to_chars (char *buf, valueT val, int n)
void md_apply_fix (fixS *fixP, valueT *valT, segT seg ATTRIBUTE_UNUSED)
static void set_prefix (void)
static unsigned char is_a_LSinstr (const char *ln_pointer)
static void LS_processing (const char *line)
static char * parse_insn (char *line, char *mnemonic)
static int pwr (int x, int y)
static reg_entryparse_reg_by_index (char *imm_start)
static reg_entryparse_register (char *reg_string, char **end_op)
static reg_bitparse_register_bit (char *reg_string, char **end_op)
static void pfx_for_imm_val (int arg)
static int maxq20_immediate (char *imm_start)
static int extract_int_val (const char *imm_start)
static char check_for_parse (const char *line)
static mem_accessmaxq20_mem_access (char *mem_string, char **end_op)
static symbolS * maxq20_data (char *op_string)
static int maxq20_displacement (char *disp_start, char *disp_end)
static int maxq20_operand (char *operand_string)
static char * parse_operands (char *l, const char *mnemonic)
static int match_operands (int type, MAX_ARG_TYPE flag_type, MAX_ARG_TYPE arg_type, int op_num)
static int match_template (void)
static int match_filters (void)
static int decode_insn (void)
static void output_disp (fragS *insn_start_frag, offsetT insn_start_off)
static void output_data (fragS *insn_start_frag, offsetT insn_start_off)
static void output_insn (void)
static void make_new_reg_table (void)
static void pmmain (void)
void md_begin (void)
void md_assemble (char *line)

Variables

unsigned int max_version = bfd_mach_maxq20
const char * default_arch = DEFAULT_ARCH
const char * extra_symbol_chars = "@(#"
const char comment_chars [] = ";"
const char line_comment_chars [] = ";#"
const char line_separator_chars [] = ""
const char * md_shortopts = "q"
const char EXP_CHARS [] = "eE"
const char FLT_CHARS [] = ""
size_t md_longopts_size = sizeof (md_longopts)
static char mnemonic_chars [256]
static char register_chars [256]
static char operand_chars [256]
static char identifier_chars [256]
static char digit_chars [256]
static char operand_special_chars [] = "[]@.-+"
static char save_stack [32]
static char * save_stack_p
static maxq20_insn i
static MAXQ20_OPCODEScurrent_templates
static expressionS disp_expressions
static int this_operand
static char PFX_INSN [2]
static char INSERT_BUFFER [2]
char * input_line_pointer
static struct hash_controlop_hash
static struct hash_controlreg_hash
static struct hash_controlmem_hash
static struct hash_controlbit_hash
static struct hash_controlmem_syntax_hash
const pseudo_typeS md_pseudo_table []

Class Documentation

union _maxq20_op

Definition at line 75 of file tc-maxq.c.

Collaboration diagram for _maxq20_op:
Class Members
symbolS * data
expressionS * disps
int flag
char imms
const mem_access * mem
const reg_bit * r_bit
const reg_entry * reg
struct _maxq20_insn

Definition at line 99 of file tc-maxq.c.

Collaboration diagram for _maxq20_insn:
Class Members
unsigned int bit_operands
unsigned int data_operands
unsigned int disp_operands
unsigned int flag_operands
unsigned int imm_bit_operands
unsigned int imm_operands
unsigned char instr
unsigned char Instr_Prefix
maxq20_opcode maxq20_op
unsigned int mem_operands
MAXQ20_OPCODE_INFO op
unsigned int operands
int prefix
unsigned int reg_operands
int reloc
UNKNOWN_OP types

Define Documentation

Definition at line 93 of file tc-maxq.c.

#define DEFAULT_ARCH   "MAXQ20"

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

#define END_STRING_AND_SAVE (   s)
Value:
do                          \
    {                       \
      *save_stack_p++ = *(s);      \
      *s = '\0';            \
    }                       \
  while (0)

Definition at line 621 of file tc-maxq.c.

#define EXPLICT_LONG_PREFIX   14

Definition at line 96 of file tc-maxq.c.

#define is_digit_char (   x)    (identifier_chars[(unsigned char)(x)])

Definition at line 611 of file tc-maxq.c.

#define is_identifier_char (   x)    (identifier_chars[(unsigned char)(x)])

Definition at line 610 of file tc-maxq.c.

#define is_mnemonic_char (   x)    (mnemonic_chars[(unsigned char)(x)])

Definition at line 606 of file tc-maxq.c.

#define is_operand_char (   x)    (operand_chars[(unsigned char)(x)])

Definition at line 608 of file tc-maxq.c.

#define is_register_char (   x)    (register_chars[(unsigned char)(x)])

Definition at line 607 of file tc-maxq.c.

#define is_space_char (   x)    (x==' ')

Definition at line 609 of file tc-maxq.c.

Definition at line 91 of file tc-maxq.c.

#define MAX_LITTLENUMS   6

Definition at line 383 of file tc-maxq.c.

#define MAXQ10S   1

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

#define MAXQ_10   (OPTION_MD_BASE + 2)

Definition at line 155 of file tc-maxq.c.

#define MAXQ_20   (OPTION_MD_BASE + 3)

Definition at line 156 of file tc-maxq.c.

#define NO_PREFIX   0

Definition at line 95 of file tc-maxq.c.

#define OPTION_EB   (OPTION_MD_BASE + 0)

Definition at line 153 of file tc-maxq.c.

#define OPTION_EL   (OPTION_MD_BASE + 1)

Definition at line 154 of file tc-maxq.c.

#define PFX0   0x0b

Definition at line 66 of file tc-maxq.c.

#define RESTORE_END_STRING (   s)
Value:
do                          \
    {                       \
      *(s) = *(--save_stack_p);    \
    }                       \
  while (0)

Definition at line 629 of file tc-maxq.c.

#define SET_PFX_ARG (   x)    (PFX_INSN[1] = x)

Definition at line 683 of file tc-maxq.c.

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


Typedef Documentation

typedef union _maxq20_op

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


Function Documentation

static char check_for_parse ( const char *  line) [static]

Definition at line 1389 of file tc-maxq.c.

{
  int val;

  if (*(line + 1) == '[')
    {
      do
       {
         line++;
         if ((*line == '-') || (*line == '+'))
           break;
       }
      while (!is_space_char (*line));

      if ((*line == '-') || (*line == '+'))
       val = extract_int_val (line);
      else
       val = extract_int_val (line + 1);

      INSERT_BUFFER[0] = 0x3E;
      INSERT_BUFFER[1] = val;

      return 1;
    }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int decode_insn ( void  ) [static]

Definition at line 2462 of file tc-maxq.c.

{
  /* Check for the format Bit if defined.  */
  if (i.op.format == 0 || i.op.format == 1)
    i.instr[0] = i.op.format << 7;
  else
    {
      /* Format bit not defined. We will have to be find it out ourselves.  */
      if (i.imm_operands == 1 || i.data_operands == 1 || i.disp_operands == 1)
       i.op.format = 0;
      else
       i.op.format = 1;
      i.instr[0] = i.op.format << 7;
    }

  /* Now for the destination register.  */

  /* If destination register is already defined . The conditions are the
     following: (1) The second entry in the destination array should be 0 (2) 
     If there are two operands then the first entry should not be a register,
     memory or a register bit (3) If there are less than two operands and the
     it is not a pop operation (4) The second argument is the carry
     flag(applicable to move Acc.<b>,C.  */
  if (i.op.dst[1] == 0
      &&
      ((i.types[0] != REG && i.types[0] != MEM && i.types[0] != BIT
       && i.operands == 2) || (i.operands < 2 && strcmp (i.op.name, "POP")
                            && strcmp (i.op.name, "POPI"))
       || (i.op.arg[1] == FLAG_C)))
    {
      i.op.dst[0] &= 0x7f;
      i.instr[0] |= i.op.dst[0];
    }
  else if (i.op.dst[1] == 0 && !strcmp (i.op.name, "DJNZ")
          &&
          (((i.types[0] == REG)
            && (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]")
               || !strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]")))))
    {
      i.op.dst[0] &= 0x7f;
      if (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]"))
       i.instr[0] |= 0x4D;

      if (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]"))
       i.instr[0] |= 0x5D;
    }
  else
    {
      unsigned char temp;

      /* Target register will have to be specified.  */
      if (i.types[0] == REG
         && (i.op.dst[0] == REG || i.op.dst[0] == (REG | MEM)))
       {
         temp = (i.maxq20_op[0].reg)->opcode;
         temp &= 0x7f;
         i.instr[0] |= temp;
       }
      else if (i.types[0] == MEM && (i.op.dst[0] == (REG | MEM)))
       {
         temp = (i.maxq20_op[0].mem)->opcode;
         temp &= 0x7f;
         i.instr[0] |= temp;
       }
      else if (i.types[0] == BIT && (i.op.dst[0] == REG))
       {
         temp = (i.maxq20_op[0].r_bit)->reg->opcode;
         temp &= 0x7f;
         i.instr[0] |= temp;
       }
      else if (i.types[1] == BIT && (i.op.dst[0] == BIT))
       {
         temp = (i.maxq20_op[1].r_bit)->bit;
         temp = temp << 4;
         temp |= i.op.dst[1];
         temp &= 0x7f;
         i.instr[0] |= temp;
       }
      else
       {
         as_bad (_("Invalid Instruction"));
         return 0;
       }
    }

  /* Now for the source register.  */

  /* If Source register is already known. The following conditions are
     checked: (1) There are no operands (2) If there is only one operand and
     it is a flag (3) If the operation is MOVE C,#0/#1 (4) If it is a POP
     operation.  */

  if (i.operands == 0 || (i.operands == 1 && i.types[0] == FLAG)
      || (i.types[0] == FLAG && i.types[1] == IMMBIT)
      || !strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
    i.instr[1] = i.op.src[0];

  else if (i.imm_operands == 1 && ((i.op.src[0] & IMM) == IMM))
    i.instr[1] = i.maxq20_op[this_operand].imms;
  
  else if (i.types[this_operand] == REG && ((i.op.src[0] & REG) == REG))
    i.instr[1] = (char) ((i.maxq20_op[this_operand].reg)->opcode);

  else if (i.types[this_operand] == BIT && ((i.op.src[0] & REG) == REG))
    i.instr[1] = (char) (i.maxq20_op[this_operand].r_bit->reg->opcode);

  else if (i.types[this_operand] == MEM && ((i.op.src[0] & MEM) == MEM))
    i.instr[1] = (char) ((i.maxq20_op[this_operand].mem)->opcode);

  else if (i.types[this_operand] == DATA && ((i.op.src[0] & DATA) == DATA))
    /* This will copy only the lower order bytes into the instruction. The
       higher order bytes have already been copied into the prefix register.  */
    i.instr[1] = 0;

  /* Decoding the source in the case when the second array entry is not 0.
     This means that the source register has been divided into two nibbles.  */

  else if (i.op.src[1] != 0)
    {
      /* If the first operand is a accumulator bit then
        the first 4 bits will be filled with the bit number.  */
      if (i.types[0] == BIT && ((i.op.src[0] & BIT) == BIT))
       {
         unsigned char temp = (i.maxq20_op[0].r_bit)->bit;

         temp = temp << 4;
         temp |= i.op.src[1];
         i.instr[1] = temp;
       }
      /* In case of MOVE dst.<b>,#1 The first nibble in the source register
         has to start with a zero. This is called a ZEROBIT */
      else if (i.types[0] == BIT && ((i.op.src[0] & ZEROBIT) == ZEROBIT))
       {
         char temp = (i.maxq20_op[0].r_bit)->bit;

         temp = temp << 4;
         temp |= i.op.src[1];
         temp &= 0x7f;
         i.instr[1] = temp;
       }
      /* Similarly for a ONEBIT */
      else if (i.types[0] == BIT && ((i.op.src[0] & ONEBIT) == ONEBIT))
       {
         char temp = (i.maxq20_op[0].r_bit)->bit;

         temp = temp << 4;
         temp |= i.op.src[1];
         temp |= 0x80;
         i.instr[1] = temp;
       }
      /* In case the second operand is a register bit (MOVE C,Acc.<b> or MOVE 
         C,src.<b> */
      else if (i.types[1] == BIT)
       {
         if (i.op.src[1] == 0 && i.op.src[1] == REG)
           i.instr[1] = (i.maxq20_op[1].r_bit)->reg->opcode;

         else if (i.op.src[0] == BIT && i.op.src)
           {
             char temp = (i.maxq20_op[1].r_bit)->bit;

             temp = temp << 4;
             temp |= i.op.src[1];
             i.instr[1] = temp;
           }
       }
      else
       {
         as_bad (_("Invalid Instruction"));
         return 0;
       }
    }
  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int extract_int_val ( const char *  imm_start) [static]

Definition at line 1321 of file tc-maxq.c.

{
  int k, j, val;
  char sign_val;
  int temp[4];

  k = 0;
  j = 0;
  val = 0;
  sign_val = 0;
  do
    {
      if (imm_start[k] == '-' && k == 0)
       sign_val = -1;

      else if (imm_start[k] == '+' && k == 0)
       sign_val = 1;

      else if (isdigit (imm_start[k]))
       temp[k] = imm_start[k] - '0';

      else if (isalpha (imm_start[k]) && (tolower (imm_start[k])) < 'g')
       temp[k] = 10 + (int) (tolower (imm_start[k]) - 'a');

      else if (tolower (imm_start[k]) == 'h')
       break;

      else if ((imm_start[k] == '\0') || (imm_start[k] == ']'))
       /* imm_start[k]='d'; */
       break;

      else
       {
         as_bad (_("Invalid Character in immediate Value : %c"),
                imm_start[k]);
         return 0;
       }
      k++;
    }
  while (imm_start[k] != '\n');

  switch (imm_start[k])
    {
    case 'h':
      for (j = (sign_val ? 1 : 0); j < k; j++)
       val += temp[j] * pwr (16, k - j - 1);
      break;

    default:
      for (j = (sign_val ? 1 : 0); j < k; j++)
       {
         if (temp[j] > 9)
           {
             as_bad (_("Invalid Character in immediate value : %c"),
                    imm_start[j]);
             return 0;
           }
         val += temp[j] * pwr (10, k - j - 1);
       }
    }

  if (!sign_val)
    sign_val = 1;

  return val * sign_val;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned char is_a_LSinstr ( const char *  ln_pointer) [static]

Definition at line 787 of file tc-maxq.c.

{
  int i = 0;

  for (i = 0; LSInstr[i] != NULL; i++)
    if (!strcmp (LSInstr[i], ln_pointer))
      return 1;

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void LS_processing ( const char *  line) [static]

Definition at line 799 of file tc-maxq.c.

{
  if (is_a_LSinstr (line))
    {
      if ((line[0] == 'L') || (line[0] == 'l'))
       {
         i.prefix = 0;
         INSERT_BUFFER[0] = PFX0;
         i.Instr_Prefix = LONG_PREFIX;
       }
      else if ((line[0] == 'S') || (line[0] == 's'))
       i.Instr_Prefix = SHORT_PREFIX;
      else
       i.Instr_Prefix = NO_PREFIX;
    }
  else
    i.Instr_Prefix = LONG_PREFIX;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void make_new_reg_table ( void  ) [static]

Definition at line 2821 of file tc-maxq.c.

{
  unsigned long size_pm = sizeof (peripheral_reg_table);
  num_of_reg = ARRAY_SIZE (peripheral_reg_table);

  new_reg_table = xmalloc (size_pm);
  if (new_reg_table == NULL)
    as_bad (_("Cannot allocate memory"));

  memcpy (new_reg_table, peripheral_reg_table, size_pm);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int match_filters ( void  ) [static]

Definition at line 2056 of file tc-maxq.c.

{
  /* Now we have at our disposal the instruction i. We will be using the
     following fields i.op.name : This is the mnemonic name. i.types[2] :
     These are the types of the operands (REG/IMM/DISP/MEM/BIT/FLAG/IMMBIT)
     i.maxq20_op[2] : This contains the specific info of the operands.  */

  /* Our first filter : NO ALU OPERATIONS CAN HAVE THE ACTIVE ACCUMULATOR AS
     SOURCE.  */
  if (!strcmp (i.op.name, "AND") || !strcmp (i.op.name, "OR")
      || !strcmp (i.op.name, "XOR") || !strcmp (i.op.name, "ADD")
      || !strcmp (i.op.name, "ADDC") || !strcmp (i.op.name, "SUB")
      || !strcmp (i.op.name, "SUBB"))
    {
      if (i.types[0] == REG)
       {
         if (i.maxq20_op[0].reg->Mod_name == 0xa)
           {
             as_bad (_
                    ("The Accumulator cannot be used as a source in ALU instructions\n"));
             return 0;
           }
       }
    }

  if (!strcmp (i.op.name, "MOVE") && (i.types[0] == MEM || i.types[1] == MEM)
      && i.operands == 2)
    {
      mem_access_syntax *mem_op = NULL;

      if (i.types[0] == MEM)
       {
         mem_op =
           (mem_access_syntax *) hash_find (mem_syntax_hash,
                                        i.maxq20_op[0].mem->name);
         if ((mem_op->type == SRC) && mem_op)
           {
             as_bad (_("'%s' operand cant be used as destination in %s"),
                    mem_op->name, i.op.name);
             return 0;
           }
         else if ((mem_op->invalid_op != NULL) && (i.types[1] == MEM)
                 && mem_op)
           {
             int k = 0;

             for (k = 0; k < 5 || !mem_op->invalid_op[k]; k++)
              {
                if (mem_op->invalid_op[k] != NULL)
                  if (!strcmp
                     (mem_op->invalid_op[k], i.maxq20_op[1].mem->name))
                    {
                     as_bad (_
                            ("Invalid Instruction '%s' operand cant be used with %s"),
                            mem_op->name, i.maxq20_op[1].mem->name);
                     return 0;
                    }
              }
           }
       }

      if (i.types[1] == MEM)
       {
         mem_op = NULL;
         mem_op =
           (mem_access_syntax *) hash_find (mem_syntax_hash,
                                        i.maxq20_op[1].mem->name);
         if (mem_op->type == DST && mem_op)
           {
             as_bad (_("'%s' operand cant be used as source in %s"),
                    mem_op->name, i.op.name);
             return 0;
           }
         else if (mem_op->invalid_op != NULL && i.types[0] == MEM && mem_op)
           {
             int k = 0;

             for (k = 0; k < 5 || !mem_op->invalid_op[k]; k++)
              {
                if (mem_op->invalid_op[k] != NULL)
                  if (!strcmp
                     (mem_op->invalid_op[k], i.maxq20_op[0].mem->name))
                    {
                     as_bad (_
                            ("Invalid Instruction '%s' operand cant be used with %s"),
                            mem_op->name, i.maxq20_op[0].mem->name);
                     return 0;
                    }
              }
           }
         else if (i.types[0] == REG
                 && !strcmp (i.maxq20_op[0].reg->reg_name, "OFFS")
                 && mem_op)
           {
             if (!strcmp (mem_op->name, "@BP[OFFS--]")
                || !strcmp (mem_op->name, "@BP[OFFS++]"))
              {
                as_bad (_
                       ("Invalid Instruction '%s' operand cant be used with %s"),
                       mem_op->name, i.maxq20_op[0].mem->name);
                return 0;
              }
           }
       }
    }

  /* Added for SRC and DST in one operand instructioni i.e OR @--DP[1] added
     on 10-March-2004.  */
  if ((i.types[0] == MEM) && (i.operands == 1)
      && !(!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI")))
    {
      mem_access_syntax *mem_op = NULL;

      if (i.types[0] == MEM)
       {
         mem_op =
           (mem_access_syntax *) hash_find (mem_syntax_hash,
                                        i.maxq20_op[0].mem->name);
         if (mem_op->type == DST && mem_op)
           {
             as_bad (_("'%s' operand cant be used as source in %s"),
                    mem_op->name, i.op.name);
             return 0;
           }
       }
    }

  if (i.operands == 2 && i.types[0] == IMM)
    {
      as_bad (_("'%s' instruction cant have first operand as Immediate vale"),
             i.op.name);
      return 0;
    }

  /* Our second filter : SP or @SP-- cannot be used with PUSH or POP */
  if (!strcmp (i.op.name, "PUSH") || !strcmp (i.op.name, "POP")
      || !strcmp (i.op.name, "POPI"))
    {
      if (i.types[0] == REG)
       {
         if (!strcmp (i.maxq20_op[0].reg->reg_name, "SP"))
           {
             as_bad (_("SP cannot be used with %s\n"), i.op.name);
             return 0;
           }
       }
      else if (i.types[0] == MEM
              && !strcmp (i.maxq20_op[0].mem->name, "@SP--"))
       {
         as_bad (_("@SP-- cannot be used with PUSH\n"));
         return 0;
       }
    }

  /* This filter checks that two memory references using DP's cannot be used
     together in an instruction */
  if (!strcmp (i.op.name, "MOVE") && i.mem_operands == 2)
    {
      if (strlen (i.maxq20_op[0].mem->name) != 6 ||
         strcmp (i.maxq20_op[0].mem->name, i.maxq20_op[1].mem->name))
       {
         if (!strncmp (i.maxq20_op[0].mem->name, "@DP", 3)
             && !strncmp (i.maxq20_op[1].mem->name, "@DP", 3))
           {
             as_bad (_
                    ("Operands either contradictory or use the data bus in read/write state together"));
             return 0;
           }

         if (!strncmp (i.maxq20_op[0].mem->name, "@SP", 3)
             && !strncmp (i.maxq20_op[1].mem->name, "@SP", 3))
           {
             as_bad (_
                    ("Operands either contradictory or use the data bus in read/write state together"));
             return 0;
           }
       }
      if ((i.maxq20_op[1].mem != NULL)
         && !strncmp (i.maxq20_op[1].mem->name, "NUL", 3))
       {
         as_bad (_("MOVE Cant Use NUL as SRC"));
         return 0;
       }
    }

  /* This filter checks that contradictory movement between DP register and
     Memory access using DP followed by increment or decrement.  */

  if (!strcmp (i.op.name, "MOVE") && i.mem_operands == 1
      && i.reg_operands == 1)
    {
      int memnum, regnum;

      memnum = (i.types[0] == MEM) ? 0 : 1;
      regnum = (memnum == 0) ? 1 : 0;
      if (!strncmp (i.maxq20_op[regnum].reg->reg_name, "DP", 2) &&
         !strncmp ((i.maxq20_op[memnum].mem->name) + 1,
                  i.maxq20_op[regnum].reg->reg_name, 5)
         && strcmp ((i.maxq20_op[memnum].mem->name) + 1,
                   i.maxq20_op[regnum].reg->reg_name))
       {
         as_bad (_
                ("Contradictory movement between DP register and memory access using DP"));
         return 0;
       }
      else if (!strcmp (i.maxq20_op[regnum].reg->reg_name, "SP") &&
              !strncmp ((i.maxq20_op[memnum].mem->name) + 1,
                      i.maxq20_op[regnum].reg->reg_name, 2))
       {
         as_bad (_
                ("SP and @SP-- cannot be used together in a move instruction"));
         return 0;
       }
    }

  /* This filter restricts the instructions containing source and destination 
     bits to only CTRL module of the serial registers. Peripheral registers
     yet to be defined.  */

  if (i.bit_operands == 1 && i.operands == 2)
    {
      int bitnum = (i.types[0] == BIT) ? 0 : 1;

      if (strcmp (i.maxq20_op[bitnum].r_bit->reg->reg_name, "ACC"))
       {
         if (i.maxq20_op[bitnum].r_bit->reg->Mod_name >= 0x7 &&
             i.maxq20_op[bitnum].r_bit->reg->Mod_name != CTRL)
           {
             as_bad (_
                    ("Only Module 8 system registers allowed in this operation"));
             return 0;
           }
       }
    }

  /* This filter is for checking the register bits.  */
  if (i.bit_operands == 1 || i.operands == 2)
    {
      int bitnum = 0, size = 0;

      bitnum = (i.types[0] == BIT) ? 0 : 1;
      if (i.bit_operands == 1)
       {
         switch (i.maxq20_op[bitnum].r_bit->reg->rtype)
           {
           case Reg_8W:
             size = 7;             /* 8 bit register, both read and write.  */
             break;
           case Reg_16W:
             size = 15;
             break;
           case Reg_8R:
             size = 7;
             if (bitnum == 0)
              {
                as_fatal (_("Read only Register used as destination"));
                return 0;
              }
             break;

           case Reg_16R:
             size = 15;
             if (bitnum == 0)
              {
                as_fatal (_("Read only Register used as destination"));
                return 0;
              }
             break;
           }

         if (size < (i.maxq20_op[bitnum].r_bit)->bit)
           {
             as_bad (_("Bit No '%d'exceeds register size in this operation"),
                    (i.maxq20_op[bitnum].r_bit)->bit);
             return 0;
           }
       }

      if (i.bit_operands == 2)
       {
         switch ((i.maxq20_op[0].r_bit)->reg->rtype)
           {
           case Reg_8W:
             size = 7;             /* 8 bit register, both read and write.  */
             break;
           case Reg_16W:
             size = 15;
             break;
           case Reg_8R:
           case Reg_16R:
             as_fatal (_("Read only Register used as destination"));
             return 0;
           }

         if (size < (i.maxq20_op[0].r_bit)->bit)
           {
             as_bad (_
                    ("Bit No '%d' exceeds register size in this operation"),
                    (i.maxq20_op[0].r_bit)->bit);
             return 0;
           }

         size = 0;
         switch ((i.maxq20_op[1].r_bit)->reg->rtype)
           {
           case Reg_8R:
           case Reg_8W:
             size = 7;             /* 8 bit register, both read and write.  */
             break;
           case Reg_16R:
           case Reg_16W:
             size = 15;
             break;
           }

         if (size < (i.maxq20_op[1].r_bit)->bit)
           {
             as_bad (_
                    ("Bit No '%d' exceeds register size in this operation"),
                    (i.maxq20_op[1].r_bit)->bit);
             return 0;
           }
       }
    }

  /* No branch operations should occur into the data memory. Hence any memory 
     references have to be filtered out when used with instructions like
     jump, djnz[] and call.  */

  if (!strcmp (i.op.name, "JUMP") || !strcmp (i.op.name, "CALL")
      || !strncmp (i.op.name, "DJNZ", 4))
    {
      if (i.mem_operands)
       as_warn (_
               ("Memory References cannot be used with branching operations\n"));
    }

  if (!strcmp (i.op.name, "DJNZ"))
    {
      if (!
         (strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]")
          || strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]")))
       {
         as_bad (_("DJNZ uses only LC[n] register \n"));
         return 0;
       }
    }

  /* No destination register used should be read only!  */
  if ((i.operands == 2 && i.types[0] == REG) || !strcmp (i.op.name, "POP")
      || !strcmp (i.op.name, "POPI"))
    {                       /* The destination is a register */
      int regnum = 0;

      if (!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
       {
         regnum = 0;

         if (i.types[regnum] == MEM)
           {
             mem_access_syntax *mem_op = NULL;

             mem_op =
              (mem_access_syntax *) hash_find (mem_syntax_hash,
                                           i.maxq20_op[regnum].mem->
                                           name);
             if (mem_op->type == SRC && mem_op)
              {
                as_bad (_
                       ("'%s' operand cant be used as destination  in %s"),
                       mem_op->name, i.op.name);
                return 0;
              }
           }
       }

      if (i.maxq20_op[regnum].reg->rtype == Reg_8R
         || i.maxq20_op[regnum].reg->rtype == Reg_16R)
       {
         as_bad (_("Read only register used for writing purposes '%s'"),
                i.maxq20_op[regnum].reg->reg_name);
         return 0;
       }
    }

  /* While moving the address of a data in the data section, the destination
     should be either data pointers only.  */
  if ((i.data_operands) && (i.operands == 2))
    {
      if ((i.types[0] != REG) && (i.types[0] != MEM))
       {
         as_bad (_("Invalid destination for this kind of source."));
         return 0;
       }

       if (i.types[0] == REG && i.maxq20_op[0].reg->rtype == Reg_8W)
         {
           as_bad (_
                  ("Invalid register as destination for this kind of source.Only data pointers can be used."));
           return 0;
         }
    }
  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int match_operands ( int  type,
MAX_ARG_TYPE  flag_type,
MAX_ARG_TYPE  arg_type,
int  op_num 
) [static]

Definition at line 1953 of file tc-maxq.c.

{
  switch (type)
    {
    case REG:
      if ((arg_type & A_REG) == A_REG)
       return 1;
      break;
    case IMM:
      if ((arg_type & A_IMM) == A_IMM)
       return 1;
      break;
    case IMMBIT:
      if ((arg_type & A_BIT_0) == A_BIT_0 && (i.maxq20_op[op_num].imms == 0))
       return 1;
      else if ((arg_type & A_BIT_1) == A_BIT_1
              && (i.maxq20_op[op_num].imms == 1))
       return 1;
      break;
    case MEM:
      if ((arg_type & A_MEM) == A_MEM)
       return 1;
      break;

    case FLAG:
      if ((arg_type & flag_type) == flag_type)
       return 1;

      break;

    case BIT:
      if ((arg_type & ACC_BIT) == ACC_BIT && !strcmp (i.maxq20_op[op_num].r_bit->reg->reg_name, "ACC"))
       return 1;
      else if ((arg_type & SRC_BIT) == SRC_BIT && (op_num == 1))
       return 1;
      else if ((op_num == 0) && (arg_type & DST_BIT) == DST_BIT)
       return 1;
      break;
    case DISP:
      if ((arg_type & A_DISP) == A_DISP)
       return 1;
    case DATA:
      if ((arg_type & A_DATA) == A_DATA)
       return 1;
    case BIT_BUCKET:
      if ((arg_type & A_BIT_BUCKET) == A_BIT_BUCKET)
       return 1;
    }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int match_template ( void  ) [static]

Definition at line 2006 of file tc-maxq.c.

{
  /* Points to template once we've found it.  */
  const MAXQ20_OPCODE_INFO *t;
  char inv_oper;
  inv_oper = 0;

  for (t = current_templates->start; t < current_templates->end; t++)
    {
      /* Must have right number of operands.  */
      if (i.operands != t->op_number)
       continue;
      else if (!t->op_number)
       break;

      switch (i.operands)
       {
       case 2:
         if (!match_operands (i.types[1], i.maxq20_op[1].flag, t->arg[1], 1))
           {
             inv_oper = 1;
             continue;
           }
       case 1:
         if (!match_operands (i.types[0], i.maxq20_op[0].flag, t->arg[0], 0))
           {
             inv_oper = 2;
             continue;
           }
       }
      break;
    }

  if (t == current_templates->end)
    {
      /* We found no match.  */
      as_bad (_("operand %d is invalid for `%s'"),
             inv_oper, current_templates->start->name);
      return 0;
    }

  /* Copy the template we have found.  */
  i.op = *t;
  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maxq20_cons_fix_new ( fragS *  frag,
unsigned int  off,
unsigned int  len,
expressionS exp 
)

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

{
  int r = 0;

  switch (len)
    {
    case 2:
      r = MAXQ_WORDDATA;    /* Word+n */
      break;
    case 4:
      r = MAXQ_LONGDATA;    /* Long+n */
      break;
    }

  fix_new_exp (frag, off, len, exp, 0, r);
  return;
}

Here is the call graph for this function:

static symbolS* maxq20_data ( char *  op_string) [static]

Definition at line 1450 of file tc-maxq.c.

{
  symbolS *symbolP;
  symbolP = symbol_find (op_string);

  if (symbolP != NULL
      && S_GET_SEGMENT (symbolP) != now_seg
      && S_GET_SEGMENT (symbolP) != bfd_und_section_ptr)
    {
      /* In case we do not want to always include the prefix instruction and
         let the loader handle the job or in case of a 8 bit addressing mode, 
         we will just check for val_pfx to be equal to zero and then load the 
         prefix instruction. Otherwise no prefix instruction needs to be
         loaded.  */
      /* The prefix register will have to be loaded automatically as we have 
        a 16 bit addressing field.  */
      pfx_for_imm_val (0);
      return symbolP;
    }

  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int maxq20_displacement ( char *  disp_start,
char *  disp_end 
) [static]

Definition at line 1474 of file tc-maxq.c.

{
  expressionS *exp;
  segT exp_seg = 0;
  char *save_input_line_pointer;
#ifndef LEX_AT
  char *gotfree_input_line;
#endif

  gotfree_input_line = NULL;
  exp = &disp_expressions;
  i.maxq20_op[this_operand].disps = exp;
  i.disp_operands++;
  save_input_line_pointer = input_line_pointer;
  input_line_pointer = disp_start;

  END_STRING_AND_SAVE (disp_end);

#ifndef LEX_AT
  /* gotfree_input_line = lex_got (&i.reloc[this_operand], NULL); if
     (gotfree_input_line) input_line_pointer = gotfree_input_line; */
#endif
  exp_seg = expression (exp);

  SKIP_WHITESPACE ();
  if (*input_line_pointer)
    as_bad (_("junk `%s' after expression"), input_line_pointer);
#if GCC_ASM_O_HACK
  RESTORE_END_STRING (disp_end + 1);
#endif
  RESTORE_END_STRING (disp_end);
  input_line_pointer = save_input_line_pointer;
#ifndef LEX_AT
  if (gotfree_input_line)
    free (gotfree_input_line);
#endif
  if (exp->X_op == O_absent || exp->X_op == O_big)
    {
      /* Missing or bad expr becomes absolute 0.  */
      as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
             disp_start);
      exp->X_op = O_constant;
      exp->X_add_number = 0;
      exp->X_add_symbol = (symbolS *) 0;
      exp->X_op_symbol = (symbolS *) 0;
    }
#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))

  if (exp->X_op != O_constant
      && OUTPUT_FLAVOR == bfd_target_aout_flavour
      && exp_seg != absolute_section
      && exp_seg != text_section
      && exp_seg != data_section
      && exp_seg != bss_section && exp_seg != undefined_section
      && !bfd_is_com_section (exp_seg))
    {
      as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
      return 0;
    }
#endif
  i.maxq20_op[this_operand].disps = exp;
  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int maxq20_immediate ( char *  imm_start) [static]

Definition at line 1126 of file tc-maxq.c.

{
  int val = 0, val_pfx = 0;
  char sign_val = 0;
  int k = 0, j;
  int temp[4] = { 0 };

  imm_start++;

  if (imm_start[1] == '\0' && (imm_start[0] == '0' || imm_start[0] == '1')
      && (this_operand == 1 && ((i.types[0] == BIT || i.types[0] == FLAG))))
    {
      val = imm_start[0] - '0';
      i.imm_bit_operands++;
      i.types[this_operand] = IMMBIT;
      i.maxq20_op[this_operand].imms = (char) val;
#if CHANGE_PFX
      if (i.prefix == 2)
       pfx_for_imm_val (0);
#endif
      return 1;
    }

  /* Check For Sign Character.  */
  sign_val = 0;

  do
    {
      if (imm_start[k] == '-' && k == 0)
       sign_val = -1;

      else if (imm_start[k] == '+' && k == 0)
       sign_val = 1;

      else if (isdigit (imm_start[k]))
       temp[k] = imm_start[k] - '0';

      else if (isalpha (imm_start[k])
              && (imm_start[k] = tolower (imm_start[k])) < 'g')
       temp[k] = 10 + (int) (imm_start[k] - 'a');

      else if (imm_start[k] == 'h')
       break;

      else if (imm_start[k] == '\0')
       {
         imm_start[k] = 'd';
         break;
       }
      else
       {
         as_bad (_("Invalid Character in immediate Value : %c"),
                imm_start[k]);
         return 0;
       }
      k++;
    }
  while (imm_start[k] != '\n');

  switch (imm_start[k])
    {
    case 'h':
      for (j = (sign_val ? 1 : 0); j < k; j++)
       val += temp[j] * pwr (16, k - j - 1);
      break;

    case 'd':
      for (j = (sign_val ? 1 : 0); j < k; j++)
       {
         if (temp[j] > 9)
           {
             as_bad (_("Invalid Character in immediate value : %c"),
                    imm_start[j]);
             return 0;
           }
         val += temp[j] * pwr (10, k - j - 1);
       }
    }

  if (!sign_val)
    sign_val = 1;

  /* Now over here the value val stores the 8 bit/16 bit value. We will put a 
     check if we are moving a 16 bit immediate value into an 8 bit register. 
     In that case we will generate a warning and move only the lower 8 bits */
  if (val > 65535)
    {
      as_bad (_("Immediate value greater than 16 bits"));
      return 0;
    }

  val = val * sign_val;

  /* If it is a stack pointer and the value is greater than the maximum
     permissible size */
  if (this_operand == 1)
    {
      if ((val * sign_val) > MAX_STACK && i.types[0] == REG
         && !strcmp (i.maxq20_op[0].reg->reg_name, "SP"))
       {
         as_warn (_
                 ("Attempt to move a value in the stack pointer greater than the size of the stack"));
         val = val & MAX_STACK;
       }

      /* Check the range for 8 bit registers.  */
      else if (((val * sign_val) > 0xFF) && (i.types[0] == REG)
              && (i.maxq20_op[0].reg->rtype == Reg_8W))
       {
         as_warn (_
                 ("Attempt to move 16 bit value into an 8 bit register.Truncating..\n"));
         val = val & 0xfe;
       }

      else if (((sign_val == -1) || (val > 0xFF)) && (i.types[0] == REG)
              && (i.maxq20_op[0].reg->rtype == Reg_8W))
       {
         val_pfx = val >> 8;
         val = ((val) & 0x00ff);
         SET_PFX_ARG (val_pfx);
         i.maxq20_op[this_operand].imms = (char) val;
       }

      else if ((val <= 0xff) && (i.types[0] == REG)
              && (i.maxq20_op[0].reg->rtype == Reg_8W))
       i.maxq20_op[this_operand].imms = (char) val;


      /* Check for 16 bit registers.  */
      else if (((sign_val == -1) || val > 0xFE) && i.types[0] == REG
              && i.maxq20_op[0].reg->rtype == Reg_16W)
       {
         /* Add PFX for any negative value -> 16bit register.  */
         val_pfx = val >> 8;
         val = ((val) & 0x00ff);
         SET_PFX_ARG (val_pfx);
         i.maxq20_op[this_operand].imms = (char) val;
       }

      else if (val < 0xFF && i.types[0] == REG
              && i.maxq20_op[0].reg->rtype == Reg_16W)
       {
         i.maxq20_op[this_operand].imms = (char) val;
       }

      /* All the immediate memory access - no PFX.  */
      else if (i.types[0] == MEM)
       {
         if ((sign_val == -1) || val > 0xFE)
           {
             val_pfx = val >> 8;
             val = ((val) & 0x00ff);
             SET_PFX_ARG (val_pfx);
             i.maxq20_op[this_operand].imms = (char) val;
           }
         else
           i.maxq20_op[this_operand].imms = (char) val;
       }

      /* Special handling for immediate jumps like jump nz, #03h etc.  */
      else if (val < 0xFF && i.types[0] == FLAG)
       i.maxq20_op[this_operand].imms = (char) val;

      else if ((((sign_val == -1) || val > 0xFE)) && i.types[0] == FLAG)
       {
         val_pfx = val >> 8;
         val = ((val) & 0x00ff);
         SET_PFX_ARG (val_pfx);
         i.maxq20_op[this_operand].imms = (char) val;
       }
      else
       {
         as_bad (_("Invalid immediate move operation"));
         return 0;
       }
    }
  else
    {
      /* All the instruction with operation on ACC: like ADD src, etc.  */
      if ((sign_val == -1) || val > 0xFE)
       {
         val_pfx = val >> 8;
         val = ((val) & 0x00ff);
         SET_PFX_ARG (val_pfx);
         i.maxq20_op[this_operand].imms = (char) val;
       }
      else
       i.maxq20_op[this_operand].imms = (char) val;
    }

  i.imm_operands++;
  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 218 of file tc-maxq.c.

{
  if (!(strcmp (default_arch, "MAXQ20")))
    return 0;

  as_fatal (_("Unknown architecture"));
  return 1;
}

Here is the call graph for this function:

static mem_access* maxq20_mem_access ( char *  mem_string,
char **  end_op 
) [static]

Definition at line 1418 of file tc-maxq.c.

{
  char *s = mem_string;
  char *p;
  char mem_name_given[MAX_MEM_NAME_SIZE + 1];
  mem_access *m;

  m = NULL;

  /* Skip possible whitespace.  */
  if (is_space_char (*s))
    ++s;

  p = mem_name_given;
  while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
    {
      if (p >= mem_name_given + MAX_MEM_NAME_SIZE)
       return (mem_access *) NULL;
      s++;
    }

  *end_op = s;

  m = (mem_access *) hash_find (mem_hash, mem_name_given);

  return m;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int maxq20_operand ( char *  operand_string) [static]

Definition at line 1542 of file tc-maxq.c.

{
  reg_entry *r = NULL;
  reg_bit *rb = NULL;
  mem_access *m = NULL;
  char *end_op = NULL;
  symbolS *sym = NULL;
  char *base_string = NULL;
  int ii = 0;
  /* Start and end of displacement string expression (if found).  */
  char *displacement_string_start = NULL;
  char *displacement_string_end = NULL;
  /* This maintains the  case sentivness.  */
  char case_str_op_string[MAX_OPERAND_SIZE + 1];
  char str_op_string[MAX_OPERAND_SIZE + 1];
  char *org_case_op_string = case_str_op_string;
  char *op_string = str_op_string;

  
  memset (op_string, END_OF_INSN, (MAX_OPERAND_SIZE + 1));
  memset (org_case_op_string, END_OF_INSN, (MAX_OPERAND_SIZE + 1));

  memcpy (op_string, operand_string, strlen (operand_string) + 1);
  memcpy (org_case_op_string, operand_string, strlen (operand_string) + 1);

  ii = strlen (operand_string) + 1;

  if (ii > MAX_OPERAND_SIZE)
    {
      as_bad (_("Size of Operand '%s' greater than %d"), op_string,
             MAX_OPERAND_SIZE);
      return 0;
    }

  while (ii)
    {
      op_string[ii - 1] = toupper ((char) op_string[ii - 1]);
      ii--;
    }

  if (is_space_char (*op_string))
    ++op_string;

  if (isxdigit (operand_string[0]))
    {
      /* Now the operands can start with an Integer.  */
      r = parse_reg_by_index (op_string);
      if (r != NULL)
       {
         if (is_space_char (*op_string))
           ++op_string;
         i.types[this_operand] = REG;     /* Set the type.  */
         i.maxq20_op[this_operand].reg = r;      /* Set the Register value.  */
         i.reg_operands++;
         return 1;
       }

      /* Get the original string.  */
      memcpy (op_string, operand_string, strlen (operand_string) + 1);
      ii = strlen (operand_string) + 1;

      while (ii)
       {
         op_string[ii - 1] = toupper ((char) op_string[ii - 1]);
         ii--;
       }
    }

  /* Check for flags.  */
  if (!strcmp (op_string, "Z"))
    {
      if (is_space_char (*op_string))
       ++op_string;

      i.types[this_operand] = FLAG;              /* Set the type.  */
      i.maxq20_op[this_operand].flag = FLAG_Z;   /* Set the Register value.  */

      i.flag_operands++;

      return 1;
    }

  else if (!strcmp (op_string, "NZ"))
    {
      if (is_space_char (*op_string))
       ++op_string;

      i.types[this_operand] = FLAG;              /* Set the type.  */
      i.maxq20_op[this_operand].flag = FLAG_NZ;  /* Set the Register value.  */
      i.flag_operands++;
      return 1;
    }

  else if (!strcmp (op_string, "NC"))
    {
      if (is_space_char (*op_string))
       ++op_string;

      i.types[this_operand] = FLAG;              /* Set the type.  */
      i.maxq20_op[this_operand].flag = FLAG_NC;  /* Set the Register value.  */
      i.flag_operands++;
      return 1;
    }

  else if (!strcmp (op_string, "E"))
    {
      if (is_space_char (*op_string))
       ++op_string;

      i.types[this_operand] = FLAG;              /* Set the type.  */
      i.maxq20_op[this_operand].flag = FLAG_E;   /* Set the Register value.  */

      i.flag_operands++;

      return 1;
    }

  else if (!strcmp (op_string, "S"))
    {
      if (is_space_char (*op_string))
       ++op_string;

      i.types[this_operand] = FLAG;       /* Set the type.  */
      i.maxq20_op[this_operand].flag = FLAG_S;   /* Set the Register value.  */

      i.flag_operands++;

      return 1;
    }

  else if (!strcmp (op_string, "C"))
    {
      if (is_space_char (*op_string))
       ++op_string;

      i.types[this_operand] = FLAG;       /* Set the type.  */
      i.maxq20_op[this_operand].flag = FLAG_C;   /* Set the Register value.  */

      i.flag_operands++;

      return 1;
    }

  else if (!strcmp (op_string, "NE"))
    {

      if (is_space_char (*op_string))
       ++op_string;

      i.types[this_operand] = FLAG;       /* Set the type.  */

      i.maxq20_op[this_operand].flag = FLAG_NE;  /* Set the Register value.  */

      i.flag_operands++;

      return 1;
    }

  /* CHECK FOR REGISTER BIT */
  else if ((rb = parse_register_bit (op_string, &end_op)) != NULL)
    {
      op_string = end_op;

      if (is_space_char (*op_string))
       ++op_string;

      i.types[this_operand] = BIT;

      i.maxq20_op[this_operand].r_bit = rb;

      i.bit_operands++;

      return 1;
    }

  else if (*op_string == IMMEDIATE_PREFIX)       /* FOR IMMEDITE.  */
    {
      if (is_space_char (*op_string))
       ++op_string;

      i.types[this_operand] = IMM;

      if (!maxq20_immediate (op_string))
       {
         as_bad (_("illegal immediate operand '%s'"), op_string);
         return 0;
       }
      return 1;
    }

  else if (*op_string == ABSOLUTE_PREFIX || !strcmp (op_string, "NUL"))
    {
     if (is_space_char (*op_string))
       ++op_string;

      /* For new requiremnt of copiler of for, @(BP,cons).  */
      if (check_for_parse (op_string))
       {
         memset (op_string, '\0', strlen (op_string) + 1);
         memcpy (op_string, "@BP[OFFS]\0", 11);
       }

      i.types[this_operand] = MEM;

      if ((m = maxq20_mem_access (op_string, &end_op)) == NULL)
       {
         as_bad (_("Invalid operand for memory access '%s'"), op_string);
         return 0;
       }
      i.maxq20_op[this_operand].mem = m;

      i.mem_operands++;

      return 1;
    }

  else if ((r = parse_register (op_string, &end_op)) != NULL)  /* Check for register.  */
    {
      op_string = end_op;

      if (is_space_char (*op_string))
       ++op_string;

      i.types[this_operand] = REG; /* Set the type.  */
      i.maxq20_op[this_operand].reg = r;  /* Set the Register value.  */
      i.reg_operands++;
      return 1;
    }

  if (this_operand == 1)
    {
      /* Changed for orginal case of data refrence on 30 Nov 2003.  */
      /* The operand can either be a data reference or a symbol reference.  */
      if ((sym = maxq20_data (org_case_op_string)) != NULL)    /* Check for data memory.  */
       {
         while (is_space_char (*op_string))
           ++op_string;

         /* Set the type of the operand.  */
         i.types[this_operand] = DATA;

         /* Set the value of the data.  */
         i.maxq20_op[this_operand].data = sym;
         i.data_operands++;

         return 1;
       }

      else if (is_digit_char (*op_string) || is_identifier_char (*op_string))
       {
         /* This is a memory reference of some sort. char *base_string;
            Start and end of displacement string expression (if found). char 
            *displacement_string_start; char *displacement_string_end.  */
         base_string = org_case_op_string + strlen (org_case_op_string);

         --base_string;
         if (is_space_char (*base_string))
           --base_string;

         /* If we only have a displacement, set-up for it to be parsed
            later.  */
         displacement_string_start = org_case_op_string;
         displacement_string_end = base_string + 1;
         if (displacement_string_start != displacement_string_end)
           {
             if (!maxq20_displacement (displacement_string_start,
                                   displacement_string_end))
              {
                as_bad (_("illegal displacement operand "));
                return 0;
              }
             /* A displacement operand found.  */
             i.types[this_operand] = DISP;       /* Set the type.  */
             return 1;
           }
       }
    }
  
  /* Check for displacement.  */
  else if (is_digit_char (*op_string) || is_identifier_char (*op_string))
    {
      /* This is a memory reference of some sort. char *base_string;
         Start and end of displacement string expression (if found). char
         *displacement_string_start; char *displacement_string_end;  */
      base_string = org_case_op_string + strlen (org_case_op_string);

      --base_string;
      if (is_space_char (*base_string))
       --base_string;

      /* If we only have a displacement, set-up for it to be parsed later.  */
      displacement_string_start = org_case_op_string;
      displacement_string_end = base_string + 1;
      if (displacement_string_start != displacement_string_end)
       {
         if (!maxq20_displacement (displacement_string_start,
                                displacement_string_end))
           return 0;
         /* A displacement operand found.  */
         i.types[this_operand] = DISP;    /* Set the type.  */
       }
    }
  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 536 of file tc-maxq.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void maxq_target ( int  target) [static]

Definition at line 175 of file tc-maxq.c.

Here is the caller graph for this function:

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

Definition at line 552 of file tc-maxq.c.

{
  char *p = fixP->fx_frag->fr_literal + fixP->fx_where;
  char *frag_to_fix_at =
    fixP->fx_frag->fr_literal + fixP->fx_frag->fr_fix - 2;

  if (fixP)
    {
      if (fixP->fx_frag && valT)
       {
         /* If the relaxation substate is not defined we make it equal
            to the kind of relocation the fixup is generated for.  */
         if (!fixP->fx_frag->fr_subtype)
           fixP->fx_frag->fr_subtype = fixP->fx_r_type;

         /* For any instruction in which either we have specified an
            absolute address or it is a long jump we need to add a PFX0
            instruction to it. In this case as the instruction has already
            being written at 'fx_where' in the frag we copy it at the end of 
            the frag(which is where the relocation was generated) as when
            the relocation is generated the frag is grown by 2 type, this is 
            where we copy the contents of fx_where and add a pfx0 at
            fx_where.  */
         if ((fixP->fx_frag->fr_subtype == ABSOLUTE_ADDR_FOR_DATA)
             || (fixP->fx_frag->fr_subtype == LONG_PREFIX))
           {
             *(frag_to_fix_at + 1) = *(p + 1);
             maxq_number_to_chars (p + 1, PFX0, 1);
           }

         /* Remember value for tc_gen_reloc.  */
         fixP->fx_addnumber = *valT;
       }

      /* Some fixups generated by GAS which gets resovled before this this
         func. is called need to be wriiten to the frag as here we are going
         to go away with the relocations fx_done=1.  */
      if (fixP->fx_addsy == NULL)
       {
         maxq_number_to_chars (p, *valT, fixP->fx_size);
         fixP->fx_addnumber = *valT;
         fixP->fx_done = 1;
       }
    }
}

Here is the call graph for this function:

void md_assemble ( char *  line)

Definition at line 3057 of file tc-maxq.c.

{
  int j;

  char mnemonic[MAX_MNEM_SIZE];
  char temp4prev[256];
  static char prev_insn[256];

  /* Initialize globals.  */
  memset (&i, '\0', sizeof (i));
  for (j = 0; j < MAX_OPERANDS; j++)
    i.reloc[j] = NO_RELOC;

  i.prefix = -1;
  PFX_INSN[0] = 0;
  PFX_INSN[1] = 0;
  INSERT_BUFFER[0] = 0;
  INSERT_BUFFER[1] = 0;

  memcpy (temp4prev, line, strlen (line) + 1);

  save_stack_p = save_stack;

  line = (char *) parse_insn (line, mnemonic);
  if (line == NULL)
    return;

  line = (char *) parse_operands (line, mnemonic);
  if (line == NULL)
    return;

  /* Next, we find a template that matches the given insn, making sure the
     overlap of the given operands types is consistent with the template
     operand types.  */
  if (!match_template ())
    return;

  /* In the MAXQ20, there are certain register combinations, and other
     restrictions which are not allowed. We will try to resolve these right
     now.  */
  if (!match_filters ())
    return;

  /* Check for the appropriate PFX register.  */
  set_prefix ();
  pfx_for_imm_val (0);

  if (!decode_insn ())             /* decode insn. */
    need_pass_2 = 1;

  /* Check for Exlipct PFX instruction.  */
  if (PFX_INSN[0] && (strstr (prev_insn, "PFX") || strstr (prev_insn, "pfx")))
    as_warn (_("Ineffective insntruction %s \n"), prev_insn);

  memcpy (prev_insn, temp4prev, strlen (temp4prev) + 1);

  /* We are ready to output the insn.  */
  output_insn ();
}

Here is the call graph for this function:

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

Definition at line 390 of file tc-maxq.c.

{
  int prec;
  LITTLENUM_TYPE words[4];
  char *t;
  int i;

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

    case 'd':
      prec = 2;
      /* The size of Double has been changed to 2 words ie 32 bits.  */
      /* prec = 4; */
      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 * 2;

  for (i = prec - 1; i >= 0; i--)
    {
      md_number_to_chars (litP, (valueT) words[i], 2);
      litP += 2;
    }

  return NULL;
}

Here is the call graph for this function:

void md_begin ( void  )

Definition at line 2843 of file tc-maxq.c.

{
  const char *hash_err = NULL;
  int c = 0;
  char *p;
  const MAXQ20_OPCODE_INFO *optab;
  MAXQ20_OPCODES *core_optab;      /* For opcodes of the same name. This will
                               be inserted into the hash table.  */
  struct reg *reg_tab;
  struct mem_access_syntax const *memsyntab;
  struct mem_access *memtab;
  struct bit_name *bittab;

  /* Initilize pherioipheral modules.  */
  pmmain ();

  /* Initialise the opcode hash table.  */
  op_hash = hash_new ();

  optab = op_table;         /* Initialise it to the first entry of the
                               maxq20 operand table.  */

  /* Setup for loop.  */
  core_optab = xmalloc (sizeof (MAXQ20_OPCODES));
  core_optab->start = optab;

  while (1)
    {
      ++optab;
      if (optab->name == NULL || strcmp (optab->name, (optab - 1)->name) != 0)
       {
         /* different name --> ship out current template list; add to hash
            table; & begin anew.  */

         core_optab->end = optab;
#ifdef MAXQ10S
         if (max_version == bfd_mach_maxq10)
           {
             if (((optab - 1)->arch == MAXQ10) || ((optab - 1)->arch == MAX))
              {
                hash_err = hash_insert (op_hash,
                                     (optab - 1)->name,
                                     (PTR) core_optab);
              }
           }
         else if (max_version == bfd_mach_maxq20)
           {
             if (((optab - 1)->arch == MAXQ20) || ((optab - 1)->arch == MAX))
              {
#endif
                hash_err = hash_insert (op_hash,
                                     (optab - 1)->name,
                                     (PTR) core_optab);
#if MAXQ10S
              }
           }
         else
           as_fatal (_("Internal Error: Illegal Architecure specified"));
#endif
         if (hash_err)
           as_fatal (_("Internal Error:  Can't hash %s: %s"),
                    (optab - 1)->name, hash_err);

         if (optab->name == NULL)
           break;
         core_optab = xmalloc (sizeof (MAXQ20_OPCODES));
         core_optab->start = optab;
       }
    }

  /* Initialise a new register table.  */
  reg_hash = hash_new ();

  for (reg_tab = system_reg_table;
       reg_tab < (system_reg_table + ARRAY_SIZE (system_reg_table));
       reg_tab++)
    {
#if MAXQ10S
      switch (max_version)
       {
       case bfd_mach_maxq10:
         if ((reg_tab->arch == MAXQ10) || (reg_tab->arch == MAX))
           hash_err = hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
         break;

       case bfd_mach_maxq20:
         if ((reg_tab->arch == MAXQ20) || (reg_tab->arch == MAX))
           {
#endif
             hash_err =
              hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
#if MAXQ10S
           }
         break;
       default:
         as_fatal (_("Invalid architecture type"));
       }
#endif

      if (hash_err)
       as_fatal (_("Internal Error : Can't Hash %s : %s"),
                reg_tab->reg_name, hash_err);
    }

  /* Pheripheral Registers Entry.  */
  for (reg_tab = new_reg_table;
       reg_tab < (new_reg_table + num_of_reg - 1); reg_tab++)
    {
      hash_err = hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);

      if (hash_err)
       as_fatal (_("Internal Error : Can't Hash %s : %s"),
                reg_tab->reg_name, hash_err);
    }

  /* Initialise a new memory operand table.  */
  mem_hash = hash_new ();

  for (memtab = mem_table;
       memtab < mem_table + ARRAY_SIZE (mem_table);
       memtab++)
    {
      hash_err = hash_insert (mem_hash, memtab->name, (PTR) memtab);
      if (hash_err)
       as_fatal (_("Internal Error : Can't Hash %s : %s"),
                memtab->name, hash_err);
    }

  bit_hash = hash_new ();

  for (bittab = bit_table;
       bittab < bit_table + ARRAY_SIZE (bit_table);
       bittab++)
    {
      hash_err = hash_insert (bit_hash, bittab->name, (PTR) bittab);
      if (hash_err)
       as_fatal (_("Internal Error : Can't Hash %s : %s"),
                bittab->name, hash_err);
    }

  mem_syntax_hash = hash_new ();

  for (memsyntab = mem_access_syntax_table;
       memsyntab < mem_access_syntax_table + ARRAY_SIZE (mem_access_syntax_table);
       memsyntab++)
    {
      hash_err =
       hash_insert (mem_syntax_hash, memsyntab->name, (PTR) memsyntab);
      if (hash_err)
       as_fatal (_("Internal Error : Can't Hash %s : %s"),
                memsyntab->name, hash_err);
    }

  /* Initialise the lexical tables,mnemonic chars,operand chars.  */
  for (c = 0; c < 256; c++)
    {
      if (ISDIGIT (c))
       {
         digit_chars[c] = c;
         mnemonic_chars[c] = c;
         operand_chars[c] = c;
         register_chars[c] = c;
       }
      else if (ISLOWER (c))
       {
         mnemonic_chars[c] = c;
         operand_chars[c] = c;
         register_chars[c] = c;
       }
      else if (ISUPPER (c))
       {
         mnemonic_chars[c] = TOLOWER (c);
         register_chars[c] = c;
         operand_chars[c] = c;
       }

      if (ISALPHA (c) || ISDIGIT (c))
       {
         identifier_chars[c] = c;
       }
      else if (c > 128)
       {
         identifier_chars[c] = c;
         operand_chars[c] = c;
       }
    }

  /* All the special characters.  */
  register_chars['@'] = '@';
  register_chars['+'] = '+';
  register_chars['-'] = '-';
  digit_chars['-'] = '-';
  identifier_chars['_'] = '_';
  identifier_chars['.'] = '.';
  register_chars['['] = '[';
  register_chars[']'] = ']';
  operand_chars['_'] = '_';
  operand_chars['#'] = '#';
  mnemonic_chars['['] = '[';
  mnemonic_chars[']'] = ']';

  for (p = operand_special_chars; *p != '\0'; p++)
    operand_chars[(unsigned char) *p] = (unsigned char) *p;

  /* Set the maxq arch type.  */
  maxq_target (max_version);
}

Here is the call graph for this function:

void md_convert_frag ( bfd *headers  ATTRIBUTE_UNUSED,
segT seg  ATTRIBUTE_UNUSED,
fragS *  fragP 
)

Definition at line 453 of file tc-maxq.c.

{
  char *opcode;
  offsetT target_address;
  offsetT opcode_address;
  offsetT displacement_from_opcode_start;
  int address;

  opcode = fragP->fr_opcode;
  address = 0;
  target_address = opcode_address = displacement_from_opcode_start = 0;

  target_address =
    (S_GET_VALUE (fragP->fr_symbol) / MAXQ_OCTETS_PER_BYTE) +
    (fragP->fr_offset / MAXQ_OCTETS_PER_BYTE);

  opcode_address =
    (fragP->fr_address / MAXQ_OCTETS_PER_BYTE) +
    ((fragP->fr_fix - 2) / MAXQ_OCTETS_PER_BYTE);

  /* PC points to the next Instruction.  */
  displacement_from_opcode_start = ((target_address - opcode_address)  - 1);

  if ((displacement_from_opcode_start >= -128
       && displacement_from_opcode_start <= 127)
      && (fragP->fr_subtype == SHORT_PREFIX
         || fragP->fr_subtype == NO_PREFIX))
    {
      /* Its a displacement.  */
      *opcode = (char) displacement_from_opcode_start;
    }
  else
    {
      /* Its an absolute 16 bit jump. Now we have to
        load the prefix operator with the upper 8 bits.  */
      if (fragP->fr_subtype == SHORT_PREFIX)
       {
         as_bad (_("Cant make long jump/call into short jump/call : %d"),
                fragP->fr_line);
         return;
       }

      /* Check whether the symbol has been resolved or not.
        Otherwise we will have to generate a fixup.  */

      if (fragP->fr_subtype != SHORT_PREFIX)
       {
         RELOC_ENUM reloc_type;
         int old_fr_fix;
         int size = 2;

         /* Now this is a basolute jump/call.
            Hence we will have to create a fixup.  */
         if (fragP->fr_subtype == NO_PREFIX)
           fragP->fr_subtype = LONG_PREFIX;

         reloc_type =
           (fragP->fr_subtype ? fragP->fr_subtype : LONG_PREFIX);

         if (reloc_type == 1)
           size = 0;
         old_fr_fix = fragP->fr_fix;

         fragP->fr_fix += (size);

         fix_new (fragP, old_fr_fix - 2, size + 2,
                 fragP->fr_symbol, fragP->fr_offset, 0, reloc_type);
         frag_wane (fragP);
       }
    }
}

Here is the call graph for this function:

int md_estimate_size_before_relax ( fragS *  fragP,
segT segment   
)

Definition at line 297 of file tc-maxq.c.

{
  /* Check whether the symbol has been resolved or not.
     Otherwise we will have to generate a fixup.  */
  if ((S_GET_SEGMENT (fragP->fr_symbol) != segment)
      || fragP->fr_subtype == EXPLICT_LONG_PREFIX)
    {
      RELOC_ENUM reloc_type;
      unsigned char *opcode;
      int old_fr_fix;

      /* Now this symbol has not been defined in this file.
        Hence we will have to create a fixup.  */
      int size = 2;

      /* This is for the prefix instruction.  */

      if (fragP->fr_subtype == EXPLICT_LONG_PREFIX)
       fragP->fr_subtype = LONG_PREFIX;

      if (S_GET_SEGMENT (fragP->fr_symbol) != segment
         && ((!(fragP->fr_subtype) == EXPLICT_LONG_PREFIX)))
       fragP->fr_subtype = ABSOLUTE_ADDR_FOR_DATA;

      reloc_type =
       (fragP->fr_subtype ? fragP->fr_subtype : ABSOLUTE_ADDR_FOR_DATA);

      fragP->fr_subtype = reloc_type;

      if (reloc_type == SHORT_PREFIX)
       size = 0;
      old_fr_fix = fragP->fr_fix;
      opcode = (unsigned char *) fragP->fr_opcode;

      fragP->fr_fix += (size);

      fix_new (fragP, old_fr_fix - 2, size + 2,
              fragP->fr_symbol, fragP->fr_offset, 0, reloc_type);
      frag_wane (fragP);
      return fragP->fr_fix - old_fr_fix;
    }

  if (fragP->fr_subtype == SHORT_PREFIX)
    {
      fragP->fr_subtype = SHORT_PREFIX;
      return 0;
    }

  if (fragP->fr_subtype == NO_PREFIX || fragP->fr_subtype == LONG_PREFIX)
    {
      unsigned long instr;
      unsigned long call_addr;
      long diff;
      fragS *f;
      diff = diff ^ diff;;
      call_addr = call_addr ^ call_addr;
      instr = 0;
      f = NULL;

      /* segment_info_type *seginfo = seg_info (segment);  */
      instr = fragP->fr_address + fragP->fr_fix - 2;

      /* This is the offset if it is a PC relative jump.  */
      call_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;

      /* PC stores the value of the next instruction.  */
      diff = (call_addr - instr) - 1;

      if (diff >= (-128 * 2) && diff <= (2 * 127))
       {
         /* Now as offset is an 8 bit value, we will pass
            that to the jump instruction directly.  */
         fragP->fr_subtype = NO_PREFIX;
         return 0;
       }

      fragP->fr_subtype = LONG_PREFIX;
      return 2;
    }

  as_fatal (_("Illegal Reloc type in md_estimate_size_before_relax for line : %d"),
           frag_now->fr_line);
  return 0;
}

Here is the call graph for this function:

int md_parse_option ( int c  ,
char *arg  ATTRIBUTE_UNUSED 
)

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

{
  /* Any options support will be added onto this switch case.  */
  switch (c)
    {
    case MAXQ_10:
      max_version = bfd_mach_maxq10;
      break;
    case MAXQ_20:
      max_version = bfd_mach_maxq20;
      break;

    default:
      return 0;
    }

  return 1;
}
long md_pcrel_from ( fixS *  fixP)

Definition at line 528 of file tc-maxq.c.

{
  return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
}
void md_show_usage ( FILE *  stream)

Definition at line 205 of file tc-maxq.c.

{
  /* Over here we will fill the description of the machine specific options.  */

  fprintf (stream, _(" MAXQ-specific assembler options:\n"));

  fprintf (stream, _("\
       -MAXQ20                     generate obj for MAXQ20(default)\n\
       -MAXQ10                     generate obj for MAXQ10\n\
       "));
}

Here is the call graph for this function:

symbolS* md_undefined_symbol ( char *name  ATTRIBUTE_UNUSED)

Definition at line 169 of file tc-maxq.c.

{
  return NULL;
}
static void output_data ( fragS *  insn_start_frag,
offsetT  insn_start_off 
) [static]

Definition at line 2727 of file tc-maxq.c.

{
  char *p;
  relax_substateT subtype;
  symbolS *sym;
  offsetT off;
  int diff;

  diff = 0;
  off = 0;
  insn_start_frag = frag_now;
  insn_start_off = frag_now_fix ();

  subtype = EXPLICT_LONG_PREFIX;

  frag_grow (2 + 2);
  p = frag_more (2);

  sym = i.maxq20_op[this_operand].data;
  off = 0;

  /* This will be overwritten later when the symbol is resolved.  */
  *p = i.instr[1];
  *(p + 1) = i.instr[0];

  if (i.maxq20_op[this_operand].disps->X_op != O_constant
      && i.maxq20_op[this_operand].disps->X_op != O_symbol)
    /* Handle complex expressions.  */
    /* Because data is already in terms of symbol so no
       need to convert it from expression to symbol.  */
    off = 0;

  frag_var (rs_machine_dependent, 2, i.reloc[this_operand], subtype, sym, off,  p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void output_disp ( fragS *  insn_start_frag,
offsetT  insn_start_off 
) [static]

Definition at line 2640 of file tc-maxq.c.

{
  char *p;
  relax_substateT subtype;
  symbolS *sym;
  offsetT off;
  int diff;

  diff = 0;
  insn_start_frag = frag_now;
  insn_start_off = frag_now_fix ();

  switch (i.Instr_Prefix)
    {
    case LONG_PREFIX:
      subtype = EXPLICT_LONG_PREFIX;
      break;
    case SHORT_PREFIX:
      subtype = SHORT_PREFIX;
      break;
    default:
      subtype = NO_PREFIX;
      break;
    }

  /* Its a symbol. Here we end the frag and start the relaxation. Now in our
     case there is no need for relaxation. But we do need support for a
     prefix operator. Hence we will check whethere is room for 4 bytes ( 2
     for prefix + 2 for the current instruction ) Hence if at a particular
     time we find out whether the prefix operator is reqd , we shift the
     current instruction two places ahead and insert the prefix instruction.  */
  frag_grow (2 + 2);
  p = frag_more (2);

  sym = i.maxq20_op[this_operand].disps->X_add_symbol;
  off = i.maxq20_op[this_operand].disps->X_add_number;

  if (i.maxq20_op[this_operand].disps->X_add_symbol != NULL && sym && frag_now
      && (subtype != EXPLICT_LONG_PREFIX))
    {
      /* If in the same frag.  */
      if (frag_now == symbol_get_frag (sym))
       {
         diff =
           ((((expressionS *) symbol_get_value_expression (sym))->
             X_add_number) - insn_start_off);

         /* PC points to the next instruction.  */
         diff = (diff / MAXQ_OCTETS_PER_BYTE) - 1;

         if (diff >= -128 && diff <= 127)
           {
             i.instr[1] = (char) diff;

             /* This will be overwritten later when the symbol is resolved.  */
             *p = i.instr[1];
             *(p + 1) = i.instr[0];

             /* No Need to create a FIXUP.  */
             return;
           }
       }
    }

  /* This will be overwritten later when the symbol is resolved.  */
  *p = i.instr[1];
  *(p + 1) = i.instr[0];

  if (i.maxq20_op[this_operand].disps->X_op != O_constant
      && i.maxq20_op[this_operand].disps->X_op != O_symbol)
    {
      /* Handle complex expressions.  */
      sym = make_expr_symbol (i.maxq20_op[this_operand].disps);
      off = 0;
    }

  /* Vineet : This has been added for md_estimate_size_before_relax to
     estimate the correct size.  */
  if (subtype != SHORT_PREFIX)
    i.reloc[this_operand] = LONG_PREFIX;

  frag_var (rs_machine_dependent, 2, i.reloc[this_operand], subtype, sym, off,  p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void output_insn ( void  ) [static]

Definition at line 2763 of file tc-maxq.c.

{
  fragS *insn_start_frag;
  offsetT insn_start_off;
  char *p;

  /* Tie dwarf2 debug info to the address at the start of the insn. We can't
     do this after the insn has been output as the current frag may have been 
     closed off.  eg. by frag_var.  */
  dwarf2_emit_insn (0);

  /* To ALign the text section on word.  */

  frag_align (1, 0, 1);

  /* We initialise the frags for this particular instruction.  */
  insn_start_frag = frag_now;
  insn_start_off = frag_now_fix ();

  /* If there are displacement operators(unresolved) present, then handle
     them separately.  */
  if (i.disp_operands)
    {
      output_disp (insn_start_frag, insn_start_off);
      return;
    }

  if (i.data_operands)
    {
      output_data (insn_start_frag, insn_start_off);
      return;
    }

  /* Check whether the INSERT_BUFFER has to be written.  */
  if (strcmp (INSERT_BUFFER, ""))
    {
      p = frag_more (2);

      *p++ = INSERT_BUFFER[1];
      *p = INSERT_BUFFER[0];
    }

  /* Check whether the prefix instruction has to be written.  */
  if (strcmp (PFX_INSN, ""))
    {
      p = frag_more (2);

      *p++ = PFX_INSN[1];
      *p = PFX_INSN[0];
    }

  p = frag_more (2);
  /* For Little endian.  */
  *p++ = i.instr[1];
  *p = i.instr[0];
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* parse_insn ( char *  line,
char *  mnemonic 
) [static]

Definition at line 821 of file tc-maxq.c.

{
  char *l = line;
  char *token_start = l;
  char *mnem_p;
  char temp[MAX_MNEM_SIZE];
  int ii = 0;

  memset (temp, END_OF_INSN, MAX_MNEM_SIZE);
  mnem_p = mnemonic;

  while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0)
    {
      ii++;
      mnem_p++;
      if (mnem_p >= mnemonic + MAX_MNEM_SIZE)
       {
         as_bad (_("no such instruction: `%s'"), token_start);
         return NULL;
       }
      l++;
    }

  if (!is_space_char (*l) && *l != END_OF_INSN)
    {
      as_bad (_("invalid character %s in mnemonic"), l);
      return NULL;
    }

  while (ii)
    {
      temp[ii - 1] = toupper ((char) mnemonic[ii - 1]);
      ii--;
    }

  LS_processing (temp);

  if (i.Instr_Prefix != 0 && is_a_LSinstr (temp))
    /* Skip the optional L-S.  */
    memcpy (temp, temp + 1, MAX_MNEM_SIZE);

  /* Look up instruction (or prefix) via hash table.  */
  current_templates = (MAXQ20_OPCODES *) hash_find (op_hash, temp);

  if (current_templates != NULL)
    return l;

  as_bad (_("no such instruction: `%s'"), token_start);
  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* parse_operands ( char *  l,
const char *  mnemonic 
) [static]

Definition at line 1851 of file tc-maxq.c.

{
  char *token_start;

  /* 1 if operand is pending after ','.  */
  short int expecting_operand = 0;

  /* Non-zero if operand parens not balanced.  */
  short int paren_not_balanced;

  int operand_ok;

  /* For Overcoming Warning of unused variable.  */
  if (mnemonic)
    operand_ok = 0;

  while (*l != END_OF_INSN)
    {
      /* Skip optional white space before operand.  */
      if (is_space_char (*l))
       ++l;

      if (!is_operand_char (*l) && *l != END_OF_INSN)
       {
         as_bad (_("invalid character %c before operand %d"),
                (char) (*l), i.operands + 1);
         return NULL;
       }
      token_start = l;

      paren_not_balanced = 0;
      while (paren_not_balanced || *l != ',')
       {
         if (*l == END_OF_INSN)
           {
             if (paren_not_balanced)
              {
                as_bad (_("unbalanced brackets in operand %d."),
                       i.operands + 1);
                return NULL;
              }

             break;
           }
         else if (!is_operand_char (*l) && !is_space_char (*l))
           {
             as_bad (_("invalid character %c in operand %d"),
                    (char) (*l), i.operands + 1);
             return NULL;
           }
         if (*l == '[')
           ++paren_not_balanced;
         if (*l == ']')
           --paren_not_balanced;
         l++;
       }

      if (l != token_start)
       {
         /* Yes, we've read in another operand.  */
         this_operand = i.operands++;
         if (i.operands > MAX_OPERANDS)
           {
             as_bad (_("spurious operands; (%d operands/instruction max)"),
                    MAX_OPERANDS);
             return NULL;
           }

         /* Now parse operand adding info to 'i' as we go along.  */
         END_STRING_AND_SAVE (l);

         operand_ok = maxq20_operand (token_start);

         RESTORE_END_STRING (l);

         if (!operand_ok)
           return NULL;
       }
      else
       {
         if (expecting_operand)
           {
           expecting_operand_after_comma:
             as_bad (_("expecting operand after ','; got nothing"));
             return NULL;
           }
       }

      if (*l == ',')
       {
         if (*(++l) == END_OF_INSN)
           /* Just skip it, if it's \n complain.  */
           goto expecting_operand_after_comma;

         expecting_operand = 1;
       }
    }

  return l;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static reg_entry* parse_reg_by_index ( char *  imm_start) [static]

Definition at line 887 of file tc-maxq.c.

{
  int k = 0, mid = 0, rid = 0, val = 0, j = 0;
  char temp[4] = { 0 };
  reg_entry *reg = NULL;

  do
    {
      if (isdigit (imm_start[k]))
       temp[k] = imm_start[k] - '0';

      else if (isalpha (imm_start[k])
              && (imm_start[k] = tolower (imm_start[k])) < 'g')
       temp[k] = 10 + (int) (imm_start[k] - 'a');

      else if (imm_start[k] == 'h')
       break;

      else if (imm_start[k] == END_OF_INSN)
       {
         imm_start[k] = 'd';
         break;
       }

      else
       return NULL;         /* not a hex digit */

      k++;
    }
  while (imm_start[k] != '\n');

  switch (imm_start[k])
    {
    case 'h':
      for (j = 0; j < k; j++)
       val += temp[j] * pwr (16, k - j - 1);
      break;

    case 'd':
      for (j = 0; j < k; j++)
       {
         if (temp[j] > 9)
           return NULL;     /* not a number */

         val += temp[j] * pwr (10, k - j - 1);
         break;
       }
    }

  /* Get the module and register id's.  */
  mid = val & 0x0f;
  rid = (val >> 4) & 0x0f;

  if (mid < 6)
    {
      /* Search the pheripheral reg table.  */
      for (j = 0; j < num_of_reg; j++)
       {
         if (new_reg_table[j].opcode == val)
           {
             reg = (reg_entry *) & new_reg_table[j];
             break;
           }
       }
    }

  else
    {
      /* Search the system register table.  */
      j = 0;

      while (system_reg_table[j].reg_name != NULL)
       {
         if (system_reg_table[j].opcode == val)
           {
             reg = (reg_entry *) & system_reg_table[j];
             break;
           }
         j++;
       }
    }

  if (reg == NULL)
    {
      as_bad (_("Invalid register value %s"), imm_start);
      return reg;
    }

#if CHANGE_PFX
  if (this_operand == 0 && reg != NULL)
    {
      if (reg->Mod_index > 7)
       i.prefix = 2;
      else
       i.prefix = 0;
    }
#endif
  return (reg_entry *) reg;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static reg_entry* parse_register ( char *  reg_string,
char **  end_op 
) [static]

Definition at line 990 of file tc-maxq.c.

{
  char *s = reg_string;
  char *p = NULL;
  char reg_name_given[MAX_REG_NAME_SIZE + 1];
  reg_entry *r = NULL;

  r = NULL;
  p = NULL;

  /* Skip possible REGISTER_PREFIX and possible whitespace.  */
  if (is_space_char (*s))
    ++s;

  p = reg_name_given;
  while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
    {
      if (p >= reg_name_given + MAX_REG_NAME_SIZE)
       return (reg_entry *) NULL;
      s++;
    }

  *end_op = s;

  r = (reg_entry *) hash_find (reg_hash, reg_name_given);

#if CHANGE_PFX
  if (this_operand == 0 && r != NULL)
    {
      if (r->Mod_index > 7)
       i.prefix = 2;
      else
       i.prefix = 0;
    }
#endif
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static reg_bit* parse_register_bit ( char *  reg_string,
char **  end_op 
) [static]

Definition at line 1029 of file tc-maxq.c.

{
  const char *s = reg_string;
  short k = 0;
  char diff = 0;
  reg_bit *rb = NULL;
  reg_entry *r = NULL;
  bit_name *b = NULL;
  char temp_bitname[MAX_REG_NAME_SIZE + 2];
  char temp[MAX_REG_NAME_SIZE + 1];

  memset (&temp, '\0', (MAX_REG_NAME_SIZE + 1));
  memset (&temp_bitname, '\0', (MAX_REG_NAME_SIZE + 2));

  diff = 0;
  r = NULL;
  rb = NULL;
  rb = xmalloc (sizeof (reg_bit));
  rb->reg = xmalloc (sizeof (reg_entry));
  k = 0;

  /* For supporting bit names.  */
  b = (bit_name *) hash_find (bit_hash, reg_string);

  if (b != NULL)
    {
      *end_op = reg_string + strlen (reg_string);
      strcpy (temp_bitname, b->reg_bit);
      s = temp_bitname;
    }

  if (strchr (s, '.'))
    {
      while (*s != '.')
       {
         if (*s == '\0')
           return NULL;
         temp[k] = *s++;

         k++;
       }
      temp[k] = '\0';
    }

  if ((r = parse_register (temp, end_op)) == NULL)
    return NULL;

  rb->reg = r;

  /* Skip the "."  */
  s++;

  if (isdigit ((char) *s))
    rb->bit = atoi (s);
  else if (isalpha ((char) *s))
    {
      rb->bit = (char) *s - 'a';
      rb->bit += 10;
      if (rb->bit > 15)
       {
         as_bad (_("Invalid bit number : '%c'"), (char) *s);
         return NULL;
       }
    }

  if (b != NULL)
    diff = strlen (temp_bitname) - strlen (temp) - 1;
  else
    diff = strlen (reg_string) - strlen (temp) - 1;

  if (*(s + diff) != '\0')
    {
      as_bad (_("Illegal character after operand '%s'"), reg_string);
      return NULL;
    }

  return rb;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pfx_for_imm_val ( int  arg) [static]

Definition at line 1109 of file tc-maxq.c.

{
  if (i.prefix == -1)
    return;

  if (i.prefix == 0 && arg == 0 && PFX_INSN[1] == 0 && !(i.data_operands))
    return;

  if (!(i.prefix < 0) && !(i.prefix > 7))
    PFX_INSN[0] = (i.prefix << 4) | PFX0;

  if (!PFX_INSN[1])
    PFX_INSN[1] = arg;

}

Here is the caller graph for this function:

static void pmmain ( void  ) [static]

Definition at line 2836 of file tc-maxq.c.

{
  make_new_reg_table ();
  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pwr ( int  x,
int  y 
) [static]

Definition at line 876 of file tc-maxq.c.

{
  int k, ans = 1;

  for (k = 0; k < y; k++)
    ans *= x;

  return ans;
}

Here is the caller graph for this function:

static void set_prefix ( void  ) [static]

Definition at line 695 of file tc-maxq.c.

{
  short int src_index = 0, dst_index = 0;

  if (i.operands == 0)
    return;
  if (i.operands == 1)             /* Only SRC is Present */
    {
      if (i.types[0] == REG)
       {
         if (!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
           {
             dst_index = i.maxq20_op[0].reg[0].Mod_index;
             src_index = 0x00;
           }
         else
           {
             src_index = i.maxq20_op[0].reg[0].Mod_index;
             dst_index = 0x00;
           }
       }
    }

  if (i.operands == 2)
    {
      if (i.types[0] == REG && i.types[1] == REG)
       {
         dst_index = i.maxq20_op[0].reg[0].Mod_index;
         src_index = i.maxq20_op[1].reg[0].Mod_index;
       }
      else if (i.types[0] != REG && i.types[1] == REG)  /* DST is Absent */
       {
         src_index = i.maxq20_op[1].reg[0].Mod_index;
         dst_index = 0x00;
       }
      else if (i.types[0] == REG && i.types[1] != REG)  /* Id SRC is Absent */
       {
         dst_index = i.maxq20_op[0].reg[0].Mod_index;
         src_index = 0x00;
       }
      else if (i.types[0] == BIT && i.maxq20_op[0].r_bit)
       {
         dst_index = i.maxq20_op[0].r_bit->reg->Mod_index;
         src_index = 0x00;
       }

      else if (i.types[1] == BIT && i.maxq20_op[1].r_bit)
       {
         dst_index = 0x00;
         src_index = i.maxq20_op[1].r_bit->reg->Mod_index;
       }
    }

  if (src_index >= 0x00 && src_index <= 0xF)
    {
      if (dst_index >= 0x00 && dst_index <= 0x07)
       /* Set PFX[0] */
       i.prefix = 0;

      else if (dst_index >= 0x08 && dst_index <= 0x0F)
       /* Set PFX[2] */
       i.prefix = 2;

      else if (dst_index >= 0x10 && dst_index <= 0x17)
       /* Set PFX[4] */
       i.prefix = 4;

      else if (dst_index >= 0x18 && dst_index <= 0x1F)
       /* Set PFX[6] */
       i.prefix = 6;
    }
  else if (src_index >= 0x10 && src_index <= 0x1F)
    {
      if (dst_index >= 0x00 && dst_index <= 0x07)
       /* Set PFX[1] */
       i.prefix = 1;

      else if (dst_index >= 0x08 && dst_index <= 0x0F)
       /* Set PFX[3] */
       i.prefix = 3;

      else if (dst_index >= 0x10 && dst_index <= 0x17)
       /* Set PFX[5] */
       i.prefix = 5;

      else if (dst_index >= 0x18 && dst_index <= 0x1F)
       /* Set PFX[7] */
       i.prefix = 7;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 228 of file tc-maxq.c.

{
  arelent *rel;
  bfd_reloc_code_real_type code;

  switch (fixp->fx_r_type)
    {
    case MAXQ_INTERSEGMENT:
    case MAXQ_LONGJUMP:
    case BFD_RELOC_16_PCREL_S2:
      code = fixp->fx_r_type;
      break;

    case 0:
    default:
      switch (fixp->fx_size)
       {
       default:
         as_bad_where (fixp->fx_file, fixp->fx_line,
                     _("can not do %d byte relocation"), fixp->fx_size);
         code = BFD_RELOC_32;
         break;

       case 1:
         code = BFD_RELOC_8;
         break;
       case 2:
         code = BFD_RELOC_16;
         break;
       case 4:
         code = BFD_RELOC_32;
         break;
       }
    }

  rel = xmalloc (sizeof (arelent));
  rel->sym_ptr_ptr  = xmalloc (sizeof (asymbol *));
  *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);

  rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
  rel->addend  = fixp->fx_addnumber;
  rel->howto   = bfd_reloc_type_lookup (stdoutput, code);

  if (rel->howto == NULL)
    {
      as_bad_where (fixp->fx_file, fixp->fx_line,
                  _("cannot represent relocation type %s"),
                  bfd_get_reloc_code_name (code));

      /* Set howto to a garbage value so that we can keep going.  */
      rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
      assert (rel->howto != NULL);
    }

  return rel;
}

Here is the call graph for this function:


Variable Documentation

Definition at line 667 of file tc-maxq.c.

const char comment_chars[] = ";"

Definition at line 136 of file tc-maxq.c.

Definition at line 640 of file tc-maxq.c.

Definition at line 71 of file tc-maxq.c.

char digit_chars[256] [static]

Definition at line 603 of file tc-maxq.c.

Definition at line 643 of file tc-maxq.c.

const char EXP_CHARS[] = "eE"

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

const char* extra_symbol_chars = "@(#"

Definition at line 133 of file tc-maxq.c.

const char FLT_CHARS[] = ""

Definition at line 150 of file tc-maxq.c.

maxq20_insn i [static]

Definition at line 637 of file tc-maxq.c.

char identifier_chars[256] [static]

Definition at line 602 of file tc-maxq.c.

Definition at line 135 of file tc-ns32k.c.

char INSERT_BUFFER[2] [static]

Definition at line 650 of file tc-maxq.c.

const char line_comment_chars[] = ";#"

Definition at line 139 of file tc-maxq.c.

Definition at line 141 of file tc-maxq.c.

Definition at line 69 of file tc-maxq.c.

size_t md_longopts_size = sizeof (md_longopts)

Definition at line 164 of file tc-maxq.c.

const pseudo_typeS md_pseudo_table[]
Initial value:
{
  {"int", cons, 2},         
  {"maxq10", maxq_target, bfd_mach_maxq10},
  {"maxq20", maxq_target, bfd_mach_maxq20},
  {NULL, 0, 0},
}

Definition at line 674 of file tc-maxq.c.

const char* md_shortopts = "q"

Definition at line 146 of file tc-maxq.c.

Definition at line 664 of file tc-maxq.c.

Definition at line 670 of file tc-maxq.c.

char mnemonic_chars[256] [static]

Definition at line 599 of file tc-maxq.c.

Definition at line 658 of file tc-maxq.c.

char operand_chars[256] [static]

Definition at line 601 of file tc-maxq.c.

char operand_special_chars[] = "[]@.-+" [static]

Definition at line 614 of file tc-maxq.c.

char PFX_INSN[2] [static]

Definition at line 649 of file tc-maxq.c.

Definition at line 661 of file tc-maxq.c.

char register_chars[256] [static]

Definition at line 600 of file tc-maxq.c.

char save_stack[32] [static]

Definition at line 618 of file tc-maxq.c.

char* save_stack_p [static]

Definition at line 619 of file tc-maxq.c.

int this_operand [static]

Definition at line 646 of file tc-maxq.c.