Handle indirect branches for AMD64 and Intel64
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 3 Jun 2016 22:55:29 +0000 (15:55 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 3 Jun 2016 22:55:29 +0000 (15:55 -0700)
AMD64 spec and Intel64 spec differ in indirect branches in 64-bit mode.
AMD64 supports indirect branches with 16-bit address via the data size
prefix while the data size prefix is ignored by Intel64.

gas/

PR binutis/18386
* testsuite/gas/i386/i386.exp: Run x86-64-branch-4.
* testsuite/gas/i386/x86-64-branch.d: Updated.
* testsuite/gas/i386/ilp32/x86-64-branch.d: Likewise.
* testsuite/gas/i386/x86-64-branch-4.l: New file.
* testsuite/gas/i386/x86-64-branch-4.s: Likewise.

opcodes/

PR binutis/18386
* i386-dis.c (indirEv): Replace stack_v_mode with indir_v_mode.
(indir_v_mode): New.
Add comments for '&'.
(reg_table): Replace "{T|}" with "{&|}" on call and jmp.
(putop): Handle '&'.
(intel_operand_size): Handle indir_v_mode.
(OP_E_register): Likewise.
* i386-opc.tbl: Mark 64-bit indirect call/jmp as AMD64.  Add
64-bit indirect call/jmp for AMD64.
* i386-tbl.h: Regenerated

gas/ChangeLog
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/ilp32/x86-64-branch.d
gas/testsuite/gas/i386/x86-64-branch-4.l [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-branch-4.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-branch.d
opcodes/ChangeLog
opcodes/i386-dis.c
opcodes/i386-opc.tbl
opcodes/i386-tbl.h

index 33a1e28907569a0ebd7ddb441814e88b79f4a321..50b17fa21c328082f9cd4c58a082348947292c93 100644 (file)
@@ -1,3 +1,12 @@
+2016-06-03  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR binutis/18386
+       * testsuite/gas/i386/i386.exp: Run x86-64-branch-4.
+       * testsuite/gas/i386/x86-64-branch.d: Updated.
+       * testsuite/gas/i386/ilp32/x86-64-branch.d: Likewise.
+       * testsuite/gas/i386/x86-64-branch-4.l: New file.
+       * testsuite/gas/i386/x86-64-branch-4.s: Likewise.
+
 2016-06-03  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/tc-aarch64.c (aarch64_cpus): Add cortex-a73 entry.
index 959cd14fe00f80c160c41de08061b7d21ca2909c..e7073e0dea3ea97d097b7bc297dc681033a12578 100644 (file)
@@ -816,6 +816,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
        run_dump_test "x86-64-jump"
        run_dump_test "x86-64-branch-2"
        run_list_test "x86-64-branch-3" "-al -mintel64"
+       run_list_test "x86-64-branch-4" "-al -mintel64"
 
        run_dump_test "x86-64-gotpcrel"
        run_dump_test "x86-64-gotpcrel-no-relax"
index 8200282d10ad2b68ccaeb3d9af730e11abec9544..915dbf3f1c95a6343e3f01c33504ef137d3fdfed 100644 (file)
@@ -10,14 +10,14 @@ Disassembly of section .text:
 0+ <.text>:
 [      ]*[a-f0-9]+:    ff d0                   callq  \*%rax
 [      ]*[a-f0-9]+:    ff d0                   callq  \*%rax
-[      ]*[a-f0-9]+:    66 ff d0                callw  \*%ax
-[      ]*[a-f0-9]+:    66 ff d0                callw  \*%ax
-[      ]*[a-f0-9]+:    66 ff 10                callw  \*\(%rax\)
+[      ]*[a-f0-9]+:    66 ff d0                data16 callq \*%rax
+[      ]*[a-f0-9]+:    66 ff d0                data16 callq \*%rax
+[      ]*[a-f0-9]+:    66 ff 10                data16 callq \*\(%rax\)
 [      ]*[a-f0-9]+:    ff e0                   jmpq   \*%rax
 [      ]*[a-f0-9]+:    ff e0                   jmpq   \*%rax
-[      ]*[a-f0-9]+:    66 ff e0                jmpw   \*%ax
-[      ]*[a-f0-9]+:    66 ff e0                jmpw   \*%ax
-[      ]*[a-f0-9]+:    66 ff 20                jmpw   \*\(%rax\)
+[      ]*[a-f0-9]+:    66 ff e0                data16 jmpq \*%rax
+[      ]*[a-f0-9]+:    66 ff e0                data16 jmpq \*%rax
+[      ]*[a-f0-9]+:    66 ff 20                data16 jmpq \*\(%rax\)
 [      ]*[a-f0-9]+:    e8 00 00 00 00          callq  0x1f     1b: R_X86_64_PC32       \*ABS\*\+0x10003c
 [      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   0x24     20: R_X86_64_PC32       \*ABS\*\+0x10003c
 [      ]*[a-f0-9]+:    66 e8 00 00 00 00       data16 callq 0x2a       26: R_X86_64_PC32       foo-0x4
@@ -25,14 +25,14 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    66 0f 82 00 00 00 00    data16 jb 0x37  33: R_X86_64_PC32       foo-0x4
 [      ]*[a-f0-9]+:    ff d0                   callq  \*%rax
 [      ]*[a-f0-9]+:    ff d0                   callq  \*%rax
-[      ]*[a-f0-9]+:    66 ff d0                callw  \*%ax
-[      ]*[a-f0-9]+:    66 ff d0                callw  \*%ax
-[      ]*[a-f0-9]+:    66 ff 10                callw  \*\(%rax\)
+[      ]*[a-f0-9]+:    66 ff d0                data16 callq \*%rax
+[      ]*[a-f0-9]+:    66 ff d0                data16 callq \*%rax
+[      ]*[a-f0-9]+:    66 ff 10                data16 callq \*\(%rax\)
 [      ]*[a-f0-9]+:    ff e0                   jmpq   \*%rax
 [      ]*[a-f0-9]+:    ff e0                   jmpq   \*%rax
-[      ]*[a-f0-9]+:    66 ff e0                jmpw   \*%ax
-[      ]*[a-f0-9]+:    66 ff e0                jmpw   \*%ax
-[      ]*[a-f0-9]+:    66 ff 20                jmpw   \*\(%rax\)
+[      ]*[a-f0-9]+:    66 ff e0                data16 jmpq \*%rax
+[      ]*[a-f0-9]+:    66 ff e0                data16 jmpq \*%rax
+[      ]*[a-f0-9]+:    66 ff 20                data16 jmpq \*\(%rax\)
 [      ]*[a-f0-9]+:    e8 00 00 00 00          callq  0x56     52: R_X86_64_PC32       \*ABS\*\+0x10003c
 [      ]*[a-f0-9]+:    e9 00 00 00 00          jmpq   0x5b     57: R_X86_64_PC32       \*ABS\*\+0x10003c
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-branch-4.l b/gas/testsuite/gas/i386/x86-64-branch-4.l
new file mode 100644 (file)
index 0000000..db55394
--- /dev/null
@@ -0,0 +1,33 @@
+.*: Assembler messages:
+.*:2: Error: invalid instruction suffix for `call'
+.*:3: Error: invalid instruction suffix for `call'
+.*:4: Error: operand type mismatch for `jmp'
+.*:5: Error: invalid instruction suffix for `jmp'
+.*:6: Error: invalid instruction suffix for `jmp'
+.*:9: Error: operand type mismatch for `call'
+.*:10: Error: invalid instruction suffix for `call'
+.*:11: Error: invalid instruction suffix for `call'
+.*:12: Error: invalid instruction suffix for `call'
+.*:13: Error: operand type mismatch for `jmp'
+.*:14: Error: invalid instruction suffix for `jmp'
+.*:15: Error: invalid instruction suffix for `jmp'
+.*:16: Error: invalid instruction suffix for `jmp'
+GAS LISTING .*
+#...
+[      ]*1[    ]+\.text
+[      ]*2[    ]+callw \*%ax
+[      ]*3[    ]+callw \*\(%rax\)
+[      ]*4[    ]+jmp   \*%ax
+[      ]*5[    ]+jmpw  \*%ax
+[      ]*6[    ]+jmpw  \*\(%rax\)
+[      ]*7[    ]+
+[      ]*8[    ]+\.intel_syntax noprefix
+[      ]*9[    ]+call  ax
+[      ]*10[   ]+callw ax
+[      ]*11[   ]+callw \[rax\]
+[      ]*12[   ]+call  WORD PTR \[rax\]
+[      ]*13[   ]+jmp   ax
+[      ]*14[   ]+jmpw  ax
+[      ]*15[   ]+jmpw  \[rax\]
+[      ]*16[   ]+jmp   WORD PTR \[rax\]
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-branch-4.s b/gas/testsuite/gas/i386/x86-64-branch-4.s
new file mode 100644 (file)
index 0000000..67d6e1f
--- /dev/null
@@ -0,0 +1,16 @@
+.text
+       callw   *%ax
+       callw   *(%rax)
+       jmp     *%ax
+       jmpw    *%ax
+       jmpw    *(%rax)
+
+       .intel_syntax noprefix
+       call    ax
+       callw   ax
+       callw   [rax]
+       call    WORD PTR [rax]
+       jmp     ax
+       jmpw    ax
+       jmpw    [rax]
+       jmp     WORD PTR [rax]
index 612acc0e1ebe4d55b22110f57ba7aa43abf49455..773ce71344318b08fa6ca31b0e75212fdf0b53b7 100644 (file)
@@ -9,14 +9,14 @@ Disassembly of section .text:
 0+ <.text>:
 [      ]*[a-f0-9]+:    ff d0                   callq  \*%rax
 [      ]*[a-f0-9]+:    ff d0                   callq  \*%rax
-[      ]*[a-f0-9]+:    66 ff d0                callw  \*%ax
-[      ]*[a-f0-9]+:    66 ff d0                callw  \*%ax
-[      ]*[a-f0-9]+:    66 ff 10                callw  \*\(%rax\)
+[      ]*[a-f0-9]+:    66 ff d0                data16 callq \*%rax
+[      ]*[a-f0-9]+:    66 ff d0                data16 callq \*%rax
+[      ]*[a-f0-9]+:    66 ff 10                data16 callq \*\(%rax\)
 [      ]*[a-f0-9]+:    ff e0                   jmpq   \*%rax
 [      ]*[a-f0-9]+:    ff e0                   jmpq   \*%rax
-[      ]*[a-f0-9]+:    66 ff e0                jmpw   \*%ax
-[      ]*[a-f0-9]+:    66 ff e0                jmpw   \*%ax
-[      ]*[a-f0-9]+:    66 ff 20                jmpw   \*\(%rax\)
+[      ]*[a-f0-9]+:    66 ff e0                data16 jmpq \*%rax
+[      ]*[a-f0-9]+:    66 ff e0                data16 jmpq \*%rax
+[      ]*[a-f0-9]+:    66 ff 20                data16 jmpq \*\(%rax\)
 [      ]*[a-f0-9]+:    e8 (00|5b) 00 (00|10) 00        callq  (0x1f|10007a <.text\+0x10007a>)
 [      ]*[a-f0-9]+:    e9 (00|60) 00 (00|10) 00        jmpq   (0x24|100084 <.text\+0x100084>)
 [      ]*[a-f0-9]+:    66 e8 00 00 00 00       data16 callq (0x2a|2a <.text\+0x2a>)
@@ -24,14 +24,14 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    66 0f 82 00 00 00 00    data16 jb (0x37|37 <.text\+0x37>)
 [      ]*[a-f0-9]+:    ff d0                   callq  \*%rax
 [      ]*[a-f0-9]+:    ff d0                   callq  \*%rax
-[      ]*[a-f0-9]+:    66 ff d0                callw  \*%ax
-[      ]*[a-f0-9]+:    66 ff d0                callw  \*%ax
-[      ]*[a-f0-9]+:    66 ff 10                callw  \*\(%rax\)
+[      ]*[a-f0-9]+:    66 ff d0                data16 callq \*%rax
+[      ]*[a-f0-9]+:    66 ff d0                data16 callq \*%rax
+[      ]*[a-f0-9]+:    66 ff 10                data16 callq \*\(%rax\)
 [      ]*[a-f0-9]+:    ff e0                   jmpq   \*%rax
 [      ]*[a-f0-9]+:    ff e0                   jmpq   \*%rax
-[      ]*[a-f0-9]+:    66 ff e0                jmpw   \*%ax
-[      ]*[a-f0-9]+:    66 ff e0                jmpw   \*%ax
-[      ]*[a-f0-9]+:    66 ff 20                jmpw   \*\(%rax\)
+[      ]*[a-f0-9]+:    66 ff e0                data16 jmpq \*%rax
+[      ]*[a-f0-9]+:    66 ff e0                data16 jmpq \*%rax
+[      ]*[a-f0-9]+:    66 ff 20                data16 jmpq \*\(%rax\)
 [      ]*[a-f0-9]+:    e8 (00|92) 00 (00|10) 00        callq  (0x56|1000e8 <.text\+0x1000e8>)
 [      ]*[a-f0-9]+:    e9 (00|97) 00 (00|10) 00        jmpq   (0x5b|1000f2 <.text\+0x1000f2>)
 #pass
index f0a106e180ff471ff5ae4c4fd2f206ab196ed773..592b8b568f2d74fab27059f22acb24247722dd82 100644 (file)
@@ -1,3 +1,17 @@
+2016-06-03  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR binutis/18386
+       * i386-dis.c (indirEv): Replace stack_v_mode with indir_v_mode.
+       (indir_v_mode): New.
+       Add comments for '&'.
+       (reg_table): Replace "{T|}" with "{&|}" on call and jmp.
+       (putop): Handle '&'.
+       (intel_operand_size): Handle indir_v_mode.
+       (OP_E_register): Likewise.
+       * i386-opc.tbl: Mark 64-bit indirect call/jmp as AMD64.  Add
+       64-bit indirect call/jmp for AMD64.
+       * i386-tbl.h: Regenerated
+
 2016-06-02  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * arc-dis.c (struct arc_operand_iterator): New structure.
index b0ade382f8e14b638ea4e82e86521c1a155b7f84..da20d36204b2d6ed64bef8096344be5b2b3e01d8 100644 (file)
@@ -258,7 +258,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Edw { OP_E, dw_mode }
 #define Edqd { OP_E, dqd_mode }
 #define Eq { OP_E, q_mode }
-#define indirEv { OP_indirE, stack_v_mode }
+#define indirEv { OP_indirE, indir_v_mode }
 #define indirEp { OP_indirE, f_mode }
 #define stackEv { OP_E, stack_v_mode }
 #define Em { OP_E, m_mode }
@@ -561,6 +561,8 @@ enum
   /* 4- or 6-byte pointer operand */
   f_mode,
   const_1_mode,
+  /* v_mode for indirect branch opcodes.  */
+  indir_v_mode,
   /* v_mode for stack-related opcodes.  */
   stack_v_mode,
   /* non-quad operand size depends on prefixes */
@@ -2483,6 +2485,9 @@ struct dis386 {
          suffix_always is true (lcall/ljmp).
    '@' => print 'q' for Intel64 ISA, 'w' or 'q' for AMD64 ISA depending
          on operand size prefix.
+   '&' => print 'q' in 64bit mode for Intel64 ISA or if instruction
+         has no operand size prefix for AMD64 ISA, behave as 'P'
+         otherwise
 
    2 upper case letter macros:
    "XY" => print 'x' or 'y' if suffix_always is true or no register
@@ -3531,9 +3536,9 @@ static const struct dis386 reg_table[][8] = {
   {
     { "incQ",  { Evh1 }, 0 },
     { "decQ",  { Evh1 }, 0 },
-    { "call{T|}", { indirEv, BND }, 0 },
+    { "call{&|}", { indirEv, BND }, 0 },
     { MOD_TABLE (MOD_FF_REG_3) },
-    { "jmp{T|}", { indirEv, BND }, 0 },
+    { "jmp{&|}", { indirEv, BND }, 0 },
     { MOD_TABLE (MOD_FF_REG_5) },
     { "pushU", { stackEv }, 0 },
     { Bad_Opcode },
@@ -14296,6 +14301,15 @@ case_L:
          if (!(rex & REX_W))
            used_prefixes |= (prefixes & PREFIX_DATA);
          break;
+       case '&':
+         if (!intel_syntax
+             && address_mode == mode_64bit
+             && isa64 == intel64)
+           {
+             *obufp++ = 'q';
+             break;
+           }
+         /* Fall through.  */
        case 'T':
          if (!intel_syntax
              && address_mode == mode_64bit
@@ -14816,6 +14830,12 @@ intel_operand_size (int bytemode, int sizeflag)
     case dqw_swap_mode:
       oappend ("WORD PTR ");
       break;
+    case indir_v_mode:
+      if (address_mode == mode_64bit && isa64 == intel64)
+       {
+         oappend ("QWORD PTR ");
+         break;
+       }
     case stack_v_mode:
       if (address_mode == mode_64bit && ((sizeflag & DFLAG) || (rex & REX_W)))
        {
@@ -15193,6 +15213,12 @@ OP_E_register (int bytemode, int sizeflag)
     case bnd_mode:
       names = names_bnd;
       break;
+    case indir_v_mode:
+      if (address_mode == mode_64bit && isa64 == intel64)
+       {
+         names = names64;
+         break;
+       }
     case stack_v_mode:
       if (address_mode == mode_64bit && ((sizeflag & DFLAG) || (rex & REX_W)))
        {
index 66b28e5bfad4ece890933d1be21210e62ad9dca2..91f5b4a3e204197020c89fdd2ce1d2f862d18769 100644 (file)
@@ -322,7 +322,8 @@ call, 1, 0xe8, None, 1, CpuNo64, JumpDword|DefaultSize|No_bSuf|No_sSuf|No_qSuf|N
 call, 1, 0xe8, None, 1, Cpu64, AMD64|JumpDword|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp16|Disp32S }
 call, 1, 0xe8, None, 1, Cpu64, Intel64|JumpDword|DefaultSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp32S }
 call, 1, 0xff, 0x2, 1, CpuNo64, Modrm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Reg16|Reg32|Word|Dword|Unspecified|BaseIndex|Disp8|Disp16|Disp32|JumpAbsolute }
-call, 1, 0xff, 0x2, 1, Cpu64, Modrm|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Reg16|Reg64|Word|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
+call, 1, 0xff, 0x2, 1, Cpu64, AMD64|Modrm|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Reg16|Reg64|Word|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
+call, 1, 0xff, 0x2, 1, Cpu64, Intel64|Modrm|DefaultSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Reg64|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
 // Intel Syntax
 call, 2, 0x9a, None, 1, CpuNo64, JumpInterSegment|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }
 // Intel Syntax
@@ -334,7 +335,8 @@ jmp, 1, 0xeb, None, 1, CpuNo64, Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_
 jmp, 1, 0xeb, None, 1, Cpu64, AMD64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32S }
 jmp, 1, 0xeb, None, 1, Cpu64, Intel64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp32S }
 jmp, 1, 0xff, 0x4, 1, CpuNo64, Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Reg16|Reg32|Word|Dword|Unspecified|BaseIndex|Disp8|Disp16|Disp32|JumpAbsolute }
-jmp, 1, 0xff, 0x4, 1, Cpu64, Modrm|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Reg16|Reg64|Word|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
+jmp, 1, 0xff, 0x4, 1, Cpu64, AMD64|Modrm|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Reg16|Reg64|Word|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
+jmp, 1, 0xff, 0x4, 1, Cpu64, Intel64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Reg64|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
 // Intel Syntax.
 jmp, 2, 0xea, None, 1, CpuNo64, JumpInterSegment|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }
 // Intel Syntax.
index 2e8437012839ff38a968c8ab1ae62865c7566c13..66f0074778db076ce4e115ca0f32f72029d59913 100644 (file)
@@ -3230,10 +3230,23 @@ const insn_template i386_optab[] =
     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
       1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-      0, 0, 0, 0 },
+      0, 0, 1, 0 },
     { { { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0,
          1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 } } } },
+  { "call", 1, 0xff, 0x2, 1,
+    { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+      1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 1 },
+    { { { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+         0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+         1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 } } } },
   { "call", 2, 0x9a, None, 1,
     { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -3353,10 +3366,23 @@ const insn_template i386_optab[] =
     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
       1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-      0, 0, 0, 0 },
+      0, 0, 1, 0 },
     { { { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0,
          1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 } } } },
+  { "jmp", 1, 0xff, 0x4, 1,
+    { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+      1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 1 },
+    { { { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+         0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+         1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 } } } },
   { "jmp", 2, 0xea, None, 1,
     { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,