diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 11 | ||||
-rw-r--r-- | gas/config/tc-z80.c | 42 |
2 files changed, 40 insertions, 13 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 5343503667c..2c09ee72a26 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,14 @@ +2018-08-21 Arnold Metselaar <arnold.metsel@gmail.com> + + * config/tc-z80.c: Correct treatment of undocumented instruction + sli/sll. + (emit_mr): Add argument unportable. + (emit_bit): Adapt call to emit_mr. + (emit_mr_z80): New function. + (emit_mr_unportable): New function. + (instab[]): Replace emit_mr with emit_mr_z80 or emit_mr_unportable + as appropriate. + 2018-08-21 Andreas Schwab <schwab@suse.de> * read.c (do_repeat_with_expander): Use memmove instead of strcpy diff --git a/gas/config/tc-z80.c b/gas/config/tc-z80.c index 5a4fd38fce1..cf4fe897b9a 100644 --- a/gas/config/tc-z80.c +++ b/gas/config/tc-z80.c @@ -849,8 +849,9 @@ emit_m (char prefix, char opcode, const char *args) /* The operand m may be as above or one of the undocumented combinations (ix+d),r and (iy+d),r (if unportable instructions are allowed). */ + static const char * -emit_mr (char prefix, char opcode, const char *args) +emit_mr (char prefix, char opcode, const char *args, bfd_boolean unportable) { expressionS arg_m, arg_r; const char *p; @@ -867,16 +868,19 @@ emit_mr (char prefix, char opcode, const char *args) 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. */ + opcode += arg_r.X_add_number - 6; /* Emit_mx () will add 6. */ else { ill_op (); break; } check_mach (INS_UNPORT); + unportable = TRUE; } /* Fall through. */ case O_register: + if (unportable) + check_mach (INS_UNPORT); emit_mx (prefix, opcode, 0, & arg_m); break; default: @@ -885,6 +889,18 @@ emit_mr (char prefix, char opcode, const char *args) return p; } +static const char * +emit_mr_z80 (char prefix, char opcode, const char *args) +{ + return emit_mr (prefix, opcode, args, FALSE); +} + +static const char * +emit_mr_unport (char prefix, char opcode, const char *args) +{ + return emit_mr (prefix, opcode, args, TRUE); +} + static void emit_sx (char prefix, char opcode, expressionS * arg_p) { @@ -1203,7 +1219,7 @@ emit_bit (char prefix, char opcode, const char * args) 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); + p = emit_mr (prefix, opcode + (bn << 3), p, FALSE); } else ill_op (); @@ -1888,31 +1904,31 @@ static table_t instab[] = { "ret", 0xC9, 0xC0, emit_retcc }, { "reti", 0xED, 0x4D, emit_insn }, { "retn", 0xED, 0x45, emit_insn }, - { "rl", 0xCB, 0x10, emit_mr }, + { "rl", 0xCB, 0x10, emit_mr_z80 }, { "rla", 0x00, 0x17, emit_insn }, - { "rlc", 0xCB, 0x00, emit_mr }, + { "rlc", 0xCB, 0x00, emit_mr_z80 }, { "rlca", 0x00, 0x07, emit_insn }, { "rld", 0xED, 0x6F, emit_insn }, - { "rr", 0xCB, 0x18, emit_mr }, + { "rr", 0xCB, 0x18, emit_mr_z80 }, { "rra", 0x00, 0x1F, emit_insn }, - { "rrc", 0xCB, 0x08, emit_mr }, + { "rrc", 0xCB, 0x08, emit_mr_z80 }, { "rrca", 0x00, 0x0F, emit_insn }, { "rrd", 0xED, 0x67, emit_insn }, { "rst", 0x00, 0xC7, emit_rst}, { "sbc", 0x98, 0x42, emit_adc }, { "scf", 0x00, 0x37, emit_insn }, { "set", 0xCB, 0xC0, emit_bit }, - { "sla", 0xCB, 0x20, emit_mr }, - { "sli", 0xCB, 0x30, emit_mr }, - { "sll", 0xCB, 0x30, emit_mr }, - { "sra", 0xCB, 0x28, emit_mr }, - { "srl", 0xCB, 0x38, emit_mr }, + { "sla", 0xCB, 0x20, emit_mr_z80 }, + { "sli", 0xCB, 0x30, emit_mr_unport }, + { "sll", 0xCB, 0x30, emit_mr_unport }, + { "sra", 0xCB, 0x28, emit_mr_z80 }, + { "srl", 0xCB, 0x38, emit_mr_z80 }, { "sub", 0x00, 0x90, emit_s }, { "xor", 0x00, 0xA8, emit_s }, } ; void -md_assemble (char* str) +md_assemble (char *str) { const char *p; char * old_ptr; |