Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Typedefs | Functions | Variables
tc-z8k.c File Reference
#include "as.h"
#include "safe-ctype.h"
#include "opcodes/z8k-opc.h"

Go to the source code of this file.

Classes

struct  z8k_op
struct  ctrl_names
struct  flag_names
struct  interrupt_names
struct  cc_names

Defines

#define DEFINE_TABLE
#define MAX_LITTLENUMS   6
#define OPTION_RELAX   (OPTION_MD_BASE)

Typedefs

typedef struct z8k_op op_type

Functions

static void s_segm (int segm)
static void even (int ignore ATTRIBUTE_UNUSED)
static int tohex (int c)
static void sval (int ignore ATTRIBUTE_UNUSED)
void md_begin (void)
static char * whatreg (unsigned int *reg, char *src)
static char * parse_reg (char *src, int *mode, unsigned int *reg)
static char * parse_exp (char *s, expressionS *op)
static char * checkfor (char *ptr, char what)
static void regword (int mode, char *string)
static void regaddr (int mode, char *string)
static void get_ctrl_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
static void get_flags_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
static void get_interrupt_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
static void get_cc_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
static void get_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
static char * get_operands (const opcode_entry_type *opcode, char *op_end, op_type *operand)
static opcode_entry_typeget_specific (opcode_entry_type *opcode, op_type *operands)
static void newfix (int ptr, int type, int size, expressionS *operand)
static char * apply_fix (char *ptr, int type, expressionS *operand, int size)
static void build_bytes (opcode_entry_type *this_try, struct z8k_op *operand ATTRIBUTE_UNUSED)
void md_assemble (char *str)
symbolS * md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
char * md_atof (int type, char *litP, int *sizeP)
int md_parse_option (int c, char *arg)
void md_show_usage (FILE *stream)
void md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, fragS *fragP ATTRIBUTE_UNUSED)
arelenttc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp ATTRIBUTE_UNUSED)
valueT md_section_align (segT seg, valueT size)
void md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED)
int md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, segT segment_type ATTRIBUTE_UNUSED)
void md_number_to_chars (char *ptr, valueT use, int nbytes)
long md_pcrel_from (fixS *fixP)
void tc_coff_symbol_emit_hook (symbolS *s ATTRIBUTE_UNUSED)

Variables

const char comment_chars [] = "!"
const char line_comment_chars [] = "#"
const char line_separator_chars [] = ";"
int machine
int coff_flags
int segmented_mode
static int z8k_target_from_cmdline
const pseudo_typeS md_pseudo_table []
const char EXP_CHARS [] = "eE"
const char FLT_CHARS [] = "rRsSfFdDxXpP"
static struct hash_controlopcode_hash_control
static expressionSda_operand
static expressionSimm_operand
static int reg [16]
static int the_cc
static int the_ctrl
static int the_flags
static int the_interrupt
static struct ctrl_names []
static struct flag_names []
static struct interrupt_names []
static struct cc_names []
static char buffer [20]
const char * md_shortopts = "z:"
size_t md_longopts_size = sizeof (md_longopts)

Class Documentation

struct z8k_op

Definition at line 174 of file tc-z8k.c.

Collaboration diagram for z8k_op:
Class Members
expressionS exp
int mode
unsigned int reg
int regsize
unsigned int x_reg
struct ctrl_names

Definition at line 409 of file tc-z8k.c.

Class Members
char * name
int value
struct flag_names

Definition at line 452 of file tc-z8k.c.

Class Members
char * name
int value
struct interrupt_names

Definition at line 502 of file tc-z8k.c.

Class Members
char * name
int value
struct cc_names

Definition at line 566 of file tc-z8k.c.

Class Members
char * name
int value

Define Documentation

#define DEFINE_TABLE

Definition at line 26 of file tc-z8k.c.

#define MAX_LITTLENUMS   6

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

#define OPTION_RELAX   (OPTION_MD_BASE)

Typedef Documentation


Function Documentation

static char* apply_fix ( char *  ptr,
int  type,
expressionS operand,
int  size 
) [static]

Definition at line 985 of file tc-z8k.c.

{
  long n = operand->X_add_number;

  /* size is in nibbles.  */

  newfix ((ptr - buffer) / 2, type, size + 1, operand);
  switch (size)
    {
    case 8:                 /* 8 nibbles == 32 bits.  */
      *ptr++ = n >> 28;
      *ptr++ = n >> 24;
      *ptr++ = n >> 20;
      *ptr++ = n >> 16;
    case 4:                 /* 4 nibbles == 16 bits.  */
      *ptr++ = n >> 12;
      *ptr++ = n >> 8;
    case 2:
      *ptr++ = n >> 4;
    case 1:
      *ptr++ = n >> 0;
      break;
    }
  return ptr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void build_bytes ( opcode_entry_type this_try,
struct z8k_op *operand  ATTRIBUTE_UNUSED 
) [static]

Definition at line 1014 of file tc-z8k.c.

{
  char *output_ptr = buffer;
  int c;
  int nibble;
  unsigned int *class_ptr;

  frag_wane (frag_now);
  frag_new (0);

  if (frag_room () < 8)
    frag_grow (8);  /* Make room for maximum instruction size.  */

  memset (buffer, 0, sizeof (buffer));
  class_ptr = this_try->byte_info;

  for (nibble = 0; (c = *class_ptr++); nibble++)
    {

      switch (c & CLASS_MASK)
       {
       default:
         abort ();

       case CLASS_ADDRESS:
         /* Direct address, we don't cope with the SS mode right now.  */
         if (segmented_mode)
           {
             /* da_operand->X_add_number |= 0x80000000;  --  Now set at relocation time.  */
             output_ptr = apply_fix (output_ptr, BFD_RELOC_32, da_operand, 8);
           }
         else
           {
             output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4);
           }
         da_operand = 0;
         break;
       case CLASS_DISP8:
         /* pc rel 8 bit  */
         output_ptr = apply_fix (output_ptr, BFD_RELOC_8_PCREL, da_operand, 2);
         da_operand = 0;
         break;

       case CLASS_0DISP7:
         /* pc rel 7 bit  */
         *output_ptr = 0;
         output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2);
         da_operand = 0;
         break;

       case CLASS_1DISP7:
         /* pc rel 7 bit  */
         *output_ptr = 0x80;
         output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2);
         output_ptr[-2] = 0x8;
         da_operand = 0;
         break;

       case CLASS_BIT_1OR2:
         *output_ptr = c & 0xf;
         if (imm_operand)
           {
             if (imm_operand->X_add_number == 2)
              *output_ptr |= 2;
             else if (imm_operand->X_add_number != 1)
              as_bad (_("immediate must be 1 or 2"));
           }
         else
           as_bad (_("immediate 1 or 2 expected"));
         output_ptr++;
         break;
       case CLASS_CC:
         *output_ptr++ = the_cc;
         break;
       case CLASS_0CCC:
         if (the_ctrl < 2 || the_ctrl > 7)
           as_bad (_("invalid control register name"));
         *output_ptr++ = the_ctrl;
         break;
       case CLASS_1CCC:
         if (the_ctrl < 2 || the_ctrl > 7)
           as_bad (_("invalid control register name"));
         *output_ptr++ = the_ctrl | 0x8;
         break;
       case CLASS_00II:
         *output_ptr++ = (~the_interrupt & 0x3);
         break;
       case CLASS_01II:
         *output_ptr++ = (~the_interrupt & 0x3) | 0x4;
         break;
       case CLASS_FLAGS:
         *output_ptr++ = the_flags;
         break;
       case CLASS_IGNORE:
       case CLASS_BIT:
         *output_ptr++ = c & 0xf;
         break;
       case CLASS_REGN0:
         if (reg[c & 0xf] == 0)
           as_bad (_("can't use R0 here"));
         /* Fall through.  */
       case CLASS_REG:
       case CLASS_REG_BYTE:
       case CLASS_REG_WORD:
       case CLASS_REG_LONG:
       case CLASS_REG_QUAD:
         /* Insert bit mattern of right reg.  */
         *output_ptr++ = reg[c & 0xf];
         break;
       case CLASS_DISP:
          switch (c & ARG_MASK)
            {
            case ARG_DISP12:
              output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_CALLR, da_operand, 4);
              break;
            case ARG_DISP16:
             output_ptr = apply_fix (output_ptr, BFD_RELOC_16_PCREL, da_operand, 4);
             break;
           default:
             output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4);
           }
         da_operand = 0;
         break;

       case CLASS_IMM:
         {
           switch (c & ARG_MASK)
             {
             case ARG_NIM4:
                if (imm_operand->X_add_number > 15)
                as_bad (_("immediate value out of range"));
              imm_operand->X_add_number = -imm_operand->X_add_number;
              output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1);
              break;
              /*case ARG_IMMNMINUS1: not used.  */
             case ARG_IMM4M1:
              imm_operand->X_add_number--;
                /* Drop through.  */
             case ARG_IMM4:
                if (imm_operand->X_add_number > 15)
                as_bad (_("immediate value out of range"));
              output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1);
              break;
             case ARG_NIM8:
              imm_operand->X_add_number = -imm_operand->X_add_number;
                /* Drop through.  */
             case ARG_IMM8:
              output_ptr = apply_fix (output_ptr, BFD_RELOC_8, imm_operand, 2);
              break;
             case ARG_IMM16:
              output_ptr = apply_fix (output_ptr, BFD_RELOC_16, imm_operand, 4);
              break;
             case ARG_IMM32:
              output_ptr = apply_fix (output_ptr, BFD_RELOC_32, imm_operand, 8);
              break;
             default:
              abort ();
             }
         }
       }
    }

  /* Copy from the nibble buffer into the frag.  */
  {
    int length = (output_ptr - buffer) / 2;
    char *src = buffer;
    char *fragp = frag_more (length);

    while (src < output_ptr)
      {
       *fragp = (src[0] << 4) | src[1];
       src += 2;
       fragp++;
      }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* checkfor ( char *  ptr,
char  what 
) [static]

Definition at line 371 of file tc-z8k.c.

{
  if (*ptr == what)
    ptr++;
  else
    as_bad (_("expected %c"), what);

  return ptr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void even ( int ignore  ATTRIBUTE_UNUSED) [static]

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

{
  frag_align (1, 0, 0);
  record_alignment (now_seg, 1);
}

Here is the call graph for this function:

static void get_cc_operand ( char **  ptr,
struct z8k_op mode,
unsigned int dst  ATTRIBUTE_UNUSED 
) [static]

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

{
  char *src = *ptr;
  int i, l;

  while (*src == ' ')
    src++;

  mode->mode = CLASS_CC;
  for (i = 0; table[i].name; i++)
    {
      l = strlen (table[i].name);
      if (! strncasecmp (table[i].name, src, l))
        {
          the_cc = table[i].value;
          if (*(src + l) && *(src + l) != ',')
            break;
          *ptr = src + l;  /* Valid cc found: "consume" it.  */
          return;
        }
    }
  the_cc = 0x8;  /* Not recognizing the cc defaults to t.  (Assuming no cc present.)  */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void get_ctrl_operand ( char **  ptr,
struct z8k_op mode,
unsigned int dst  ATTRIBUTE_UNUSED 
) [static]

Definition at line 428 of file tc-z8k.c.

{
  char *src = *ptr;
  int i, l;

  while (*src == ' ')
    src++;

  mode->mode = CLASS_CTRL;
  for (i = 0; ctrl_table[i].name; i++)
    {
      l = strlen (ctrl_table[i].name);
      if (! strncasecmp (ctrl_table[i].name, src, l))
        {
          the_ctrl = ctrl_table[i].value;
          if (*(src + l) && *(src + l) != ',')
            break;
          *ptr = src + l;  /* Valid control name found: "consume" it.  */
          return;
        }
    }
  the_ctrl = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void get_flags_operand ( char **  ptr,
struct z8k_op mode,
unsigned int dst  ATTRIBUTE_UNUSED 
) [static]

Definition at line 469 of file tc-z8k.c.

{
  char *src = *ptr;
  char c;
  int i;
  int j;

  while (*src == ' ')
    src++;

  mode->mode = CLASS_FLAGS;
  the_flags = 0;
  for (j = 0; j <= 9; j++)
    {
      if (!src[j])
       goto done;
      c = TOUPPER(src[j]);
      for (i = 0; flag_table[i].name; i++)
       {
         if (flag_table[i].name[0] == c)
           {
             the_flags = the_flags | flag_table[i].value;
             goto match;
           }
       }
      goto done;
    match:
      ;
    }
 done:
  *ptr = src + j;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void get_interrupt_operand ( char **  ptr,
struct z8k_op mode,
unsigned int dst  ATTRIBUTE_UNUSED 
) [static]

Definition at line 516 of file tc-z8k.c.

{
  char *src = *ptr;
  int i, l;

  while (*src == ' ')
    src++;

  mode->mode = CLASS_IMM;
  the_interrupt = 0;

  while (*src)
    {
      for (i = 0; intr_table[i].name; i++)
       {
         l = strlen (intr_table[i].name);
         if (! strncasecmp (intr_table[i].name, src, l))
           {
             the_interrupt |= intr_table[i].value;
             if (*(src + l) && *(src + l) != ',')
              {
                *ptr = src + l;
              invalid:
                as_bad (_("unknown interrupt %s"), src);
                while (**ptr && ! is_end_of_line[(unsigned char) **ptr])
                  (*ptr)++;  /* Consume rest of line.  */
                return;
              }
             src += l;
             if (! *src)
              {
                *ptr = src;
                return;
              }
           }
       }
      if (*src == ',')
       src++;
      else
       {
         *ptr = src;
         goto invalid;
       }
    }

  /* No interrupt type specified, opcode won't do anything.  */
  as_warn (_("opcode has no effect"));
  the_interrupt = 0x0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void get_operand ( char **  ptr,
struct z8k_op mode,
unsigned int dst  ATTRIBUTE_UNUSED 
) [static]

Definition at line 631 of file tc-z8k.c.

{
  char *src = *ptr;
  char *end;

  mode->mode = 0;

  while (*src == ' ')
    src++;
  if (*src == '#')
    {
      mode->mode = CLASS_IMM;
      imm_operand = &(mode->exp);
      src = parse_exp (src + 1, &(mode->exp));
    }
  else if (*src == '@')
    {
      mode->mode = CLASS_IR;
      src = parse_reg (src + 1, &mode->regsize, &mode->reg);
    }
  else
    {
      unsigned int regn;

      end = parse_reg (src, &mode->mode, &regn);

      if (end)
       {
         int nw;
         unsigned int nr;

         src = end;
         if (*src == '(')
           {
             src++;
             end = parse_reg (src, &nw, &nr);
             if (end)
              {
                /* Got Ra(Rb).  */
                src = end;

                if (*src != ')')
                  as_bad (_("Missing ) in ra(rb)"));
                else
                  src++;

                regaddr (mode->mode, "ra(rb) ra");
                mode->mode = CLASS_BX;
                mode->reg = regn;
                mode->x_reg = nr;
                reg[ARG_RX] = nr;
              }
             else
              {
                /* Got Ra(disp).  */
                if (*src == '#')
                  src++;
                src = parse_exp (src, &(mode->exp));
                src = checkfor (src, ')');
                mode->mode = CLASS_BA;
                mode->reg = regn;
                mode->x_reg = 0;
                imm_operand = &(mode->exp);
              }
           }
         else
           {
             mode->reg = regn;
             mode->x_reg = 0;
           }
       }
      else
       {
         /* No initial reg.  */
         src = parse_exp (src, &(mode->exp));
         if (*src == '(')
           {
             src++;
             end = parse_reg (src, &(mode->mode), &regn);
             regword (mode->mode, "addr(Ra) ra");
             mode->mode = CLASS_X;
             mode->reg = regn;
             mode->x_reg = 0;
             da_operand = &(mode->exp);
             src = checkfor (end, ')');
           }
         else
           {
             /* Just an address.  */
             mode->mode = CLASS_DA;
             mode->reg = 0;
             mode->x_reg = 0;
             da_operand = &(mode->exp);
           }
       }
    }
  *ptr = src;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* get_operands ( const opcode_entry_type opcode,
char *  op_end,
op_type operand 
) [static]

Definition at line 731 of file tc-z8k.c.

{
  char *ptr = op_end;
  char *savptr;

  switch (opcode->noperands)
    {
    case 0:
      operand[0].mode = 0;
      operand[1].mode = 0;
      while (*ptr == ' ')
        ptr++;
      break;

    case 1:
      if (opcode->arg_info[0] == CLASS_CC)
        {
          get_cc_operand (&ptr, operand + 0, 0);
          while (*ptr == ' ')
            ptr++;
          if (*ptr && ! is_end_of_line[(unsigned char) *ptr])
            {
              as_bad (_("invalid condition code '%s'"), ptr);
              while (*ptr && ! is_end_of_line[(unsigned char) *ptr])
                ptr++;   /* Consume rest of line.  */
            }
        }
      else if (opcode->arg_info[0] == CLASS_FLAGS)
       {
         get_flags_operand (&ptr, operand + 0, 0);
         while (*ptr == ' ')
           ptr++;
         if (*ptr && ! is_end_of_line[(unsigned char) *ptr])
           {
             as_bad (_("invalid flag '%s'"), ptr);
             while (*ptr && ! is_end_of_line[(unsigned char) *ptr])
              ptr++;  /* Consume rest of line.  */
           }
       }
      else if (opcode->arg_info[0] == (CLASS_IMM + (ARG_IMM2)))
       get_interrupt_operand (&ptr, operand + 0, 0);
      else
       get_operand (&ptr, operand + 0, 0);

      operand[1].mode = 0;
      break;

    case 2:
      savptr = ptr;
      if (opcode->arg_info[0] == CLASS_CC)
        {
          get_cc_operand (&ptr, operand + 0, 0);
          while (*ptr == ' ')
            ptr++;
          if (*ptr != ',' && strchr (ptr + 1, ','))
            {
              savptr = ptr;
              while (*ptr != ',')
                ptr++;
              *ptr = 0;
              ptr++;
              as_bad (_("invalid condition code '%s'"), savptr);
            }
        }
      else if (opcode->arg_info[0] == CLASS_CTRL)
       {
         get_ctrl_operand (&ptr, operand + 0, 0);

         if (the_ctrl == 0)
           {
             ptr = savptr;
             get_operand (&ptr, operand + 0, 0);

             if (ptr == 0)
              return NULL;
             if (*ptr == ',')
              ptr++;
             get_ctrl_operand (&ptr, operand + 1, 1);
             if (the_ctrl == 0)
              return NULL;
             return ptr;
           }
       }
      else
       get_operand (&ptr, operand + 0, 0);

      if (ptr == 0)
       return NULL;
      if (*ptr == ',')
       ptr++;
      get_operand (&ptr, operand + 1, 1);
      break;

    case 3:
      get_operand (&ptr, operand + 0, 0);
      if (*ptr == ',')
       ptr++;
      get_operand (&ptr, operand + 1, 1);
      if (*ptr == ',')
       ptr++;
      get_operand (&ptr, operand + 2, 2);
      break;

    case 4:
      get_operand (&ptr, operand + 0, 0);
      if (*ptr == ',')
       ptr++;
      get_operand (&ptr, operand + 1, 1);
      if (*ptr == ',')
       ptr++;
      get_operand (&ptr, operand + 2, 2);
      if (*ptr == ',')
       ptr++;
      get_cc_operand (&ptr, operand + 3, 3);
      break;

    default:
      abort ();
    }

  return ptr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static opcode_entry_type* get_specific ( opcode_entry_type opcode,
op_type operands 
) [static]

Definition at line 859 of file tc-z8k.c.

{
  opcode_entry_type *this_try = opcode;
  int found = 0;
  unsigned int noperands = opcode->noperands;

  int this_index = opcode->idx;

  while (this_index == opcode->idx && !found)
    {
      unsigned int i;

      this_try = opcode++;
      for (i = 0; i < noperands; i++)
       {
         unsigned int mode = operands[i].mode;

          if (((mode & CLASS_MASK) == CLASS_IR) && ((this_try->arg_info[i] & CLASS_MASK) == CLASS_IRO))
            {
              mode = operands[i].mode = (operands[i].mode & ~CLASS_MASK) | CLASS_IRO;
            }

         if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
           {
             /* It could be a pc rel operand, if this is a da mode
               and we like disps, then insert it.  */

             if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)
              {
                /* This is the case.  */
                operands[i].mode = CLASS_DISP;
              }
             else if (mode == CLASS_BA && this_try->arg_info[i])
              {
                /* Can't think of a way to turn what we've been
                   given into something that's OK.  */
                goto fail;
              }
             else if (this_try->arg_info[i] & CLASS_PR)
              {
                if (mode == CLASS_REG_LONG && segmented_mode)
                  {
                    /* OK.  */
                  }
                else if (mode == CLASS_REG_WORD && !segmented_mode)
                  {
                    /* OK.  */
                  }
                else
                  goto fail;
              }
             else
              goto fail;
           }
         switch (mode & CLASS_MASK)
           {
           default:
             break;
           case CLASS_IRO:
             if (operands[i].regsize != CLASS_REG_WORD)
              as_bad (_("invalid indirect register size"));
             reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
             break;
           case CLASS_IR:
             if ((segmented_mode && operands[i].regsize != CLASS_REG_LONG)
                || (!segmented_mode && operands[i].regsize != CLASS_REG_WORD))
              as_bad (_("invalid indirect register size"));
             reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
             break;
           case CLASS_X:
           case CLASS_BA:
           case CLASS_BX:
           case CLASS_DISP:
           case CLASS_REG:
           case CLASS_REG_WORD:
           case CLASS_REG_BYTE:
           case CLASS_REG_QUAD:
           case CLASS_REG_LONG:
           case CLASS_REGN0:
             reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
             break;
           case CLASS_CTRL:
             if (this_try->opcode == OPC_ldctlb && the_ctrl != 1)
              as_bad (_("invalid control register name"));
             break;
           }
       }

      found = 1;
    fail:
      ;
    }
  if (found)
    return this_try;
  else
    return 0;
}

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 segment  ATTRIBUTE_UNUSED 
)

Definition at line 1444 of file tc-z8k.c.

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

  switch (fixP->fx_r_type)
    {
    case BFD_RELOC_Z8K_IMM4L:
      if (fixP->fx_addsy)
        {
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 0;
        }
      else
       buf[0] = (buf[0] & 0xf0) | (val & 0xf);
      break;

    case BFD_RELOC_8:
      if (fixP->fx_addsy)
        {
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 0;
        }
      else
       *buf++ = val;
      break;

    case BFD_RELOC_16:
      if (fixP->fx_addsy)
        {
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 0;
        }
      else
        {
          *buf++ = (val >> 8);
          *buf++ = val;
        }
      break;

    case BFD_RELOC_32:
      if (fixP->fx_addsy)
        {
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 0;
        }
      else
        {
          *buf++ = (val >> 24);
          *buf++ = (val >> 16);
          *buf++ = (val >> 8);
          *buf++ = val;
        }
      break;

    case BFD_RELOC_8_PCREL:
      if (fixP->fx_addsy)
        {
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 0;
        }
      else
        {
          if (val & 1)
            as_bad_where (fixP->fx_file, fixP->fx_line,
                          _("cannot branch to odd address"));
          val /= 2;
          if (val > 127 || val < -128)
            as_bad_where (fixP->fx_file, fixP->fx_line,
                          _("relative jump out of range"));
          *buf++ = val;
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 1;
        }
      break;

    case BFD_RELOC_16_PCREL:
      if (fixP->fx_addsy)
        {
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 0;
        }
      else
        {
          val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size;
          if (val > 32767 || val < -32768)
            as_bad_where (fixP->fx_file, fixP->fx_line,
                          _("relative address out of range"));
          *buf++ = (val >> 8);
          *buf++ = val;
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 1;
        }
      break;

    case BFD_RELOC_Z8K_CALLR:
      if (fixP->fx_addsy)
        {
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 0;
        }
      else
        {
          if (val & 1)
            as_bad_where (fixP->fx_file, fixP->fx_line,
                          _("cannot branch to odd address"));
          if (val > 4096 || val < -4095)
            as_bad_where (fixP->fx_file, fixP->fx_line,
                          _("relative call out of range"));
          val = -val / 2;
          *buf = (*buf & 0xf0) | ((val >> 8) & 0xf);
          buf++;
          *buf++ = val & 0xff;
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 1;
        }
      break;

    case BFD_RELOC_Z8K_DISP7:
      if (fixP->fx_addsy)
        {
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 0;
        }
      else
        {
          if (val & 1)
            as_bad_where (fixP->fx_file, fixP->fx_line,
                          _("cannot branch to odd address"));
          val /= 2;
          if (val > 0 || val < -127)
            as_bad_where (fixP->fx_file, fixP->fx_line,
                          _("relative jump out of range"));
          *buf = (*buf & 0x80) | (-val & 0x7f);
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 1;
        }
      break;

    default:
      printf(_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
      abort ();
    }

  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
    fixP->fx_done = 1;
}

Here is the call graph for this function:

void md_assemble ( char *  str)

Definition at line 1196 of file tc-z8k.c.

{
  char c;
  char *op_start;
  char *op_end;
  struct z8k_op operand[4];
  opcode_entry_type *opcode;

  /* Drop leading whitespace.  */
  while (*str == ' ')
    str++;

  /* Find the op code end.  */
  for (op_start = op_end = str;
       *op_end != 0 && *op_end != ' ' && ! is_end_of_line[(unsigned char) *op_end];
       op_end++)
    ;

  if (op_end == op_start)
    {
      as_bad (_("can't find opcode "));
    }
  c = *op_end;

  *op_end = 0;  /* Zero-terminate op code string for hash_find() call.  */

  opcode = (opcode_entry_type *) hash_find (opcode_hash_control, op_start);

  if (opcode == NULL)
    {
      as_bad (_("unknown opcode"));
      return;
    }

  *op_end = c;  /* Restore original string.  */

  if (opcode->opcode == 250)
    {
      pseudo_typeS *p;
      char oc;
      char *old = input_line_pointer;

      /* Was really a pseudo op.  */

      input_line_pointer = op_end;

      oc = *old;
      *old = '\n';
      while (*input_line_pointer == ' ')
       input_line_pointer++;
      p = (pseudo_typeS *) (opcode->func);

      (p->poc_handler) (p->poc_val);
      input_line_pointer = old;
      *old = oc;
    }
  else
    {
      char *new_input_line_pointer;

      new_input_line_pointer = get_operands (opcode, op_end, operand);
      if (new_input_line_pointer)
        {
          input_line_pointer = new_input_line_pointer;
          opcode = get_specific (opcode, operand);
        }

      if (new_input_line_pointer == NULL || opcode == NULL)
       {
         /* Couldn't find an opcode which matched the operands.  */
         char *where = frag_more (2);

         where[0] = 0x0;
         where[1] = 0x0;

         as_bad (_("Can't find opcode to match operands"));
         return;
       }

      build_bytes (opcode, operand);
    }
}

Here is the call graph for this function:

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

Definition at line 1297 of file tc-z8k.c.

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

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

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

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

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

    default:
      *sizeP = 0;
      return _("Bad call to MD_ATOF()");
    }
  t = atof_ieee (input_line_pointer, type, words);
  if (t)
    input_line_pointer = t;

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

Here is the call graph for this function:

void md_begin ( void  )

Definition at line 143 of file tc-z8k.c.

{
  const opcode_entry_type *opcode;
  int idx = -1;

  opcode_hash_control = hash_new ();

  for (opcode = z8k_table; opcode->name; opcode++)
    {
      /* Only enter unique codes into the table.  */
      if (idx != opcode->idx)
       hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
      idx = opcode->idx;
    }

  /* Default to z8002.  */
  if (! z8k_target_from_cmdline)
    s_segm (0);

  /* Insert the pseudo ops, too.  */
  for (idx = 0; md_pseudo_table[idx].poc_name; idx++)
    {
      opcode_entry_type *fake_opcode;
      fake_opcode = (opcode_entry_type *) malloc (sizeof (opcode_entry_type));
      fake_opcode->name = md_pseudo_table[idx].poc_name;
      fake_opcode->func = (void *) (md_pseudo_table + idx);
      fake_opcode->opcode = 250;
      hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode);
    }
}

Here is the call graph for this function:

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

Definition at line 1398 of file tc-z8k.c.

{
  printf (_("call to md_convert_frag\n"));
  abort ();
}

Here is the call graph for this function:

int md_estimate_size_before_relax ( fragS *fragP  ATTRIBUTE_UNUSED,
segT segment_type  ATTRIBUTE_UNUSED 
)

Definition at line 1593 of file tc-z8k.c.

{
  printf (_("call to md_estimate_size_before_relax\n"));
  abort ();
}

Here is the call graph for this function:

void md_number_to_chars ( char *  ptr,
valueT  use,
int  nbytes 
)

Definition at line 1603 of file tc-z8k.c.

{
  number_to_chars_bigendian (ptr, use, nbytes);
}

Here is the call graph for this function:

int md_parse_option ( int c  ,
char *  arg 
)

Definition at line 1359 of file tc-z8k.c.

{
  switch (c)
    {
    case 'z':
      if (!strcmp (arg, "8001"))
       s_segm (1);
      else if (!strcmp (arg, "8002"))
       s_segm (0);
      else
       {
         as_bad (_("invalid architecture -z%s"), arg);
         return 0;
       }
      z8k_target_from_cmdline = 1;
      break;

    case OPTION_RELAX:
      linkrelax = 1;
      break;

    default:
      return 0;
    }

  return 1;
}

Here is the call graph for this function:

long md_pcrel_from ( fixS *  fixP)

Definition at line 1611 of file tc-z8k.c.

{
  return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
}

Definition at line 1432 of file tc-z8k.c.

{
  int align = bfd_get_section_alignment (stdoutput, seg);
  valueT mask = ((valueT) 1 << align) - 1;

  return (size + mask) & ~mask;
}

Here is the call graph for this function:

void md_show_usage ( FILE *  stream)

Definition at line 1388 of file tc-z8k.c.

{
  fprintf (stream, _("\
 Z8K options:\n\
  -z8001                  generate segmented code\n\
  -z8002                  generate unsegmented code\n\
  -linkrelax              create linker relaxable code\n"));
}

Here is the call graph for this function:

symbolS* md_undefined_symbol ( char *name  ATTRIBUTE_UNUSED)

Definition at line 1282 of file tc-z8k.c.

{
  return 0;
}
static void newfix ( int  ptr,
int  type,
int  size,
expressionS operand 
) [static]

Definition at line 960 of file tc-z8k.c.

{
  int is_pcrel = 0;
  fixS *fixP;

  /* Size is in nibbles.  */
  if (operand->X_add_symbol
      || operand->X_op_symbol
      || operand->X_add_number)
    {
      switch(type)
        {
        case BFD_RELOC_8_PCREL:
        case BFD_RELOC_Z8K_CALLR:
        case BFD_RELOC_Z8K_DISP7:
          is_pcrel = 1;
        }
      fixP = fix_new_exp (frag_now, ptr, size / 2,
                          operand, is_pcrel, type);
      if (is_pcrel)
       fixP->fx_no_overflow = 1;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* parse_exp ( char *  s,
expressionS op 
) [static]

Definition at line 342 of file tc-z8k.c.

{
  char *save = input_line_pointer;
  char *new;

  input_line_pointer = s;
  expression (op);
  if (op->X_op == O_absent)
    as_bad (_("missing operand"));
  new = input_line_pointer;
  input_line_pointer = save;
  return new;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* parse_reg ( char *  src,
int mode,
unsigned int reg 
) [static]

Definition at line 247 of file tc-z8k.c.

{
  char *res = NULL;
  char regno;

  /* Check for stack pointer "sp" alias.  */
  if ((src[0] == 's' || src[0] == 'S')
      && (src[1] == 'p' || src[1] == 'P')
      && (src[2] == 0 || src[2] == ','))
    {
      if (segmented_mode)
       {
         *mode = CLASS_REG_LONG;
         *reg = 14;
       }
      else
       {
         *mode = CLASS_REG_WORD;
         *reg = 15;
       }
      return src + 2;
    }

  if (src[0] == 'r' || src[0] == 'R')
    {
      if (src[1] == 'r' || src[1] == 'R')
       {
         if (src[2] < '0' || src[2] > '9')
           return NULL;     /* Assume no register name but a label starting with 'rr'.  */
         *mode = CLASS_REG_LONG;
         res = whatreg (reg, src + 2);
         if (res == NULL)
           return NULL;     /* Not a valid register name.  */
         regno = *reg;
         if (regno > 14)
           as_bad (_("register rr%d out of range"), regno);
         if (regno & 1)
           as_bad (_("register rr%d does not exist"), regno);
       }
      else if (src[1] == 'h' || src[1] == 'H')
       {
         if (src[2] < '0' || src[2] > '9')
           return NULL;     /* Assume no register name but a label starting with 'rh'.  */
         *mode = CLASS_REG_BYTE;
         res = whatreg (reg, src + 2);
         if (res == NULL)
           return NULL;     /* Not a valid register name.  */
         regno = *reg;
         if (regno > 7)
           as_bad (_("register rh%d out of range"), regno);
       }
      else if (src[1] == 'l' || src[1] == 'L')
       {
         if (src[2] < '0' || src[2] > '9')
           return NULL;     /* Assume no register name but a label starting with 'rl'.  */
         *mode = CLASS_REG_BYTE;
         res = whatreg (reg, src + 2);
         if (res == NULL)
           return NULL;     /* Not a valid register name.  */
         regno = *reg;
         if (regno > 7)
           as_bad (_("register rl%d out of range"), regno);
         *reg += 8;
       }
      else if (src[1] == 'q' || src[1] == 'Q')
       {
         if (src[2] < '0' || src[2] > '9')
           return NULL;     /* Assume no register name but a label starting with 'rq'.  */
         *mode = CLASS_REG_QUAD;
         res = whatreg (reg, src + 2);
         if (res == NULL)
           return NULL;     /* Not a valid register name.  */
         regno = *reg;
         if (regno > 12)
           as_bad (_("register rq%d out of range"), regno);
         if (regno & 3)
           as_bad (_("register rq%d does not exist"), regno);
       }
      else
       {
         if (src[1] < '0' || src[1] > '9')
           return NULL;     /* Assume no register name but a label starting with 'r'.  */
         *mode = CLASS_REG_WORD;
         res = whatreg (reg, src + 1);
         if (res == NULL)
           return NULL;     /* Not a valid register name.  */
         regno = *reg;
         if (regno > 15)
           as_bad (_("register r%d out of range"), regno);
       }
    }
  return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void regaddr ( int  mode,
char *  string 
) [static]

Definition at line 398 of file tc-z8k.c.

{
  int ok;

  ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD;
  if (ok != mode)
    {
      as_bad (_("register is wrong size for address %s"), string);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void regword ( int  mode,
char *  string 
) [static]

Definition at line 384 of file tc-z8k.c.

{
  int ok;

  ok = CLASS_REG_WORD;
  if (ok != mode)
    {
      as_bad (_("register is wrong size for a word %s"), string);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void s_segm ( int  segm) [static]

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

Here is the caller graph for this function:

static void sval ( int ignore  ATTRIBUTE_UNUSED) [static]

Definition at line 73 of file tc-z8k.c.

{
  SKIP_WHITESPACE ();
  if (*input_line_pointer == '\'')
    {
      int c;
      input_line_pointer++;
      c = *input_line_pointer++;
      while (c != '\'')
       {
         if (c == '%')
           {
             c = (tohex (input_line_pointer[0]) << 4)
              | tohex (input_line_pointer[1]);
             input_line_pointer += 2;
           }
         FRAG_APPEND_1_CHAR (c);
         c = *input_line_pointer++;
       }
      demand_empty_rest_of_line ();
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void tc_coff_symbol_emit_hook ( symbolS *s  ATTRIBUTE_UNUSED)

Definition at line 1617 of file tc-z8k.c.

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

Definition at line 1409 of file tc-z8k.c.

{
  arelent *reloc;

  reloc = xmalloc (sizeof (*reloc));
  reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
  reloc->addend = fixp->fx_offset;
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);

  if (! reloc->howto)
    {
      as_bad_where (fixp->fx_file, fixp->fx_line,
                    "Cannot represent %s relocation in object file",
                    bfd_get_reloc_code_name (fixp->fx_r_type));
      abort ();
    }
  return reloc;
}

Here is the call graph for this function:

static int tohex ( int  c) [static]

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

{
  if (ISDIGIT (c))
    return c - '0';
  if (ISLOWER (c))
    return c - 'a' + 10;
  return c - 'A' + 10;
}

Here is the caller graph for this function:

static char* whatreg ( unsigned int reg,
char *  src 
) [static]

Definition at line 206 of file tc-z8k.c.

{
  unsigned int new_reg;

  /* src[0] is already known to be a digit.  */
  if (ISDIGIT (src[1]))
    {
      new_reg = (src[0] - '0') * 10 + src[1] - '0';
      src += 2;
    }
  else
    {
      new_reg = (src[0] - '0');
      src += 1;
    }

  if (src[0] != 0 && src[0] != ',' && src[0] != '(' && src[0] != ')')
    return NULL;

  *reg = new_reg;
  return src;
}

Here is the caller graph for this function:


Variable Documentation

char buffer[20] [static]

Definition at line 957 of file tc-z8k.c.

struct cc_names[] [static]

Definition at line 571 of file tc-z8k.c.

const char comment_chars[] = "!"

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

struct ctrl_names[] [static]
Initial value:
 {
  { 0x1, "flags" },   
  { 0x2, "fcw" },     
  { 0x3, "refresh" },
  { 0x4, "psapseg" },
  { 0x5, "psapoff" },
  { 0x5, "psap" },
  { 0x6, "nspseg" },
  { 0x7, "nspoff" },
  { 0x7, "nsp" },
  { 0  , 0 }
}

Definition at line 414 of file tc-z8k.c.

Definition at line 190 of file tc-z8k.c.

const char EXP_CHARS[] = "eE"

Definition at line 132 of file tc-z8k.c.

struct flag_names[] [static]
Initial value:
 {
  { 0x1, "P" },
  { 0x1, "V" },
  { 0x2, "S" },
  { 0x4, "Z" },
  { 0x8, "C" },
  { 0x0, "+" },
  { 0x0, "," },
  { 0, 0 }
}

Definition at line 457 of file tc-z8k.c.

const char FLT_CHARS[] = "rRsSfFdDxXpP"

Definition at line 137 of file tc-z8k.c.

Definition at line 191 of file tc-z8k.c.

struct interrupt_names[] [static]
Initial value:
 {
  { 0x1, "nvi" },
  { 0x2, "vi" },
  { 0x3, "both" },
  { 0x3, "all" },
  { 0, 0 }
}

Definition at line 507 of file tc-z8k.c.

const char line_comment_chars[] = "#"

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

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

size_t md_longopts_size = sizeof (md_longopts)

Definition at line 1356 of file tc-z8k.c.

const pseudo_typeS md_pseudo_table[]
Initial value:
 {
  {"int"    , cons            , 2},
  {"data.b" , cons            , 1},
  {"data.w" , cons            , 2},
  {"data.l" , cons            , 4},
  {"form"   , listing_psize   , 0},
  {"heading", listing_title   , 0},
  {"import" , s_ignore        , 0},
  {"page"   , listing_eject   , 0},
  {"program", s_ignore        , 0},
  {"z8001"  , s_segm          , 1},
  {"z8002"  , s_segm          , 0},

  {"segm"   , s_segm          , 1},
  {"unsegm" , s_segm          , 0},
  {"unseg"  , s_segm          , 0},
  {"name"   , s_app_file      , 0},
  {"global" , s_globl         , 0},
  {"wval"   , cons            , 2},
  {"lval"   , cons            , 4},
  {"bval"   , cons            , 1},
  {"sval"   , sval            , 0},
  {"rsect"  , obj_coff_section, 0},
  {"sect"   , obj_coff_section, 0},
  {"block"  , s_space         , 0},
  {"even"   , even            , 0},
  {0        , 0               , 0}
}

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

const char* md_shortopts = "z:"

Definition at line 1347 of file tc-z8k.c.

Definition at line 140 of file tc-z8k.c.

int reg[16] [static]

Definition at line 193 of file tc-z8k.c.

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

int the_cc [static]

Definition at line 194 of file tc-z8k.c.

int the_ctrl [static]

Definition at line 195 of file tc-z8k.c.

int the_flags [static]

Definition at line 196 of file tc-z8k.c.

int the_interrupt [static]

Definition at line 197 of file tc-z8k.c.

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