Fix overflow detection in the Z80 assembler.
authorSergey Belyashov <sergey.belyashov@gmail.com>
Thu, 20 May 2021 15:14:10 +0000 (16:14 +0100)
committerNick Clifton <nickc@redhat.com>
Thu, 20 May 2021 15:14:10 +0000 (16:14 +0100)
 * 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.

gas/ChangeLog
gas/config/tc-z80.c
gas/testsuite/gas/z80/ez80_adl_suf.d
gas/testsuite/gas/z80/ez80_isuf.s
gas/testsuite/gas/z80/ez80_z80_suf.d

index 75eb501cf7b9e0a9cdb7f627ede7d118c0ff43a9..b9a59b66b808d27e499331882310fe4670a77a95 100644 (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
index 2146e675672a6ec09f3f41f8577bcc1e87cf413f..47d1405c2b629c1446253658345a4969f56a40ad 100644 (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;
index 0e223624d63699df8c5911195f1fe9d92d3c47e5..6b92b1daa56e72634719cd7fe488653cd4161bcb 100644 (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
index 8b20852a28fa1859d8e53f0900773e694525843b..145b56e9b84278390d7ba1f86b19a69c7abb5a73 100644 (file)
-       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
        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
index 4fa7cd9c15368b1602a634c23c54e133dd2e82a4..126940271d6a9c446641ba6f9b9b47675a127998 100644 (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