Back to index

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

Go to the source code of this file.

Classes

struct  _table_t
struct  reg_entry

Defines

#define INS_Z80   1
#define INS_UNDOC   2
#define INS_UNPORT   4
#define INS_R800   8
#define BUFLEN   8 /* Large enough for any keyword. */
#define R_STACKABLE   (0x80)
#define R_ARITH   (0x40)
#define R_IX   (0x20)
#define R_IY   (0x10)
#define R_INDEX   (R_IX | R_IY)
#define REG_A   (7)
#define REG_B   (0)
#define REG_C   (1)
#define REG_D   (2)
#define REG_E   (3)
#define REG_H   (4)
#define REG_L   (5)
#define REG_F   (6 | 8)
#define REG_I   (9)
#define REG_R   (10)
#define REG_AF   (3 | R_STACKABLE)
#define REG_BC   (0 | R_STACKABLE | R_ARITH)
#define REG_DE   (1 | R_STACKABLE | R_ARITH)
#define REG_HL   (2 | R_STACKABLE | R_ARITH)
#define REG_SP   (3 | R_ARITH)

Typedefs

typedef const char *( asfunc )(char, char, const char *)
typedef struct _table_t table_t

Enumerations

enum  options {
  OPTION_EB = OPTION_MD_BASE, OPTION_EL, OPTION_ARC5, OPTION_ARC6,
  OPTION_ARC7, OPTION_ARC8, OPTION_ARC, OPTION_ALL_OPCODES = OPTION_MD_BASE + 1,
  OPTION_NO_SKIP_BUG, OPTION_NO_WRAP, OPTION_NOWARNSWAP = OPTION_MD_BASE, OPTION_GSTABSPACKING,
  OPTION_NOGSTABSPACKING, OPTION_CPU_IP2022 = OPTION_MD_BASE, OPTION_CPU_IP2022EXT, OPTION_JSRI2BSR_ON = OPTION_MD_BASE,
  OPTION_JSRI2BSR_OFF, OPTION_SIFILTER_ON, OPTION_SIFILTER_OFF, OPTION_CPU,
  OPTION_EB, OPTION_EL, OPTION_RELAX = OPTION_MD_BASE, OPTION_BIG,
  OPTION_LITTLE, OPTION_SMALL, OPTION_DSP, OPTION_ISA,
  OPTION_RENESAS, OPTION_ALLOW_REG_PREFIX, OPTION_DUMMY, OPTION_MACH_Z80 = OPTION_MD_BASE,
  OPTION_MACH_R800, OPTION_MACH_IUD, OPTION_MACH_WUD, OPTION_MACH_FUD,
  OPTION_MACH_IUP, OPTION_MACH_WUP, OPTION_MACH_FUP
}

Functions

int md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
void md_show_usage (FILE *f)
void md_begin (void)
void z80_md_end (void)
static const char * skip_space (const char *s)
int z80_start_line_hook (void)
symbolS * md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
char * md_atof (int type ATTRIBUTE_UNUSED, char *litP ATTRIBUTE_UNUSED, int *sizeP ATTRIBUTE_UNUSED)
valueT md_section_align (segT seg ATTRIBUTE_UNUSED, valueT size)
long md_pcrel_from (fixS *fixp)
static int key_cmp (const void *a, const void *b)
static void error (const char *message)
static void ill_op (void)
static void wrong_mach (int ins_type)
static void check_mach (int ins_type)
static int is_indir (const char *s)
static const char * parse_exp2 (const char *s, expressionS *op, segT *pseg)
static const char * parse_exp (const char *s, expressionS *op)
static const char * parse_cc (const char *s, char *op)
static const char * emit_insn (char prefix, char opcode, const char *args)
void z80_cons_fix_new (fragS *frag_p, int offset, int nbytes, expressionS *exp)
static void emit_byte (expressionS *val, bfd_reloc_code_real_type r_type)
static void emit_word (expressionS *val)
static void emit_mx (char prefix, char opcode, int shift, expressionS *arg)
static const char * emit_m (char prefix, char opcode, const char *args)
static const char * emit_mr (char prefix, char opcode, const char *args)
static void emit_sx (char prefix, char opcode, expressionS *arg_p)
static const char * emit_s (char prefix, char opcode, const char *args)
static const char * emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char *args)
static const char * emit_incdec (char prefix, char opcode, const char *args)
static const char * emit_jr (char prefix ATTRIBUTE_UNUSED, char opcode, const char *args)
static const char * emit_jp (char prefix, char opcode, const char *args)
static const char * emit_im (char prefix, char opcode, const char *args)
static const char * emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char *args)
static const char * emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char *args)
static const char * emit_adc (char prefix, char opcode, const char *args)
static const char * emit_add (char prefix, char opcode, const char *args)
static const char * emit_bit (char prefix, char opcode, const char *args)
static const char * emit_jpcc (char prefix, char opcode, const char *args)
static const char * emit_jrcc (char prefix, char opcode, const char *args)
static const char * emit_ex (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED, const char *args)
static const char * emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED, const char *args)
static const char * emit_out (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED, const char *args)
static const char * emit_rst (char prefix ATTRIBUTE_UNUSED, char opcode, const char *args)
static void emit_ldxhl (char prefix, char opcode, expressionS *src, expressionS *d)
static void emit_ldreg (int dest, expressionS *src)
static const char * emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED, const char *args)
static void emit_data (int size ATTRIBUTE_UNUSED)
static const char * emit_mulub (char prefix ATTRIBUTE_UNUSED, char opcode, const char *args)
static const char * emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char *args)
void md_assemble (char *str)
void md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
arelenttc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)

Variables

const char comment_chars [] = ";\0"
const char line_comment_chars [] = "#;\0"
const char line_separator_chars [] = "\0"
const char EXP_CHARS [] = "eE\0"
const char FLT_CHARS [] = "RrFf\0"
const char * md_shortopts = ""
size_t md_longopts_size = sizeof (md_longopts)
int coff_flags
static int ins_ok = INS_Z80 | INS_UNDOC
static int ins_err = INS_R800
static int ins_used = INS_Z80
static symbolS * zero
char buf [BUFLEN]
const char * key = buf
static struct reg_entry regtable []
static char err_flag
static struct reg_entry []
const pseudo_typeS md_pseudo_table []
static table_t instab []

Class Documentation

struct _table_t

Definition at line 332 of file tc-z80.c.

Class Members
asfunc * fp
char * name
char opcode
char prefix
struct reg_entry

Definition at line 471 of file tc-arm.c.

Collaboration diagram for reg_entry:
Class Members
unsigned char builtin
int image
char * name
const char * name
struct neon_typed_alias * neon
int number
unsigned char number
unsigned int reg_flags
char * reg_name
unsigned int reg_num
unsigned int reg_type
reg_type type
unsigned char type
union reg_entry value

Define Documentation

#define BUFLEN   8 /* Large enough for any keyword. */

Definition at line 351 of file tc-z80.c.

#define INS_R800   8

Definition at line 51 of file tc-z80.c.

#define INS_UNDOC   2

Definition at line 49 of file tc-z80.c.

#define INS_UNPORT   4

Definition at line 50 of file tc-z80.c.

#define INS_Z80   1

Definition at line 48 of file tc-z80.c.

#define R_ARITH   (0x40)

Definition at line 357 of file tc-z80.c.

#define R_INDEX   (R_IX | R_IY)

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

#define R_IX   (0x20)

Definition at line 358 of file tc-z80.c.

#define R_IY   (0x10)

Definition at line 359 of file tc-z80.c.

#define R_STACKABLE   (0x80)

Definition at line 356 of file tc-z80.c.

#define REG_A   (7)

Definition at line 362 of file tc-z80.c.

#define REG_AF   (3 | R_STACKABLE)

Definition at line 373 of file tc-z80.c.

#define REG_B   (0)

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

#define REG_BC   (0 | R_STACKABLE | R_ARITH)

Definition at line 374 of file tc-z80.c.

#define REG_C   (1)

Definition at line 364 of file tc-z80.c.

#define REG_D   (2)

Definition at line 365 of file tc-z80.c.

#define REG_DE   (1 | R_STACKABLE | R_ARITH)

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

#define REG_E   (3)

Definition at line 366 of file tc-z80.c.

#define REG_F   (6 | 8)

Definition at line 369 of file tc-z80.c.

#define REG_H   (4)

Definition at line 367 of file tc-z80.c.

#define REG_HL   (2 | R_STACKABLE | R_ARITH)

Definition at line 376 of file tc-z80.c.

#define REG_I   (9)

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

#define REG_L   (5)

Definition at line 368 of file tc-z80.c.

#define REG_R   (10)

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

#define REG_SP   (3 | R_ARITH)

Definition at line 377 of file tc-z80.c.


Typedef Documentation

typedef const char*( asfunc)(char, char, const char *)

Definition at line 330 of file tc-z80.c.


Enumeration Type Documentation

enum options
Enumerator:
OPTION_EB 
OPTION_EL 
OPTION_ARC5 
OPTION_ARC6 
OPTION_ARC7 
OPTION_ARC8 
OPTION_ARC 
OPTION_ALL_OPCODES 
OPTION_NO_SKIP_BUG 
OPTION_NO_WRAP 
OPTION_NOWARNSWAP 
OPTION_GSTABSPACKING 
OPTION_NOGSTABSPACKING 
OPTION_CPU_IP2022 
OPTION_CPU_IP2022EXT 
OPTION_JSRI2BSR_ON 
OPTION_JSRI2BSR_OFF 
OPTION_SIFILTER_ON 
OPTION_SIFILTER_OFF 
OPTION_CPU 
OPTION_EB 
OPTION_EL 
OPTION_RELAX 
OPTION_BIG 
OPTION_LITTLE 
OPTION_SMALL 
OPTION_DSP 
OPTION_ISA 
OPTION_RENESAS 
OPTION_ALLOW_REG_PREFIX 
OPTION_DUMMY 
OPTION_MACH_Z80 
OPTION_MACH_R800 
OPTION_MACH_IUD 
OPTION_MACH_WUD 
OPTION_MACH_FUD 
OPTION_MACH_IUP 
OPTION_MACH_WUP 
OPTION_MACH_FUP 

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


Function Documentation

static void check_mach ( int  ins_type) [static]

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

{
  if ((ins_type & ins_ok) == 0)
    wrong_mach (ins_type);
  ins_used |= ins_type;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* emit_adc ( char  prefix,
char  opcode,
const char *  args 
) [static]

Definition at line 1060 of file tc-z80.c.

{
  expressionS term;
  int rnum;
  const char *p;
  char *q;

  p = parse_exp (args, &term);
  if (*p++ != ',')
    {
      error (_("bad intruction syntax"));
      return p;
    }

  if ((term.X_md) || (term.X_op != O_register))
    ill_op ();
  else
    switch (term.X_add_number)
      {
      case REG_A:
       p = emit_s (0, prefix, p);
       break;
      case REG_HL:
       p = parse_exp (p, &term);
       if ((!term.X_md) && (term.X_op == O_register))
         {
           rnum = term.X_add_number;
           if (R_ARITH == (rnum & (R_ARITH | R_INDEX)))
             {
              q = frag_more (2);
              *q++ = 0xED;
              *q = opcode + ((rnum & 3) << 4);
              break;
             }
         }
       /* Fall through.  */
      default:
       ill_op ();
      }
  return p;
}

Here is the call graph for this function:

static const char* emit_add ( char  prefix,
char  opcode,
const char *  args 
) [static]

Definition at line 1103 of file tc-z80.c.

{
  expressionS term;
  int lhs, rhs;
  const char *p;
  char *q;

  p = parse_exp (args, &term);
  if (*p++ != ',')
    {
      error (_("bad intruction syntax"));
      return p;
    }

  if ((term.X_md) || (term.X_op != O_register))
    ill_op ();
  else
    switch (term.X_add_number & ~R_INDEX)
      {
      case REG_A:
       p = emit_s (0, prefix, p);
       break;
      case REG_HL:
       lhs = term.X_add_number;
       p = parse_exp (p, &term);
       if ((!term.X_md) && (term.X_op == O_register))
         {
           rhs = term.X_add_number;
           if ((rhs & R_ARITH)
              && ((rhs == lhs) || ((rhs & ~R_INDEX) != REG_HL)))
             {
              q = frag_more ((lhs & R_INDEX) ? 2 : 1);
              if (lhs & R_INDEX)
                *q++ = (lhs & R_IX) ? 0xDD : 0xFD;
              *q = opcode + ((rhs & 3) << 4);
              break;
             }
         }
       /* Fall through.  */
      default:
       ill_op ();
      }
  return p;
}

Here is the call graph for this function:

static const char* emit_bit ( char  prefix,
char  opcode,
const char *  args 
) [static]

Definition at line 1149 of file tc-z80.c.

{
  expressionS b;
  int bn;
  const char *p;

  p = parse_exp (args, &b);
  if (*p++ != ',')
    error (_("bad intruction syntax"));

  bn = b.X_add_number;
  if ((!b.X_md)
      && (b.X_op == O_constant)
      && (0 <= bn)
      && (bn < 8))
    {
      if (opcode == 0x40)
       /* Bit : no optional third operand.  */
       p = emit_m (prefix, opcode + (bn << 3), p);
      else
       /* Set, res : resulting byte can be copied to register.  */
       p = emit_mr (prefix, opcode + (bn << 3), p);
    }
  else
    ill_op ();
  return p;
}

Here is the call graph for this function:

static void emit_byte ( expressionS val,
bfd_reloc_code_real_type  r_type 
) [static]

Definition at line 680 of file tc-z80.c.

{
  char *p;
  int lo, hi;
  fixS * fixp;

  p = frag_more (1);
  *p = val->X_add_number;
  if ((r_type == BFD_RELOC_8_PCREL) && (val->X_op == O_constant))
    {
      as_bad(_("cannot make a relative jump to an absolute location"));
    }
  else if (val->X_op == O_constant)
    {
      lo = -128;
      hi = (BFD_RELOC_8 == r_type) ? 255 : 127;

      if ((val->X_add_number < lo) || (val->X_add_number > hi))
       {
         if (r_type == BFD_RELOC_Z80_DISP8)
           as_bad (_("offset too large"));
         else
           as_warn (_("overflow"));
       }
    }
  else
    {
      fixp = fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val,
                       (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type);
      /* FIXME : Process constant offsets immediately.  */
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* emit_call ( char prefix  ATTRIBUTE_UNUSED,
char  opcode,
const char *  args 
) [static]

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

{
  expressionS addr;
  const char *p;  char *q;

  p = parse_exp (args, &addr);
  if (addr.X_md)
    ill_op ();
  else
    {
      q = frag_more (1);
      *q = opcode;
      emit_word (& addr);
    }
  return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void emit_data ( int size  ATTRIBUTE_UNUSED) [static]

Definition at line 1668 of file tc-z80.c.

{
  const char *p, *q;
  char *u, quote;
  int cnt;
  expressionS exp;

  if (is_it_end_of_statement ())
    {
      demand_empty_rest_of_line ();
      return;
    }
  p = skip_space (input_line_pointer);

  do
    {
      if (*p == '\"' || *p == '\'')
       {
           for (quote = *p, q = ++p, cnt = 0; *p && quote != *p; ++p, ++cnt)
             ;
           u = frag_more (cnt);
           memcpy (u, q, cnt);
           if (!*p)
             as_warn (_("unterminated string"));
           else
             p = skip_space (p+1);
       }
      else
       {
         p = parse_exp (p, &exp);
         if (exp.X_op == O_md1 || exp.X_op == O_register)
           {
             ill_op ();
             break;
           }
         if (exp.X_md)
           as_warn (_("parentheses ignored"));
         emit_byte (&exp, BFD_RELOC_8);
         p = skip_space (p);
       }
    }
  while (*p++ == ',') ;
  input_line_pointer = (char *)(p-1);
}

Here is the call graph for this function:

static const char* emit_ex ( char prefix_in  ATTRIBUTE_UNUSED,
char opcode_in  ATTRIBUTE_UNUSED,
const char *  args 
) [static]

Definition at line 1214 of file tc-z80.c.

{
  expressionS op;
  const char * p;
  char prefix, opcode;

  p = parse_exp (args, &op);
  p = skip_space (p);
  if (*p++ != ',')
    {
      error (_("bad instruction syntax"));
      return p;
    }

  prefix = opcode = 0;
  if (op.X_op == O_register)
    switch (op.X_add_number | (op.X_md ? 0x8000 : 0))
      {
      case REG_AF:
       if (TOLOWER (*p++) == 'a' && TOLOWER (*p++) == 'f')
         {
           /* The scrubber changes '\'' to '`' in this context.  */
           if (*p == '`')
             ++p;
           opcode = 0x08;
         }
       break;
      case REG_DE:
       if (TOLOWER (*p++) == 'h' && TOLOWER (*p++) == 'l')
         opcode = 0xEB;
       break;
      case REG_SP|0x8000:
       p = parse_exp (p, & op);
       if (op.X_op == O_register
           && op.X_md == 0
           && (op.X_add_number & ~R_INDEX) == REG_HL)
         {
           opcode = 0xE3;
           if (R_INDEX & op.X_add_number)
             prefix = (R_IX & op.X_add_number) ? 0xDD : 0xFD;
         }
       break;
      }
  if (opcode)
    emit_insn (prefix, opcode, p);
  else
    ill_op ();

  return p;
}

Here is the call graph for this function:

static const char* emit_im ( char  prefix,
char  opcode,
const char *  args 
) [static]

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

{
  expressionS mode;
  const char *p;
  char *q;

  p = parse_exp (args, & mode);
  if (mode.X_md || (mode.X_op != O_constant))
    ill_op ();
  else
    switch (mode.X_add_number)
      {
      case 1:
      case 2:
       ++mode.X_add_number;
       /* Fall through.  */
      case 0:
       q = frag_more (2);
       *q++ = prefix;
       *q = opcode + 8*mode.X_add_number;
       break;
      default:
       ill_op ();
      }
  return p;
}

Here is the call graph for this function:

static const char* emit_in ( char prefix  ATTRIBUTE_UNUSED,
char opcode  ATTRIBUTE_UNUSED,
const char *  args 
) [static]

Definition at line 1267 of file tc-z80.c.

{
  expressionS reg, port;
  const char *p;
  char *q;

  p = parse_exp (args, &reg);
  if (*p++ != ',')
    {
      error (_("bad intruction syntax"));
      return p;
    }

  p = parse_exp (p, &port);
  if (reg.X_md == 0
      && reg.X_op == O_register
      && (reg.X_add_number <= 7 || reg.X_add_number == REG_F)
      && (port.X_md))
    {
      if (port.X_op != O_md1 && port.X_op != O_register)
       {
         if (REG_A == reg.X_add_number)
           {
             q = frag_more (1);
             *q = 0xDB;
             emit_byte (&port, BFD_RELOC_8);
           }
         else
           ill_op ();
       }
      else
       {
         if (port.X_add_number == REG_C)
           {
             if (reg.X_add_number == REG_F)
              check_mach (INS_UNDOC);
             else
              {
                q = frag_more (2);
                *q++ = 0xED;
                *q = 0x40|((reg.X_add_number&7)<<3);
              }
           }
         else
           ill_op ();
       }
    }
  else
    ill_op ();
  return p;
}

Here is the call graph for this function:

static const char* emit_incdec ( char  prefix,
char  opcode,
const char *  args 
) [static]

Definition at line 906 of file tc-z80.c.

{
  expressionS operand;
  int rnum;
  const char *p;  char *q;

  p = parse_exp (args, &operand);
  rnum = operand.X_add_number;
  if ((! operand.X_md)
      && (operand.X_op == O_register)
      && (R_ARITH&rnum))
    {
      q = frag_more ((rnum & R_INDEX) ? 2 : 1);
      if (rnum & R_INDEX)
       *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
      *q = prefix + ((rnum & 3) << 4);
    }
  else
    {
      if ((operand.X_op == O_md1) || (operand.X_op == O_register))
       emit_mx (0, opcode, 3, & operand);
      else
       ill_op ();
    }
  return p;
}

Here is the call graph for this function:

static const char* emit_insn ( char  prefix,
char  opcode,
const char *  args 
) [static]

Definition at line 644 of file tc-z80.c.

{
  char *p;

  if (prefix)
    {
      p = frag_more (2);
      *p++ = prefix;
    }
  else
    p = frag_more (1);
  *p = opcode;
  return args;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* emit_jp ( char  prefix,
char  opcode,
const char *  args 
) [static]

Definition at line 953 of file tc-z80.c.

{
  expressionS addr;
  const char *p;
  char *q;
  int rnum;

  p = parse_exp (args, & addr);
  if (addr.X_md)
    {
      rnum = addr.X_add_number;
      if ((addr.X_op == O_register && (rnum & ~R_INDEX) == REG_HL)
        /* An operand (i[xy]) would have been rewritten to (i[xy]+0)
            in parse_exp ().  */
         || (addr.X_op == O_md1 && addr.X_add_symbol == zero))
       {
         q = frag_more ((rnum & R_INDEX) ? 2 : 1);
         if (rnum & R_INDEX)
           *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
         *q = prefix;
       }
      else
       ill_op ();
    }
  else
    {
      q = frag_more (1);
      *q = opcode;
      emit_word (& addr);
    }
  return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* emit_jpcc ( char  prefix,
char  opcode,
const char *  args 
) [static]

Definition at line 1178 of file tc-z80.c.

{
  char cc;
  const char *p;

  p = parse_cc (args, & cc);
  if (p && *p++ == ',')
    p = emit_call (0, opcode + cc, p);
  else
    p = (prefix == (char)0xC3)
      ? emit_jp (0xE9, prefix, args)
      : emit_call (0, prefix, args);
  return p;
}

Here is the call graph for this function:

static const char* emit_jr ( char prefix  ATTRIBUTE_UNUSED,
char  opcode,
const char *  args 
) [static]

Definition at line 934 of file tc-z80.c.

{
  expressionS addr;
  const char *p;
  char *q;

  p = parse_exp (args, &addr);
  if (addr.X_md)
    ill_op ();
  else
    {
      q = frag_more (1);
      *q = opcode;
      emit_byte (&addr, BFD_RELOC_8_PCREL);
    }
  return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* emit_jrcc ( char  prefix,
char  opcode,
const char *  args 
) [static]

Definition at line 1194 of file tc-z80.c.

{
  char cc;
  const char *p;

  p = parse_cc (args, &cc);
  if (p && *p++ == ',')
    {
      if (cc > (3 << 3))
       error (_("condition code invalid for jr"));
      else
       p = emit_jr (0, opcode + cc, p);
    }
  else
    p = emit_jr (0, prefix, args);

  return p;
}

Here is the call graph for this function:

static const char* emit_ld ( char prefix_in  ATTRIBUTE_UNUSED,
char opcode_in  ATTRIBUTE_UNUSED,
const char *  args 
) [static]

Definition at line 1590 of file tc-z80.c.

{
  expressionS dst, src;
  const char *p;
  char *q;
  char prefix, opcode;

  p = parse_exp (args, &dst);
  if (*p++ != ',')
    error (_("bad intruction syntax"));
  p = parse_exp (p, &src);

  switch (dst.X_op)
    {
    case O_md1:
      emit_ldxhl ((dst.X_add_number & R_IX) ? 0xDD : 0xFD, 0x70,
                &src, symbol_get_value_expression (dst.X_add_symbol));
      break;

    case O_register:
      if (dst.X_md)
       {
         switch (dst.X_add_number)
           {
           case REG_BC:
           case REG_DE:
             if (src.X_md == 0 && src.X_op == O_register && src.X_add_number == REG_A)
              {
                q = frag_more (1);
                *q = 0x02 + ( (dst.X_add_number & 1) << 4);
              }
             else
              ill_op ();
             break;
           case REG_HL:
             emit_ldxhl (0, 0x70, &src, NULL);
             break;
           default:
             ill_op ();
           }
       }
      else
       emit_ldreg (dst.X_add_number, &src);
      break;

    default:
      if (src.X_md != 0 || src.X_op != O_register)
       ill_op ();
      prefix = opcode = 0;
      switch (src.X_add_number)
       {
       case REG_A:
         opcode = 0x32; break;
       case REG_BC: case REG_DE: case REG_SP:
         prefix = 0xED; opcode = 0x43 + ((src.X_add_number&3)<<4); break;
       case REG_HL:
         opcode = 0x22; break;
       case REG_HL|R_IX:
         prefix = 0xDD; opcode = 0x22; break;
       case REG_HL|R_IY:
         prefix = 0xFD; opcode = 0x22; break;
       }
      if (opcode)
       {
         q = frag_more (prefix?2:1);
         if (prefix)
           *q++ = prefix;
         *q = opcode;
         emit_word (&dst);
       }
      else
       ill_op ();
    }
  return p;
}

Here is the call graph for this function:

static void emit_ldreg ( int  dest,
expressionS src 
) [static]

Definition at line 1440 of file tc-z80.c.

{
  char *q;
  int rnum;

  switch (dest)
    {
      /* 8 Bit ld group:  */
    case REG_I:
    case REG_R:
      if (src->X_md == 0 && src->X_op == O_register && src->X_add_number == REG_A)
       {
         q = frag_more (2);
         *q++ = 0xED;
         *q = (dest == REG_I) ? 0x47 : 0x4F;
       }
      else
       ill_op ();
      break;

    case REG_A:
      if ((src->X_md) && src->X_op != O_register && src->X_op != O_md1)
       {
         q = frag_more (1);
         *q = 0x3A;
         emit_word (src);
         break;
       }

      if ((src->X_md)
         && src->X_op == O_register
         && (src->X_add_number == REG_BC || src->X_add_number == REG_DE))
       {
         q = frag_more (1);
         *q = 0x0A + ((dest & 1) << 4);
         break;
       }

      if ((!src->X_md)
         && src->X_op == O_register
         && (src->X_add_number == REG_R || src->X_add_number == REG_I))
       {
         q = frag_more (2);
         *q++ = 0xED;
         *q = (src->X_add_number == REG_I) ? 0x57 : 0x5F;
         break;
       }
      /* Fall through.  */
    case REG_B:
    case REG_C:
    case REG_D:
    case REG_E:
      emit_sx (0, 0x40 + (dest << 3), src);
      break;

    case REG_H:
    case REG_L:
      if ((src->X_md == 0)
         && (src->X_op == O_register)
         && (src->X_add_number & R_INDEX))
       ill_op ();
      else
       emit_sx (0, 0x40 + (dest << 3), src);
      break;

    case R_IX | REG_H:
    case R_IX | REG_L:
    case R_IY | REG_H:
    case R_IY | REG_L:
      if (src->X_md)
       {
         ill_op ();
         break;
       }
      check_mach (INS_UNDOC);
      if (src-> X_op == O_register)
       {
         rnum = src->X_add_number;
         if ((rnum & ~R_INDEX) < 8
             && ((rnum & R_INDEX) == (dest & R_INDEX)
                 || (   (rnum & ~R_INDEX) != REG_H
                     && (rnum & ~R_INDEX) != REG_L)))
           {
             q = frag_more (2);
             *q++ = (dest & R_IX) ? 0xDD : 0xFD;
             *q = 0x40 + ((dest & 0x07) << 3) + (rnum & 7);
           }
         else
           ill_op ();
       }
      else
       {
         q = frag_more (2);
         *q++ = (dest & R_IX) ? 0xDD : 0xFD;
         *q = 0x06 + ((dest & 0x07) << 3);
         emit_byte (src, BFD_RELOC_8);
       }
      break;

      /* 16 Bit ld group:  */
    case REG_SP:
      if (src->X_md == 0
         && src->X_op == O_register
         && REG_HL == (src->X_add_number &~ R_INDEX))
       {
         q = frag_more ((src->X_add_number & R_INDEX) ? 2 : 1);
         if (src->X_add_number & R_INDEX)
           *q++ = (src->X_add_number & R_IX) ? 0xDD : 0xFD;
         *q = 0xF9;
         break;
       }
      /* Fall through.  */
    case REG_BC:
    case REG_DE:
      if (src->X_op == O_register || src->X_op == O_md1)
       ill_op ();
      q = frag_more (src->X_md ? 2 : 1);
      if (src->X_md)
       {
         *q++ = 0xED;
         *q = 0x4B + ((dest & 3) << 4);
       }
      else
       *q = 0x01 + ((dest & 3) << 4);
      emit_word (src);
      break;

    case REG_HL:
    case REG_HL | R_IX:
    case REG_HL | R_IY:
      if (src->X_op == O_register || src->X_op == O_md1)
       ill_op ();
      q = frag_more ((dest & R_INDEX) ? 2 : 1);
      if (dest & R_INDEX)
       * q ++ = (dest & R_IX) ? 0xDD : 0xFD;
      *q = (src->X_md) ? 0x2A : 0x21;
      emit_word (src);
      break;

    case REG_AF:
    case REG_F:
      ill_op ();
      break;

    default:
      abort ();
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void emit_ldxhl ( char  prefix,
char  opcode,
expressionS src,
expressionS d 
) [static]

Definition at line 1399 of file tc-z80.c.

{
  char *q;

  if (src->X_md)
    ill_op ();
  else
    {
      if (src->X_op == O_register)
       {
         if (src->X_add_number>7)
           ill_op ();
         if (prefix)
           {
             q = frag_more (2);
             *q++ = prefix;
           }
         else
       q = frag_more (1);
         *q = opcode + src->X_add_number;
         if (d)
           emit_byte (d, BFD_RELOC_Z80_DISP8);
       }
      else
       {
         if (prefix)
           {
             q = frag_more (2);
             *q++ = prefix;
           }
         else
           q = frag_more (1);
         *q = opcode^0x46;
         if (d)
           emit_byte (d, BFD_RELOC_Z80_DISP8);
         emit_byte (src, BFD_RELOC_8);
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* emit_m ( char  prefix,
char  opcode,
const char *  args 
) [static]

Definition at line 793 of file tc-z80.c.

{
  expressionS arg_m;
  const char *p;

  p = parse_exp (args, &arg_m);
  switch (arg_m.X_op)
    {
    case O_md1:
    case O_register:
      emit_mx (prefix, opcode, 0, &arg_m);
      break;
    default:
      ill_op ();
    }
  return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* emit_mr ( char  prefix,
char  opcode,
const char *  args 
) [static]

Definition at line 815 of file tc-z80.c.

{
  expressionS arg_m, arg_r;
  const char *p;

  p = parse_exp (args, & arg_m);

  switch (arg_m.X_op)
    {
    case O_md1:
      if (*p == ',')
       {
         p = parse_exp (p + 1, & arg_r);

         if ((arg_r.X_md == 0)
             && (arg_r.X_op == O_register)
             && (arg_r.X_add_number < 8))
           opcode += arg_r.X_add_number-6; /* Emit_mx () will add 6.  */
         else
           {
             ill_op ();
             break;
           }
         check_mach (INS_UNPORT);
       }
    case O_register:
      emit_mx (prefix, opcode, 0, & arg_m);
      break;
    default:
      ill_op ();
    }
  return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* emit_mulub ( char prefix  ATTRIBUTE_UNUSED,
char  opcode,
const char *  args 
) [static]

Definition at line 1714 of file tc-z80.c.

{
  const char *p;

  p = skip_space (args);
  if (TOLOWER (*p++) != 'a' || *p++ != ',')
    ill_op ();
  else
    {
      char *q, reg;

      reg = TOLOWER (*p++);
      switch (reg)
       {
       case 'b':
       case 'c':
       case 'd':
       case 'e':
         check_mach (INS_R800);
         if (!*skip_space (p))
           {
             q = frag_more (2);
             *q++ = prefix;
             *q = opcode + ((reg - 'b') << 3);
             break;
           }
       default:
         ill_op ();
       }
    }
  return p;
}

Here is the call graph for this function:

static const char* emit_muluw ( char prefix  ATTRIBUTE_UNUSED,
char  opcode,
const char *  args 
) [static]

Definition at line 1748 of file tc-z80.c.

{
  const char *p;

  p = skip_space (args);
  if (TOLOWER (*p++) != 'h' || TOLOWER (*p++) != 'l' || *p++ != ',')
    ill_op ();
  else
    {
      expressionS reg;
      char *q;

      p = parse_exp (p, & reg);

      if ((!reg.X_md) && reg.X_op == O_register)
       switch (reg.X_add_number)
         {
         case REG_BC:
         case REG_SP:
           check_mach (INS_R800);
           q = frag_more (2);
           *q++ = prefix;
           *q = opcode + ((reg.X_add_number & 3) << 4);
           break;
         default:
           ill_op ();
         }
    }
  return p;
}

Here is the call graph for this function:

static void emit_mx ( char  prefix,
char  opcode,
int  shift,
expressionS arg 
) [static]

Definition at line 733 of file tc-z80.c.

{
  char *q;
  int rnum;

  rnum = arg->X_add_number;
  switch (arg->X_op)
    {
    case O_register:
      if (arg->X_md)
       {
         if (rnum != REG_HL)
           {
             ill_op ();
             break;
           }
         else
           rnum = 6;
       }
      else
       {
         if ((prefix == 0) && (rnum & R_INDEX))
           {
             prefix = (rnum & R_IX) ? 0xDD : 0xFD;
             check_mach (INS_UNDOC);
             rnum &= ~R_INDEX;
           }
         if (rnum > 7)
           {
             ill_op ();
             break;
           }
       }
      q = frag_more (prefix ? 2 : 1);
      if (prefix)
       * q ++ = prefix;
      * q ++ = opcode + (rnum << shift);
      break;
    case O_md1:
      q = frag_more (2);
      *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
      *q = (prefix) ? prefix : (opcode + (6 << shift));
      emit_byte (symbol_get_value_expression (arg->X_add_symbol),
               BFD_RELOC_Z80_DISP8);
      if (prefix)
       {
         q = frag_more (1);
         *q = opcode+(6<<shift);
       }
      break;
    default:
      abort ();
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* emit_out ( char prefix  ATTRIBUTE_UNUSED,
char opcode  ATTRIBUTE_UNUSED,
const char *  args 
) [static]

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

{
  expressionS reg, port;
  const char *p;
  char *q;

  p = parse_exp (args, & port);
  if (*p++ != ',')
    {
      error (_("bad intruction syntax"));
      return p;
    }
  p = parse_exp (p, &reg);
  if (!port.X_md)
    { ill_op (); return p; }
  /* Allow "out (c), 0" as unportable instruction.  */
  if (reg.X_op == O_constant && reg.X_add_number == 0)
    {
      check_mach (INS_UNPORT);
      reg.X_op = O_register;
      reg.X_add_number = 6;
    }
  if (reg.X_md
      || reg.X_op != O_register
      || reg.X_add_number > 7)
    ill_op ();
  else
    if (port.X_op != O_register && port.X_op != O_md1)
      {
       if (REG_A == reg.X_add_number)
         {
           q = frag_more (1);
           *q = 0xD3;
           emit_byte (&port, BFD_RELOC_8);
         }
       else
         ill_op ();
      }
    else
      {
       if (REG_C == port.X_add_number)
         {
           q = frag_more (2);
           *q++ = 0xED;
           *q = 0x41 | (reg.X_add_number << 3);
         }
       else
         ill_op ();
      }
  return p;
}

Here is the call graph for this function:

static const char* emit_pop ( char prefix  ATTRIBUTE_UNUSED,
char  opcode,
const char *  args 
) [static]

Definition at line 1015 of file tc-z80.c.

{
  expressionS regp;
  const char *p;
  char *q;

  p = parse_exp (args, & regp);
  if ((!regp.X_md)
      && (regp.X_op == O_register)
      && (regp.X_add_number & R_STACKABLE))
    {
      int rnum;

      rnum = regp.X_add_number;
      if (rnum&R_INDEX)
       {
         q = frag_more (2);
         *q++ = (rnum&R_IX)?0xDD:0xFD;
       }
      else
       q = frag_more (1);
      *q = opcode + ((rnum & 3) << 4);
    }
  else
    ill_op ();

  return p;
}

Here is the call graph for this function:

static const char* emit_retcc ( char prefix  ATTRIBUTE_UNUSED,
char  opcode,
const char *  args 
) [static]

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

{
  char cc, *q;
  const char *p;

  p = parse_cc (args, &cc);
  q = frag_more (1);
  if (p)
    *q = opcode + cc;
  else
    *q = prefix;
  return p ? p : args;
}

Here is the call graph for this function:

static const char* emit_rst ( char prefix  ATTRIBUTE_UNUSED,
char  opcode,
const char *  args 
) [static]

Definition at line 1375 of file tc-z80.c.

{
  expressionS addr;
  const char *p;
  char *q;

  p = parse_exp (args, &addr);
  if (addr.X_op != O_constant)
    {
      error ("rst needs constant address");
      return p;
    }

  if (addr.X_add_number & ~(7 << 3))
    ill_op ();
  else
    {
      q = frag_more (1);
      *q = opcode + (addr.X_add_number & (7 << 3));
    }
  return p;
}

Here is the call graph for this function:

static const char* emit_s ( char  prefix,
char  opcode,
const char *  args 
) [static]

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

{
  expressionS arg_s;
  const char *p;

  p = parse_exp (args, & arg_s);
  emit_sx (prefix, opcode, & arg_s);
  return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void emit_sx ( char  prefix,
char  opcode,
expressionS arg_p 
) [static]

Definition at line 850 of file tc-z80.c.

{
  char *q;

  switch (arg_p->X_op)
    {
    case O_register:
    case O_md1:
      emit_mx (prefix, opcode, 0, arg_p);
      break;
    default:
      if (arg_p->X_md)
       ill_op ();
      else
       {
         q = frag_more (prefix ? 2 : 1);
         if (prefix)
           *q++ = prefix;
         *q = opcode ^ 0x46;
         emit_byte (arg_p, BFD_RELOC_8);
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void emit_word ( expressionS val) [static]

Definition at line 714 of file tc-z80.c.

{
  char *p;

  p = frag_more (2);
  if (   (val->X_op == O_register)
      || (val->X_op == O_md1))
    ill_op ();
  else
    {
      *p = val->X_add_number;
      p[1] = (val->X_add_number>>8);
      if (val->X_op != O_constant)
       fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
                   val, FALSE, BFD_RELOC_16);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void error ( const char *  message) [static]

Definition at line 413 of file tc-z80.c.

{
  as_bad (message);
  err_flag = 1;
}

Here is the call graph for this function:

static void ill_op ( void  ) [static]

Definition at line 420 of file tc-z80.c.

{
  error (_("illegal operand"));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int is_indir ( const char *  s) [static]

Definition at line 461 of file tc-z80.c.

{
  char quote;
  const char *p;
  int indir, depth;

  /* Indirection is indicated with parentheses.  */
  indir = (*s == '(');

  for (p = s, depth = 0; *p && *p != ','; ++p)
    {
      switch (*p)
       {
       case '"':
       case '\'':
         for (quote = *p++; quote != *p && *p != '\n'; ++p)
           if (*p == '\\' && p[1])
             ++p;
         break;
       case '(':
         ++ depth;
         break;
       case ')':
         -- depth;
         if (depth == 0)
           {
             p = skip_space (p + 1);
             if (*p && *p != ',')
              indir = 0;
             --p;
           }
         if (depth < 0)
           error (_("mismatched parentheses"));
         break;
       }
    }

  if (depth != 0)
    error (_("mismatched parentheses"));

  return indir;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int key_cmp ( const void *  a,
const void *  b 
) [static]

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

{
  const char *str_a, *str_b;

  str_a = *((const char**)a);
  str_b = *((const char**)b);
  return strcmp (str_a, str_b);
}

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 1917 of file tc-z80.c.

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

  switch (fixP->fx_r_type)
    {
    case BFD_RELOC_8_PCREL:
      if (fixP->fx_addsy)
        {
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 0;
        }
      else
        {
         fixP->fx_no_overflow = (-128 <= val && val < 128);
         if (!fixP->fx_no_overflow)
            as_bad_where (fixP->fx_file, fixP->fx_line,
                       _("relative jump out of range"));
         *buf++ = val;
          fixP->fx_done = 1;
        }
      break;

    case BFD_RELOC_Z80_DISP8:
      if (fixP->fx_addsy)
        {
          fixP->fx_no_overflow = 1;
          fixP->fx_done = 0;
        }
      else
        {
         fixP->fx_no_overflow = (-128 <= val && val < 128);
         if (!fixP->fx_no_overflow)
            as_bad_where (fixP->fx_file, fixP->fx_line,
                       _("index offset  out of range"));
         *buf++ = val;
          fixP->fx_done = 1;
        }
      break;

    case BFD_RELOC_8:
      if (val > 255 || val < -128)
       as_warn_where (fixP->fx_file, fixP->fx_line, _("overflow"));
      *buf++ = val;
      fixP->fx_no_overflow = 1; 
      if (fixP->fx_addsy == NULL)
       fixP->fx_done = 1;
      break;

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

    case BFD_RELOC_24: /* Def24 may produce this.  */
      *buf++ = val;
      *buf++ = (val >> 8);
      *buf++ = (val >> 16);
      fixP->fx_no_overflow = 1; 
      if (fixP->fx_addsy == NULL)
       fixP->fx_done = 1;
      break;

    case BFD_RELOC_32: /* Def32 and .long may produce this.  */
      *buf++ = val;
      *buf++ = (val >> 8);
      *buf++ = (val >> 16);
      *buf++ = (val >> 24);
      if (fixP->fx_addsy == NULL)
       fixP->fx_done = 1;
      break;

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

Here is the call graph for this function:

void md_assemble ( char *  str)

Definition at line 1873 of file tc-z80.c.

{
  const char *p;
  char * old_ptr;
  int i;
  table_t *insp;

  err_flag = 0;
  old_ptr = input_line_pointer;
  p = skip_space (str);
  for (i = 0; (i < BUFLEN) && (ISALPHA (*p));)
    buf[i++] = TOLOWER (*p++);

  if (i == BUFLEN)
    {
      buf[BUFLEN-3] = buf[BUFLEN-2] = '.'; /* Mark opcode as abbreviated.  */
      buf[BUFLEN-1] = 0;
      as_bad (_("Unknown instruction '%s'"), buf);
    }
  else if ((*p) && (!ISSPACE (*p)))
    as_bad (_("syntax error"));
  else 
    {
      buf[i] = 0;
      p = skip_space (p);
      key = buf;
      
      insp = bsearch (&key, instab, ARRAY_SIZE (instab),
                  sizeof (instab[0]), key_cmp);
      if (!insp)
       as_bad (_("Unknown instruction '%s'"), buf);
      else
       {
         p = insp->fp (insp->prefix, insp->opcode, p);
         p = skip_space (p);
       if ((!err_flag) && *p)
         as_bad (_("junk at end of line, first unrecognized character is `%c'"),
                *p);
       }
    }
  input_line_pointer = old_ptr;
}

Here is the call graph for this function:

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

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

{
  return _("floating point numbers are not implemented");
}
void md_begin ( void  )

Definition at line 165 of file tc-z80.c.

{
  expressionS nul;
  char * p;

  p = input_line_pointer;
  input_line_pointer = "0";
  nul.X_md=0;
  expression (& nul);
  input_line_pointer = p;
  zero = make_expr_symbol (& nul);
  /* We do not use relaxation (yet).  */
  linkrelax = 0;
}

Here is the call graph for this function:

int md_parse_option ( int c  ,
char *arg  ATTRIBUTE_UNUSED 
)

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

{
  switch (c)
    {
    default:
      return 0;
    case OPTION_MACH_Z80:
      ins_ok &= ~INS_R800;
      ins_err |= INS_R800;
      break;
    case OPTION_MACH_R800:
      ins_ok = INS_Z80 | INS_UNDOC | INS_R800;
      ins_err = INS_UNPORT;
      break;
    case OPTION_MACH_IUD:
      ins_ok |= INS_UNDOC;
      ins_err &= ~INS_UNDOC;
      break;
    case OPTION_MACH_IUP:
      ins_ok |= INS_UNDOC | INS_UNPORT;
      ins_err &= ~(INS_UNDOC | INS_UNPORT);
      break;
    case OPTION_MACH_WUD:
      if ((ins_ok & INS_R800) == 0)
       {
         ins_ok &= ~(INS_UNDOC|INS_UNPORT);
         ins_err &= ~INS_UNDOC;
       }
      break;
    case OPTION_MACH_WUP:
      ins_ok &= ~INS_UNPORT;
      ins_err &= ~(INS_UNDOC|INS_UNPORT);
      break;
    case OPTION_MACH_FUD:
      if ((ins_ok & INS_R800) == 0)
       {
         ins_ok &= (INS_UNDOC | INS_UNPORT);
         ins_err |= INS_UNDOC | INS_UNPORT;
       }
      break;
    case OPTION_MACH_FUP:
      ins_ok &= ~INS_UNPORT;
      ins_err |= INS_UNPORT;
      break;
    }

  return 1;
}
long md_pcrel_from ( fixS *  fixp)

Definition at line 324 of file tc-z80.c.

{
  return fixp->fx_where +
    fixp->fx_frag->fr_address + 1;
}
valueT md_section_align ( segT seg  ATTRIBUTE_UNUSED,
valueT  size 
)

Definition at line 318 of file tc-z80.c.

{
  return size;
}
void md_show_usage ( FILE *  f)

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

{
  fprintf (f, "\n\
CPU model/instruction set options:\n\
\n\
  -z80\t\t  assemble for Z80\n\
  -ignore-undocumented-instructions\n\
  -Wnud\n\
\tsilently assemble undocumented Z80-instructions that work on R800\n\
  -ignore-unportable-instructions\n\
  -Wnup\n\
\tsilently assemble all undocumented Z80-instructions\n\
  -warn-undocumented-instructions\n\
  -Wud\n\
\tissue warnings for undocumented Z80-instructions that work on R800\n\
  -warn-unportable-instructions\n\
  -Wup\n\
\tissue warnings for other undocumented Z80-instructions\n\
  -forbid-undocumented-instructions\n\
  -Fud\n\
\ttreat all undocumented z80-instructions as errors\n\
  -forbid-unportable-instructions\n\
  -Fup\n\
\ttreat undocumented z80-instructions that do not work on R800 as errors\n\
  -r800\t  assemble for R800\n\n\
Default: -z80 -ignore-undocument-instructions -warn-unportable-instructions.\n");
}

Here is the call graph for this function:

symbolS* md_undefined_symbol ( char *name  ATTRIBUTE_UNUSED)

Definition at line 305 of file tc-z80.c.

{
  return NULL;
}
static const char* parse_cc ( const char *  s,
char *  op 
) [static]

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

{
  const char *p;
  int i;
  struct reg_entry * cc_p;

  for (i = 0; i < BUFLEN; ++i)
    {
      if (!ISALPHA (s[i])) /* Condition codes consist of letters only.  */
       break;
      buf[i] = TOLOWER (s[i]);
    }

  if ((i < BUFLEN)
      && ((s[i] == 0) || (s[i] == ',')))
    {
      buf[i] = 0;
      cc_p = bsearch (&key, cc_tab, ARRAY_SIZE (cc_tab),
                    sizeof (cc_tab[0]), key_cmp);
    }
  else
    cc_p = NULL;

  if (cc_p)
    {
      *op = cc_p->number;
      p = s + i;
    }
  else
    p = NULL;

  return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 582 of file tc-z80.c.

{
  segT dummy;
  return parse_exp2 (s, op, & dummy);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* parse_exp2 ( const char *  s,
expressionS op,
segT pseg 
) [static]

Definition at line 506 of file tc-z80.c.

{
  const char *p;
  int indir;
  int i;
  const struct reg_entry * regp;
  expressionS offset;

  p = skip_space (s);
  op->X_md = indir = is_indir (p);
  if (indir)
    p = skip_space (p + 1);

  for (i = 0; i < BUFLEN; ++i)
    {
      if (!ISALPHA (p[i])) /* Register names consist of letters only.  */
       break;
      buf[i] = TOLOWER (p[i]);
    }

  if ((i < BUFLEN) && ((p[i] == 0) || (strchr (")+-, \t", p[i]))))
    {
      buf[i] = 0;
      regp = bsearch (& key, regtable, ARRAY_SIZE (regtable),
                    sizeof (regtable[0]), key_cmp);
      if (regp)
       {
         *pseg = reg_section;
         op->X_add_symbol = op->X_op_symbol = 0;
         op->X_add_number = regp->number;
         op->X_op = O_register;
         p += strlen (regp->name);
         p = skip_space (p);
         if (indir)
           {
             if (*p == ')')
              ++p;
             if ((regp->number & R_INDEX) && (regp->number & R_ARITH))
              {
                op->X_op = O_md1;

                if  ((*p == '+') || (*p == '-'))
                  {
                    input_line_pointer = (char*) p;
                    expression (& offset);
                    p = skip_space (input_line_pointer);
                    if (*p != ')')
                     error (_("bad offset expression syntax"));
                    else
                     ++ p;
                    op->X_add_symbol = make_expr_symbol (& offset);
                    return p;
                  }

                /* We treat (i[xy]) as (i[xy]+0), which is how it will
                   end up anyway, unless we're processing jp (i[xy]).  */
                op->X_add_symbol = zero;
              }
           }
         p = skip_space (p);

         if ((*p == 0) || (*p == ','))
           return p;
       }
    }
  /* Not an argument involving a register; use the generic parser.  */
  input_line_pointer = (char*) s ;
  *pseg = expression (op);
  if (op->X_op == O_absent)
    error (_("missing operand"));
  if (op->X_op == O_illegal)
    error (_("bad expression syntax"));
  return input_line_pointer;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* skip_space ( const char *  s) [static]

Definition at line 210 of file tc-z80.c.

{
  while (*s == ' ' || *s == '\t')
    ++s;
  return s;
}

Here is the caller graph for this function:

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

Definition at line 2010 of file tc-z80.c.

{
  arelent *reloc;

  if (! bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type))
    {
      as_bad_where (fixp->fx_file, fixp->fx_line,
                  _("reloc %d not supported by object file format"),
                  (int) fixp->fx_r_type);
      return NULL;
    }

  reloc               = xmalloc (sizeof (arelent));
  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->howto        = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
  reloc->addend       = fixp->fx_offset;

  return reloc;
}

Here is the call graph for this function:

static void wrong_mach ( int  ins_type) [static]

Definition at line 426 of file tc-z80.c.

{
  const char *p;

  switch (ins_type)
    {
    case INS_UNDOC:
      p = "undocumented instruction";
      break;
    case INS_UNPORT:
      p = "instruction does not work on R800";
      break;
    case INS_R800:
      p = "instruction only works R800";
      break;
    default:
      p = 0; /* Not reachable.  */
    }

  if (ins_type & ins_err)
    error (_(p));
  else
    as_warn (_(p));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void z80_cons_fix_new ( fragS *  frag_p,
int  offset,
int  nbytes,
expressionS exp 
)

Definition at line 659 of file tc-z80.c.

{
  bfd_reloc_code_real_type r[4] =
    {
      BFD_RELOC_8,
      BFD_RELOC_16,
      BFD_RELOC_24,
      BFD_RELOC_32
    };

  if (nbytes < 1 || nbytes > 4) 
    {
      as_bad (_("unsupported BFD relocation size %u"), nbytes);
    }
  else
    {
      fix_new_exp (frag_p, offset, nbytes, exp, 0, r[nbytes-1]);
    }
}

Here is the call graph for this function:

void z80_md_end ( void  )

Definition at line 181 of file tc-z80.c.

{
  int mach_type;

  if (ins_used & (INS_UNPORT | INS_R800))
    ins_used |= INS_UNDOC;

  switch (ins_used)
    {
    case INS_Z80:
      mach_type = bfd_mach_z80strict;
      break;
    case INS_Z80|INS_UNDOC:
      mach_type = bfd_mach_z80;
      break;
    case INS_Z80|INS_UNDOC|INS_UNPORT:
      mach_type = bfd_mach_z80full;
      break;
    case INS_Z80|INS_UNDOC|INS_R800:
      mach_type = bfd_mach_r800;
      break;
    default:
      mach_type = 0;
    }

  bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach_type);
}

Definition at line 220 of file tc-z80.c.

{
  char *p, quote;
  char buf[4];

  /* Convert one character constants.  */
  for (p = input_line_pointer; *p && *p != '\n'; ++p)
    {
      switch (*p)
       {
       case '\'':
         if (p[1] != 0 && p[1] != '\'' && p[2] == '\'')
           {
             snprintf (buf, 4, "%3d", (unsigned char)p[1]);
             *p++ = buf[0];
             *p++ = buf[1];
             *p++ = buf[2];
             break;
           }
       case '"':
         for (quote = *p++; quote != *p && '\n' != *p; ++p)
           /* No escapes.  */ ;
         if (quote != *p)
           {
             as_bad (_("-- unterminated string"));
             ignore_rest_of_line ();
             return 1;
           }
         break;
       }
    }
  /* Check for <label>[:] [.](EQU|DEFL) <value>.  */
  if (is_name_beginner (*input_line_pointer))
    {
      char c, *rest, *line_start;
      int len;
      symbolS * symbolP;

      line_start = input_line_pointer;
      LISTING_NEWLINE ();
      if (ignore_input ())
       return 0;

      c = get_symbol_end ();
      rest = input_line_pointer + 1;

      if (*rest == ':')
       ++rest;
      if (*rest == ' ' || *rest == '\t')
       ++rest;
      if (*rest == '.')
       ++rest;
      if (strncasecmp (rest, "EQU", 3) == 0)
       len = 3;
      else if (strncasecmp (rest, "DEFL", 4) == 0)
       len = 4;
      else
       len = 0;
      if (len && (rest[len] == ' ' || rest[len] == '\t'))
       {
         /* Handle assignment here.  */
         input_line_pointer = rest + len;
         if (line_start[-1] == '\n')
           bump_line_counters ();
         /* Most Z80 assemblers require the first definition of a
             label to use "EQU" and redefinitions to have "DEFL".  */
         if (len == 3 && (symbolP = symbol_find (line_start)) != NULL) 
           {
             if (S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP))
              as_bad (_("symbol `%s' is already defined"), line_start);
           }
         equals (line_start, 1);
         return 1;
       }
      else
       {
         /* Restore line and pointer.  */
         *input_line_pointer = c;
         input_line_pointer = line_start;
       }
    }
  return 0;
}

Here is the call graph for this function:


Variable Documentation

char buf[BUFLEN]

Definition at line 353 of file tc-z80.c.

const char comment_chars[] = ";\0"

Definition at line 27 of file tc-z80.c.

char err_flag [static]

Definition at line 410 of file tc-z80.c.

const char EXP_CHARS[] = "eE\0"

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

const char FLT_CHARS[] = "RrFf\0"

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

int ins_err = INS_R800 [static]

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

int ins_ok = INS_Z80 | INS_UNDOC [static]

Definition at line 77 of file tc-z80.c.

int ins_used = INS_Z80 [static]

Definition at line 81 of file tc-z80.c.

table_t instab[] [static]

Definition at line 1797 of file tc-z80.c.

const char* key = buf

Definition at line 354 of file tc-z80.c.

const char line_comment_chars[] = "#;\0"

Definition at line 28 of file tc-z80.c.

const char line_separator_chars[] = "\0"

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

size_t md_longopts_size = sizeof (md_longopts)

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

const pseudo_typeS md_pseudo_table[]
Initial value:
{
  { "db" , emit_data, 1},
  { "d24", cons, 3},
  { "d32", cons, 4},
  { "def24", cons, 3},
  { "def32", cons, 4},
  { "defb", emit_data, 1},  
  { "defs", s_space, 1}, 
  { "defw", cons, 2},
  { "ds",   s_space, 1}, 
  { "dw", cons, 2},
  { "psect", obj_coff_section, 0}, 
  { "set", 0, 0},           
  { NULL, 0, 0 }
}

Definition at line 1780 of file tc-z80.c.

const char* md_shortopts = ""

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

struct reg_entry[] [static]
Initial value:
{
  { "age", 6 << 3 },
  { "alt", 7 << 3 },
  { "c",   3 << 3 },
  { "di",  4 << 3 },
  { "ei",  5 << 3 },
  { "lge", 2 << 3 },
  { "llt", 3 << 3 },
  { "m",   7 << 3 },
  { "nc",  2 << 3 },
  { "nz",  0 << 3 },
  { "p",   6 << 3 },
  { "pe",  5 << 3 },
  { "po",  4 << 3 },
  { "z",   1 << 3 },
}

Definition at line 589 of file tc-z80.c.

symbolS* zero [static]

Definition at line 162 of file tc-z80.c.