Fix printvideo regression and minor improvements

main
Justine Tunney 2020-08-26 09:41:07 -07:00
parent eb4bb43275
commit e86cff8ba0
25 changed files with 240 additions and 207 deletions

View File

@ -28,12 +28,9 @@
# Other flags will usually be the ones that provide us marginal gains # Other flags will usually be the ones that provide us marginal gains
# in terms of performance and code size, but the world won't end when # in terms of performance and code size, but the world won't end when
# they aren't used. Flags that play a critical role in source working # they aren't used. Flags that play a critical role in source working
# correctly will usually be specified on a target-by-target basis, in # correctly will usually be specified on a object-by-object basis, in
# their respective packages. # their respective packages.
# #
# NOTE might have gotten the per-target override flag flow wrong since
# flags defined that way might flow quadratically opposite blaze.
#
# VARIABLES # VARIABLES
# #
# CCFLAGS gcc frontend flags (.i, .c, .cc, .f, .S, .lds, etc.) # CCFLAGS gcc frontend flags (.i, .c, .cc, .f, .S, .lds, etc.)

View File

@ -43,7 +43,7 @@
* @see Magikarp * @see Magikarp
*/ */
#define M 15 #define M 14
#define SQR(X) ((X) * (X)) #define SQR(X) ((X) * (X))
struct SamplingSolution { struct SamplingSolution {

View File

@ -50,78 +50,104 @@ unsigned long hamming(unsigned long, unsigned long) pureconst;
((uint16_t)kReverseBits[(X)&0xff] << 010 | \ ((uint16_t)kReverseBits[(X)&0xff] << 010 | \
kReverseBits[((uint16_t)(X) >> 010) & 0xff]) kReverseBits[((uint16_t)(X) >> 010) & 0xff])
#ifndef __GNUC__ #define READ16LE(S) \
#define READ16LE(P) ((unsigned)(P)[1] << 010 | (unsigned)(P)[0]) ((uint16_t)((unsigned char *)(S))[1] << 010 | \
#define READ32LE(P) \ (uint16_t)((unsigned char *)(S))[0] << 000)
((unsigned long)(P)[3] << 030 | (unsigned long)(P)[2] << 020 | \ #define READ32LE(S) \
(unsigned long)(P)[1] << 010 | (unsigned long)(P)[0]) ((uint32_t)((unsigned char *)(S))[3] << 030 | \
#define READ64LE(P) \ (uint32_t)((unsigned char *)(S))[2] << 020 | \
((unsigned long long)(P)[3] << 030 | (unsigned long)(P)[2] << 020 | \ (uint32_t)((unsigned char *)(S))[1] << 010 | \
(unsigned long long)(P)[1] << 010 | (unsigned long)(P)[0]) (uint32_t)((unsigned char *)(S))[0] << 000)
#else #define READ64LE(S) \
#define READ16LE(P) read16le(P) ((uint64_t)((unsigned char *)(S))[7] << 070 | \
#define READ32LE(P) read32le(P) (uint64_t)((unsigned char *)(S))[6] << 060 | \
#define READ64LE(P) read64le(P) (uint64_t)((unsigned char *)(S))[5] << 050 | \
#define read16le(P) \ (uint64_t)((unsigned char *)(S))[4] << 040 | \
({ \ (uint64_t)((unsigned char *)(S))[3] << 030 | \
const unsigned char *Pu = (const unsigned char *)(P); \ (uint64_t)((unsigned char *)(S))[2] << 020 | \
(uint16_t) Pu[1] << 010 | (uint16_t)Pu[0]; \ (uint64_t)((unsigned char *)(S))[1] << 010 | \
(uint64_t)((unsigned char *)(S))[0] << 000)
#define READ16BE(S) \
((uint16_t)((unsigned char *)(S))[0] << 010 | \
(uint16_t)((unsigned char *)(S))[1] << 000)
#define READ32BE(S) \
((uint32_t)((unsigned char *)(S))[0] << 030 | \
(uint32_t)((unsigned char *)(S))[1] << 020 | \
(uint32_t)((unsigned char *)(S))[2] << 010 | \
(uint32_t)((unsigned char *)(S))[3] << 000)
#define READ64BE(S) \
((uint64_t)((unsigned char *)(S))[0] << 070 | \
(uint64_t)((unsigned char *)(S))[1] << 060 | \
(uint64_t)((unsigned char *)(S))[2] << 050 | \
(uint64_t)((unsigned char *)(S))[3] << 040 | \
(uint64_t)((unsigned char *)(S))[4] << 030 | \
(uint64_t)((unsigned char *)(S))[5] << 020 | \
(uint64_t)((unsigned char *)(S))[6] << 010 | \
(uint64_t)((unsigned char *)(S))[7] << 000)
#define read16le(S) \
({ \
unsigned char *Str = (unsigned char *)(S); \
READ16LE(Str); \
}) })
#define read32le(P) \ #define read32le(S) \
({ \ ({ \
const unsigned char *Pu = (const unsigned char *)(P); \ unsigned char *Str = (unsigned char *)(S); \
((uint32_t)Pu[3] << 030 | (uint32_t)Pu[2] << 020 | \ READ32LE(Str); \
(uint32_t)Pu[1] << 010 | (uint32_t)Pu[0] << 000); \
}) })
#define read64le(P) \ #define read64le(S) \
({ \ ({ \
const unsigned char *Pu = (const unsigned char *)(P); \ unsigned char *Str = (unsigned char *)(S); \
((uint64_t)Pu[7] << 070 | (uint64_t)Pu[6] << 060 | \ READ64LE(Str); \
(uint64_t)Pu[5] << 050 | (uint64_t)Pu[4] << 040 | \
(uint64_t)Pu[3] << 030 | (uint64_t)Pu[2] << 020 | \
(uint64_t)Pu[1] << 010 | (uint64_t)Pu[0] << 000); \
}) })
#endif
#define WRITE16LE(P, V) \ #define read16be(S) \
do { \ ({ \
uint8_t *Ple = (unsigned char *)(P); \ unsigned char *Str = (unsigned char *)(S); \
uint16_t Vle = (V); \ READ16BE(Str); \
Ple[0] = (uint8_t)(Vle >> 000); \ })
Ple[1] = (uint8_t)(Vle >> 010); \ #define read32be(S) \
({ \
unsigned char *Str = (unsigned char *)(S); \
READ32BE(Str); \
})
#define read64be(S) \
({ \
unsigned char *Str = (unsigned char *)(S); \
READ64BE(Str); \
})
#define WRITE16LE(P, V) \
do { \
uint8_t *Ple = (uint8_t *)(P); \
uint16_t Vle = (V); \
Ple[0] = (uint8_t)(Vle >> 000); \
Ple[1] = (uint8_t)(Vle >> 010); \
} while (0) } while (0)
#define WRITE32LE(P, V) \
#define WRITE32LE(P, V) \ do { \
do { \ uint8_t *Ple = (uint8_t *)(P); \
uint8_t *Ple = (unsigned char *)(P); \ uint32_t Vle = (V); \
uint32_t Vle = (V); \ Ple[0] = (uint8_t)(Vle >> 000); \
Ple[0] = (uint8_t)(Vle >> 000); \ Ple[1] = (uint8_t)(Vle >> 010); \
Ple[1] = (uint8_t)(Vle >> 010); \ Ple[2] = (uint8_t)(Vle >> 020); \
Ple[2] = (uint8_t)(Vle >> 020); \ Ple[3] = (uint8_t)(Vle >> 030); \
Ple[3] = (uint8_t)(Vle >> 030); \
} while (0) } while (0)
#define WRITE64LE(P, V) \
#define WRITE64LE(P, V) \ do { \
do { \ uint8_t *Ple = (uint8_t *)(P); \
uint8_t *Ple = (unsigned char *)(P); \ uint64_t Vle = (V); \
uint64_t Vle = (V); \ Ple[0] = (uint8_t)(Vle >> 000); \
Ple[0] = (uint8_t)(Vle >> 000); \ Ple[1] = (uint8_t)(Vle >> 010); \
Ple[1] = (uint8_t)(Vle >> 010); \ Ple[2] = (uint8_t)(Vle >> 020); \
Ple[2] = (uint8_t)(Vle >> 020); \ Ple[3] = (uint8_t)(Vle >> 030); \
Ple[3] = (uint8_t)(Vle >> 030); \ Ple[4] = (uint8_t)(Vle >> 040); \
Ple[4] = (uint8_t)(Vle >> 040); \ Ple[5] = (uint8_t)(Vle >> 050); \
Ple[5] = (uint8_t)(Vle >> 050); \ Ple[6] = (uint8_t)(Vle >> 060); \
Ple[6] = (uint8_t)(Vle >> 060); \ Ple[7] = (uint8_t)(Vle >> 070); \
Ple[7] = (uint8_t)(Vle >> 070); \
} while (0) } while (0)
/* TODO(jart): these ones aren't coded correctly */
#define read128le(P) ((uint128_t)read64le((P) + 8) << 0100 | read64le(P))
#define read16be(P) ((uint16_t)(*(P) << 010) | (uint16_t)(*((P) + 1)))
#define read32be(P) ((uint32_t)read16be(P) << 020 | (uint32_t)read16be((P) + 2))
#define read64be(P) ((uint64_t)read32be(P) << 040 | read32be((P) + 4))
#define read128be(P) ((uint128_t)read64be(P) << 0100 | read64be((P) + 8))
/*───────────────────────────────────────────────────────────────────────────│─╗ /*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § bits » some assembly required cosmopolitan § bits » some assembly required
*/ */

View File

@ -148,7 +148,7 @@ float atanf(float);
float atanhf(float); float atanhf(float);
float cbrtf(float); float cbrtf(float);
float ceilf(float); float ceilf(float);
float copysignf(float, float y); float copysignf(float, float);
float cosf(float); float cosf(float);
float coshf(float); float coshf(float);
float dremf(float, float); float dremf(float, float);

View File

@ -38,7 +38,7 @@ memrchr:.leafprologue
jz 5f jz 5f
vmovd %esi,%xmm0 vmovd %esi,%xmm0
vpbroadcastb %xmm0,%ymm0 vpbroadcastb %xmm0,%ymm0
3: vmovups -32(%rdi,%rdx),%ymm1 3: vmovdqu -32(%rdi,%rdx),%ymm1
vpcmpeqb %ymm1,%ymm0,%ymm1 vpcmpeqb %ymm1,%ymm0,%ymm1
vpmovmskb %ymm1,%eax vpmovmskb %ymm1,%eax
lzcnt %eax,%eax lzcnt %eax,%eax

View File

@ -38,7 +38,7 @@ memrchr16:
jz 5f jz 5f
vmovd %esi,%xmm0 vmovd %esi,%xmm0
vpbroadcastw %xmm0,%ymm0 vpbroadcastw %xmm0,%ymm0
3: vmovups -32(%rdi,%rdx,2),%ymm1 3: vmovdqu -32(%rdi,%rdx,2),%ymm1
vpcmpeqw %ymm1,%ymm0,%ymm1 vpcmpeqw %ymm1,%ymm0,%ymm1
vpmovmskb %ymm1,%eax vpmovmskb %ymm1,%eax
lzcnt %eax,%eax lzcnt %eax,%eax

View File

@ -38,7 +38,7 @@ wmemrchr:
jz 5f jz 5f
vmovd %esi,%xmm0 vmovd %esi,%xmm0
vpbroadcastd %xmm0,%ymm0 vpbroadcastd %xmm0,%ymm0
3: vmovups -32(%rdi,%rdx,4),%ymm1 3: vmovdqu -32(%rdi,%rdx,4),%ymm1
vpcmpeqd %ymm1,%ymm0,%ymm1 vpcmpeqd %ymm1,%ymm0,%ymm1
vpmovmskb %ymm1,%eax vpmovmskb %ymm1,%eax
lzcnt %eax,%eax lzcnt %eax,%eax

View File

@ -7,9 +7,9 @@ COSMOPOLITAN_C_START_
cosmopolitan § characters » unicode cosmopolitan § characters » unicode
*/ */
extern const uint64_t kEastAsianWidth[]; extern const uint8_t kEastAsianWidth[];
extern const uint32_t kEastAsianWidthBits; extern const uint32_t kEastAsianWidthBits;
extern const uint64_t kCombiningChars[]; extern const uint8_t kCombiningChars[];
extern const uint32_t kCombiningCharsBits; extern const uint32_t kCombiningCharsBits;
/*───────────────────────────────────────────────────────────────────────────│─╗ /*───────────────────────────────────────────────────────────────────────────│─╗

View File

@ -17,7 +17,6 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA 02110-1301 USA
*/ */
#include "libc/bits/bits.h"
#include "libc/unicode/unicode.h" #include "libc/unicode/unicode.h"
/** /**
@ -28,10 +27,10 @@ int wcwidth(wchar_t ucs) {
if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) { if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) {
return -1; return -1;
} else if (0 <= ucs && ucs < kCombiningCharsBits && } else if (0 <= ucs && ucs < kCombiningCharsBits &&
bt(kCombiningChars, ucs)) { !!(kCombiningChars[ucs >> 3] & (1 << (ucs & 7)))) {
return 0; return 0;
} else if (0 <= ucs && ucs < kEastAsianWidthBits) { } else if (0 <= ucs && ucs < kEastAsianWidthBits) {
return 1 + bt(kEastAsianWidth, ucs); return 1 + !!(kEastAsianWidth[ucs >> 3] & (1 << (ucs & 7)));
} else { } else {
return 1; return 1;
} }

View File

@ -19,6 +19,7 @@
*/ */
#include "libc/bits/bits.h" #include "libc/bits/bits.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
#include "libc/unicode/unicode.h" #include "libc/unicode/unicode.h"
@ -73,3 +74,8 @@ TEST(strwidth, testTextDelimitingControlCodes_dontHaveSubstance) {
EXPECT_EQ(0, strwidth("\0")); EXPECT_EQ(0, strwidth("\0"));
EXPECT_EQ(0, strwidth("\1")); EXPECT_EQ(0, strwidth("\1"));
} }
BENCH(wcwidth, bench) {
volatile int x;
EZBENCH2("wcwidth", donothing, x = wcwidth(VEIL("r", u'')));
}

View File

@ -21,6 +21,7 @@
#include "libc/macros.h" #include "libc/macros.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h" #include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
#include "tool/build/lib/memory.h" #include "tool/build/lib/memory.h"

73
third_party/xed/x86.h vendored
View File

@ -1,10 +1,5 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_XED_X86_H_ #ifndef COSMOPOLITAN_THIRD_PARTY_XED_X86_H_
#define COSMOPOLITAN_THIRD_PARTY_XED_X86_H_ #define COSMOPOLITAN_THIRD_PARTY_XED_X86_H_
#include "libc/bits/bits.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
/* ▓▓▓▓▓▓▓▓▓▓▓▓▓ ▄▄▄▄ /* ▓▓▓▓▓▓▓▓▓▓▓▓▓ ▄▄▄▄
@ -47,6 +42,9 @@ COSMOPOLITAN_C_START_
#define xed_sib_scale(M) (((M)&0xff) >> 6) #define xed_sib_scale(M) (((M)&0xff) >> 6)
#define xed_get_modrm_reg_field(M) (((M)&0x38) >> 3) #define xed_get_modrm_reg_field(M) (((M)&0x38) >> 3)
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
enum XedMachineMode { enum XedMachineMode {
XED_MACHINE_MODE_INVALID, XED_MACHINE_MODE_INVALID,
XED_MACHINE_MODE_LONG_64, XED_MACHINE_MODE_LONG_64,
@ -321,44 +319,44 @@ struct XedChipFeatures {
}; };
struct XedOperands { /* struct XedOperands { /*
prefix66 rep
log𝑏 log𝑏
rexx rexx
index index
mod mod
rexb rexb
base base
asz asz
rex REGISTER rex REGISTER
rexb DISPATCH rexb DISPATCH
srm ENCODING srm ENCODING
rexw rexw
rex rex
rexb rexb
rm rm
osz osz
rex rex
rexr rexr
reg reg
2 2 2 2
82421812 6 0 82421812 6 0
0b00000000000000000000000000000000*/ 0b00000000000000000000000000000000*/
uint32_t rde; uint32_t rde;
bool osz : 1; // operand size override prefix bool rexw : 1; // rex.w or rex.wb or etc. 64-bit override
bool rexw : 1; // rex.w or rex.wb or etc. 64-bit override bool rexb : 1; // rex.b or rex.wb or etc. see modrm table
bool rexb : 1; // rex.b or rex.wb or etc. see modrm table bool rexr : 1; // rex.r or rex.wr or etc. see modrm table
bool rexr : 1; // rex.r or rex.wr or etc. see modrm table bool rex : 1; // any rex prefix including rex
bool rex : 1; // any rex prefix including rex bool rexx : 1; // rex.x or rex.wx or etc. see sib table
bool asz : 1; // address size override bool rexrr : 1; // evex
bool rexx : 1; // rex.x or rex.wx or etc. see sib table bool asz : 1; // address size override
bool osz : 1; // operand size override prefix
bool out_of_bytes : 1; bool out_of_bytes : 1;
bool is_intel_specific : 1; bool is_intel_specific : 1;
bool ild_f2 : 1; bool ild_f2 : 1;
bool ild_f3 : 1; bool ild_f3 : 1;
bool has_modrm : 1; bool has_modrm : 1;
bool has_sib : 1; bool has_sib : 1;
bool prefix66 : 1; // rexw except for xmm ops
bool realmode : 1; bool realmode : 1;
bool amd3dnow : 1; bool amd3dnow : 1;
uint8_t max_bytes; uint8_t max_bytes;
@ -385,8 +383,6 @@ struct XedOperands { /*
uint8_t map : 4; // enum XedIldMap uint8_t map : 4; // enum XedIldMap
uint8_t hint : 2; // static branch prediction uint8_t hint : 2; // static branch prediction
uint8_t seg_ovd : 3; // XED_SEG_xx uint8_t seg_ovd : 3; // XED_SEG_xx
uint8_t first_f2f3 : 2; // internal see rep, ild_f2, ild_f3
uint8_t last_f2f3 : 2; // internal see rep, ild_f2, ild_f3
uint8_t error : 5; // enum XedError uint8_t error : 5; // enum XedError
uint8_t mode : 3; // real,legacy,long uint8_t mode : 3; // real,legacy,long
uint8_t rep : 2; // 0, 2 (0xf2 repnz), 3 (0xf3 rep/repe) uint8_t rep : 2; // 0, 2 (0xf2 repnz), 3 (0xf3 rep/repe)
@ -410,7 +406,6 @@ struct XedOperands { /*
uint8_t vex_prefix; // vex uint8_t vex_prefix; // vex
uint8_t zeroing; // evex uint8_t zeroing; // evex
uint8_t bcrc; // evex uint8_t bcrc; // evex
uint8_t rexrr; // evex
uint8_t llrc; // evex uint8_t llrc; // evex
uint8_t vl; // evex uint8_t vl; // evex
uint8_t mask; // evex uint8_t mask; // evex
@ -453,7 +448,7 @@ forceinline void xed_operands_set_mode(struct XedOperands *p,
p->mode = 0; p->mode = 0;
break; break;
default: default:
abort(); unreachable;
} }
} }

View File

@ -517,17 +517,17 @@ privileged static int xed_consume_byte(struct XedDecodedInst *d) {
} }
privileged static void xed_prefix_scanner(struct XedDecodedInst *d) { privileged static void xed_prefix_scanner(struct XedDecodedInst *d) {
xed_bits_t first_f2f3, last_f2f3;
xed_bits_t b, max_bytes, length, nprefixes, nseg_prefixes, nrexes, rex; xed_bits_t b, max_bytes, length, nprefixes, nseg_prefixes, nrexes, rex;
length = d->length; length = d->length;
max_bytes = d->op.max_bytes; max_bytes = d->op.max_bytes;
rex = nrexes = nprefixes = nseg_prefixes = 0; first_f2f3 = last_f2f3 = rex = nrexes = nprefixes = nseg_prefixes = 0;
while (length < max_bytes) { while (length < max_bytes) {
b = d->bytes[length]; b = d->bytes[length];
if (xed_get_prefix_table_bit(b) == 0) goto out; if (xed_get_prefix_table_bit(b) == 0) goto out;
switch (b) { switch (b) {
case 0x66: case 0x66:
d->op.osz = true; d->op.osz = true;
d->op.prefix66 = true;
rex = 0; rex = 0;
break; break;
case 0x67: case 0x67:
@ -558,17 +558,17 @@ privileged static void xed_prefix_scanner(struct XedDecodedInst *d) {
break; break;
case 0xF3: case 0xF3:
d->op.ild_f3 = true; d->op.ild_f3 = true;
d->op.last_f2f3 = 3; last_f2f3 = 3;
if (!d->op.first_f2f3) { if (!first_f2f3) {
d->op.first_f2f3 = 3; first_f2f3 = 3;
} }
rex = 0; rex = 0;
break; break;
case 0xF2: case 0xF2:
d->op.ild_f2 = true; d->op.ild_f2 = true;
d->op.last_f2f3 = 2; last_f2f3 = 2;
if (!d->op.first_f2f3) { if (!first_f2f3) {
d->op.first_f2f3 = 2; first_f2f3 = 2;
} }
rex = 0; rex = 0;
break; break;
@ -597,9 +597,9 @@ out:
d->op.rex = true; d->op.rex = true;
} }
if (d->op.mode_first_prefix) { if (d->op.mode_first_prefix) {
d->op.rep = d->op.first_f2f3; d->op.rep = first_f2f3;
} else { } else {
d->op.rep = d->op.last_f2f3; d->op.rep = last_f2f3;
} }
switch (d->op.ild_seg) { switch (d->op.ild_seg) {
case 0x2e: case 0x2e:
@ -752,8 +752,8 @@ privileged static void xed_evex_scanner(struct XedDecodedInst *d) {
d->op.rexb = ~evex1.s.b_inv & 1; d->op.rexb = ~evex1.s.b_inv & 1;
d->op.rexrr = ~evex1.s.rr_inv & 1; d->op.rexrr = ~evex1.s.rr_inv & 1;
} }
d->op.map = evex1.s.map;
d->op.rexw = evex2.s.rexw & 1; d->op.rexw = evex2.s.rexw & 1;
d->op.map = evex1.s.map;
d->op.vexdest3 = evex2.s.vexdest3; d->op.vexdest3 = evex2.s.vexdest3;
d->op.vexdest210 = evex2.s.vexdest210; d->op.vexdest210 = evex2.s.vexdest210;
d->op.ubit = evex2.s.ubit; d->op.ubit = evex2.s.ubit;
@ -1199,7 +1199,7 @@ privileged static void xed_encode_rde(struct XedDecodedInst *x) {
/* fragile examples: addb, cmpxchgb */ /* fragile examples: addb, cmpxchgb */
/* fragile counterexamples: btc, bsr, etc. */ /* fragile counterexamples: btc, bsr, etc. */
const uint8_t kWordLog2[2][2][2] = {{{2, 3}, {1, 3}}, {{0, 0}, {0, 0}}}; const uint8_t kWordLog2[2][2][2] = {{{2, 3}, {1, 3}}, {{0, 0}, {0, 0}}};
x->op.rde = x->op.prefix66 << 30 | x->op.rde = x->op.rep << 30 |
kWordLog2[~x->op.opcode & 1][x->op.osz][x->op.rexw] << 28 | kWordLog2[~x->op.opcode & 1][x->op.osz][x->op.rexw] << 28 |
x->op.mod << 22 | x->op.rexw << 11 | x->op.osz << 5 | x->op.mod << 22 | x->op.rexw << 11 | x->op.osz << 5 |
x->op.asz << 17 | (x->op.rexx << 3 | x->op.index) << 24 | x->op.asz << 17 | (x->op.rexx << 3 | x->op.index) << 24 |

View File

@ -241,9 +241,7 @@ static void OpVdqWpdCvtpd2dq(struct Machine *m) {
} }
void OpCvt(struct Machine *m, unsigned long op) { void OpCvt(struct Machine *m, unsigned long op) {
op |= m->xedd->op.rep; switch (op | Rep(m->xedd) | Osz(m->xedd)) {
op |= Prefix66(m->xedd);
switch (op) {
case kOpCvt0f2a + 0: case kOpCvt0f2a + 0:
OpVpsQpiCvtpi2ps(m); OpVpsQpiCvtpi2ps(m);
break; break;

View File

@ -23,8 +23,17 @@
#include "libc/macros.h" #include "libc/macros.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "tool/build/lib/dis.h" #include "tool/build/lib/dis.h"
#include "tool/build/lib/endian.h"
#include "tool/build/lib/modrm.h" #include "tool/build/lib/modrm.h"
#define SSTRCMP8(S1, S2) \
({ \
uint64_t x, y; \
x = READ64BE(S1); \
y = READ64BE(S2); \
x > y ? 1 : x < y ? -1 : 0; \
})
static const char kScale[4][4] = {"", ",2", ",4", ",8"}; static const char kScale[4][4] = {"", ",2", ",4", ",8"};
static const char kSegName[8][3] = {"es", "cs", "ss", "ds", "fs", "gs"}; static const char kSegName[8][3] = {"es", "cs", "ss", "ds", "fs", "gs"};
static const char kSegOverride[8][3] = {"", "cs", "ds", "es", "fs", "gs", "ss"}; static const char kSegOverride[8][3] = {"", "cs", "ds", "es", "fs", "gs", "ss"};
@ -541,12 +550,14 @@ static const struct DisArg {
}; };
char *DisArg(struct DisBuilder b, char *p, const char *s) { char *DisArg(struct DisBuilder b, char *p, const char *s) {
char key[8];
int c, m, l, r; int c, m, l, r;
l = 0; l = 0;
r = ARRAYLEN(kDisArgs) - 1; r = ARRAYLEN(kDisArgs) - 1;
strncpy(key, s, 8);
while (l <= r) { while (l <= r) {
m = (l + r) >> 1; m = (l + r) >> 1;
c = strcmp(kDisArgs[m].s, s); c = SSTRCMP8(kDisArgs[m].s, key);
if (c < 0) { if (c < 0) {
l = m + 1; l = m + 1;
} else if (c > 0) { } else if (c > 0) {

View File

@ -45,7 +45,7 @@ static int IsRepOpcode(struct DisBuilder b) {
static char *DisRepPrefix(struct DisBuilder b, char *p) { static char *DisRepPrefix(struct DisBuilder b, char *p) {
const char *s; const char *s;
if (b.xedd->op.rep && b.xedd->op.map == XED_ILD_MAP0) { if (Rep(b.xedd) && b.xedd->op.map == XED_ILD_MAP0) {
switch (IsRepOpcode(b)) { switch (IsRepOpcode(b)) {
case 0: case 0:
break; break;
@ -53,7 +53,7 @@ static char *DisRepPrefix(struct DisBuilder b, char *p) {
p = stpcpy(p, "rep "); p = stpcpy(p, "rep ");
break; break;
case 2: case 2:
p = stpcpy(p, b.xedd->op.rep == 2 ? "repnz " : "repz "); p = stpcpy(p, Rep(b.xedd) == 2 ? "repnz " : "repz ");
break; break;
default: default:
break; break;
@ -135,7 +135,7 @@ static char *DisName(struct DisBuilder b, char *bp, const char *name,
p = DisBranchTaken(b, p); p = DisBranchTaken(b, p);
} }
if (wantsuffixsd) { if (wantsuffixsd) {
if (b.xedd->op.prefix66) { if (Osz(b.xedd)) {
*p++ = 'd'; *p++ = 'd';
} else { } else {
*p++ = 's'; *p++ = 's';

View File

@ -49,7 +49,7 @@ char *DisOpFpu1(struct XedDecodedInst *x, char *p, const char *extra) {
char *DisOp66(struct XedDecodedInst *x, char *p, const char *s, const char *a, char *DisOp66(struct XedDecodedInst *x, char *p, const char *s, const char *a,
const char *b) { const char *b) {
stpcpy(stpcpy(p, s), !Prefix66(x) ? a : b); stpcpy(stpcpy(p, s), !Osz(x) ? a : b);
return p; return p;
} }
@ -80,7 +80,7 @@ char *DisOpVpsWpsVssWssVpdWpdVsdWsd(struct XedDecodedInst *x, char *p,
stpcpy(q, "ss %Vss Wss"); stpcpy(q, "ss %Vss Wss");
} else if (x->op.ild_f2) { } else if (x->op.ild_f2) {
stpcpy(q, "sd %Vsd Wsd"); stpcpy(q, "sd %Vsd Wsd");
} else if (Prefix66(x)) { } else if (Osz(x)) {
stpcpy(q, "pd %Vpd Wpd"); stpcpy(q, "pd %Vpd Wpd");
} else { } else {
stpcpy(q, "ps %Vps Wps"); stpcpy(q, "ps %Vps Wps");
@ -580,8 +580,8 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
RCASE(0x28, "movapSD %Vps Wps"); RCASE(0x28, "movapSD %Vps Wps");
RCASE(0x29, "movapSD Wps %Vps"); RCASE(0x29, "movapSD Wps %Vps");
RCASE(0x2B, "movntpSD Mps %Vps"); RCASE(0x2B, "movntpSD Mps %Vps");
RCASE(0x2E, Prefix66(x) ? "ucomisd %Vsd Wsd" : "ucomiss %Vss Wss"); RCASE(0x2E, Osz(x) ? "ucomisd %Vsd Wsd" : "ucomiss %Vss Wss");
RCASE(0x2F, Prefix66(x) ? "comisd %Vsd Wsd" : "comiss %Vss Wss"); RCASE(0x2F, Osz(x) ? "comisd %Vsd Wsd" : "comiss %Vss Wss");
RCASE(0x31, "rdtsc"); RCASE(0x31, "rdtsc");
RCASE(0x40, "cmovo %Gvqp Evqp"); RCASE(0x40, "cmovo %Gvqp Evqp");
RCASE(0x41, "cmovno %Gvqp Evqp"); RCASE(0x41, "cmovno %Gvqp Evqp");
@ -693,7 +693,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
RCASE(0xD3, DisOpPqQqVdqWdq(x, p, "psrlq")); RCASE(0xD3, DisOpPqQqVdqWdq(x, p, "psrlq"));
RCASE(0xD4, DisOpPqQqVdqWdq(x, p, "paddq")); RCASE(0xD4, DisOpPqQqVdqWdq(x, p, "paddq"));
RCASE(0xD5, DisOpPqQqVdqWdq(x, p, "pmullw")); RCASE(0xD5, DisOpPqQqVdqWdq(x, p, "pmullw"));
RCASE(0xD7, Prefix66(x) ? "pmovmskb %Gdqp %Udq" : "pmovmskb %Gdqp %Nq"); RCASE(0xD7, Osz(x) ? "pmovmskb %Gdqp %Udq" : "pmovmskb %Gdqp %Nq");
RCASE(0xD8, DisOpPqQqVdqWdq(x, p, "psubusb")); RCASE(0xD8, DisOpPqQqVdqWdq(x, p, "psubusb"));
RCASE(0xD9, DisOpPqQqVdqWdq(x, p, "psubusw")); RCASE(0xD9, DisOpPqQqVdqWdq(x, p, "psubusw"));
RCASE(0xDA, DisOpPqQqVdqWdq(x, p, "pminub")); RCASE(0xDA, DisOpPqQqVdqWdq(x, p, "pminub"));
@ -708,7 +708,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
RCASE(0xE3, DisOpPqQqVdqWdq(x, p, "pavgw")); RCASE(0xE3, DisOpPqQqVdqWdq(x, p, "pavgw"));
RCASE(0xE4, DisOpPqQqVdqWdq(x, p, "pmulhuw")); RCASE(0xE4, DisOpPqQqVdqWdq(x, p, "pmulhuw"));
RCASE(0xE5, DisOpPqQqVdqWdq(x, p, "pmulhw")); RCASE(0xE5, DisOpPqQqVdqWdq(x, p, "pmulhw"));
RCASE(0xE7, Prefix66(x) ? "movntdq Mdq %Vdq" : "movntq Mq %Pq"); RCASE(0xE7, Osz(x) ? "movntdq Mdq %Vdq" : "movntq Mq %Pq");
RCASE(0xE8, DisOpPqQqVdqWdq(x, p, "psubsb")); RCASE(0xE8, DisOpPqQqVdqWdq(x, p, "psubsb"));
RCASE(0xE9, DisOpPqQqVdqWdq(x, p, "psubsw")); RCASE(0xE9, DisOpPqQqVdqWdq(x, p, "psubsw"));
RCASE(0xEA, DisOpPqQqVdqWdq(x, p, "pminsw")); RCASE(0xEA, DisOpPqQqVdqWdq(x, p, "pminsw"));
@ -740,7 +740,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
} }
break; break;
case 0x70: case 0x70:
switch (x->op.rep | Prefix66(x)) { switch (Rep(x) | Osz(x)) {
RCASE(0, "pshufw %Pq Qq Ib"); RCASE(0, "pshufw %Pq Qq Ib");
RCASE(1, "pshufd %Vdq Wdq Ib"); RCASE(1, "pshufd %Vdq Wdq Ib");
RCASE(2, "pshuflw %Vdq Wdq Ib"); RCASE(2, "pshuflw %Vdq Wdq Ib");
@ -799,7 +799,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
return "movss %Vss Wss"; return "movss %Vss Wss";
} else if (x->op.ild_f2) { } else if (x->op.ild_f2) {
return "movsd %Vsd Wsd"; return "movsd %Vsd Wsd";
} else if (Prefix66(x)) { } else if (Osz(x)) {
return "movupd %Vpd Wpd"; return "movupd %Vpd Wpd";
} else { } else {
return "movups %Vps Wps"; return "movups %Vps Wps";
@ -810,14 +810,14 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
return "movss Wss %Vss"; return "movss Wss %Vss";
} else if (x->op.ild_f2) { } else if (x->op.ild_f2) {
return "movsd Wsd %Vsd"; return "movsd Wsd %Vsd";
} else if (Prefix66(x)) { } else if (Osz(x)) {
return "movupd Wpd %Vpd"; return "movupd Wpd %Vpd";
} else { } else {
return "movups Wps %Vps"; return "movups Wps %Vps";
} }
break; break;
case 0xC4: case 0xC4:
if (!Prefix66(x)) { if (!Osz(x)) {
if (IsModrmRegister(x)) { if (IsModrmRegister(x)) {
return "pinsrw %Pq %Rdqp Ib"; return "pinsrw %Pq %Rdqp Ib";
} else { } else {
@ -832,14 +832,14 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
} }
break; break;
case 0xC5: case 0xC5:
if (!Prefix66(x)) { if (!Osz(x)) {
return "pextrw %Gdqp %Nq Ib"; return "pextrw %Gdqp %Nq Ib";
} else { } else {
return "pextrw %Gdqp %Udq Ib"; return "pextrw %Gdqp %Udq Ib";
} }
break; break;
case 0xC6: case 0xC6:
if (!Prefix66(x)) { if (!Osz(x)) {
return "shufps %Vps Wps Ib"; return "shufps %Vps Wps Ib";
} else { } else {
return "shufpd %Vpd Wpd Ib"; return "shufpd %Vpd Wpd Ib";
@ -853,7 +853,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
} }
break; break;
case 0xD6: case 0xD6:
if (Prefix66(x)) { if (Osz(x)) {
return "movq Wq %Vq"; return "movq Wq %Vq";
} else if (x->op.ild_f3) { } else if (x->op.ild_f3) {
return "movq2dq %Vdq %Nq"; return "movq2dq %Vdq %Nq";
@ -862,7 +862,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
} }
break; break;
case 0x12: case 0x12:
switch (x->op.rep | Prefix66(x)) { switch (Rep(x) | Osz(x)) {
case 0: case 0:
if (IsModrmRegister(x)) { if (IsModrmRegister(x)) {
return "movhlps %Vq %Uq"; return "movhlps %Vq %Uq";
@ -881,14 +881,14 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
} }
break; break;
case 0x13: case 0x13:
if (Prefix66(x)) { if (Osz(x)) {
return "movlpd Mq %Vq"; return "movlpd Mq %Vq";
} else { } else {
return "movlps Mq %Vq"; return "movlps Mq %Vq";
} }
break; break;
case 0x16: case 0x16:
switch (x->op.rep | Prefix66(x)) { switch (Rep(x) | Osz(x)) {
case 0: case 0:
if (IsModrmRegister(x)) { if (IsModrmRegister(x)) {
return "movlhps %Vq %Uq"; return "movlhps %Vq %Uq";
@ -905,7 +905,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
} }
break; break;
case 0x17: case 0x17:
if (Prefix66(x)) { if (Osz(x)) {
return "movhpd Mq %Vq"; return "movhpd Mq %Vq";
} else { } else {
return "movhps Mq %Vq"; return "movhps Mq %Vq";
@ -916,7 +916,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
return "cvtsi2ss %Vss Edqp"; return "cvtsi2ss %Vss Edqp";
} else if (x->op.ild_f2) { } else if (x->op.ild_f2) {
return "cvtsi2sd %Vsd Edqp"; return "cvtsi2sd %Vsd Edqp";
} else if (Prefix66(x)) { } else if (Osz(x)) {
return "cvtpi2pd %Vpd Qpi"; return "cvtpi2pd %Vpd Qpi";
} else { } else {
return "cvtpi2ps %Vps Qpi"; return "cvtpi2ps %Vps Qpi";
@ -927,7 +927,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
return "cvttss2si %Gdqp Wss"; return "cvttss2si %Gdqp Wss";
} else if (x->op.ild_f2) { } else if (x->op.ild_f2) {
return "cvttsd2si %Gdqp Wsd"; return "cvttsd2si %Gdqp Wsd";
} else if (Prefix66(x)) { } else if (Osz(x)) {
return "cvttpd2pi %Ppi Wpd"; return "cvttpd2pi %Ppi Wpd";
} else { } else {
return "cvttps2pi %Ppi Wpsq"; return "cvttps2pi %Ppi Wpsq";
@ -938,7 +938,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
return "cvtss2si %Gdqp Wss"; return "cvtss2si %Gdqp Wss";
} else if (x->op.ild_f2) { } else if (x->op.ild_f2) {
return "cvtsd2si %Gdqp Wsd"; return "cvtsd2si %Gdqp Wsd";
} else if (Prefix66(x)) { } else if (Osz(x)) {
return "cvtpd2pi %Ppi Wpd"; return "cvtpd2pi %Ppi Wpd";
} else { } else {
return "cvtps2pi %Ppi Wpsq"; return "cvtps2pi %Ppi Wpsq";
@ -949,7 +949,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
return "cvtss2sd %Vsd Wss"; return "cvtss2sd %Vsd Wss";
} else if (x->op.ild_f2) { } else if (x->op.ild_f2) {
return "cvtsd2ss %Vss Wsd"; return "cvtsd2ss %Vss Wsd";
} else if (Prefix66(x)) { } else if (Osz(x)) {
return "cvtpd2ps %Vps Wpd"; return "cvtpd2ps %Vps Wpd";
} else { } else {
return "cvtps2pd %Vpd Wps"; return "cvtps2pd %Vpd Wps";
@ -958,7 +958,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
case 0x5b: case 0x5b:
if (x->op.ild_f3) { if (x->op.ild_f3) {
return "cvttps2dq %Vdq Wps"; return "cvttps2dq %Vdq Wps";
} else if (Prefix66(x)) { } else if (Osz(x)) {
return "cvtps2dq %Vdq Wps"; return "cvtps2dq %Vdq Wps";
} else { } else {
return "cvtdq2ps %Vps Wdq"; return "cvtdq2ps %Vps Wdq";
@ -969,14 +969,14 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
return "sqrtss %Vss Wss"; return "sqrtss %Vss Wss";
} else if (x->op.ild_f2) { } else if (x->op.ild_f2) {
return "sqrtsd %Vsd Wsd"; return "sqrtsd %Vsd Wsd";
} else if (Prefix66(x)) { } else if (Osz(x)) {
return "sqrtpd %Vpd Wpd"; return "sqrtpd %Vpd Wpd";
} else { } else {
return "sqrtps %Vps Wps"; return "sqrtps %Vps Wps";
} }
break; break;
case 0x6E: case 0x6E:
if (Prefix66(x)) { if (Osz(x)) {
if (Rexw(x)) { if (Rexw(x)) {
return "movq %Vdq Eqp"; return "movq %Vdq Eqp";
} else { } else {
@ -993,7 +993,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
case 0x6F: case 0x6F:
if (x->op.ild_f3) { if (x->op.ild_f3) {
return "movdqu %Vdq Wdq"; return "movdqu %Vdq Wdq";
} else if (Prefix66(x)) { } else if (Osz(x)) {
return "movdqa %Vdq Wdq"; return "movdqa %Vdq Wdq";
} else { } else {
return "movq %Pq Qq"; return "movq %Pq Qq";
@ -1002,7 +1002,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
case 0x7E: case 0x7E:
if (x->op.ild_f3) { if (x->op.ild_f3) {
return "movq %Vq Wq"; return "movq %Vq Wq";
} else if (Prefix66(x)) { } else if (Osz(x)) {
if (Rexw(x)) { if (Rexw(x)) {
return "movq Eqp %Vdq"; return "movq Eqp %Vdq";
} else { } else {
@ -1019,7 +1019,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
case 0x7F: case 0x7F:
if (x->op.ild_f3) { if (x->op.ild_f3) {
return "movdqu Wdq %Vdq"; return "movdqu Wdq %Vdq";
} else if (Prefix66(x)) { } else if (Osz(x)) {
return "movdqa Wdq %Vdq"; return "movdqa Wdq %Vdq";
} else { } else {
return "movq Qq %Pq"; return "movq Qq %Pq";
@ -1028,7 +1028,7 @@ const char *DisSpecMap1(struct XedDecodedInst *x, char *p) {
case 0xE6: case 0xE6:
if (x->op.ild_f2) { if (x->op.ild_f2) {
return "cvtpd2dq %Vdq Wpd"; return "cvtpd2dq %Vdq Wpd";
} else if (Prefix66(x)) { } else if (Osz(x)) {
return "cvttpd2dq %Vdq Wpd"; return "cvttpd2dq %Vdq Wpd";
} else if (x->op.ild_f3) { } else if (x->op.ild_f3) {
return "cvtdq2pd %Vpd Wdq"; return "cvtdq2pd %Vpd Wdq";

View File

@ -329,7 +329,7 @@ static void OpLoop(struct Machine *m, bool cond) {
static void OpXlat(struct Machine *m) { static void OpXlat(struct Machine *m) {
int64_t v; int64_t v;
uint8_t al, *p; uint8_t al;
v = Read64(m->bx) + Read8(m->ax); v = Read64(m->bx) + Read8(m->ax);
if (Asz(m->xedd)) v &= 0xffffffff; if (Asz(m->xedd)) v &= 0xffffffff;
SetReadAddr(m, v, 1); SetReadAddr(m, v, 1);
@ -613,7 +613,7 @@ static uint8_t pmovmskb(uint64_t x) {
static void OpPmovmskbGdqpNqUdq(struct Machine *m) { static void OpPmovmskbGdqpNqUdq(struct Machine *m) {
uint64_t bitmask; uint64_t bitmask;
if (Prefix66(m->xedd)) { if (Osz(m->xedd)) {
bitmask = pmovmskb(Read64(XmmRexbRm(m) + 8)) << 8 | bitmask = pmovmskb(Read64(XmmRexbRm(m) + 8)) << 8 |
pmovmskb(Read64(XmmRexbRm(m))); pmovmskb(Read64(XmmRexbRm(m)));
} else { } else {
@ -895,7 +895,7 @@ static void OpMaskMovDiXmmRegXmmRm(struct Machine *m) {
uint64_t v; uint64_t v;
unsigned i, n; unsigned i, n;
uint8_t *mem, b[16]; uint8_t *mem, b[16];
n = Prefix66(m->xedd) ? 16 : 8; n = Osz(m->xedd) ? 16 : 8;
v = GetSegment() + Read64(m->di); v = GetSegment() + Read64(m->di);
if (Asz(m->xedd)) v &= 0xffffffff; if (Asz(m->xedd)) v &= 0xffffffff;
mem = BeginStore(m, v, n, p, b); mem = BeginStore(m, v, n, p, b);
@ -1011,7 +1011,7 @@ static void OpMovapdWpdVpd(struct Machine *m) {
static void OpMovWpsVps(struct Machine *m) { static void OpMovWpsVps(struct Machine *m) {
uint8_t *p, *r; uint8_t *p, *r;
switch (m->xedd->op.rep | Prefix66(m->xedd)) { switch (Rep(m->xedd) | Osz(m->xedd)) {
case 0: case 0:
OpMovupsWpsVps(m); OpMovupsWpsVps(m);
break; break;
@ -1030,7 +1030,7 @@ static void OpMovWpsVps(struct Machine *m) {
} }
static void OpMov0f28(struct Machine *m) { static void OpMov0f28(struct Machine *m) {
if (!Prefix66(m->xedd)) { if (!Osz(m->xedd)) {
OpMovapsVpsWps(m); OpMovapsVpsWps(m);
} else { } else {
OpMovapdVpdWpd(m); OpMovapdVpdWpd(m);
@ -1038,7 +1038,7 @@ static void OpMov0f28(struct Machine *m) {
} }
static void OpMov0f6e(struct Machine *m) { static void OpMov0f6e(struct Machine *m) {
if (Prefix66(m->xedd)) { if (Osz(m->xedd)) {
if (Rexw(m->xedd)) { if (Rexw(m->xedd)) {
OpMovqVdqEqp(m); OpMovqVdqEqp(m);
} else { } else {
@ -1054,7 +1054,7 @@ static void OpMov0f6e(struct Machine *m) {
} }
static void OpMov0f6f(struct Machine *m) { static void OpMov0f6f(struct Machine *m) {
if (Prefix66(m->xedd)) { if (Osz(m->xedd)) {
OpMovdqaVdqWdq(m); OpMovdqaVdqWdq(m);
} else if (m->xedd->op.ild_f3) { } else if (m->xedd->op.ild_f3) {
OpMovdquVdqWdq(m); OpMovdquVdqWdq(m);
@ -1064,7 +1064,7 @@ static void OpMov0f6f(struct Machine *m) {
} }
static void OpMov0fE7(struct Machine *m) { static void OpMov0fE7(struct Machine *m) {
if (!Prefix66(m->xedd)) { if (!Osz(m->xedd)) {
OpMovntqMqPq(m); OpMovntqMqPq(m);
} else { } else {
OpMovntdqMdqVdq(m); OpMovntdqMdqVdq(m);
@ -1074,7 +1074,7 @@ static void OpMov0fE7(struct Machine *m) {
static void OpMov0f7e(struct Machine *m) { static void OpMov0f7e(struct Machine *m) {
if (m->xedd->op.ild_f3) { if (m->xedd->op.ild_f3) {
OpMovqVqWq(m); OpMovqVqWq(m);
} else if (Prefix66(m->xedd)) { } else if (Osz(m->xedd)) {
if (Rexw(m->xedd)) { if (Rexw(m->xedd)) {
OpMovqEqpVdq(m); OpMovqEqpVdq(m);
} else { } else {
@ -1092,7 +1092,7 @@ static void OpMov0f7e(struct Machine *m) {
static void OpMov0f7f(struct Machine *m) { static void OpMov0f7f(struct Machine *m) {
if (m->xedd->op.ild_f3) { if (m->xedd->op.ild_f3) {
OpMovdquWdqVdq(m); OpMovdquWdqVdq(m);
} else if (Prefix66(m->xedd)) { } else if (Osz(m->xedd)) {
OpMovdqaWdqVdq(m); OpMovdqaWdqVdq(m);
} else { } else {
OpMovqQqPq(m); OpMovqQqPq(m);
@ -1101,7 +1101,7 @@ static void OpMov0f7f(struct Machine *m) {
static void OpMov0f10(struct Machine *m) { static void OpMov0f10(struct Machine *m) {
uint8_t *p, *r; uint8_t *p, *r;
switch (m->xedd->op.rep | Prefix66(m->xedd)) { switch (Rep(m->xedd) | Osz(m->xedd)) {
case 0: case 0:
OpMovupsVpsWps(m); OpMovupsVpsWps(m);
break; break;
@ -1120,7 +1120,7 @@ static void OpMov0f10(struct Machine *m) {
} }
static void OpMov0f29(struct Machine *m) { static void OpMov0f29(struct Machine *m) {
if (!Prefix66(m->xedd)) { if (!Osz(m->xedd)) {
OpMovapsWpsVps(m); OpMovapsWpsVps(m);
} else { } else {
OpMovapdWpdVpd(m); OpMovapdWpdVpd(m);
@ -1128,7 +1128,7 @@ static void OpMov0f29(struct Machine *m) {
} }
static void OpMov0f2b(struct Machine *m) { static void OpMov0f2b(struct Machine *m) {
if (!Prefix66(m->xedd)) { if (!Osz(m->xedd)) {
OpMovntpsMpsVps(m); OpMovntpsMpsVps(m);
} else { } else {
OpMovntpdMpdVpd(m); OpMovntpdMpdVpd(m);
@ -1136,7 +1136,7 @@ static void OpMov0f2b(struct Machine *m) {
} }
static void OpMov0f12(struct Machine *m) { static void OpMov0f12(struct Machine *m) {
switch (m->xedd->op.rep | Prefix66(m->xedd)) { switch (Rep(m->xedd) | Osz(m->xedd)) {
case 0: case 0:
if (IsModrmRegister(m->xedd)) { if (IsModrmRegister(m->xedd)) {
OpMovhlpsVqUq(m); OpMovhlpsVqUq(m);
@ -1159,7 +1159,7 @@ static void OpMov0f12(struct Machine *m) {
} }
static void OpMov0f13(struct Machine *m) { static void OpMov0f13(struct Machine *m) {
if (Prefix66(m->xedd)) { if (Osz(m->xedd)) {
OpMovlpdMqVq(m); OpMovlpdMqVq(m);
} else { } else {
OpMovlpsMqVq(m); OpMovlpsMqVq(m);
@ -1167,7 +1167,7 @@ static void OpMov0f13(struct Machine *m) {
} }
static void OpMov0f16(struct Machine *m) { static void OpMov0f16(struct Machine *m) {
switch (m->xedd->op.rep | Prefix66(m->xedd)) { switch (Rep(m->xedd) | Osz(m->xedd)) {
case 0: case 0:
if (IsModrmRegister(m->xedd)) { if (IsModrmRegister(m->xedd)) {
OpMovlhpsVqUq(m); OpMovlhpsVqUq(m);
@ -1188,7 +1188,7 @@ static void OpMov0f16(struct Machine *m) {
} }
static void OpMov0f17(struct Machine *m) { static void OpMov0f17(struct Machine *m) {
if (Prefix66(m->xedd)) { if (Osz(m->xedd)) {
OpMovhpdMqVq(m); OpMovhpdMqVq(m);
} else { } else {
OpMovhpsMqVq(m); OpMovhpsMqVq(m);
@ -1200,7 +1200,7 @@ static void OpMov0fD6(struct Machine *m) {
OpMovq2dqVdqNq(m); OpMovq2dqVdqNq(m);
} else if (m->xedd->op.ild_f2) { } else if (m->xedd->op.ild_f2) {
OpMovdq2qPqUq(m); OpMovdq2qPqUq(m);
} else if (Prefix66(m->xedd)) { } else if (Osz(m->xedd)) {
OpMovqWqVq(m); OpMovqWqVq(m);
} else { } else {
OpUd(m); OpUd(m);
@ -1211,7 +1211,7 @@ static void OpUnpcklpsd(struct Machine *m) {
uint8_t *a, *b; uint8_t *a, *b;
a = XmmRexrReg(m); a = XmmRexrReg(m);
b = GetModrmRegisterXmmPointerRead8(m); b = GetModrmRegisterXmmPointerRead8(m);
if (Prefix66(m->xedd)) { if (Osz(m->xedd)) {
memcpy(a + 8, b, 8); memcpy(a + 8, b, 8);
} else { } else {
memcpy(a + 4 * 3, b + 4, 4); memcpy(a + 4 * 3, b + 4, 4);
@ -1224,7 +1224,7 @@ static void OpUnpckhpsd(struct Machine *m) {
uint8_t *a, *b; uint8_t *a, *b;
a = XmmRexrReg(m); a = XmmRexrReg(m);
b = GetModrmRegisterXmmPointerRead16(m); b = GetModrmRegisterXmmPointerRead16(m);
if (Prefix66(m->xedd)) { if (Osz(m->xedd)) {
memcpy(a + 0, b + 8, 8); memcpy(a + 0, b + 8, 8);
memcpy(a + 8, b + 8, 8); memcpy(a + 8, b + 8, 8);
} else { } else {
@ -1238,14 +1238,14 @@ static void OpUnpckhpsd(struct Machine *m) {
static void OpPextrwGdqpUdqIb(struct Machine *m) { static void OpPextrwGdqpUdqIb(struct Machine *m) {
uint8_t i; uint8_t i;
i = m->xedd->op.uimm0; i = m->xedd->op.uimm0;
i &= Prefix66(m->xedd) ? 7 : 3; i &= Osz(m->xedd) ? 7 : 3;
Write16(RegRexrReg(m), Read16(XmmRexbRm(m) + i * 2)); Write16(RegRexrReg(m), Read16(XmmRexbRm(m) + i * 2));
} }
static void OpPinsrwVdqEwIb(struct Machine *m) { static void OpPinsrwVdqEwIb(struct Machine *m) {
uint8_t i; uint8_t i;
i = m->xedd->op.uimm0; i = m->xedd->op.uimm0;
i &= Prefix66(m->xedd) ? 7 : 3; i &= Osz(m->xedd) ? 7 : 3;
Write16(XmmRexrReg(m) + i * 2, Read16(GetModrmRegisterWordPointerRead2(m))); Write16(XmmRexrReg(m) + i * 2, Read16(GetModrmRegisterWordPointerRead2(m)));
} }
@ -1253,7 +1253,7 @@ static void OpShuffle(struct Machine *m) {
int16_t q16[4]; int16_t q16[4];
int16_t x16[8]; int16_t x16[8];
int32_t x32[4]; int32_t x32[4];
switch (m->xedd->op.rep | Prefix66(m->xedd)) { switch (Rep(m->xedd) | Osz(m->xedd)) {
case 0: case 0:
memcpy(q16, GetModrmRegisterXmmPointerRead8(m), 8); memcpy(q16, GetModrmRegisterXmmPointerRead8(m), 8);
(pshufw)(q16, q16, m->xedd->op.uimm0); (pshufw)(q16, q16, m->xedd->op.uimm0);
@ -1282,7 +1282,7 @@ static void OpShuffle(struct Machine *m) {
static void OpShufpsd(struct Machine *m) { static void OpShufpsd(struct Machine *m) {
float s[4]; float s[4];
double d[2]; double d[2];
if (Prefix66(m->xedd)) { if (Osz(m->xedd)) {
memcpy(d, GetModrmRegisterXmmPointerRead16(m), 16); memcpy(d, GetModrmRegisterXmmPointerRead16(m), 16);
(shufpd)(d, d, m->xedd->op.uimm0); (shufpd)(d, d, m->xedd->op.uimm0);
memcpy(XmmRexrReg(m), d, 16); memcpy(XmmRexrReg(m), d, 16);
@ -1297,7 +1297,7 @@ static void OpSqrtpsd(struct Machine *m) {
long i; long i;
float_v xf; float_v xf;
double_v xd; double_v xd;
switch (m->xedd->op.rep | Prefix66(m->xedd)) { switch (Rep(m->xedd) | Osz(m->xedd)) {
case 0: case 0:
memcpy(&xf, GetModrmRegisterXmmPointerRead16(m), 16); memcpy(&xf, GetModrmRegisterXmmPointerRead16(m), 16);
for (i = 0; i < 4; ++i) xf[i] = sqrtf(xf[i]); for (i = 0; i < 4; ++i) xf[i] = sqrtf(xf[i]);
@ -1375,13 +1375,13 @@ static void OpVpsdWpsd(struct Machine *m,
static void OpVpsdWpsd66(struct Machine *m, static void OpVpsdWpsd66(struct Machine *m,
float_v opf(struct Machine *, float_v, float_v), float_v opf(struct Machine *, float_v, float_v),
double_v opd(struct Machine *, double_v, double_v)) { double_v opd(struct Machine *, double_v, double_v)) {
OpVpsdWpsd(m, opf, opd, !Prefix66(m->xedd), Prefix66(m->xedd)); OpVpsdWpsd(m, opf, opd, !Osz(m->xedd), Osz(m->xedd));
} }
static void OpVpsdWpsd66f2(struct Machine *m, static void OpVpsdWpsd66f2(struct Machine *m,
float_v opf(struct Machine *, float_v, float_v), float_v opf(struct Machine *, float_v, float_v),
double_v opd(struct Machine *, double_v, double_v)) { double_v opd(struct Machine *, double_v, double_v)) {
OpVpsdWpsd(m, opf, opd, m->xedd->op.ild_f2, Prefix66(m->xedd)); OpVpsdWpsd(m, opf, opd, m->xedd->op.ild_f2, Osz(m->xedd));
} }
static void OpVspsdWspsd(struct Machine *m, static void OpVspsdWspsd(struct Machine *m,
@ -1389,7 +1389,7 @@ static void OpVspsdWspsd(struct Machine *m,
double_v opd(struct Machine *, double_v, double_v)) { double_v opd(struct Machine *, double_v, double_v)) {
float_v xf, yf; float_v xf, yf;
double_v xd, yd; double_v xd, yd;
switch (m->xedd->op.rep | Prefix66(m->xedd)) { switch (Rep(m->xedd) | Osz(m->xedd)) {
case 0: case 0:
memcpy(&yf, GetModrmRegisterXmmPointerRead16(m), 16); memcpy(&yf, GetModrmRegisterXmmPointerRead16(m), 16);
memcpy(&xf, XmmRexrReg(m), 16); memcpy(&xf, XmmRexrReg(m), 16);
@ -1423,7 +1423,7 @@ static void OpComissVsWs(struct Machine *m) {
float xf, yf; float xf, yf;
double xd, yd; double xd, yd;
uint8_t zf, cf, pf, ie; uint8_t zf, cf, pf, ie;
if (!Prefix66(m->xedd)) { if (!Osz(m->xedd)) {
memcpy(&xf, XmmRexrReg(m), 4); memcpy(&xf, XmmRexrReg(m), 4);
memcpy(&yf, GetModrmRegisterXmmPointerRead4(m), 4); memcpy(&yf, GetModrmRegisterXmmPointerRead4(m), 4);
if (!isnan(xf) && !isnan(yf)) { if (!isnan(xf) && !isnan(yf)) {
@ -2366,6 +2366,7 @@ static void SaveStash(struct Machine *m) {
} }
void ExecuteInstruction(struct Machine *m) { void ExecuteInstruction(struct Machine *m) {
uint8_t *p;
m->ip += m->xedd->length; m->ip += m->xedd->length;
switch (m->xedd->op.map) { switch (m->xedd->op.map) {
CASE(XED_ILD_MAP0, ExecuteInstructionMap0(m)); CASE(XED_ILD_MAP0, ExecuteInstructionMap0(m));

View File

@ -1,6 +1,7 @@
#ifndef COSMOPOLITAN_TOOL_BUILD_LIB_MACHINE_H_ #ifndef COSMOPOLITAN_TOOL_BUILD_LIB_MACHINE_H_
#define COSMOPOLITAN_TOOL_BUILD_LIB_MACHINE_H_ #define COSMOPOLITAN_TOOL_BUILD_LIB_MACHINE_H_
#include "libc/elf/struct/ehdr.h" #include "libc/elf/struct/ehdr.h"
#include "libc/runtime/runtime.h"
#include "third_party/xed/x86.h" #include "third_party/xed/x86.h"
#include "tool/build/lib/pml4t.h" #include "tool/build/lib/pml4t.h"

View File

@ -27,7 +27,7 @@ COSMOPOLITAN_C_START_
#define Rexb(x) (((x)->op.rde & 000010000000) >> 21) #define Rexb(x) (((x)->op.rde & 000010000000) >> 21)
#define Rex(x) (((x)->op.rde & 000000000020) >> 4) #define Rex(x) (((x)->op.rde & 000000000020) >> 4)
#define Osz(x) (((x)->op.rde & 000000000040) >> 5) #define Osz(x) (((x)->op.rde & 000000000040) >> 5)
#define Prefix66(x) (((x)->op.rde & 010000000000) >> 30) #define Rep(x) (((x)->op.rde & 030000000000) >> 30)
#define ByteRexrReg(m) m->beg[(m->xedd->op.rde & 00000000037) >> 0] #define ByteRexrReg(m) m->beg[(m->xedd->op.rde & 00000000037) >> 0]
#define ByteRexbRm(m) m->beg[(m->xedd->op.rde & 00000003700) >> 6] #define ByteRexbRm(m) m->beg[(m->xedd->op.rde & 00000003700) >> 6]
#define ByteRexbSrm(m) m->beg[(m->xedd->op.rde & 00000370000) >> 12] #define ByteRexbSrm(m) m->beg[(m->xedd->op.rde & 00000370000) >> 12]

View File

@ -119,7 +119,7 @@ void OpSse(struct Machine *m, enum OpSseKernel kernel) {
uint8_t *p; uint8_t *p;
union MachineVector x, y, t; union MachineVector x, y, t;
p = GetModrmRegisterXmmPointerRead16(m); p = GetModrmRegisterXmmPointerRead16(m);
if (Prefix66(m->xedd)) { if (Osz(m->xedd)) {
memcpy(&y, p, 16); memcpy(&y, p, 16);
} else { } else {
memset(&t, 0, 16); memset(&t, 0, 16);
@ -204,7 +204,7 @@ void OpSse(struct Machine *m, enum OpSseKernel kernel) {
default: default:
unreachable; unreachable;
} }
if (Prefix66(m->xedd)) { if (Osz(m->xedd)) {
memcpy(XmmRexrReg(m), &x, 16); memcpy(XmmRexrReg(m), &x, 16);
} else { } else {
memcpy(XmmRexrReg(m), &x, 8); memcpy(XmmRexrReg(m), &x, 8);
@ -230,7 +230,7 @@ void OpSseUdqIb(struct Machine *m, enum OpSseUdqIbKernel kernel) {
default: default:
unreachable; unreachable;
} }
if (Prefix66(m->xedd)) { if (Osz(m->xedd)) {
memcpy(XmmRexbRm(m), &x, 16); memcpy(XmmRexbRm(m), &x, 16);
} else { } else {
memcpy(XmmRexbRm(m), &x, 8); memcpy(XmmRexbRm(m), &x, 8);
@ -246,7 +246,7 @@ static void OpSsePalignrMmx(struct Machine *m) {
} }
void OpSsePalignr(struct Machine *m) { void OpSsePalignr(struct Machine *m) {
if (Prefix66(m->xedd)) { if (Osz(m->xedd)) {
palignr(XmmRexrReg(m), XmmRexrReg(m), GetModrmRegisterXmmPointerRead8(m), palignr(XmmRexrReg(m), XmmRexrReg(m), GetModrmRegisterXmmPointerRead8(m),
m->xedd->op.uimm0); m->xedd->op.uimm0);
} else { } else {

View File

@ -78,7 +78,7 @@ void OpString(struct Machine *m, int op) {
lg2 = RegLog2(m->xedd); lg2 = RegLog2(m->xedd);
n = 1 << lg2; n = 1 << lg2;
for (;;) { for (;;) {
if (m->xedd->op.rep && !Read64(m->cx)) break; if (Rep(m->xedd) && !Read64(m->cx)) break;
v = 0; v = 0;
*p = NULL; *p = NULL;
compare = false; compare = false;
@ -125,11 +125,11 @@ void OpString(struct Machine *m, int op) {
abort(); abort();
} }
EndStore(m, v, n, p, s[0]); EndStore(m, v, n, p, s[0]);
if (!m->xedd->op.rep) break; if (!Rep(m->xedd)) break;
Write64(m->cx, Read64(m->cx) - 1); Write64(m->cx, Read64(m->cx) - 1);
if (compare) { if (compare) {
if (m->xedd->op.rep == 2 && GetFlag(m->flags, FLAGS_ZF)) break; if (Rep(m->xedd) == 2 && GetFlag(m->flags, FLAGS_ZF)) break;
if (m->xedd->op.rep == 3 && !GetFlag(m->flags, FLAGS_ZF)) break; if (Rep(m->xedd) == 3 && !GetFlag(m->flags, FLAGS_ZF)) break;
} }
} }
} }
@ -211,7 +211,7 @@ void OpRepStosbEnhanced(struct Machine *m) {
} }
void OpMovsb(struct Machine *m) { void OpMovsb(struct Machine *m) {
if (m->xedd->op.rep && !GetFlag(m->flags, FLAGS_DF)) { if (Rep(m->xedd) && !GetFlag(m->flags, FLAGS_DF)) {
OpRepMovsbEnhanced(m); OpRepMovsbEnhanced(m);
} else { } else {
OpString(m, STRING_MOVS); OpString(m, STRING_MOVS);
@ -219,7 +219,7 @@ void OpMovsb(struct Machine *m) {
} }
void OpStosb(struct Machine *m) { void OpStosb(struct Machine *m) {
if (m->xedd->op.rep && !GetFlag(m->flags, FLAGS_DF)) { if (Rep(m->xedd) && !GetFlag(m->flags, FLAGS_DF)) {
OpRepStosbEnhanced(m); OpRepStosbEnhanced(m);
} else { } else {
OpString(m, STRING_STOS); OpString(m, STRING_STOS);

View File

@ -19,6 +19,7 @@
*/ */
#include "libc/log/check.h" #include "libc/log/check.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "tool/build/lib/throw.h" #include "tool/build/lib/throw.h"
static bool IsHaltingInitialized(struct Machine *m) { static bool IsHaltingInitialized(struct Machine *m) {

View File

@ -189,7 +189,6 @@ int main(int argc, char *argv[]) {
SHOWOP(amd3dnow); SHOWOP(amd3dnow);
SHOWOP(bcrc); SHOWOP(bcrc);
SHOWOP(disp_width); SHOWOP(disp_width);
SHOWOP(first_f2f3);
SHOWOP(hint); SHOWOP(hint);
SHOWOP(ild_f2); SHOWOP(ild_f2);
SHOWOP(ild_f3); SHOWOP(ild_f3);
@ -197,10 +196,8 @@ int main(int argc, char *argv[]) {
SHOWOP(imm1_bytes); SHOWOP(imm1_bytes);
SHOWOP(imm_width); SHOWOP(imm_width);
SHOWOP(imm_signed); SHOWOP(imm_signed);
SHOWOP(last_f2f3);
SHOWOP(llrc); SHOWOP(llrc);
SHOWOP(mask); SHOWOP(mask);
SHOWOP(prefix66);
SHOWOP(max_bytes); SHOWOP(max_bytes);
SHOWOP(mode_first_prefix); SHOWOP(mode_first_prefix);
SHOWOP(nprefixes); SHOWOP(nprefixes);