Fix printvideo regression and minor improvements
parent
eb4bb43275
commit
e86cff8ba0
|
@ -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.)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
154
libc/bits/bits.h
154
libc/bits/bits.h
|
@ -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 ─╬─│┼
|
||||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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'→')));
|
||||||
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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││ ││││ ││││ ││││
|
||||||
││8││24│2││18││││12││││ 6││││ 0
|
│ │8││24│2││18││││12││││ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 |
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue