Fix overflow detection in the Z80 assembler.

* config/tc-z80.c (emit_data_val): Warn on constant overflow.
 (signed_overflow): New function.
 (unsigned_overflow): New function.
 (is_overflow): Use new functions.
 (md_apply_fix): Use signed_overflow.
 * testsuite/gas/z80/ez80_adl_suf.d: Fix test.
 * testsuite/gas/z80/ez80_isuf.s: Likewise.
 * testsuite/gas/z80/ez80_z80_suf.d: Likewise.
This commit is contained in:
Sergey Belyashov 2021-05-20 16:14:10 +01:00 committed by Nick Clifton
parent ed3130b740
commit 9a01ec4c03
5 changed files with 227 additions and 200 deletions

View File

@ -1,3 +1,14 @@
2021-05-20 Sergey Belyashov <sergey.belyashov@gmail.com>
* config/tc-z80.c (emit_data_val): Warn on constant overflow.
(signed_overflow): New function.
(unsigned_overflow): New function.
(is_overflow): Use new functions.
(md_apply_fix): Use signed_overflow.
* testsuite/gas/z80/ez80_adl_suf.d: Fix test.
* testsuite/gas/z80/ez80_isuf.s: Likewise.
* testsuite/gas/z80/ez80_z80_suf.d: Likewise.
2021-05-20 Nicolas Boulenguez <nicolas@debian.org>
PR 27888

View File

@ -175,6 +175,11 @@ match_ext_table [] =
{"xdcb", INS_ROT_II_LD, 0, 0, "instructions like RL (IX+d),R (DD/FD CB dd oo)" }
};
static int signed_overflow (signed long value, unsigned bitsize);
static int unsigned_overflow (unsigned long value, unsigned bitsize);
static int is_overflow (long value, unsigned bitsize);
static void
setup_march (const char *name, int *ok, int *err, int *mode)
{
@ -1129,6 +1134,8 @@ emit_data_val (expressionS * val, int size)
if (val->X_op == O_constant)
{
int i;
if (is_overflow (val->X_add_number, size*8))
as_warn ( _("%d-bit overflow (%+ld)"), size*8, val->X_add_number);
for (i = 0; i < size; ++i)
p[i] = (char)(val->X_add_number >> (i*8));
return;
@ -3693,16 +3700,25 @@ md_assemble (char *str)
input_line_pointer = old_ptr;
}
static int
signed_overflow (signed long value, unsigned bitsize)
{
signed long max = (signed long)(1UL << (bitsize-1));
return value < -max || value >= max;
}
static int
unsigned_overflow (unsigned long value, unsigned bitsize)
{
return (value >> bitsize) != 0;
}
static int
is_overflow (long value, unsigned bitsize)
{
long fieldmask = (2UL << (bitsize - 1)) - 1;
long signmask = ~fieldmask;
long a = value & fieldmask;
long ss = a & signmask;
if (ss != 0 && ss != (signmask & fieldmask))
return 1;
return 0;
if (value < 0)
return signed_overflow (value, bitsize);
return unsigned_overflow ((unsigned long)value, bitsize);
}
void
@ -3743,7 +3759,7 @@ md_apply_fix (fixS * fixP, valueT* valP, segT seg)
{
case BFD_RELOC_8_PCREL:
case BFD_RELOC_Z80_DISP8:
if (fixP->fx_done && (val < -0x80 || val > 0x7f))
if (fixP->fx_done && signed_overflow (val, 8))
as_bad_where (fixP->fx_file, fixP->fx_line,
_("8-bit signed offset out of range (%+ld)"), val);
*p_lit++ = val;

View File

@ -1,4 +1,4 @@
#as: -march=ez80+adl
#as: -march=ez80+adl --defsym VALUE=0x123456
#objdump: -d
#name: eZ80 instructions with sufficies in ADL cpu mode
#source: ez80_isuf.s

View File

@ -1,121 +1,121 @@
call.s 0x123456
call.s c,0x123456
call.s m,0x123456
call.s nc,0x123456
call.s nz,0x123456
call.s p,0x123456
call.s pe,0x123456
call.s po,0x123456
call.s z,0x123456
jp.s 0x123456
jp.s c,0x123456
jp.s m,0x123456
jp.s nc,0x123456
jp.s nz,0x123456
jp.s p,0x123456
jp.s pe,0x123456
jp.s po,0x123456
jp.s z,0x123456
ld.s (0x123456),a
ld.s (0x123456),bc
ld.s (0x123456),de
ld.s (0x123456),hl
ld.s (0x123456),ix
ld.s (0x123456),iy
ld.s (0x123456),sp
ld.s a,(0x123456)
ld.s bc,(0x123456)
ld.s bc,0x123456
ld.s de,(0x123456)
ld.s de,0x123456
ld.s hl,(0x123456)
ld.s hl,0x123456
ld.s ix,(0x123456)
ld.s ix,0x123456
ld.s iy,(0x123456)
ld.s iy,0x123456
ld.s sp,(0x123456)
ld.s sp,0x123456
call.s VALUE
call.s c,VALUE
call.s m,VALUE
call.s nc,VALUE
call.s nz,VALUE
call.s p,VALUE
call.s pe,VALUE
call.s po,VALUE
call.s z,VALUE
jp.s VALUE
jp.s c,VALUE
jp.s m,VALUE
jp.s nc,VALUE
jp.s nz,VALUE
jp.s p,VALUE
jp.s pe,VALUE
jp.s po,VALUE
jp.s z,VALUE
ld.s (VALUE),a
ld.s (VALUE),bc
ld.s (VALUE),de
ld.s (VALUE),hl
ld.s (VALUE),ix
ld.s (VALUE),iy
ld.s (VALUE),sp
ld.s a,(VALUE)
ld.s bc,(VALUE)
ld.s bc,VALUE
ld.s de,(VALUE)
ld.s de,VALUE
ld.s hl,(VALUE)
ld.s hl,VALUE
ld.s ix,(VALUE)
ld.s ix,VALUE
ld.s iy,(VALUE)
ld.s iy,VALUE
ld.s sp,(VALUE)
ld.s sp,VALUE
.page
call.l 0x123456
call.l c,0x123456
call.l m,0x123456
call.l nc,0x123456
call.l nz,0x123456
call.l p,0x123456
call.l pe,0x123456
call.l po,0x123456
call.l z,0x123456
jp.l 0x123456
jp.l c,0x123456
jp.l m,0x123456
jp.l nc,0x123456
jp.l nz,0x123456
jp.l p,0x123456
jp.l pe,0x123456
jp.l po,0x123456
jp.l z,0x123456
ld.l (0x123456),a
ld.l (0x123456),bc
ld.l (0x123456),de
ld.l (0x123456),hl
ld.l (0x123456),ix
ld.l (0x123456),iy
ld.l (0x123456),sp
ld.l a,(0x123456)
ld.l bc,(0x123456)
ld.l bc,0x123456
ld.l de,(0x123456)
ld.l de,0x123456
ld.l hl,(0x123456)
ld.l hl,0x123456
ld.l ix,(0x123456)
ld.l ix,0x123456
ld.l iy,(0x123456)
ld.l iy,0x123456
ld.l sp,(0x123456)
ld.l sp,0x123456
call.l VALUE
call.l c,VALUE
call.l m,VALUE
call.l nc,VALUE
call.l nz,VALUE
call.l p,VALUE
call.l pe,VALUE
call.l po,VALUE
call.l z,VALUE
jp.l VALUE
jp.l c,VALUE
jp.l m,VALUE
jp.l nc,VALUE
jp.l nz,VALUE
jp.l p,VALUE
jp.l pe,VALUE
jp.l po,VALUE
jp.l z,VALUE
ld.l (VALUE),a
ld.l (VALUE),bc
ld.l (VALUE),de
ld.l (VALUE),hl
ld.l (VALUE),ix
ld.l (VALUE),iy
ld.l (VALUE),sp
ld.l a,(VALUE)
ld.l bc,(VALUE)
ld.l bc,VALUE
ld.l de,(VALUE)
ld.l de,VALUE
ld.l hl,(VALUE)
ld.l hl,VALUE
ld.l ix,(VALUE)
ld.l ix,VALUE
ld.l iy,(VALUE)
ld.l iy,VALUE
ld.l sp,(VALUE)
ld.l sp,VALUE
.page
call.is 0x123456
call.is c,0x123456
call.is m,0x123456
call.is nc,0x123456
call.is nz,0x123456
call.is p,0x123456
call.is pe,0x123456
call.is po,0x123456
call.is z,0x123456
jp.is 0x123456
jp.is c,0x123456
jp.is m,0x123456
jp.is nc,0x123456
jp.is nz,0x123456
jp.is p,0x123456
jp.is pe,0x123456
jp.is po,0x123456
jp.is z,0x123456
ld.is (0x123456),a
ld.is (0x123456),bc
ld.is (0x123456),de
ld.is (0x123456),hl
ld.is (0x123456),ix
ld.is (0x123456),iy
ld.is (0x123456),sp
ld.is a,(0x123456)
ld.is bc,(0x123456)
ld.is bc,0x123456
ld.is de,(0x123456)
ld.is de,0x123456
ld.is hl,(0x123456)
ld.is hl,0x123456
ld.is ix,(0x123456)
ld.is ix,0x123456
ld.is iy,(0x123456)
ld.is iy,0x123456
ld.is sp,(0x123456)
ld.is sp,0x123456
call.is 0x3456
call.is c,0x3456
call.is m,0x3456
call.is nc,0x3456
call.is nz,0x3456
call.is p,0x3456
call.is pe,0x3456
call.is po,0x3456
call.is z,0x3456
jp.is 0x3456
jp.is c,0x3456
jp.is m,0x3456
jp.is nc,0x3456
jp.is nz,0x3456
jp.is p,0x3456
jp.is pe,0x3456
jp.is po,0x3456
jp.is z,0x3456
ld.is (0x3456),a
ld.is (0x3456),bc
ld.is (0x3456),de
ld.is (0x3456),hl
ld.is (0x3456),ix
ld.is (0x3456),iy
ld.is (0x3456),sp
ld.is a,(0x3456)
ld.is bc,(0x3456)
ld.is bc,0x3456
ld.is de,(0x3456)
ld.is de,0x3456
ld.is hl,(0x3456)
ld.is hl,0x3456
ld.is ix,(0x3456)
ld.is ix,0x3456
ld.is iy,(0x3456)
ld.is iy,0x3456
ld.is sp,(0x3456)
ld.is sp,0x3456
.page
call.il 0x123456
@ -158,84 +158,84 @@
ld.il sp,0x123456
.page
call.sis 0x123456
call.sis c,0x123456
call.sis m,0x123456
call.sis nc,0x123456
call.sis nz,0x123456
call.sis p,0x123456
call.sis pe,0x123456
call.sis po,0x123456
call.sis z,0x123456
jp.sis 0x123456
jp.sis c,0x123456
jp.sis m,0x123456
jp.sis nc,0x123456
jp.sis nz,0x123456
jp.sis p,0x123456
jp.sis pe,0x123456
jp.sis po,0x123456
jp.sis z,0x123456
ld.sis (0x123456),a
ld.sis (0x123456),bc
ld.sis (0x123456),de
ld.sis (0x123456),hl
ld.sis (0x123456),ix
ld.sis (0x123456),iy
ld.sis (0x123456),sp
ld.sis a,(0x123456)
ld.sis bc,(0x123456)
ld.sis bc,0x123456
ld.sis de,(0x123456)
ld.sis de,0x123456
ld.sis hl,(0x123456)
ld.sis hl,0x123456
ld.sis ix,(0x123456)
ld.sis ix,0x123456
ld.sis iy,(0x123456)
ld.sis iy,0x123456
ld.sis sp,(0x123456)
ld.sis sp,0x123456
call.sis 0x3456
call.sis c,0x3456
call.sis m,0x3456
call.sis nc,0x3456
call.sis nz,0x3456
call.sis p,0x3456
call.sis pe,0x3456
call.sis po,0x3456
call.sis z,0x3456
jp.sis 0x3456
jp.sis c,0x3456
jp.sis m,0x3456
jp.sis nc,0x3456
jp.sis nz,0x3456
jp.sis p,0x3456
jp.sis pe,0x3456
jp.sis po,0x3456
jp.sis z,0x3456
ld.sis (0x3456),a
ld.sis (0x3456),bc
ld.sis (0x3456),de
ld.sis (0x3456),hl
ld.sis (0x3456),ix
ld.sis (0x3456),iy
ld.sis (0x3456),sp
ld.sis a,(0x3456)
ld.sis bc,(0x3456)
ld.sis bc,0x3456
ld.sis de,(0x3456)
ld.sis de,0x3456
ld.sis hl,(0x3456)
ld.sis hl,0x3456
ld.sis ix,(0x3456)
ld.sis ix,0x3456
ld.sis iy,(0x3456)
ld.sis iy,0x3456
ld.sis sp,(0x3456)
ld.sis sp,0x3456
.page
call.lis 0x123456
call.lis c,0x123456
call.lis m,0x123456
call.lis nc,0x123456
call.lis nz,0x123456
call.lis p,0x123456
call.lis pe,0x123456
call.lis po,0x123456
call.lis z,0x123456
jp.lis 0x123456
jp.lis c,0x123456
jp.lis m,0x123456
jp.lis nc,0x123456
jp.lis nz,0x123456
jp.lis p,0x123456
jp.lis pe,0x123456
jp.lis po,0x123456
jp.lis z,0x123456
ld.lis (0x123456),a
ld.lis (0x123456),bc
ld.lis (0x123456),de
ld.lis (0x123456),hl
ld.lis (0x123456),ix
ld.lis (0x123456),iy
ld.lis (0x123456),sp
ld.lis a,(0x123456)
ld.lis bc,(0x123456)
ld.lis bc,0x123456
ld.lis de,(0x123456)
ld.lis de,0x123456
ld.lis hl,(0x123456)
ld.lis hl,0x123456
ld.lis ix,(0x123456)
ld.lis ix,0x123456
ld.lis iy,(0x123456)
ld.lis iy,0x123456
ld.lis sp,(0x123456)
ld.lis sp,0x123456
call.lis 0x3456
call.lis c,0x3456
call.lis m,0x3456
call.lis nc,0x3456
call.lis nz,0x3456
call.lis p,0x3456
call.lis pe,0x3456
call.lis po,0x3456
call.lis z,0x3456
jp.lis 0x3456
jp.lis c,0x3456
jp.lis m,0x3456
jp.lis nc,0x3456
jp.lis nz,0x3456
jp.lis p,0x3456
jp.lis pe,0x3456
jp.lis po,0x3456
jp.lis z,0x3456
ld.lis (0x3456),a
ld.lis (0x3456),bc
ld.lis (0x3456),de
ld.lis (0x3456),hl
ld.lis (0x3456),ix
ld.lis (0x3456),iy
ld.lis (0x3456),sp
ld.lis a,(0x3456)
ld.lis bc,(0x3456)
ld.lis bc,0x3456
ld.lis de,(0x3456)
ld.lis de,0x3456
ld.lis hl,(0x3456)
ld.lis hl,0x3456
ld.lis ix,(0x3456)
ld.lis ix,0x3456
ld.lis iy,(0x3456)
ld.lis iy,0x3456
ld.lis sp,(0x3456)
ld.lis sp,0x3456
.page
call.sil 0x123456

View File

@ -1,4 +1,4 @@
#as: -march=ez80
#as: -march=ez80 --defsym VALUE=0x3456
#objdump: -d
#name: eZ80 instructions with sufficies in Z80 cpu mode
#source: ez80_isuf.s