diff options
author | Sergey Belyashov <sergey.belyashov@gmail.com> | 2020-03-17 16:55:32 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2020-03-17 16:55:32 +0000 |
commit | 68e52bc7ecfbfdc8d5f85716a8ac7668e211f360 (patch) | |
tree | b6fad703f9e73ec0191841e9dcc13d15dae614ce /gas/config/tc-z80.c | |
parent | ecbbbdba7182865e522e0893915e9be487fe14b0 (diff) | |
download | gdb-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.c | 131 |
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; |