x86-64: Intel64 adjustments for insns dealing with far pointers
authorJan Beulich <jbeulich@suse.com>
Wed, 12 Feb 2020 15:19:03 +0000 (16:19 +0100)
committerJan Beulich <jbeulich@suse.com>
Wed, 12 Feb 2020 15:19:03 +0000 (16:19 +0100)
AMD and Intel differ in their handling of far indirect branches as well
as LFS/LGS/LSS: AMD CPUs ignore REX.W while Intel ones honors it. (Note
how the latter three were hybrids so far, while far branches were fully
AMD-like.)

15 files changed:
gas/ChangeLog
gas/config/tc-i386-intel.c
gas/config/tc-i386.c
gas/doc/c-i386.texi
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/x86-64-branch-3.d
gas/testsuite/gas/i386/x86-64-branch-3.s
gas/testsuite/gas/i386/x86-64-branch-5.l [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-branch-5.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-intel64.d
gas/testsuite/gas/i386/x86-64-intel64.s
opcodes/ChangeLog
opcodes/i386-dis.c
opcodes/i386-opc.tbl
opcodes/i386-tbl.h

index 3e08345377b448fa93768e193c1cbd09719bd196..e7fac9530c517571a66345326e00d46cd528d37b 100644 (file)
@@ -1,3 +1,20 @@
+2020-02-12  Jan Beulich  <jbeulich@suse.com>
+
+       PR gas/24546
+       * config/tc-i386.c (match_template): Apply AMD64 check to 64-bit
+       code only.
+       * config/tc-i386-intel.c (i386_intel_operand): Also handle
+       CALL/JMP in O_tbyte_ptr case.
+       * doc/c-i386.texi: Mention far call and full pointer load ISA
+       differences.
+       * testsuite/gas/i386/x86-64-branch-3.s,
+       testsuite/gas/i386/x86-64-intel64.s: Add 64-bit far call cases.
+       * testsuite/gas/i386/x86-64-branch-3.d,
+       testsuite/gas/i386/x86-64-intel64.d: Adjust expectations.
+       * testsuite/gas/i386/x86-64-branch-5.l,
+       testsuite/gas/i386/x86-64-branch-5.s: New.
+       * testsuite/gas/i386/i386.exp: Run new test.
+
 2020-02-12  Jan Beulich  <jbeulich@suse.com>
 
        PR gas/25438
index bb8d320009056a15394d5508640191d464b428d1..76fc9972709d1c849edb14809b95e8261ab1c6d7 100644 (file)
@@ -694,9 +694,11 @@ i386_intel_operand (char *operand_string, int got_a_float)
          if (got_a_float == 1)
            suffix = LONG_DOUBLE_MNEM_SUFFIX;
          else if ((current_templates->start->operand_types[0].bitfield.fword
-                   || current_templates->start->operand_types[0].bitfield.tbyte)
+                   || current_templates->start->operand_types[0].bitfield.tbyte
+                   || current_templates->start->opcode_modifier.jump == JUMP_DWORD
+                   || current_templates->start->opcode_modifier.jump == JUMP)
                   && flag_code == CODE_64BIT)
-           suffix = QWORD_MNEM_SUFFIX; /* l[fgs]s, [ls][gi]dt */
+           suffix = QWORD_MNEM_SUFFIX; /* l[fgs]s, [ls][gi]dt, call, jmp */
          else
            i.types[this_operand].bitfield.byte = 1; /* cause an error */
          break;
index 314fd7274bf8fb70e55659c3be89cb32a25b3730..ac141b84d0b6ee914ab5ed67bdf094da367efeac 100644 (file)
@@ -5827,7 +5827,7 @@ match_template (char mnem_suffix)
          break;
        case intel64:
          /* -mintel64: Don't accept AMD64.  */
-         if (t->opcode_modifier.isa64 == AMD64)
+         if (t->opcode_modifier.isa64 == AMD64 && flag_code == CODE_64BIT)
            continue;
          break;
        }
index f0189ccb443f8f36543fb8ad859bfbe3f4986891..4eaf53311fd442794546ec782b14db93978cca84 100644 (file)
@@ -1455,6 +1455,18 @@ There are some discrepancies between AMD64 and Intel64 ISAs.
 @item For @samp{movsxd} with 16-bit destination register, AMD64
 supports 32-bit source operand and Intel64 supports 16-bit source
 operand.
+
+@item For far branches (with explicit memory operand), both ISAs support
+32- and 16-bit operand size.  Intel64 additionally supports 64-bit
+operand size, encoded as @samp{ljmpq} and @samp{lcallq} in AT&T syntax
+and with an explicit @samp{tbyte ptr} operand size specifier in Intel
+syntax.
+
+@item @samp{lfs}, @samp{lgs}, and @samp{lss} similarly allow for 16-
+and 32-bit operand size (32- and 48-bit memory operand) in both ISAs,
+while Intel64 additionally supports 64-bit operand sise (80-bit memory
+operands).
+
 @end itemize
 
 @node i386-Bugs
index c4280417c58a9f1335377b4859bb468d9be1c3a5..2ca8a941329002c172e18ce6c2dcd3a02f8268ae 100644 (file)
@@ -1140,6 +1140,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
        run_dump_test "x86-64-branch-2"
        run_dump_test "x86-64-branch-3"
        run_list_test "x86-64-branch-4" "-al -mintel64"
+       run_list_test "x86-64-branch-5" "-al"
 
        run_dump_test "x86-64-gotpcrel"
        run_dump_test "x86-64-gotpcrel-no-relax"
index 7b9e21dc661feab8139e27f12972d04c89e41f1f..1d0e64e4ebba4bfd52d80ff12bd560e4827288a0 100644 (file)
@@ -16,4 +16,6 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    66 48 e8 00 00 00 00    data16 rex\.W callq 1c <bar\+0xf>       18: R_X86_64_PLT32      foo-0x4
 [      ]*[a-f0-9]+:    66 c7 f8 00 00          xbeginw 21 <bar\+0x14>  1f: R_X86_64_PC16       foo-0x2
 [      ]*[a-f0-9]+:    66 48 c7 f8 00 00 00 00         data16 xbeginq 29 <bar\+0x1c>   25: R_X86_64_PLT32      foo-0x4
+[      ]*[a-f0-9]+:    48 ff 18                lcallq \*\(%rax\)
+[      ]*[a-f0-9]+:    48 ff 29                ljmpq  \*\(%rcx\)
 #pass
index cc16487424bc2d53d379079493ae0770f66e6247..898e5d90e1c75125e38cffea550530b5c4ffc4e9 100644 (file)
@@ -10,3 +10,6 @@ bar:
 
        data16 xbegin foo
        data16 rex.w xbegin foo
+
+       lcallq *(%rax)
+       ljmpq *(%rcx)
diff --git a/gas/testsuite/gas/i386/x86-64-branch-5.l b/gas/testsuite/gas/i386/x86-64-branch-5.l
new file mode 100644 (file)
index 0000000..188b6c2
--- /dev/null
@@ -0,0 +1,19 @@
+.*: Assembler messages:
+.*:2: Error: unsupported syntax for `lcall'
+.*:3: Error: unsupported syntax for `lfs'
+.*:4: Error: unsupported syntax for `lfs'
+.*:5: Error: unsupported syntax for `lgs'
+.*:6: Error: unsupported syntax for `lgs'
+.*:7: Error: unsupported syntax for `ljmp'
+.*:8: Error: unsupported syntax for `lss'
+.*:9: Error: unsupported syntax for `lss'
+.*:12: Error: unsupported syntax for `call'
+.*:13: Error: unsupported syntax for `lfs'
+.*:14: Error: unsupported syntax for `lfs'
+.*:15: Error: unsupported syntax for `lgs'
+.*:16: Error: unsupported syntax for `lgs'
+.*:17: Error: unsupported syntax for `jmp'
+.*:18: Error: unsupported syntax for `lss'
+.*:19: Error: unsupported syntax for `lss'
+GAS LISTING .*
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-branch-5.s b/gas/testsuite/gas/i386/x86-64-branch-5.s
new file mode 100644 (file)
index 0000000..f6a4ee2
--- /dev/null
@@ -0,0 +1,19 @@
+       .text
+       lcallq  *(%rax)
+       lfs     (%rax), %rax
+       lfsq    (%rax), %rax
+       lgs     (%rax), %rax
+       lgsq    (%rax), %rax
+       ljmpq   *(%rax)
+       lss     (%rax), %rax
+       lssq    (%rax), %rax
+
+       .intel_syntax noprefix
+       call    TBYTE PTR [rax]
+       lfs     rax, [rax]
+       lfs     rax, TBYTE PTR [rax]
+       lgs     rax, [rax]
+       lgs     rax, TBYTE PTR [rax]
+       jmp     TBYTE PTR [rax]
+       lss     rax, [rax]
+       lss     rax, TBYTE PTR [rax]
index cae797bacd9e12abbbcd0ae500d9516d0a7a5dbd..10c820f8dd2bfa21b291e9a2d5d985efbdae01e1 100644 (file)
@@ -12,6 +12,8 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    48 0f b5 11             lgs    \(%rcx\),%rdx
 [      ]*[a-f0-9]+:    48 0f b2 1a             lss    \(%rdx\),%rbx
 [      ]*[a-f0-9]+:    48 0f b2 1a             lss    \(%rdx\),%rbx
+[      ]*[a-f0-9]+:    48 ff 18                rex\.W lcall \*\(%rax\)
+[      ]*[a-f0-9]+:    48 ff 29                rex\.W ljmp \*\(%rcx\)
 [      ]*[a-f0-9]+:    0f 05                   syscall 
 [      ]*[a-f0-9]+:    0f 07                   sysret 
 [      ]*[a-f0-9]+:    48 0f 07                sysretq *
@@ -21,4 +23,6 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    48 0f b5 0a             lgs    \(%rdx\),%rcx
 [      ]*[a-f0-9]+:    48 0f b2 13             lss    \(%rbx\),%rdx
 [      ]*[a-f0-9]+:    48 0f b2 13             lss    \(%rbx\),%rdx
+[      ]*[a-f0-9]+:    48 ff 19                rex\.W lcall \*\(%rcx\)
+[      ]*[a-f0-9]+:    48 ff 2a                rex\.W ljmp \*\(%rdx\)
 #pass
index d7852ab8ff4c6013b6fb3d0e1c0b40580b585197..7097877b118b69044fbd7683af8432b501d8cb58 100644 (file)
@@ -10,6 +10,9 @@ _start:
        lss     (%rdx), %rbx
        lssq    (%rdx), %rbx
 
+       lcallq  *(%rax)
+       ljmpq   *(%rcx)
+
        syscall
        sysretl
        sysretq
@@ -21,3 +24,6 @@ _start:
        lgs     rcx, tbyte ptr [rdx]
        lss     rdx, [rbx]
        lss     rdx, tbyte ptr [rbx]
+
+       call    tbyte ptr [rcx]
+       jmp     tbyte ptr [rdx]
index 8ba9b7d7d00bbdb2aa9bfba726e83d4ce17c9c50..d92d5c447e8f815536fbe39fcb0b4b3de1fb710c 100644 (file)
@@ -1,3 +1,13 @@
+2020-02-12  Jan Beulich  <jbeulich@suse.com>
+
+       PR gas/24546
+       * i386-dis.c (putop): Handle REX.W in '^' case for Intel64 mode.
+       * i386-opc.tbl (lfs, lgs, lss, lcall, ljmp): Split into
+       Amd64 and Intel64 templates.
+       (call, jmp): Likewise for far indirect variants. Dro
+       Unspecified.
+       * i386-tbl.h: Re-generate.
+
 2020-02-11  Jan Beulich  <jbeulich@suse.com>
 
        * i386-gen.c (opcode_modifiers): Remove ShortForm entry.
index d2b33d0998168c0343fdaac5912d208f2ba616bf..8e0a9500903082b1c65ff178ef23102fdd3a0c86 100644 (file)
@@ -2331,8 +2331,8 @@ struct dis386 {
    'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
    '!' => change condition from true to false or from false to true.
    '%' => add 1 upper case letter to the macro.
-   '^' => print 'w' or 'l' depending on operand size prefix or
-         suffix_always is true (lcall/ljmp).
+   '^' => print 'w', 'l', or 'q' (Intel64 ISA only) depending on operand size
+         prefix or 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
@@ -13296,6 +13296,12 @@ case_S:
        case '^':
          if (intel_syntax)
            break;
+         if (isa64 == intel64 && (rex & REX_W))
+           {
+             USED_REX (REX_W);
+             *obufp++ = 'q';
+             break;
+           }
          if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
            {
              if (sizeflag & DFLAG)
index d805e6916a1598f34e576b08cba58bb5101516e2..c9bab40dc2754dc562c4f6151174646e835fc52a 100644 (file)
@@ -204,9 +204,12 @@ lea, 2, 0x8d, None, 1, 0, Modrm|Anysize|No_bSuf|No_sSuf|No_ldSuf, { BaseIndex, R
 // Load segment registers from memory.
 lds, 2, 0xc5, None, 1, CpuNo64, Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { DWord|Fword|Unspecified|BaseIndex, Reg16|Reg32 }
 les, 2, 0xc4, None, 1, CpuNo64, Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { DWord|Fword|Unspecified|BaseIndex, Reg16|Reg32 }
-lfs, 2, 0xfb4, None, 2, Cpu386, Modrm|No_bSuf|No_sSuf|No_ldSuf, { DWord|Fword|Tbyte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
-lgs, 2, 0xfb5, None, 2, Cpu386, Modrm|No_bSuf|No_sSuf|No_ldSuf, { DWord|Fword|Tbyte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
-lss, 2, 0xfb2, None, 2, Cpu386, Modrm|No_bSuf|No_sSuf|No_ldSuf, { DWord|Fword|Tbyte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
+lfs, 2, 0xfb4, None, 2, Cpu386, Amd64|Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Dword|Fword|Unspecified|BaseIndex, Reg16|Reg32 }
+lfs, 2, 0xfb4, None, 2, Cpu64, Intel64|Modrm|No_bSuf|No_sSuf|No_ldSuf, { Dword|Fword|Tbyte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
+lgs, 2, 0xfb5, None, 2, Cpu386, Amd64|Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Dword|Fword|Unspecified|BaseIndex, Reg16|Reg32 }
+lgs, 2, 0xfb5, None, 2, Cpu64, Intel64|Modrm|No_bSuf|No_sSuf|No_ldSuf, { Dword|Fword|Tbyte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
+lss, 2, 0xfb2, None, 2, Cpu386, Amd64|Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Dword|Fword|Unspecified|BaseIndex, Reg16|Reg32 }
+lss, 2, 0xfb2, None, 2, Cpu64, Intel64|Modrm|No_bSuf|No_sSuf|No_ldSuf, { Dword|Fword|Tbyte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
 
 // Flags register instructions.
 clc, 0, 0xf8, None, 1, 0, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
@@ -382,12 +385,13 @@ call, 1, 0xe8, None, 1, Cpu64, Intel64|JumpDword|No_bSuf|No_wSuf|No_lSuf|No_sSuf
 call, 1, 0xff, 0x2, 1, CpuNo64, Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg32|Unspecified|BaseIndex }
 call, 1, 0xff, 0x2, 1, Cpu64, Amd64|Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }
 call, 1, 0xff, 0x2, 1, Cpu64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg64|Unspecified|BaseIndex }
-// Intel Syntax
+// Intel Syntax remaining call instances.
 call, 2, 0x9a, None, 1, CpuNo64, JumpInterSegment|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }
-// Intel Syntax
-call, 1, 0xff, 0x3, 1, 0, Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf, { Dword|Fword|Unspecified|BaseIndex }
+call, 1, 0xff, 0x3, 1, 0, Amd64|Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf, { Dword|Fword|BaseIndex }
+call, 1, 0xff, 0x3, 1, Cpu64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Dword|Fword|Tbyte|BaseIndex }
 lcall, 2, 0x9a, None, 1, CpuNo64, JumpInterSegment|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }
-lcall, 1, 0xff, 0x3, 1, 0, Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Unspecified|BaseIndex }
+lcall, 1, 0xff, 0x3, 1, 0, Amd64|Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Unspecified|BaseIndex }
+lcall, 1, 0xff, 0x3, 1, Cpu64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_ldSuf, { Unspecified|BaseIndex }
 
 jmp, 1, 0xeb, None, 1, CpuNo64, Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32 }
 jmp, 1, 0xeb, None, 1, Cpu64, Amd64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32S }
@@ -395,12 +399,13 @@ jmp, 1, 0xeb, None, 1, Cpu64, Intel64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qS
 jmp, 1, 0xff, 0x4, 1, CpuNo64, Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg32|Unspecified|BaseIndex }
 jmp, 1, 0xff, 0x4, 1, Cpu64, Amd64|Modrm|JumpAbsolute|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }
 jmp, 1, 0xff, 0x4, 1, Cpu64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg64|Unspecified|BaseIndex }
-// Intel Syntax.
+// Intel Syntax remaining jmp instances.
 jmp, 2, 0xea, None, 1, CpuNo64, JumpInterSegment|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }
-// Intel Syntax.
-jmp, 1, 0xff, 0x5, 1, 0, Modrm|JumpAbsolute|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf, { Dword|Fword|Unspecified|BaseIndex }
+jmp, 1, 0xff, 0x5, 1, 0, Amd64|Modrm|JumpAbsolute|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf, { Dword|Fword|BaseIndex }
+jmp, 1, 0xff, 0x5, 1, Cpu64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Dword|Fword|Tbyte|BaseIndex }
 ljmp, 2, 0xea, None, 1, CpuNo64, JumpInterSegment|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }
-ljmp, 1, 0xff, 0x5, 1, 0, Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Unspecified|BaseIndex }
+ljmp, 1, 0xff, 0x5, 1, 0, Amd64|Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Unspecified|BaseIndex }
+ljmp, 1, 0xff, 0x5, 1, Cpu64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_ldSuf, { Unspecified|BaseIndex }
 
 ret, 0, 0xc3, None, 1, CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|RepPrefixOk|BNDPrefixOk, { 0 }
 ret, 1, 0xc2, None, 1, CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|RepPrefixOk|BNDPrefixOk, { Imm16 }
index 860646c923ce801d7e52db728661aab3773e4dfa..c8db352d369143c0f8fae78f69c66b509239e594 100644 (file)
@@ -979,10 +979,24 @@ const insn_template i386_optab[] =
         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, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0,
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 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, 1 },
     { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0,
+         0, 0, 0, 0, 1, 0 } },
+      { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
+         0, 0, 0, 0, 0, 0 } } } },
+  { "lfs", 0xfb4, None, 2, 2,
+    { { 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, 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, 1, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0,
          1, 0, 0, 0, 1, 0 } },
       { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
          0, 0, 0, 0, 0, 0 } } } },
@@ -993,10 +1007,24 @@ const insn_template i386_optab[] =
         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, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0,
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 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, 1 },
     { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0,
+         0, 0, 0, 0, 1, 0 } },
+      { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
+         0, 0, 0, 0, 0, 0 } } } },
+  { "lgs", 0xfb5, None, 2, 2,
+    { { 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, 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, 1, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0,
          1, 0, 0, 0, 1, 0 } },
       { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
          0, 0, 0, 0, 0, 0 } } } },
@@ -1007,10 +1035,24 @@ const insn_template i386_optab[] =
         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, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0,
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 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, 1 },
     { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0,
+         0, 0, 0, 0, 1, 0 } },
+      { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
+         0, 0, 0, 0, 0, 0 } } } },
+  { "lss", 0xfb2, None, 2, 2,
+    { { 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, 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, 1, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0,
          1, 0, 0, 0, 1, 0 } },
       { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
          0, 0, 0, 0, 0, 0 } } } },
@@ -2779,9 +2821,21 @@ const insn_template i386_optab[] =
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
     { 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 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, 1 },
     { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0,
-         0, 0, 0, 0, 1, 0 } } } },
+         0, 0, 0, 0, 0, 0 } } } },
+  { "call", 0xff, 0x3, 1, 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, 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, 5, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 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, 2 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0,
+         1, 0, 0, 0, 0, 0 } } } },
   { "lcall", 0x9a, None, 1, 2,
     { { 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,
@@ -2805,9 +2859,21 @@ const insn_template i386_optab[] =
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
     { 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 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, 1 },
     { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 1, 0 } } } },
+  { "lcall", 0xff, 0x3, 1, 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, 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, 5, 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, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+         0, 0, 0, 0, 1, 0 } } } },
   { "jmp", 0xeb, None, 1, 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,
@@ -2903,9 +2969,21 @@ const insn_template i386_optab[] =
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
     { 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 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, 1 },
     { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0,
-         0, 0, 0, 0, 1, 0 } } } },
+         0, 0, 0, 0, 0, 0 } } } },
+  { "jmp", 0xff, 0x5, 1, 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, 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, 5, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 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, 2 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0,
+         1, 0, 0, 0, 0, 0 } } } },
   { "ljmp", 0xea, None, 1, 2,
     { { 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,
@@ -2929,9 +3007,21 @@ const insn_template i386_optab[] =
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
     { 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 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, 1 },
     { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 1, 0 } } } },
+  { "ljmp", 0xff, 0x5, 1, 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, 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, 5, 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, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+         0, 0, 0, 0, 1, 0 } } } },
   { "ret", 0xc3, 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, 0,