Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Typedefs | Functions | Variables
tc-ns32k.c File Reference
#include "as.h"
#include "opcode/ns32k.h"
#include "obstack.h"

Go to the source code of this file.

Classes

struct  addr_mode
struct  ns32k_option
struct  iif_entryT
struct  int_ins_form

Defines

#define IIF_ENTRIES   13 /* Number of entries in iif. */
#define PRIVATE_SIZE   256 /* Size of my garbage memory. */
#define MAX_ARGS   4
#define DEFAULT
#define IIF(ptr, a1, c1, e1, g1, i1, k1, m1, o1, q1, s1, u1)
#define LINE_COMMENT_CHARS   "#"
#define ABSOLUTE_PREFIX   '@' /* One or the other MUST be defined. */
#define NS32532
#define IND(x, y)   (((x)<<2)+(y))
#define BRANCH   1
#define PCREL   2
#define BYTE   0
#define WORD   1
#define DOUBLE   2
#define UNDEF   3
#define MASK_BITS   31
#define MAX_LITTLENUMS   6
#define OPTION_DISP_SIZE   (OPTION_MD_BASE)

Typedefs

typedef struct addr_mode

Functions

static int addr_mode (char *operand, addr_modeS *addr_modeP, int recursive_level)
static void evaluate_expr (expressionS *resultP, char *ptr)
static int get_addr_mode (char *ptr, addr_modeS *addr_modeP)
static void optlist (char *str, struct ns32k_option *optionP, unsigned long *default_map)
static int list_search (char *str, struct ns32k_option *optionP, unsigned long *default_map)
static bit_fixS * bit_fix_new (int size, int offset, long min, long max, long add, long base_type, long base_adj)
static void encode_operand (int argc, char **argv, const char *operandsP, const char *suffixP, char im_size ATTRIBUTE_UNUSED, char opcode_bit_ptr)
static int parse (const char *line, int recursive_level)
static bfd_reloc_code_real_type reloc (int size, int pcrel, int type)
static void fix_new_ns32k (fragS *frag, int where, int size, symbolS *add_symbol, long offset, int pcrel, char im_disp, bit_fixS *bit_fixP, char bsr, fragS *opcode_frag, unsigned int opcode_offset)
static void fix_new_ns32k_exp (fragS *frag, int where, int size, expressionS *exp, int pcrel, char im_disp, bit_fixS *bit_fixP, char bsr, fragS *opcode_frag, unsigned int opcode_offset)
void md_number_to_chars (char *buf, valueT value, int nbytes)
static void md_number_to_disp (char *buf, long val, int n)
static void md_number_to_imm (char *buf, long val, int n)
static void md_number_to_field (char *buf, long val, bit_fixS *field_ptr)
static void convert_iif (void)
void md_assemble (char *line)
void md_begin (void)
char * md_atof (int type, char *litP, int *sizeP)
int md_pcrel_adjust (fragS *fragP)
static int md_fix_pcrel_adjust (fixS *fixP)
void md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
void md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, fragS *fragP)
int md_estimate_size_before_relax (fragS *fragP, segT segment)
void md_create_short_jump (char *ptr, addressT from_addr, addressT to_addr, fragS *frag ATTRIBUTE_UNUSED, symbolS *to_symbol ATTRIBUTE_UNUSED)
void md_create_long_jump (char *ptr, addressT from_addr, addressT to_addr, fragS *frag ATTRIBUTE_UNUSED, symbolS *to_symbol ATTRIBUTE_UNUSED)
int md_parse_option (int c, char *arg)
void md_show_usage (FILE *stream)
void cons_fix_new_ns32k (fragS *frag, int where, int size, expressionS *exp)
symbolS * md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
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)

Variables

const char comment_chars [] = "#"
const char line_comment_chars [] = LINE_COMMENT_CHARS
const char line_separator_chars [] = ";"
static int default_disp_size = 4
char * freeptr
char * freeptr_static
struct hash_controlinst_hash_handle
struct ns32k_opcodedesc
addr_modeS addr_modeP
const char EXP_CHARS [] = "eE"
const char FLT_CHARS [] = "fd"
expressionS exprP
char * input_line_pointer
struct ns32k_optioncpureg = cpureg_532
struct ns32k_optionmmureg = mmureg_532
const pseudo_typeS md_pseudo_table []
const relax_typeS md_relax_table []
char disp_test []
char disp_size []
static unsigned long l_mask []
static unsigned long r_mask []
int md_short_jump_size = 3
int md_long_jump_size = 5
const char * md_shortopts = "m:"
size_t md_longopts_size = sizeof (md_longopts)

Class Documentation

struct addr_mode

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

Class Members
char am_size
char * disp
char disp_suffix
char float_flag
char im_disp
char index_byte
signed char mode
char pcrel
signed char scaled_mode
char scaled_reg
struct ns32k_option

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

Class Members
unsigned long and
unsigned long match
unsigned long or
char * pattern
unsigned long value
struct iif_entryT

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

Class Members
int addr_mode
bit_fixS * bit_fixP
char bsr
int im_disp
unsigned long object
int object_adjust
int pcrel
int pcrel_adjust
relax_substateT relax_substate
int size
int type
struct int_ins_form

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

Collaboration diagram for int_ins_form:
Class Members
iif_entryT iifP
int instr_size

Define Documentation

#define ABSOLUTE_PREFIX   '@' /* One or the other MUST be defined. */

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

#define BRANCH   1

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

#define BYTE   0

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

#define DEFAULT
Value:
-1            /* addr_mode returns this value when
                                   plain constant or label is
                                   encountered.  */

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

#define DOUBLE   2

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

#define IIF (   ptr,
  a1,
  c1,
  e1,
  g1,
  i1,
  k1,
  m1,
  o1,
  q1,
  s1,
  u1 
)
Value:
iif.iifP[ptr].type = a1;                         \
    iif.iifP[ptr].size = c1;                            \
    iif.iifP[ptr].object = e1;                          \
    iif.iifP[ptr].object_adjust = g1;                   \
    iif.iifP[ptr].pcrel = i1;                           \
    iif.iifP[ptr].pcrel_adjust = k1;                    \
    iif.iifP[ptr].im_disp = m1;                         \
    iif.iifP[ptr].relax_substate = o1;                  \
    iif.iifP[ptr].bit_fixP = q1;                 \
    iif.iifP[ptr].addr_mode = s1;                \
    iif.iifP[ptr].bsr = u1;

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

#define IIF_ENTRIES   13 /* Number of entries in iif. */

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

#define IND (   x,
  y 
)    (((x)<<2)+(y))

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

#define LINE_COMMENT_CHARS   "#"

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

#define MASK_BITS   31

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

#define MAX_ARGS   4

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

#define MAX_LITTLENUMS   6

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

#define NS32532

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

#define PCREL   2

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

#define PRIVATE_SIZE   256 /* Size of my garbage memory. */

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

#define UNDEF   3

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

#define WORD   1

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


Typedef Documentation

typedef struct addr_mode

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


Function Documentation

static int addr_mode ( char *  operand,
addr_modeS *  addr_modeP,
int  recursive_level 
) [static]

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

{
  char *str;
  int i;
  int strl;
  int mode;
  int j;

  mode = DEFAULT;           /* Default.  */
  addr_modeP->scaled_mode = 0;     /* Why not.  */
  addr_modeP->scaled_reg = 0;      /* If 0, not scaled index.  */
  addr_modeP->float_flag = 0;
  addr_modeP->am_size = 0;
  addr_modeP->im_disp = 0;
  addr_modeP->pcrel = 0;    /* Not set in this function.  */
  addr_modeP->disp_suffix[0] = 0;
  addr_modeP->disp_suffix[1] = 0;
  addr_modeP->disp[0] = NULL;
  addr_modeP->disp[1] = NULL;
  str = operand;

  if (str[0] == 0)
    return 0;

  strl = strlen (str);

  switch (str[0])
    {
      /* The following three case statements controls the mode-chars
        this is the place to ed if you want to change them.  */
#ifdef ABSOLUTE_PREFIX
    case ABSOLUTE_PREFIX:
      if (str[strl - 1] == ']')
       break;
      addr_modeP->mode = 21;       /* absolute */
      addr_modeP->disp[0] = str + 1;
      return -1;
#endif
#ifdef IMMEDIATE_PREFIX
    case IMMEDIATE_PREFIX:
      if (str[strl - 1] == ']')
       break;
      addr_modeP->mode = 20;       /* immediate */
      addr_modeP->disp[0] = str + 1;
      return -1;
#endif
    case '.':
      if (str[strl - 1] != ']')
       {
         switch (str[1])
           {
           case '-':
           case '+':
             if (str[2] != '\000')
              {
                addr_modeP->mode = 27;    /* pc-relative */
                addr_modeP->disp[0] = str + 2;
                return -1;
              }
           default:
             as_bad (_("Invalid syntax in PC-relative addressing mode"));
             return 0;
           }
       }
      break;
    case 'e':
      if (str[strl - 1] != ']')
       {
         if ((!strncmp (str, "ext(", 4)) && strl > 7)
           {                       /* external */
             addr_modeP->disp[0] = str + 4;
             i = 0;
             j = 2;
             do
              {                    /* disp[0]'s termination point.  */
                j += 1;
                if (str[j] == '(')
                  i++;
                if (str[j] == ')')
                  i--;
              }
             while (j < strl && i != 0);
             if (i != 0 || !(str[j + 1] == '-' || str[j + 1] == '+'))
              {
                as_bad (_("Invalid syntax in External addressing mode"));
                return (0);
              }
             str[j] = '\000';             /* null terminate disp[0] */
             addr_modeP->disp[1] = str + j + 2;
             addr_modeP->mode = 22;
             return -1;
           }
       }
      break;

    default:
      ;
    }

  strl = strlen (str);

  switch (strl)
    {
    case 2:
      switch (str[0])
       {
       case 'f':
         addr_modeP->float_flag = 1;
         /* Drop through.  */
       case 'r':
         if (str[1] >= '0' && str[1] < '8')
           {
             addr_modeP->mode = str[1] - '0';
             return -1;
           }
         break;
       default:
         break;
       }
      /* Drop through.  */

    case 3:
      if (!strncmp (str, "tos", 3))
       {
         addr_modeP->mode = 23;    /* TopOfStack */
         return -1;
       }
      break;

    default:
      break;
    }

  if (strl > 4)
    {
      if (str[strl - 1] == ')')
       {
         if (str[strl - 2] == ')')
           {
             if (!strncmp (&str[strl - 5], "(fp", 3))
              mode = 16;           /* Memory Relative.  */
             else if (!strncmp (&str[strl - 5], "(sp", 3))
              mode = 17;
             else if (!strncmp (&str[strl - 5], "(sb", 3))
              mode = 18;

             if (mode != DEFAULT)
              {
                /* Memory relative.  */
                addr_modeP->mode = mode;
                j = strl - 5;             /* Temp for end of disp[0].  */
                i = 0;

                do
                  {
                    strl -= 1;
                    if (str[strl] == ')')
                     i++;
                    if (str[strl] == '(')
                     i--;
                  }
                while (strl > -1 && i != 0);

                if (i != 0)
                  {
                    as_bad (_("Invalid syntax in Memory Relative addressing mode"));
                    return (0);
                  }

                addr_modeP->disp[1] = str;
                addr_modeP->disp[0] = str + strl + 1;
                str[j] = '\000';   /* Null terminate disp[0] .  */
                str[strl] = '\000';       /* Null terminate disp[1].  */

                return -1;
              }
           }

         switch (str[strl - 3])
           {
           case 'r':
           case 'R':
             if (str[strl - 2] >= '0'
                && str[strl - 2] < '8'
                && str[strl - 4] == '(')
              {
                addr_modeP->mode = str[strl - 2] - '0' + 8;
                addr_modeP->disp[0] = str;
                str[strl - 4] = 0;
                return -1;         /* reg rel */
              }
             /* Drop through.  */

           default:
             if (!strncmp (&str[strl - 4], "(fp", 3))
              mode = 24;
             else if (!strncmp (&str[strl - 4], "(sp", 3))
              mode = 25;
             else if (!strncmp (&str[strl - 4], "(sb", 3))
              mode = 26;
             else if (!strncmp (&str[strl - 4], "(pc", 3))
              mode = 27;

             if (mode != DEFAULT)
              {
                addr_modeP->mode = mode;
                addr_modeP->disp[0] = str;
                str[strl - 4] = '\0';

                return -1;         /* Memory space.  */
              }
           }
       }

      /* No trailing ')' do we have a ']' ?  */
      if (str[strl - 1] == ']')
       {
         switch (str[strl - 2])
           {
           case 'b':
             mode = 28;
             break;
           case 'w':
             mode = 29;
             break;
           case 'd':
             mode = 30;
             break;
           case 'q':
             mode = 31;
             break;
           default:
             as_bad (_("Invalid scaled-indexed mode, use (b,w,d,q)"));

             if (str[strl - 3] != ':' || str[strl - 6] != '['
                || str[strl - 5] == 'r' || str[strl - 4] < '0'
                || str[strl - 4] > '7')
              as_bad (_("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}"));
           } /* Scaled index.  */

         if (recursive_level > 0)
           {
             as_bad (_("Scaled-indexed addressing mode combined with scaled-index"));
             return 0;
           }

         addr_modeP->am_size += 1; /* scaled index byte.  */
         j = str[strl - 4] - '0';  /* store temporary.  */
         str[strl - 6] = '\000';   /* nullterminate for recursive call.  */
         i = addr_mode (str, addr_modeP, 1);

         if (!i || addr_modeP->mode == 20)
           {
             as_bad (_("Invalid or illegal addressing mode combined with scaled-index"));
             return 0;
           }

         addr_modeP->scaled_mode = addr_modeP->mode;    /* Store the inferior mode.  */
         addr_modeP->mode = mode;
         addr_modeP->scaled_reg = j + 1;

         return -1;
       }
    }

  addr_modeP->mode = DEFAULT;      /* Default to whatever.  */
  addr_modeP->disp[0] = str;

Here is the call graph for this function:

static bit_fixS* bit_fix_new ( int  size,
int  offset,
long  min,
long  max,
long  add,
long  base_type,
long  base_adj 
) [static]

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

{
  bit_fixS *bit_fixP;

  bit_fixP = (bit_fixS *) obstack_alloc (&notes, sizeof (bit_fixS));

  bit_fixP->fx_bit_size = size;
  bit_fixP->fx_bit_offset = offset;
  bit_fixP->fx_bit_base = base_type;
  bit_fixP->fx_bit_base_adj = base_adj;
  bit_fixP->fx_bit_max = max;
  bit_fixP->fx_bit_min = min;
  bit_fixP->fx_bit_add = add;

Here is the call graph for this function:

Here is the caller graph for this function:

void cons_fix_new_ns32k ( fragS *  frag,
int  where,
int  size,
expressionS exp 
)

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

{
  fix_new_ns32k_exp (frag, where, size, exp,

Here is the call graph for this function:

static void convert_iif ( void  ) [static]

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

{
  int i;
  bit_fixS *j;
  fragS *inst_frag;
  unsigned int inst_offset;
  char *inst_opcode;
  char *memP;
  int l;
  int k;
  char type;
  char size = 0;

  frag_grow (iif.instr_size);      /* This is important.  */
  memP = frag_more (0);
  inst_opcode = memP;
  inst_offset = (memP - frag_now->fr_literal);
  inst_frag = frag_now;

  for (i = 0; i < IIF_ENTRIES; i++)
    {
      if ((type = iif.iifP[i].type))
       {
         /* The object exist, so handle it.  */
         switch (size = iif.iifP[i].size)
           {
           case 42:
             size = 0;
             /* It's a bitfix that operates on an existing object.  */
             if (iif.iifP[i].bit_fixP->fx_bit_base)
              /* Expand fx_bit_base to point at opcode.  */
              iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode;
             /* Fall through.  */

           case 8:          /* bignum or doublefloat.  */
           case 1:
           case 2:
           case 3:
           case 4:
             /* The final size in objectmemory is known.  */
             memP = frag_more (size);
             j = iif.iifP[i].bit_fixP;

             switch (type)
              {
              case 1:       /* The object is pure binary.  */
                if (j)
                  md_number_to_field (memP, exprP.X_add_number, j);

                else if (iif.iifP[i].pcrel)
                  fix_new_ns32k (frag_now,
                               (long) (memP - frag_now->fr_literal),
                               size,
                               0,
                               iif.iifP[i].object,
                               iif.iifP[i].pcrel,
                               iif.iifP[i].im_disp,
                               0,
                               iif.iifP[i].bsr,  /* Sequent hack.  */
                               inst_frag, inst_offset);
                else
                  {
                    /* Good, just put them bytes out.  */
                    switch (iif.iifP[i].im_disp)
                     {
                     case 0:
                       md_number_to_chars (memP, iif.iifP[i].object, size);
                       break;
                     case 1:
                       md_number_to_disp (memP, iif.iifP[i].object, size);
                       break;
                     default:
                       as_fatal (_("iif convert internal pcrel/binary"));
                     }
                  }
                break;

              case 2:
                /* The object is a pointer at an expression, so
                     unpack it, note that bignums may result from the
                     expression.  */
                evaluate_expr (&exprP, (char *) iif.iifP[i].object);
                if (exprP.X_op == O_big || size == 8)
                  {
                    if ((k = exprP.X_add_number) > 0)
                     {
                       /* We have a bignum ie a quad. This can only
                             happens in a long suffixed instruction.  */
                       if (k * 2 > size)
                         as_bad (_("Bignum too big for long"));

                       if (k == 3)
                         memP += 2;

                       for (l = 0; k > 0; k--, l += 2)
                         md_number_to_chars (memP + l,
                                          generic_bignum[l >> 1],
                                          sizeof (LITTLENUM_TYPE));
                     }
                    else
                     {
                       /* flonum.  */
                       LITTLENUM_TYPE words[4];

                       switch (size)
                         {
                         case 4:
                           gen_to_words (words, 2, 8);
                           md_number_to_imm (memP, (long) words[0],
                                          sizeof (LITTLENUM_TYPE));
                           md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
                                          (long) words[1],
                                          sizeof (LITTLENUM_TYPE));
                           break;
                         case 8:
                           gen_to_words (words, 4, 11);
                           md_number_to_imm (memP, (long) words[0],
                                          sizeof (LITTLENUM_TYPE));
                           md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
                                          (long) words[1],
                                          sizeof (LITTLENUM_TYPE));
                           md_number_to_imm ((memP + 2
                                           * sizeof (LITTLENUM_TYPE)),
                                          (long) words[2],
                                          sizeof (LITTLENUM_TYPE));
                           md_number_to_imm ((memP + 3
                                           * sizeof (LITTLENUM_TYPE)),
                                          (long) words[3],
                                          sizeof (LITTLENUM_TYPE));
                           break;
                         }
                     }
                    break;
                  }
                if (exprP.X_add_symbol ||
                    exprP.X_op_symbol ||
                    iif.iifP[i].pcrel)
                  {
                    /* The expression was undefined due to an
                         undefined label. Create a fix so we can fix
                         the object later.  */
                    exprP.X_add_number += iif.iifP[i].object_adjust;
                    fix_new_ns32k_exp (frag_now,
                                    (long) (memP - frag_now->fr_literal),
                                    size,
                                    &exprP,
                                    iif.iifP[i].pcrel,
                                    iif.iifP[i].im_disp,
                                    j,
                                    iif.iifP[i].bsr,
                                    inst_frag, inst_offset);
                  }
                else if (j)
                  md_number_to_field (memP, exprP.X_add_number, j);
                else
                  {
                    /* Good, just put them bytes out.  */
                    switch (iif.iifP[i].im_disp)
                     {
                     case 0:
                       md_number_to_imm (memP, exprP.X_add_number, size);
                       break;
                     case 1:
                       md_number_to_disp (memP, exprP.X_add_number, size);
                       break;
                     default:
                       as_fatal (_("iif convert internal pcrel/pointer"));
                     }
                  }
                break;
              default:
                as_fatal (_("Internal logic error in iif.iifP[n].type"));
              }
             break;

           case 0:
             /* Too bad, the object may be undefined as far as its
               final nsize in object memory is concerned.  The size
               of the object in objectmemory is not explicitly
               given.  If the object is defined its length can be
               determined and a fix can replace the frag.  */
             {
              evaluate_expr (&exprP, (char *) iif.iifP[i].object);

              if ((exprP.X_add_symbol || exprP.X_op_symbol) &&
                  !iif.iifP[i].pcrel)
                {
                  /* Size is unknown until link time so have to default.  */
                  size = default_disp_size; /* Normally 4 bytes.  */
                  memP = frag_more (size);
                  fix_new_ns32k_exp (frag_now,
                                   (long) (memP - frag_now->fr_literal),
                                   size,
                                   &exprP,
                                   0, /* never iif.iifP[i].pcrel, */
                                   1, /* always iif.iifP[i].im_disp */
                                   (bit_fixS *) 0, 0,
                                   inst_frag,
                                   inst_offset);
                  break;           /* Exit this absolute hack.  */
                }

              if (exprP.X_add_symbol || exprP.X_op_symbol)
                {
                  /* Frag it.  */
                  if (exprP.X_op_symbol)
                    /* We cant relax this case.  */
                    as_fatal (_("Can't relax difference"));
                  else
                    {
                     /* Size is not important.  This gets fixed by
                        relax, but we assume 0 in what follows.  */
                     memP = frag_more (4); /* Max size.  */
                     size = 0;

                     {
                       fragS *old_frag = frag_now;
                       frag_variant (rs_machine_dependent,
                                   4, /* Max size.  */
                                   0, /* Size.  */
                                   IND (BRANCH, UNDEF), /* Expecting
                                                                the worst.  */
                                   exprP.X_add_symbol,
                                   exprP.X_add_number,
                                   inst_opcode);
                       frag_opcode_frag (old_frag) = inst_frag;
                       frag_opcode_offset (old_frag) = inst_offset;
                       frag_bsr (old_frag) = iif.iifP[i].bsr;
                     }
                    }
                }
              else
                {
                  /* This duplicates code in md_number_to_disp.  */
                  if (-64 <= exprP.X_add_number && exprP.X_add_number <= 63)
                    size = 1;
                  else
                    {
                     if (-8192 <= exprP.X_add_number
                         && exprP.X_add_number <= 8191)
                       size = 2;
                     else
                       {
                         if (-0x20000000 <= exprP.X_add_number
                            && exprP.X_add_number<=0x1fffffff)
                           size = 4;
                         else
                           {
                            as_bad (_("Displacement too large for :d"));
                            size = 4;
                           }
                       }
                    }

                  memP = frag_more (size);
                  md_number_to_disp (memP, exprP.X_add_number, size);
                }
             }
             break;

           default:
             as_fatal (_("Internal logic error in iif.iifP[].type"));
           }
       }

Here is the call graph for this function:

Here is the caller graph for this function:

static void encode_operand ( int  argc,
char **  argv,
const char *  operandsP,
const char *  suffixP,
char im_size  ATTRIBUTE_UNUSED,
char  opcode_bit_ptr 
) [static]

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

{
  int i, j;
  char d;
  int pcrel, b, loop, pcrel_adjust;
  unsigned long tmp;

  for (loop = 0; loop < argc; loop++)
    {
      /* What operand are we supposed to work on.  */
      i = operandsP[loop << 1] - '1';
      if (i > 3)
       as_fatal (_("Internal consistency error.  check ns32k-opcode.h"));

      pcrel = 0;
      pcrel_adjust = 0;
      tmp = 0;

      switch ((d = operandsP[(loop << 1) + 1]))
       {
       case 'f':            /* Operand of sfsr turns out to be a nasty
                               specialcase.  */
         opcode_bit_ptr -= 5;
       case 'Z':            /* Float not immediate.  */
       case 'F':            /* 32 bit float      general form.  */
       case 'L':            /* 64 bit float.  */
       case 'I':            /* Integer not immediate.  */
       case 'B':            /* Byte        */
       case 'W':            /* Word        */
       case 'D':            /* Double-word.  */
       case 'A':            /* Double-word       gen-address-form ie no regs
                               allowed.  */
         get_addr_mode (argv[i], &addr_modeP);

         if ((addr_modeP.mode == 20) &&
            (d == 'I' || d == 'Z' || d == 'A'))
           as_fatal (d == 'A'? _("Address of immediate operand"):
                     _("Invalid immediate write operand."));

         if (opcode_bit_ptr == desc->opcode_size)
           b = 4;
         else
           b = 6;

         for (j = b; j < (b + 2); j++)
           {
             if (addr_modeP.disp[j - b])
              {
                IIF (j,
                     2,
                     addr_modeP.disp_suffix[j - b],
                     (unsigned long) addr_modeP.disp[j - b],
                     0,
                     addr_modeP.pcrel,
                     iif.instr_size,
                     addr_modeP.im_disp,
                     IND (BRANCH, BYTE),
                     NULL,
                     (addr_modeP.scaled_reg ? addr_modeP.scaled_mode
                     : addr_modeP.mode),
                     0);
              }
           }

         opcode_bit_ptr -= 5;
         iif.iifP[1].object |= ((long) addr_modeP.mode) << opcode_bit_ptr;

         if (addr_modeP.scaled_reg)
           {
             j = b / 2;
             IIF (j, 1, 1, (unsigned long) addr_modeP.index_byte,
                 0, 0, 0, 0, 0, NULL, -1, 0);
           }
         break;

       case 'b':            /* Multiple instruction disp.  */
         freeptr++;         /* OVE:this is an useful hack.  */
         sprintf (freeptr, "((%s-1)*%d)", argv[i], desc->im_size);
         argv[i] = freeptr;
         pcrel -= 1;        /* Make pcrel 0 in spite of what case 'p':
                               wants.  */
         /* fall thru */
       case 'p':            /* Displacement - pc relative addressing.  */
         pcrel += 1;
         /* fall thru */
       case 'd':            /* Displacement.  */
         iif.instr_size += suffixP[i] ? suffixP[i] : 4;
         IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
              pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 0);
         break;
       case 'H':            /* Sequent-hack: the linker wants a bit set
                               when bsr.  */
         pcrel = 1;
         iif.instr_size += suffixP[i] ? suffixP[i] : 4;
         IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
              pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 1);
         break;
       case 'q':            /* quick */
         opcode_bit_ptr -= 4;
         IIF (11, 2, 42, (unsigned long) argv[i], 0, 0, 0, 0, 0,
              bit_fix_new (4, opcode_bit_ptr, -8, 7, 0, 1, 0), -1, 0);
         break;
       case 'r':            /* Register number (3 bits).  */
         list_search (argv[i], opt6, &tmp);
         opcode_bit_ptr -= 3;
         iif.iifP[1].object |= tmp << opcode_bit_ptr;
         break;
       case 'O':            /* Setcfg instruction optionslist.  */
         optlist (argv[i], opt3, &tmp);
         opcode_bit_ptr -= 4;
         iif.iifP[1].object |= tmp << 15;
         break;
       case 'C':            /* Cinv instruction optionslist.  */
         optlist (argv[i], opt4, &tmp);
         opcode_bit_ptr -= 4;
         iif.iifP[1].object |= tmp << 15; /* Insert the regtype in opcode.  */
         break;
       case 'S':            /* String instruction options list.  */
         optlist (argv[i], opt5, &tmp);
         opcode_bit_ptr -= 4;
         iif.iifP[1].object |= tmp << 15;
         break;
       case 'u':
       case 'U':            /* Register list.  */
         IIF (10, 1, 1, 0, 0, 0, 0, 0, 0, NULL, -1, 0);
         switch (operandsP[(i << 1) + 1])
           {
           case 'u':        /* Restore, exit.  */
             optlist (argv[i], opt1, &iif.iifP[10].object);
             break;
           case 'U':        /* Save, enter.  */
             optlist (argv[i], opt2, &iif.iifP[10].object);
             break;
           }
         iif.instr_size += 1;
         break;
       case 'M':            /* MMU register.  */
         list_search (argv[i], mmureg, &tmp);
         opcode_bit_ptr -= 4;
         iif.iifP[1].object |= tmp << opcode_bit_ptr;
         break;
       case 'P':            /* CPU register.  */
         list_search (argv[i], cpureg, &tmp);
         opcode_bit_ptr -= 4;
         iif.iifP[1].object |= tmp << opcode_bit_ptr;
         break;
       case 'g':            /* Inss exts.  */
         iif.instr_size += 1;      /* 1 byte is allocated after the opcode.  */
         IIF (10, 2, 1,
              (unsigned long) argv[i],    /* i always 2 here.  */
              0, 0, 0, 0, 0,
              bit_fix_new (3, 5, 0, 7, 0, 0, 0), /* A bit_fix is targeted to
                                               the byte.  */
              -1, 0);
         break;
       case 'G':
         IIF (11, 2, 42,
              (unsigned long) argv[i],    /* i always 3 here.  */
              0, 0, 0, 0, 0,
              bit_fix_new (5, 0, 1, 32, -1, 0, -1), -1, 0);
         break;
       case 'i':
         iif.instr_size += 1;
         b = 2 + i;         /* Put the extension byte after opcode.  */
         IIF (b, 2, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0);
         break;
       default:
         as_fatal (_("Bad opcode-table-option, check in file ns32k-opcode.h"));
       }

Here is the call graph for this function:

Here is the caller graph for this function:

static void evaluate_expr ( expressionS resultP,
char *  ptr 
) [static]

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

{
  char *tmp_line;

  tmp_line = input_line_pointer;
  input_line_pointer = ptr;
  expression (resultP);

Here is the caller graph for this function:

static void fix_new_ns32k ( fragS *  frag,
int  where,
int  size,
symbolS *  add_symbol,
long  offset,
int  pcrel,
char  im_disp,
bit_fixS *  bit_fixP,
char  bsr,
fragS *  opcode_frag,
unsigned int  opcode_offset 
) [static]

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

{
  fixS *fixP = fix_new (frag, where, size, add_symbol,
                     offset, pcrel,
                     bit_fixP ? NO_RELOC : reloc (size, pcrel, im_disp)
                     );

  fix_opcode_frag (fixP) = opcode_frag;
  fix_opcode_offset (fixP) = opcode_offset;
  fix_im_disp (fixP) = im_disp;
  fix_bsr (fixP) = bsr;
  fix_bit_fixP (fixP) = bit_fixP;
  /* We have a MD overflow check for displacements.  */

Here is the call graph for this function:

Here is the caller graph for this function:

static void fix_new_ns32k_exp ( fragS *  frag,
int  where,
int  size,
expressionS exp,
int  pcrel,
char  im_disp,
bit_fixS *  bit_fixP,
char  bsr,
fragS *  opcode_frag,
unsigned int  opcode_offset 
) [static]

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

{
  fixS *fixP = fix_new_exp (frag, where, size, exp, pcrel,
                         bit_fixP ? NO_RELOC : reloc (size, pcrel, im_disp)
                         );

  fix_opcode_frag (fixP) = opcode_frag;
  fix_opcode_offset (fixP) = opcode_offset;
  fix_im_disp (fixP) = im_disp;
  fix_bsr (fixP) = bsr;
  fix_bit_fixP (fixP) = bit_fixP;
  /* We have a MD overflow check for displacements.  */

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_addr_mode ( char *  ptr,
addr_modeS *  addr_modeP 
) [static]

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

{
  int tmp;

  addr_mode (ptr, addr_modeP, 0);

  if (addr_modeP->mode == DEFAULT || addr_modeP->scaled_mode == -1)
    {
      /* Resolve ambiguous operands, this shouldn't be necessary if
        one uses standard NSC operand syntax. But the sequent
        compiler doesn't!!!  This finds a proper addressing mode
        if it is implicitly stated. See ns32k-opcode.h.  */
      (void) evaluate_expr (&exprP, ptr); /* This call takes time Sigh!  */

      if (addr_modeP->mode == DEFAULT)
       {
         if (exprP.X_add_symbol || exprP.X_op_symbol)
           addr_modeP->mode = desc->default_model; /* We have a label.  */
         else
           addr_modeP->mode = desc->default_modec; /* We have a constant.  */
       }
      else
       {
         if (exprP.X_add_symbol || exprP.X_op_symbol)
           addr_modeP->scaled_mode = desc->default_model;
         else
           addr_modeP->scaled_mode = desc->default_modec;
       }

      /* Must put this mess down in addr_mode to handle the scaled
         case better.  */
    }

  /* It appears as the sequent compiler wants an absolute when we have
     a label without @. Constants becomes immediates besides the addr
     case.  Think it does so with local labels too, not optimum, pcrel
     is better.  When I have time I will make gas check this and
     select pcrel when possible Actually that is trivial.  */
  if ((tmp = addr_modeP->scaled_reg))
    {                       /* Build indexbyte.  */
      tmp--;                /* Remember regnumber comes incremented for
                               flagpurpose.  */
      tmp |= addr_modeP->scaled_mode << 3;
      addr_modeP->index_byte = (char) tmp;
      addr_modeP->am_size += 1;
    }

  assert (addr_modeP->mode >= 0); 
  if (disp_test[(unsigned int) addr_modeP->mode])
    {
      char c;
      char suffix;
      char suffix_sub;
      int i;
      char *toP;
      char *fromP;

      /* There was a displacement, probe for length  specifying suffix.  */
      addr_modeP->pcrel = 0;

      assert(addr_modeP->mode >= 0);
      if (disp_test[(unsigned int) addr_modeP->mode])
       {
         /* There is a displacement.  */
         if (addr_modeP->mode == 27 || addr_modeP->scaled_mode == 27)
           /* Do we have pcrel. mode.  */
           addr_modeP->pcrel = 1;

         addr_modeP->im_disp = 1;

         for (i = 0; i < 2; i++)
           {
             suffix_sub = suffix = 0;

             if ((toP = addr_modeP->disp[i]))
              {
                /* Suffix of expression, the largest size rules.  */
                fromP = toP;

                while ((c = *fromP++))
                  {
                    *toP++ = c;
                    if (c == ':')
                     {
                       switch (*fromP)
                         {
                         case '\0':
                           as_warn (_("Premature end of suffix -- Defaulting to d"));
                           suffix = 4;
                           continue;
                         case 'b':
                           suffix_sub = 1;
                           break;
                         case 'w':
                           suffix_sub = 2;
                           break;
                         case 'd':
                           suffix_sub = 4;
                           break;
                         default:
                           as_warn (_("Bad suffix after ':' use {b|w|d} Defaulting to d"));
                           suffix = 4;
                         }

                       fromP ++;
                       toP --;     /* So we write over the ':' */

                       if (suffix < suffix_sub)
                         suffix = suffix_sub;
                     }
                  }

                *toP = '\0'; /* Terminate properly.  */
                addr_modeP->disp_suffix[i] = suffix;
                addr_modeP->am_size += suffix ? suffix : 4;
              }
           }
       }
    }
  else
    {
      if (addr_modeP->mode == 20)
       {
         /* Look in ns32k_opcode for size.  */
         addr_modeP->disp_suffix[0] = addr_modeP->am_size = desc->im_size;
         addr_modeP->im_disp = 0;
       }
    }

Here is the call graph for this function:

Here is the caller graph for this function:

static int list_search ( char *  str,
struct ns32k_option optionP,
unsigned long default_map 
) [static]

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

{
  int i;

  for (i = 0; optionP[i].pattern != 0; i++)
    {
      if (!strncmp (optionP[i].pattern, str, 20))
       {
         /* Use strncmp to be safe.  */
         *default_map |= optionP[i].or;
         *default_map &= optionP[i].and;

         return -1;
       }
    }

  as_bad (_("No such entry in list. (cpu/mmu register)"));

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 2001 of file tc-ns32k.c.

{
  long val = * (long *) valP;
  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;

  if (fix_bit_fixP (fixP))
    /* Bitfields to fix, sigh.  */
    md_number_to_field (buf, val, fix_bit_fixP (fixP));
  else switch (fix_im_disp (fixP))
    {
    case 0:
      /* Immediate field.  */
      md_number_to_imm (buf, val, fixP->fx_size);
      break;

    case 1:
      /* Displacement field.  */
      /* Calculate offset.  */
      md_number_to_disp (buf,
                      (fixP->fx_pcrel ? val + md_fix_pcrel_adjust (fixP)
                       : val), fixP->fx_size);
      break;

    case 2:
      /* Pointer in a data object.  */
      md_number_to_chars (buf, val, fixP->fx_size);
      break;
    }

  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)

Here is the call graph for this function:

void md_assemble ( char *  line)

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

{
  freeptr = freeptr_static;
  parse (line, 0);          /* Explode line to more fix form in iif.  */
  convert_iif ();           /* Convert iif to frags, fix's etc.  */
#ifdef SHOW_NUM
  printf (" \t\t\t%s\n", line);

Here is the call graph for this function:

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

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

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

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

    case 'd':
      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 * sizeof (LITTLENUM_TYPE);

  for (wordP = words + prec; prec--;)
    {
      md_number_to_chars (litP, (long) (*--wordP), sizeof (LITTLENUM_TYPE));
      litP += sizeof (LITTLENUM_TYPE);
    }

Here is the call graph for this function:

void md_begin ( void  )

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

{
  /* Build a hashtable of the instructions.  */
  const struct ns32k_opcode *ptr;
  const char *stat;
  const struct ns32k_opcode *endop;

  inst_hash_handle = hash_new ();

  endop = ns32k_opcodes + sizeof (ns32k_opcodes) / sizeof (ns32k_opcodes[0]);
  for (ptr = ns32k_opcodes; ptr < endop; ptr++)
    {
      if ((stat = hash_insert (inst_hash_handle, ptr->name, (char *) ptr)))
       /* Fatal.  */
       as_fatal (_("Can't hash %s: %s"), ptr->name, stat);
    }

  /* Some private space please!  */

Here is the call graph for this function:

void md_convert_frag ( bfd *abfd  ATTRIBUTE_UNUSED,
segT sec  ATTRIBUTE_UNUSED,
fragS *  fragP 
)

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

{
  long disp;
  long ext = 0;
  /* Address in gas core of the place to store the displacement.  */
  char *buffer_address = fragP->fr_fix + fragP->fr_literal;
  /* Address in object code of the displacement.  */
  int object_address;

  switch (fragP->fr_subtype)
    {
    case IND (BRANCH, BYTE):
      ext = 1;
      break;
    case IND (BRANCH, WORD):
      ext = 2;
      break;
    case IND (BRANCH, DOUBLE):
      ext = 4;
      break;
    }

  if (ext == 0)
    return;

  know (fragP->fr_symbol);

  object_address = fragP->fr_fix + fragP->fr_address;

  /* The displacement of the address, from current location.  */
  disp = (S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset) - object_address;
  disp += md_pcrel_adjust (fragP);

  md_number_to_disp (buffer_address, (long) disp, (int) ext);

Here is the call graph for this function:

void md_create_long_jump ( char *  ptr,
addressT from_addr  ,
addressT to_addr  ,
fragS *frag  ATTRIBUTE_UNUSED,
symbolS *to_symbol  ATTRIBUTE_UNUSED 
)

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

{
  valueT offset;

  offset = to_addr - from_addr;
  md_number_to_chars (ptr, (valueT) 0xEA, 1);

Here is the call graph for this function:

void md_create_short_jump ( char *  ptr,
addressT from_addr  ,
addressT to_addr  ,
fragS *frag  ATTRIBUTE_UNUSED,
symbolS *to_symbol  ATTRIBUTE_UNUSED 
)

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

{
  valueT offset;

  offset = to_addr - from_addr;
  md_number_to_chars (ptr, (valueT) 0xEA, 1);

Here is the call graph for this function:

int md_estimate_size_before_relax ( fragS *  fragP,
segT segment   
)

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

{
  if (fragP->fr_subtype == IND (BRANCH, UNDEF))
    {
      if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
       {
         /* We don't relax symbols defined in another segment.  The
            thing to do is to assume the object will occupy 4 bytes.  */
         fix_new_ns32k (fragP,
                      (int) (fragP->fr_fix),
                      4,
                      fragP->fr_symbol,
                      fragP->fr_offset,
                      1,
                      1,
                      0,
                      frag_bsr(fragP), /* Sequent hack.  */
                      frag_opcode_frag (fragP),
                      frag_opcode_offset (fragP));
         fragP->fr_fix += 4;
         frag_wane (fragP);
         return 4;
       }

      /* Relaxable case.  Set up the initial guess for the variable
        part of the frag.  */
      fragP->fr_subtype = IND (BRANCH, BYTE);
    }

  if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
    abort ();

  /* Return the size of the variable part of the frag.  */

Here is the call graph for this function:

static int md_fix_pcrel_adjust ( fixS *  fixP) [static]

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

{
  fragS *opcode_frag;
  addressT opcode_address;
  unsigned int offset;

  opcode_frag = fix_opcode_frag (fixP);
  if (opcode_frag == 0)
    return 0;

  offset = fix_opcode_offset (fixP);
  opcode_address = offset + opcode_frag->fr_address;

Here is the caller graph for this function:

void md_number_to_chars ( char *  buf,
valueT  value,
int  nbytes 
)

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

{

Here is the call graph for this function:

static void md_number_to_disp ( char *  buf,
long  val,
int  n 
) [static]

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

{
  switch (n)
    {
    case 1:
      if (val < -64 || val > 63)
       as_bad (_("value of %ld out of byte displacement range."), val);
      val &= 0x7f;
#ifdef SHOW_NUM
      printf ("%x ", val & 0xff);
#endif
      *buf++ = val;
      break;

    case 2:
      if (val < -8192 || val > 8191)
       as_bad (_("value of %ld out of word displacement range."), val);
      val &= 0x3fff;
      val |= 0x8000;
#ifdef SHOW_NUM
      printf ("%x ", val >> 8 & 0xff);
#endif
      *buf++ = (val >> 8);
#ifdef SHOW_NUM
      printf ("%x ", val & 0xff);
#endif
      *buf++ = val;
      break;

    case 4:
      if (val < -0x20000000 || val >= 0x20000000)
       as_bad (_("value of %ld out of double word displacement range."), val);
      val |= 0xc0000000;
#ifdef SHOW_NUM
      printf ("%x ", val >> 24 & 0xff);
#endif
      *buf++ = (val >> 24);
#ifdef SHOW_NUM
      printf ("%x ", val >> 16 & 0xff);
#endif
      *buf++ = (val >> 16);
#ifdef SHOW_NUM
      printf ("%x ", val >> 8 & 0xff);
#endif
      *buf++ = (val >> 8);
#ifdef SHOW_NUM
      printf ("%x ", val & 0xff);
#endif
      *buf++ = val;
      break;

    default:
      as_fatal (_("Internal logic error.  line %d, file \"%s\""),
              __LINE__, __FILE__);

Here is the call graph for this function:

Here is the caller graph for this function:

static void md_number_to_field ( char *  buf,
long  val,
bit_fixS *  field_ptr 
) [static]

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

{
  unsigned long object;
  unsigned long mask;
  /* Define ENDIAN on a ns32k machine.  */
#ifdef ENDIAN
  unsigned long *mem_ptr;
#else
  char *mem_ptr;
#endif

  if (field_ptr->fx_bit_min <= val && val <= field_ptr->fx_bit_max)
    {
#ifdef ENDIAN
      if (field_ptr->fx_bit_base)
       /* Override buf.  */
       mem_ptr = (unsigned long *) field_ptr->fx_bit_base;
      else
       mem_ptr = (unsigned long *) buf;

      mem_ptr = ((unsigned long *)
               ((char *) mem_ptr + field_ptr->fx_bit_base_adj));
#else
      if (field_ptr->fx_bit_base)
       mem_ptr = (char *) field_ptr->fx_bit_base;
      else
       mem_ptr = buf;

      mem_ptr += field_ptr->fx_bit_base_adj;
#endif
#ifdef ENDIAN
      /* We have a nice ns32k machine with lowbyte at low-physical mem.  */
      object = *mem_ptr;    /* get some bytes */
#else /* OVE Goof! the machine is a m68k or dito.  */
      /* That takes more byte fiddling.  */
      object = 0;
      object |= mem_ptr[3] & 0xff;
      object <<= 8;
      object |= mem_ptr[2] & 0xff;
      object <<= 8;
      object |= mem_ptr[1] & 0xff;
      object <<= 8;
      object |= mem_ptr[0] & 0xff;
#endif
      mask = 0;
      mask |= (r_mask[field_ptr->fx_bit_offset]);
      mask |= (l_mask[field_ptr->fx_bit_offset + field_ptr->fx_bit_size]);
      object &= mask;
      val += field_ptr->fx_bit_add;
      object |= ((val << field_ptr->fx_bit_offset) & (mask ^ 0xffffffff));
#ifdef ENDIAN
      *mem_ptr = object;
#else
      mem_ptr[0] = (char) object;
      object >>= 8;
      mem_ptr[1] = (char) object;
      object >>= 8;
      mem_ptr[2] = (char) object;
      object >>= 8;
      mem_ptr[3] = (char) object;
#endif
    }
  else

Here is the call graph for this function:

Here is the caller graph for this function:

static void md_number_to_imm ( char *  buf,
long  val,
int  n 
) [static]

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

{
  switch (n)
    {
    case 1:
#ifdef SHOW_NUM
      printf ("%x ", val & 0xff);
#endif
      *buf++ = val;
      break;

    case 2:
#ifdef SHOW_NUM
      printf ("%x ", val >> 8 & 0xff);
#endif
      *buf++ = (val >> 8);
#ifdef SHOW_NUM
      printf ("%x ", val & 0xff);
#endif
      *buf++ = val;
      break;

    case 4:
#ifdef SHOW_NUM
      printf ("%x ", val >> 24 & 0xff);
#endif
      *buf++ = (val >> 24);
#ifdef SHOW_NUM
      printf ("%x ", val >> 16 & 0xff);
#endif
      *buf++ = (val >> 16);
#ifdef SHOW_NUM
      printf ("%x ", val >> 8 & 0xff);
#endif
      *buf++ = (val >> 8);
#ifdef SHOW_NUM
      printf ("%x ", val & 0xff);
#endif
      *buf++ = val;
      break;

    default:
      as_fatal (_("Internal logic error. line %d, file \"%s\""),
              __LINE__, __FILE__);

Here is the call graph for this function:

Here is the caller graph for this function:

int md_parse_option ( int c  ,
char *  arg 
)

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

{
  switch (c)
    {
    case 'm':
      if (!strcmp (arg, "32032"))
       {
         cpureg = cpureg_032;
         mmureg = mmureg_032;
       }
      else if (!strcmp (arg, "32532"))
       {
         cpureg = cpureg_532;
         mmureg = mmureg_532;
       }
      else
       {
         as_warn (_("invalid architecture option -m%s, ignored"), arg);
         return 0;
       }
      break;
    case OPTION_DISP_SIZE:
      {
       int size = atoi(arg);
       switch (size)
         {
         case 1: case 2: case 4:
           default_disp_size = size;
           break;
         default:
           as_warn (_("invalid default displacement size \"%s\". Defaulting to %d."),
                   arg, default_disp_size);
         }
       break;
      }

    default:
      return 0;
    }

Here is the call graph for this function:

int md_pcrel_adjust ( fragS *  fragP)

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

{
  fragS *opcode_frag;
  addressT opcode_address;
  unsigned int offset;

  opcode_frag = frag_opcode_frag (fragP);
  if (opcode_frag == 0)
    return 0;

  offset = frag_opcode_offset (fragP);
  opcode_address = offset + opcode_frag->fr_address;

Here is the caller graph for this function:

long md_pcrel_from ( fixS *  fixP)

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

{
  long res;

  res = fixP->fx_where + fixP->fx_frag->fr_address;
#ifdef SEQUENT_COMPATABILITY
  if (frag_bsr (fixP->fx_frag))
    res += 0x12                    /* FOO Kludge alert!  */
#endif
valueT md_section_align ( segT segment  ATTRIBUTE_UNUSED,
valueT size   
)

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

{
void md_show_usage ( FILE *  stream)

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

{
  fprintf (stream, _("\
NS32K options:\n\
-m32032 | -m32532    select variant of NS32K architecture\n\

Here is the call graph for this function:

symbolS* md_undefined_symbol ( char *name  ATTRIBUTE_UNUSED)

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

{
static void optlist ( char *  str,
struct ns32k_option optionP,
unsigned long default_map 
) [static]

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

{
  int i, j, k, strlen1, strlen2;
  char *patternP, *strP;

  strlen1 = strlen (str);

  if (strlen1 < 1)
    as_fatal (_("Very short instr to option, ie you can't do it on a NULLstr"));

  for (i = 0; optionP[i].pattern != 0; i++)
    {
      strlen2 = strlen (optionP[i].pattern);

      for (j = 0; j < strlen1; j++)
       {
         patternP = optionP[i].pattern;
         strP = &str[j];

         for (k = 0; k < strlen2; k++)
           {
             if (*(strP++) != *(patternP++))
              break;
           }

         if (k == strlen2)
           {                /* match */
             *default_map |= optionP[i].or;
             *default_map &= optionP[i].and;
           }
       }

Here is the call graph for this function:

Here is the caller graph for this function:

static int parse ( const char *  line,
int  recursive_level 
) [static]

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

{
  const char *lineptr;
  char c, suffix_separator;
  int i;
  unsigned int argc;
  int arg_type;
  char sqr, sep;
  char suffix[MAX_ARGS], *argv[MAX_ARGS]; /* No more than 4 operands.  */

  if (recursive_level <= 0)
    {
      /* Called from md_assemble.  */
      for (lineptr = line; (*lineptr) != '\0' && (*lineptr) != ' '; lineptr++)
       continue;

      c = *lineptr;
      *(char *) lineptr = '\0';

      if (!(desc = (struct ns32k_opcode *) hash_find (inst_hash_handle, line)))
       as_fatal (_("No such opcode"));

      *(char *) lineptr = c;
    }
  else
    lineptr = line;

  argc = 0;

  if (*desc->operands)
    {
      if (*lineptr++ != '\0')
       {
         sqr = '[';
         sep = ',';

         while (*lineptr != '\0')
           {
             if (desc->operands[argc << 1])
              {
                suffix[argc] = 0;
                arg_type = desc->operands[(argc << 1) + 1];

                switch (arg_type)
                  {
                  case 'd':
                  case 'b':
                  case 'p':
                  case 'H':
                    /* The operand is supposed to be a displacement.  */
                    /* Hackwarning: do not forget to update the 4
                         cases above when editing ns32k-opcode.h.  */
                    suffix_separator = ':';
                    break;
                  default:
                    /* If this char occurs we loose.  */
                    suffix_separator = '\255';
                    break;
                  }

                suffix[argc] = 0; /* 0 when no ':' is encountered.  */
                argv[argc] = freeptr;
                *freeptr = '\0';

                while ((c = *lineptr) != '\0' && c != sep)
                  {
                    if (c == sqr)
                     {
                       if (sqr == '[')
                         {
                           sqr = ']';
                           sep = '\0';
                         }
                       else
                         {
                           sqr = '[';
                           sep = ',';
                         }
                     }

                    if (c == suffix_separator)
                     {
                       /* ':' - label/suffix separator.  */
                       switch (lineptr[1])
                         {
                         case 'b':
                           suffix[argc] = 1;
                           break;
                         case 'w':
                           suffix[argc] = 2;
                           break;
                         case 'd':
                           suffix[argc] = 4;
                           break;
                         default:
                           as_warn (_("Bad suffix, defaulting to d"));
                           suffix[argc] = 4;
                           if (lineptr[1] == '\0' || lineptr[1] == sep)
                            {
                              lineptr += 1;
                              continue;
                            }
                           break;
                         }

                       lineptr += 2;
                       continue;
                     }

                    *freeptr++ = c;
                    lineptr++;
                  }

                *freeptr++ = '\0';
                argc += 1;

                if (*lineptr == '\0')
                  continue;

                lineptr += 1;
              }
             else
              as_fatal (_("Too many operands passed to instruction"));
           }
       }
    }

  if (argc != strlen (desc->operands) / 2)
    {
      if (strlen (desc->default_args))
       {
         /* We can apply default, don't goof.  */
         if (parse (desc->default_args, 1) != 1)
           /* Check error in default.  */
           as_fatal (_("Wrong numbers of operands in default, check ns32k-opcodes.h"));
       }
      else
       as_fatal (_("Wrong number of operands"));
    }

  for (i = 0; i < IIF_ENTRIES; i++)
    /* Mark all entries as void.  */
    iif.iifP[i].type = 0;

  /* Build opcode iif-entry.  */
  iif.instr_size = desc->opcode_size / 8;
  IIF (1, 1, iif.instr_size, desc->opcode_seed, 0, 0, 0, 0, 0, 0, -1, 0);

  /* This call encodes operands to iif format.  */
  if (argc)
    encode_operand (argc, argv, &desc->operands[0],
                  &suffix[0], desc->im_size, desc->opcode_size);

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_reloc_code_real_type reloc ( int  size,
int  pcrel,
int  type 
) [static]

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

{
  int length, index;
  bfd_reloc_code_real_type relocs[] =
  {
    BFD_RELOC_NS32K_IMM_8,
    BFD_RELOC_NS32K_IMM_16,
    BFD_RELOC_NS32K_IMM_32,
    BFD_RELOC_NS32K_IMM_8_PCREL,
    BFD_RELOC_NS32K_IMM_16_PCREL,
    BFD_RELOC_NS32K_IMM_32_PCREL,

    /* ns32k displacements.  */
    BFD_RELOC_NS32K_DISP_8,
    BFD_RELOC_NS32K_DISP_16,
    BFD_RELOC_NS32K_DISP_32,
    BFD_RELOC_NS32K_DISP_8_PCREL,
    BFD_RELOC_NS32K_DISP_16_PCREL,
    BFD_RELOC_NS32K_DISP_32_PCREL,

    /* Normal 2's complement.  */
    BFD_RELOC_8,
    BFD_RELOC_16,
    BFD_RELOC_32,
    BFD_RELOC_8_PCREL,
    BFD_RELOC_16_PCREL,
    BFD_RELOC_32_PCREL
  };

  switch (size)
    {
    case 1:
      length = 0;
      break;
    case 2:
      length = 1;
      break;
    case 4:
      length = 2;
      break;
    default:
      length = -1;
      break;
    }

  index = length + 3 * pcrel + 6 * type;

  if (index >= 0 && (unsigned int) index < sizeof (relocs) / sizeof (relocs[0]))
    return relocs[index];

  if (pcrel)
    as_bad (_("Can not do %d byte pc-relative relocation for storage type %d"),
           size, type);
  else
    as_bad (_("Can not do %d byte relocation for storage type %d"),
           size, type);

  return BFD_RELOC_NONE;

Here is the call graph for this function:

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

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

{
  arelent *rel;
  bfd_reloc_code_real_type code;

  code = reloc (fixp->fx_size, fixp->fx_pcrel, fix_im_disp (fixp));

  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;
  if (fixp->fx_pcrel)
    rel->addend = fixp->fx_addnumber;
  else
    rel->addend = 0;

  rel->howto = bfd_reloc_type_lookup (stdoutput, code);
  if (!rel->howto)
    {
      const char *name;

      name = S_GET_NAME (fixp->fx_addsy);
      if (name == NULL)
       name = _("<unknown>");
      as_fatal (_("Cannot find relocation type for symbol %s, code %d"),
              name, (int) code);
    }

Here is the call graph for this function:


Variable Documentation

addr_modeS addr_modeP

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

const char comment_chars[] = "#"

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

struct ns32k_option* cpureg = cpureg_532

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

int default_disp_size = 4 [static]

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

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

char disp_size[]
Initial value:
{4, 1, 2, 0, 4}

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

char disp_test[]
Initial value:
{0, 0, 0, 0, 0, 0, 0, 0,
 1, 1, 1, 1, 1, 1, 1, 1,
 1, 1, 1, 0, 0, 1, 1, 0,
 1, 1, 1, 1, 1, 1, 1, 1}

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

const char EXP_CHARS[] = "eE"

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

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

const char FLT_CHARS[] = "fd"

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

char* freeptr

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

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

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

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

unsigned long l_mask[] [static]
Initial value:
{
  0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
  0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
  0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
  0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
  0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
  0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
  0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
  0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
}

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

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

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

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

size_t md_longopts_size = sizeof (md_longopts)

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

const pseudo_typeS md_pseudo_table[]
Initial value:
{                                  
  {0, 0, 0}
}

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

const relax_typeS md_relax_table[]
Initial value:
{
  {1, 1, 0, 0},
  {1, 1, 0, 0},
  {1, 1, 0, 0},
  {1, 1, 0, 0},

  {(63), (-64), 1, IND (BRANCH, WORD)},
  {(8192), (-8192), 2, IND (BRANCH, DOUBLE)},
  {0, 0, 4, 0},
  {1, 1, 0, 0}
}

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

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

const char* md_shortopts = "m:"

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

struct ns32k_option* mmureg = mmureg_532

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

unsigned long r_mask[] [static]
Initial value:
{
  0x00000000, 0x00000001, 0x00000003, 0x00000007,
  0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
  0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
  0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
  0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
  0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
  0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
  0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
}

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