mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-28 18:10:46 +00:00
Cleanup of pseudo-ops for constants and new def24,def32 pseudo-ops on z80
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
2006-02-05 Arnold Metselaar <arnold.metselaar@planet.nl>
|
||||
|
||||
* coff-z80.c (r_imm24): New howto.
|
||||
(rtype2howto): New case R_IMM24.
|
||||
(coff_z80_reloc_type_lookup): New case BFD_RELOC_24.
|
||||
(extra_case): Use bfd_get_8 for R_IMM8, new case R_IMM24.
|
||||
|
||||
2006-02-04 Richard Sandiford <richard@codesourcery.com>
|
||||
|
||||
* elfxx-mips.c (mips_elf_initialize_tls_index): If a TLS symbol
|
||||
|
||||
@@ -34,6 +34,11 @@ HOWTO (R_IMM32, 0, 1, 32, FALSE, 0,
|
||||
complain_overflow_dont, 0, "r_imm32", TRUE, 0xffffffff, 0xffffffff,
|
||||
FALSE);
|
||||
|
||||
static reloc_howto_type r_imm24 =
|
||||
HOWTO (R_IMM24, 0, 1, 24, FALSE, 0,
|
||||
complain_overflow_dont, 0, "r_imm24", TRUE, 0x00ffffff, 0x00ffffff,
|
||||
FALSE);
|
||||
|
||||
static reloc_howto_type r_imm16 =
|
||||
HOWTO (R_IMM16, 0, 1, 16, FALSE, 0,
|
||||
complain_overflow_dont, 0, "r_imm16", TRUE, 0x0000ffff, 0x0000ffff,
|
||||
@@ -84,6 +89,9 @@ rtype2howto (arelent *internal, struct internal_reloc *dst)
|
||||
case R_IMM16:
|
||||
internal->howto = &r_imm16;
|
||||
break;
|
||||
case R_IMM24:
|
||||
internal->howto = &r_imm24;
|
||||
break;
|
||||
case R_IMM32:
|
||||
internal->howto = &r_imm32;
|
||||
break;
|
||||
@@ -106,6 +114,7 @@ coff_z80_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
{
|
||||
case BFD_RELOC_8: return & r_imm8;
|
||||
case BFD_RELOC_16: return & r_imm16;
|
||||
case BFD_RELOC_24: return & r_imm24;
|
||||
case BFD_RELOC_32: return & r_imm32;
|
||||
case BFD_RELOC_8_PCREL: return & r_jr;
|
||||
case BFD_RELOC_Z80_DISP8: return & r_off8;
|
||||
@@ -173,7 +182,7 @@ extra_case (bfd *in_abfd,
|
||||
break;
|
||||
|
||||
case R_IMM8:
|
||||
val = bfd_get_16 ( in_abfd, data+*src_ptr)
|
||||
val = bfd_get_8 ( in_abfd, data+*src_ptr)
|
||||
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section);
|
||||
bfd_put_8 (in_abfd, val, data + *dst_ptr);
|
||||
(*dst_ptr) += 1;
|
||||
@@ -188,6 +197,16 @@ extra_case (bfd *in_abfd,
|
||||
(*src_ptr) += 2;
|
||||
break;
|
||||
|
||||
case R_IMM24:
|
||||
val = bfd_get_16 ( in_abfd, data+*src_ptr)
|
||||
+ (bfd_get_8 ( in_abfd, data+*src_ptr+2) << 16)
|
||||
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section);
|
||||
bfd_put_16 (in_abfd, val, data + *dst_ptr);
|
||||
bfd_put_8 (in_abfd, val >> 16, data + *dst_ptr+2);
|
||||
(*dst_ptr) += 3;
|
||||
(*src_ptr) += 3;
|
||||
break;
|
||||
|
||||
case R_IMM32:
|
||||
val = bfd_get_32 ( in_abfd, data+*src_ptr)
|
||||
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section);
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
2006-02-05 Arnold Metselaar <arnold.metselaar@planet.nl>
|
||||
|
||||
* config/tc-z80.c (z80_start_line_hook): allow .equ and .defl as
|
||||
synonyms for equ and defl.
|
||||
(z80_cons_fix_new): New function.
|
||||
(emit_byte): Disallow relative jumps to absolute locations.
|
||||
(emit_data): Only handle defb, prototype changed, because defb is
|
||||
now handled as pseudo-op rather than an instruction.
|
||||
(instab): Entries for defb,defw,db,dw moved from here...
|
||||
(md_pseudo_table): ... to here, use generic cons() for defw,dw.
|
||||
Add entries for def24,def32,d24,d32.
|
||||
(md_assemble): Improved error handling.
|
||||
(md_apply_fix): New case BFD_RELOC_24, set fixP->fx_no_overflow to one.
|
||||
* config/tc-z80.h (TC_CONS_FIX_NEW): Define.
|
||||
(z80_cons_fix_new): Declare.
|
||||
* doc/c-z80.texi (defb, db): Mention warning on overflow.
|
||||
(def24,d24,def32,d32): New pseudo-ops.
|
||||
|
||||
2006-02-02 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* config/tc-arm.c (do_shift): Remove Thumb-1 constraint.
|
||||
|
||||
@@ -210,16 +210,6 @@ z80_md_end (void)
|
||||
bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach_type);
|
||||
}
|
||||
|
||||
/* Port specific features. */
|
||||
const pseudo_typeS md_pseudo_table[] =
|
||||
{
|
||||
{ "defs", s_space, 1}, /* Synonym for ds on some assemblers. */
|
||||
{ "ds", s_space, 1}, /* Fill with bytes rather than words. */
|
||||
{ "psect", obj_coff_section, 0}, /* TODO: Translate attributes. */
|
||||
{ "set", 0, 0}, /* Real instruction on z80. */
|
||||
{ NULL, 0, 0 }
|
||||
} ;
|
||||
|
||||
static const char *
|
||||
skip_space (const char *s)
|
||||
{
|
||||
@@ -262,7 +252,7 @@ z80_start_line_hook (void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Check for <label>[:] (EQU|DEFL) <value>. */
|
||||
/* Check for <label>[:] [.](EQU|DEFL) <value>. */
|
||||
if (is_name_beginner (*input_line_pointer))
|
||||
{
|
||||
char c, *rest, *line_start;
|
||||
@@ -281,6 +271,8 @@ z80_start_line_hook (void)
|
||||
++rest;
|
||||
if (*rest == ' ' || *rest == '\t')
|
||||
++rest;
|
||||
if (*rest == '.')
|
||||
++rest;
|
||||
if (strncasecmp (rest, "EQU", 3) == 0)
|
||||
len = 3;
|
||||
else if (strncasecmp (rest, "DEFL", 4) == 0)
|
||||
@@ -300,7 +292,6 @@ z80_start_line_hook (void)
|
||||
if (S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP))
|
||||
as_bad (_("symbol `%s' is already defined"), line_start);
|
||||
}
|
||||
/* All symbols may be redefined. */
|
||||
equals (line_start, 1);
|
||||
return 1;
|
||||
}
|
||||
@@ -452,7 +443,7 @@ wrong_mach (int ins_type)
|
||||
p = "instruction only works R800";
|
||||
break;
|
||||
default:
|
||||
p = 0; /* Not reachables. */
|
||||
p = 0; /* Not reachable. */
|
||||
}
|
||||
|
||||
if (ins_type & ins_err)
|
||||
@@ -733,6 +724,26 @@ emit_insn (char prefix, char opcode, const char * args)
|
||||
return args;
|
||||
}
|
||||
|
||||
void z80_cons_fix_new (fragS *frag_p, int offset, int nbytes, expressionS *exp)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
|
||||
{
|
||||
@@ -742,7 +753,11 @@ emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
|
||||
|
||||
p = frag_more (1);
|
||||
*p = val->X_add_number;
|
||||
if ((r_type != BFD_RELOC_8_PCREL) && (val->X_op == O_constant))
|
||||
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;
|
||||
@@ -1717,38 +1732,33 @@ emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED,
|
||||
return p;
|
||||
}
|
||||
|
||||
static const char *
|
||||
emit_data (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
|
||||
static void
|
||||
emit_data (int size ATTRIBUTE_UNUSED)
|
||||
{
|
||||
const char *p, *q;
|
||||
char *u, quote;
|
||||
int cnt;
|
||||
expressionS exp;
|
||||
|
||||
p = skip_space (args);
|
||||
if (!*p)
|
||||
error (_("missing operand"));
|
||||
if (is_it_end_of_statement ())
|
||||
{
|
||||
demand_empty_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
p = skip_space (input_line_pointer);
|
||||
|
||||
while (*p)
|
||||
do
|
||||
{
|
||||
if (*p == '\"' || *p == '\'')
|
||||
{
|
||||
if (opcode == 1)
|
||||
{
|
||||
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
|
||||
{
|
||||
ill_op ();
|
||||
break;
|
||||
}
|
||||
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
|
||||
{
|
||||
@@ -1760,21 +1770,12 @@ emit_data (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
|
||||
}
|
||||
if (exp.X_md)
|
||||
as_warn (_("parentheses ignored"));
|
||||
if (opcode == 1)
|
||||
emit_byte (&exp, BFD_RELOC_8);
|
||||
else
|
||||
emit_word (&exp);
|
||||
emit_byte (&exp, BFD_RELOC_8);
|
||||
p = skip_space (p);
|
||||
}
|
||||
if (*p)
|
||||
{
|
||||
if (*p != ',')
|
||||
as_warn (_("missing ','"));
|
||||
else
|
||||
++p;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
while (*p++ == ',') ;
|
||||
input_line_pointer = (char *)(p-1);
|
||||
}
|
||||
|
||||
static const char *
|
||||
@@ -1843,6 +1844,24 @@ emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Port specific pseudo ops. */
|
||||
const pseudo_typeS md_pseudo_table[] =
|
||||
{
|
||||
{ "db" , emit_data, 1},
|
||||
{ "d24", cons, 3},
|
||||
{ "d32", cons, 4},
|
||||
{ "def24", cons, 3},
|
||||
{ "def32", cons, 4},
|
||||
{ "defb", emit_data, 1},
|
||||
{ "defs", s_space, 1}, /* Synonym for ds on some assemblers. */
|
||||
{ "defw", cons, 2},
|
||||
{ "ds", s_space, 1}, /* Fill with bytes rather than words. */
|
||||
{ "dw", cons, 2},
|
||||
{ "psect", obj_coff_section, 0}, /* TODO: Translate attributes. */
|
||||
{ "set", 0, 0}, /* Real instruction on z80. */
|
||||
{ NULL, 0, 0 }
|
||||
} ;
|
||||
|
||||
static table_t instab[] =
|
||||
{
|
||||
{ "adc", 0x88, 0x4A, emit_adc },
|
||||
@@ -1858,13 +1877,9 @@ static table_t instab[] =
|
||||
{ "cpir", 0xED, 0xB1, emit_insn },
|
||||
{ "cpl", 0x00, 0x2F, emit_insn },
|
||||
{ "daa", 0x00, 0x27, emit_insn },
|
||||
{ "db", 0x00, 0x01, emit_data },
|
||||
{ "dec", 0x0B, 0x05, emit_incdec },
|
||||
{ "defb", 0x00, 0x01, emit_data },
|
||||
{ "defw", 0x00, 0x02, emit_data },
|
||||
{ "di", 0x00, 0xF3, emit_insn },
|
||||
{ "djnz", 0x00, 0x10, emit_jr },
|
||||
{ "dw", 0x00, 0x02, emit_data },
|
||||
{ "ei", 0x00, 0xFB, emit_insn },
|
||||
{ "ex", 0x00, 0x00, emit_ex},
|
||||
{ "exx", 0x00, 0xD9, emit_insn },
|
||||
@@ -1936,25 +1951,32 @@ md_assemble (char* str)
|
||||
for (i = 0; (i < BUFLEN) && (ISALPHA (*p));)
|
||||
buf[i++] = TOLOWER (*p++);
|
||||
|
||||
if ((i == BUFLEN)
|
||||
|| ((*p) && (!ISSPACE (*p))))
|
||||
as_bad (_("illegal instruction '%s'"), buf);
|
||||
|
||||
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 (_("illegal instruction '%s'"), buf);
|
||||
else
|
||||
if (i == BUFLEN)
|
||||
{
|
||||
p = insp->fp (insp->prefix, insp->opcode, p);
|
||||
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);
|
||||
if ((!err_flag) && *p)
|
||||
as_bad (_("junk at end of line, first unrecognized character is `%c'"),
|
||||
*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;
|
||||
}
|
||||
@@ -2005,6 +2027,7 @@ md_apply_fix (fixS * fixP, valueT* valP, segT seg ATTRIBUTE_UNUSED)
|
||||
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;
|
||||
@@ -2012,11 +2035,21 @@ md_apply_fix (fixS * fixP, valueT* valP, segT seg ATTRIBUTE_UNUSED)
|
||||
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_32: /* .Long may produce this. */
|
||||
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);
|
||||
|
||||
@@ -56,10 +56,12 @@
|
||||
#define md_end z80_md_end
|
||||
#define md_start_line_hook() { if (z80_start_line_hook ()) continue; }
|
||||
#define md_optimize_expr z80_optimize_expr
|
||||
#define TC_CONS_FIX_NEW z80_cons_fix_new
|
||||
|
||||
extern void z80_md_end (void);
|
||||
extern int z80_start_line_hook (void);
|
||||
extern int z80_optimize_expr (expressionS *, operatorT, expressionS *);
|
||||
extern void z80_cons_fix_new (fragS *, int, int, expressionS *);
|
||||
|
||||
#define WORKING_DOT_WORD
|
||||
|
||||
|
||||
@@ -150,14 +150,24 @@ These are the additional directives in @code{@value{AS}} for the Z80:
|
||||
@item db @var{expression}|@var{string}[,@var{expression}|@var{string}...]
|
||||
@itemx defb @var{expression}|@var{string}[,@var{expression}|@var{string}...]
|
||||
For each @var{string} the characters are copied to the object file, for
|
||||
each other @var{expression} the value is stored in one byte, ignoring
|
||||
overflow.
|
||||
each other @var{expression} the value is stored in one byte.
|
||||
A warning is issued in case of an overflow.
|
||||
|
||||
@item dw @var{expression}[,@var{expression}...]
|
||||
@itemx defw @var{expression}[,@var{expression}...]
|
||||
For each @var{expression} the value is stored in two bytes, ignoring
|
||||
overflow.
|
||||
|
||||
@item d24 @var{expression}[,@var{expression}...]
|
||||
@itemx def24 @var{expression}[,@var{expression}...]
|
||||
For each @var{expression} the value is stored in three bytes, ignoring
|
||||
overflow.
|
||||
|
||||
@item d32 @var{expression}[,@var{expression}...]
|
||||
@itemx def32 @var{expression}[,@var{expression}...]
|
||||
For each @var{expression} the value is stored in four bytes, ignoring
|
||||
overflow.
|
||||
|
||||
@item ds @var{count}[, @var{value}]
|
||||
@itemx defs @var{count}[, @var{value}]
|
||||
@c Synonyms for @code{ds.b},
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
2006-02-05 Arnold Metselaar <arnold.metselaar@planet.nl>
|
||||
|
||||
* internal.h: Add relocation number R_IMM24 for Z80.
|
||||
|
||||
2005-10-25 Arnold Metselaar <arnold.metselaar@planet.nl>
|
||||
|
||||
* internal.h: Add relocation number for Z80
|
||||
|
||||
@@ -717,6 +717,7 @@ struct internal_reloc
|
||||
|
||||
/* Z80 modes */
|
||||
#define R_OFF8 0x32 /* 8 bit signed abs, for (i[xy]+d) */
|
||||
#define R_IMM24 0x33 /* 24 bit abs */
|
||||
/* R_JR, R_IMM8, R_IMM16, R_IMM32 - as for Z8k */
|
||||
|
||||
/* H8500 modes */
|
||||
|
||||
Reference in New Issue
Block a user