aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-z80.c
diff options
context:
space:
mode:
authorSergey Belyashov <sergey.belyashov@gmail.com>2020-03-17 16:55:32 +0000
committerNick Clifton <nickc@redhat.com>2020-03-17 16:55:32 +0000
commit68e52bc7ecfbfdc8d5f85716a8ac7668e211f360 (patch)
treeb6fad703f9e73ec0191841e9dcc13d15dae614ce /gas/config/tc-z80.c
parentecbbbdba7182865e522e0893915e9be487fe14b0 (diff)
downloadgdb-68e52bc7ecfbfdc8d5f85716a8ac7668e211f360.zip
gdb-68e52bc7ecfbfdc8d5f85716a8ac7668e211f360.tar.gz
gdb-68e52bc7ecfbfdc8d5f85716a8ac7668e211f360.tar.bz2
Fix a small set of Z80 problems.
PR 25641 PR 25668 PR 25633 gas Fix disassembling ED+A4/AC/B4/BC opcodes. Fix assembling lines containing colonless label and instruction with first operand inside parentheses. Fix registration of unsupported by target CPU registers. * config/tc-z80.c: See above. * config/tc-z80.h: See above. * testsuite/gas/z80/colonless.d: Update test. * testsuite/gas/z80/colonless.s: Likewise. * testsuite/gas/z80/ez80_adl_all.d: Likewise. * testsuite/gas/z80/ez80_unsup_regs.d: Likewise. * testsuite/gas/z80/ez80_z80_all.d: Likewise. * testsuite/gas/z80/gbz80_unsup_regs.d: Likewise. * testsuite/gas/z80/r800_unsup_regs.d: Likewise. * testsuite/gas/z80/unsup_regs.s: Likewise. * testsuite/gas/z80/z180_unsup_regs.d: Likewise. * testsuite/gas/z80/z80.exp: Likewise. * testsuite/gas/z80/z80_strict_unsup_regs.d: Likewise. * testsuite/gas/z80/z80_unsup_regs.d: Likewise. * testsuite/gas/z80/z80n_unsup_regs.d: Likewise. opcodes * z80-dis.c: Fix disassembling ED+A4/AC/B4/BC opcodes.
Diffstat (limited to 'gas/config/tc-z80.c')
-rw-r--r--gas/config/tc-z80.c131
1 files changed, 72 insertions, 59 deletions
diff --git a/gas/config/tc-z80.c b/gas/config/tc-z80.c
index 713176f..a3ab13d 100644
--- a/gas/config/tc-z80.c
+++ b/gas/config/tc-z80.c
@@ -155,7 +155,7 @@ struct match_info
static const struct match_info
match_cpu_table [] =
{
- {"z80", INS_Z80, 0, 0, "Zilog Z80 (+infc+xyhl)" },
+ {"z80", INS_Z80, 0, 0, "Zilog Z80" },
{"ez80", INS_EZ80, 0, 0, "Zilog eZ80" },
{"gbz80", INS_GBZ80, INS_UNDOC|INS_UNPORT, 0, "GameBoy Z80" },
{"r800", INS_R800, INS_UNPORT, 0, "Ascii R800" },
@@ -428,6 +428,7 @@ struct reg_entry
{
const char* name;
int number;
+ int isa;
};
#define R_STACKABLE (0x80)
#define R_ARITH (0x40)
@@ -457,28 +458,28 @@ struct reg_entry
static const struct reg_entry regtable[] =
{
- {"a", REG_A },
- {"af", REG_AF },
- {"b", REG_B },
- {"bc", REG_BC },
- {"c", REG_C },
- {"d", REG_D },
- {"de", REG_DE },
- {"e", REG_E },
- {"f", REG_F },
- {"h", REG_H },
- {"hl", REG_HL },
- {"i", REG_I },
- {"ix", REG_IX },
- {"ixh",REG_H | R_IX },
- {"ixl",REG_L | R_IX },
- {"iy", REG_IY },
- {"iyh",REG_H | R_IY },
- {"iyl",REG_L | R_IY },
- {"l", REG_L },
- {"mb", REG_MB },
- {"r", REG_R },
- {"sp", REG_SP },
+ {"a", REG_A, INS_ALL },
+ {"af", REG_AF, INS_ALL },
+ {"b", REG_B, INS_ALL },
+ {"bc", REG_BC, INS_ALL },
+ {"c", REG_C, INS_ALL },
+ {"d", REG_D, INS_ALL },
+ {"de", REG_DE, INS_ALL },
+ {"e", REG_E, INS_ALL },
+ {"f", REG_F, INS_IN_F_C | INS_Z80N | INS_R800 },
+ {"h", REG_H, INS_ALL },
+ {"hl", REG_HL, INS_ALL },
+ {"i", REG_I, INS_NOT_GBZ80 },
+ {"ix", REG_IX, INS_NOT_GBZ80 },
+ {"ixh", REG_H | R_IX, INS_IDX_HALF | INS_EZ80 | INS_R800 | INS_Z80N },
+ {"ixl", REG_L | R_IX, INS_IDX_HALF | INS_EZ80 | INS_R800 | INS_Z80N },
+ {"iy", REG_IY, INS_NOT_GBZ80 },
+ {"iyh", REG_H | R_IY, INS_IDX_HALF | INS_EZ80 | INS_R800 | INS_Z80N },
+ {"iyl", REG_L | R_IY, INS_IDX_HALF | INS_EZ80 | INS_R800 | INS_Z80N },
+ {"l", REG_L, INS_ALL },
+ {"mb", REG_MB, INS_EZ80 },
+ {"r", REG_R, INS_NOT_GBZ80 },
+ {"sp", REG_SP, INS_ALL },
} ;
#define BUFLEN 8 /* Large enough for any keyword. */
@@ -499,6 +500,8 @@ md_begin (void)
reg.X_add_symbol = reg.X_op_symbol = 0;
for ( i = 0 ; i < ARRAY_SIZE ( regtable ) ; ++i )
{
+ if (regtable[i].isa && !(regtable[i].isa & ins_ok))
+ continue;
reg.X_add_number = regtable[i].number;
k = strlen ( regtable[i].name );
buf[k] = 0;
@@ -615,7 +618,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 *name;
@@ -625,20 +628,9 @@ z80_start_line_hook (void)
line_start = input_line_pointer;
if (ignore_input ())
return 0;
-
c = get_symbol_name (&name);
rest = input_line_pointer + 1;
-
- if (ISSPACE (c) && colonless_labels)
- {
- if (c == '\n')
- {
- bump_line_counters ();
- LISTING_NEWLINE ();
- }
- c = ':';
- }
- if (*rest == ':')
+ if (c == ':' && *rest == ':')
{
/* remove second colon if SDCC compatibility enabled */
if (sdcc_compat)
@@ -646,15 +638,20 @@ z80_start_line_hook (void)
++rest;
}
rest = (char*)skip_space (rest);
- if (*rest == '.')
- ++rest;
- if (strncasecmp (rest, "EQU", 3) == 0)
- len = 3;
- else if (strncasecmp (rest, "DEFL", 4) == 0)
- len = 4;
+ if (*rest == '=')
+ len = (rest[1] == '=') ? 2 : 1;
else
- len = 0;
- if (len && (!ISALPHA (rest[len])))
+ {
+ 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 && (len <= 2 || !ISALPHA (rest[len])))
{
/* Handle assignment here. */
if (line_start[-1] == '\n')
@@ -664,7 +661,17 @@ z80_start_line_hook (void)
}
input_line_pointer = rest + len - 1;
/* Allow redefining with "DEFL" (len == 4), but not with "EQU". */
- equals (name, len == 4);
+ switch (len)
+ {
+ case 1: /* label = expr */
+ case 4: /* label DEFL expr */
+ equals (name, 1);
+ break;
+ case 2: /* label == expr */
+ case 3: /* label EQU expr */
+ equals (name, 0);
+ break;
+ }
return 1;
}
else
@@ -1011,20 +1018,20 @@ parse_exp (const char *s, expressionS *op)
/* Condition codes, including some synonyms provided by HiTech zas. */
static const struct reg_entry cc_tab[] =
{
- { "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 },
+ { "age", 6 << 3, INS_ALL },
+ { "alt", 7 << 3, INS_ALL },
+ { "c", 3 << 3, INS_ALL },
+ { "di", 4 << 3, INS_ALL },
+ { "ei", 5 << 3, INS_ALL },
+ { "lge", 2 << 3, INS_ALL },
+ { "llt", 3 << 3, INS_ALL },
+ { "m", 7 << 3, INS_ALL },
+ { "nc", 2 << 3, INS_ALL },
+ { "nz", 0 << 3, INS_ALL },
+ { "p", 6 << 3, INS_ALL },
+ { "pe", 5 << 3, INS_ALL },
+ { "po", 4 << 3, INS_ALL },
+ { "z", 1 << 3, INS_ALL },
} ;
/* Parse condition code. */
@@ -3812,6 +3819,12 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp)
}
int
+z80_tc_labels_without_colon (void)
+{
+ return colonless_labels;
+}
+
+int
z80_tc_label_is_local (const char *name)
{
const char *n;