New opcodes to deal with 8-bit immediate sign extended to opsize
authorH. Peter Anvin <hpa@zytor.com>
Tue, 7 Oct 2008 06:40:31 +0000 (23:40 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 7 Oct 2008 06:40:31 +0000 (23:40 -0700)
New opcodes to deal with 8-bit immediates which are then sign-extended
to the operand size.  These allow us to warn appropriately.
Not sure I'm using these in all the proper places; need audit of all
uses of the \14..\17 opcodes.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
assemble.c
disasm.c
insns.dat
insns.pl
test/immwarn.asm

index d7e9eae..a7a23c2 100644 (file)
  * \64..\67      - select between \6[0-3] and \7[0-3] depending on 16/32 bit
  *                 assembly mode or the operand-size override on the operand
  * \70..\73      - a long relative operand, from operand 0..3
- * \74..\77       - a word constant, from the _segment_ part of operand 0..3
+ * \74..\77      - a word constant, from the _segment_ part of operand 0..3
  * \1ab          - a ModRM, calculated on EA in operand a, with the spare
  *                 field the register value of operand b.
  * \140..\143    - an immediate word or signed byte for operand 0..3
  * \144..\147    - or 2 (s-field) into opcode byte if operand 0..3
  *                 is a signed byte rather than a word.  Opcode byte follows.
- * \150..\153     - an immediate dword or signed byte for operand 0..3
+ * \150..\153    - an immediate dword or signed byte for operand 0..3
  * \154..\157    - or 2 (s-field) into opcode byte if operand 0..3
  *                 is a signed byte rather than a dword.  Opcode byte follows.
  * \160..\163    - this instruction uses DREX rather than REX, with the
@@ -70,6 +70,8 @@
  *                 [ww] ww = 3 for W used as REX.W
  *
  *
+ * \274..\277    - a signed byte immediate operand, from operand 0..3,
+ *                 which is to be extended to the operand size.
  * \310          - indicates fixed 16-bit address size, i.e. optional 0x67.
  * \311          - indicates fixed 32-bit address size, i.e. optional 0x67.
  * \312          - (disassembler only) marker on LOOP, LOOPxx instructions.
@@ -989,6 +991,12 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
            ins->vex_m = *codes++;
            ins->vex_wlp = *codes++;
            break;
+        case 0274:
+        case 0275:
+        case 0276:
+       case 0277:
+            length++;
+            break;
         case 0300:
         case 0301:
         case 0302:
@@ -1625,6 +1633,44 @@ static void gencode(int32_t segment, int64_t offset, int bits,
            }
            break;
 
+        case 0274:
+        case 0275:
+        case 0276:
+       case 0277:
+       {
+           uint64_t uv, um;
+           int s;
+
+           if (ins->rex & REX_W)
+               s = 64;
+           else if (ins->prefixes[PPS_OSIZE] == P_O16)
+               s = 16;
+           else if (ins->prefixes[PPS_OSIZE] == P_O32)
+               s = 32;
+           else
+               s = bits;
+
+           um = (uint64_t)2 << (s-1);
+           uv = opx->offset;
+
+           if (uv > 127 && uv < (uint64_t)-128 &&
+               (uv < um-128 || uv > um-1)) {
+                errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
+                       "signed byte value exceeds bounds");
+           }
+            if (opx->segment != NO_SEG) {
+                data = um;
+                out(offset, segment, &data, OUT_ADDRESS, 1,
+                    opx->segment, opx->wrt);
+            } else {
+                bytes[0] = um;
+                out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
+                    NO_SEG);
+            }
+            offset += 1;
+            break;
+       }
+
         case 0300:
         case 0301:
         case 0302:
index f3d4d2a..46e3cf2 100644 (file)
--- a/disasm.c
+++ b/disasm.c
@@ -482,6 +482,7 @@ static int matches(const struct itemplate *t, uint8_t *data,
        }
 
        case4(014):
+       case4(0274):
             opx->offset = (int8_t)*data++;
             opx->segment |= SEG_SIGNED;
            break;
index e4a0d78..8da82ed 100644 (file)
--- a/insns.dat
+++ b/insns.dat
@@ -87,9 +87,9 @@ ADD           reg32,mem                       \321\1\x03\110                                  386,SM
 ADD            reg32,reg32                     \321\1\x03\110                                  386
 ADD            reg64,mem                       \324\1\x03\110                                  X64,SM
 ADD            reg64,reg64                     \324\1\x03\110                                  X64
-ADD            rm16,imm8                       \320\1\x83\200\15                               8086
-ADD            rm32,imm8                       \321\1\x83\200\15                               386
-ADD            rm64,imm8                       \324\1\x83\200\15                               X64
+ADD            rm16,imm8                       \320\1\x83\200\275                              8086
+ADD            rm32,imm8                       \321\1\x83\200\275                              386
+ADD            rm64,imm8                       \324\1\x83\200\275                              X64
 ADD            reg_al,imm                      \1\x04\21                                       8086,SM
 ADD            reg_ax,imm                      \320\1\x05\31                                   8086,SM
 ADD            reg_eax,imm                     \321\1\x05\41                                   386,SM
@@ -242,9 +242,9 @@ CMP         reg32,mem                       \321\1\x3B\110                                  386,SM
 CMP            reg32,reg32                     \321\1\x3B\110                                  386
 CMP            reg64,mem                       \324\1\x3B\110                                  X64,SM
 CMP            reg64,reg64                     \324\1\x3B\110                                  X64
-CMP            rm16,imm8                       \320\1\x83\207\15                               8086
-CMP            rm32,imm8                       \321\1\x83\207\15                               386
-CMP            rm64,imm8                       \324\1\x83\207\15                               X64
+CMP            rm16,imm8                       \320\1\x83\207\275                              8086
+CMP            rm32,imm8                       \321\1\x83\207\275                              386
+CMP            rm64,imm8                       \324\1\x83\207\275                              X64
 CMP            reg_al,imm                      \1\x3C\21                                       8086,SM
 CMP            reg_ax,imm                      \320\1\x3D\31                                   8086,SM
 CMP            reg_eax,imm                     \321\1\x3D\41                                   386,SM
@@ -840,9 +840,9 @@ OR          reg32,mem                       \321\1\x0B\110                                  386,SM
 OR             reg32,reg32                     \321\1\x0B\110                                  386
 OR             reg64,mem                       \324\1\x0B\110                                  X64,SM
 OR             reg64,reg64                     \324\1\x0B\110                                  X64
-OR             rm16,imm8                       \320\1\x83\201\15                               8086
-OR             rm32,imm8                       \321\1\x83\201\15                               386
-OR             rm64,imm8                       \324\1\x83\201\15                               X64
+OR             rm16,imm8                       \320\1\x83\201\275                              8086
+OR             rm32,imm8                       \321\1\x83\201\275                              386
+OR             rm64,imm8                       \324\1\x83\201\275                              X64
 OR             reg_al,imm                      \1\x0C\21                                       8086,SM
 OR             reg_ax,imm                      \320\1\x0D\31                                   8086,SM
 OR             reg_eax,imm                     \321\1\x0D\41                                   386,SM
@@ -973,7 +973,7 @@ PUSH                rm64                            \323\1\xFF\206                                  X64
 PUSH           reg_cs                          \6                                              8086,NOLONG
 PUSH           reg_dess                        \6                                              8086,NOLONG
 PUSH           reg_fsgs                        \1\x0F\7                                        386
-PUSH           imm8                            \1\x6A\14                                       186
+PUSH           imm8                            \1\x6A\274                                      186
 PUSH           imm16                           \320\144\x68\140                                186,AR0,SZ
 PUSH           imm32                           \321\154\x68\150                                386,NOLONG,AR0,SZ
 PUSH           imm32                           \321\154\x68\150                                386,NOLONG,SD
@@ -1092,9 +1092,9 @@ SBB               reg32,mem                       \321\1\x1B\110                                  386,SM
 SBB            reg32,reg32                     \321\1\x1B\110                                  386
 SBB            reg64,mem                       \324\1\x1B\110                                  X64,SM
 SBB            reg64,reg64                     \324\1\x1B\110                                  X64
-SBB            rm16,imm8                       \320\1\x83\203\15                               8086
-SBB            rm32,imm8                       \321\1\x83\203\15                               386
-SBB            rm64,imm8                       \324\1\x83\203\15                               X64
+SBB            rm16,imm8                       \320\1\x83\203\275                              8086
+SBB            rm32,imm8                       \321\1\x83\203\275                              386
+SBB            rm64,imm8                       \324\1\x83\203\275                              X64
 SBB            reg_al,imm                      \1\x1C\21                                       8086,SM
 SBB            reg_ax,imm                      \320\1\x1D\31                                   8086,SM
 SBB            reg_eax,imm                     \321\1\x1D\41                                   386,SM
@@ -1205,9 +1205,9 @@ SUB               reg32,mem                       \321\1\x2B\110                                  386,SM
 SUB            reg32,reg32                     \321\1\x2B\110                                  386
 SUB            reg64,mem                       \324\1\x2B\110                                  X64,SM
 SUB            reg64,reg64                     \324\1\x2B\110                                  X64
-SUB            rm16,imm8                       \320\1\x83\205\15                               8086
-SUB            rm32,imm8                       \321\1\x83\205\15                               386
-SUB            rm64,imm8                       \324\1\x83\205\15                               X64
+SUB            rm16,imm8                       \320\1\x83\205\275                              8086
+SUB            rm32,imm8                       \321\1\x83\205\275                              386
+SUB            rm64,imm8                       \324\1\x83\205\275                              X64
 SUB            reg_al,imm                      \1\x2C\21                                       8086,SM
 SUB            reg_ax,imm                      \320\1\x2D\31                                   8086,SM
 SUB            reg_eax,imm                     \321\1\x2D\41                                   386,SM
@@ -1333,9 +1333,9 @@ XOR               reg32,mem                       \321\1\x33\110                                  386,SM
 XOR            reg32,reg32                     \321\1\x33\110                                  386
 XOR            reg64,mem                       \324\1\x33\110                                  X64,SM
 XOR            reg64,reg64                     \324\1\x33\110                                  X64
-XOR            rm16,imm8                       \320\1\x83\206\15                               8086
-XOR            rm32,imm8                       \321\1\x83\206\15                               386
-XOR            rm64,imm8                       \324\1\x83\206\15                               X64
+XOR            rm16,imm8                       \320\1\x83\206\275                              8086
+XOR            rm32,imm8                       \321\1\x83\206\275                              386
+XOR            rm64,imm8                       \324\1\x83\206\275                              X64
 XOR            reg_al,imm                      \1\x34\21                                       8086,SM
 XOR            reg_ax,imm                      \320\1\x35\31                                   8086,SM
 XOR            reg_eax,imm                     \321\1\x35\41                                   386,SM
index 9a8d3ed..cb45496 100755 (executable)
--- a/insns.pl
+++ b/insns.pl
@@ -670,6 +670,8 @@ sub byte_code_compile($) {
                push(@codes, 024+$oppos{'i'});
            } elsif ($op eq 'iw') { # imm16
                push(@codes, 030+$oppos{'i'});
+           } elsif ($op eq 'ibx') { # imm8 sign-extended to opsize
+               push(@codes, 0274+$oppos{'i'});
            } elsif ($op eq 'iwd') { # imm16 or imm32, depending on opsize
                push(@codes, 034+$oppos{'i'});
            } elsif ($op eq 'id') { # imm32
index 3fc01c7..4b67676 100644 (file)
 %endif
        push -1
        push 0ffffh
-       push byte 0FFFFh        ; XXX - inappropriate
+       push byte 0FFFFh
 
        add ax,0FFFFh
 %if WARN
        add ax,0FFFFFFFFh
 %endif
        add ax,-1
-       add ax,byte 0FFFFh      ; XXX - inappropriate
+       add ax,byte 0FFFFh
 %if WARN
        add ax,byte 0FFFFFFFFh
 %endif
@@ -32,7 +32,7 @@
        add cx,0FFFFFFFFh
 %endif
        add cx,-1
-       add cx,byte 0FFFFh      ; XXX - inappropriate
+       add cx,byte 0FFFFh
 %if WARN
        add cx,byte 0FFFFFFFFh
 %endif
@@ -87,4 +87,3 @@
        push byte 0ffffffffh
 %endif
        push byte -1
-