forked from OSchip/llvm-project
[X86] Fix PR23271 - RIP-relative decoding bug in disassembler.
Differential Revision: http://reviews.llvm.org/D9110 llvm-svn: 237310
This commit is contained in:
parent
7c4d7b8fbe
commit
6dc1397298
|
@ -1366,16 +1366,17 @@ static int readModRM(struct InternalInstruction* insn) {
|
|||
switch (mod) {
|
||||
case 0x0:
|
||||
insn->eaDisplacement = EA_DISP_NONE; /* readSIB may override this */
|
||||
switch (rm) {
|
||||
case 0x14:
|
||||
case 0x4:
|
||||
case 0xc: /* in case REXW.b is set */
|
||||
// In determining whether RIP-relative mode is used (rm=5),
|
||||
// or whether a SIB byte is present (rm=4),
|
||||
// the extension bits (REX.b and EVEX.x) are ignored.
|
||||
switch (rm & 7) {
|
||||
case 0x4: // SIB byte is present
|
||||
insn->eaBase = (insn->addressSize == 4 ?
|
||||
EA_BASE_sib : EA_BASE_sib64);
|
||||
if (readSIB(insn) || readDisplacement(insn))
|
||||
return -1;
|
||||
break;
|
||||
case 0x5:
|
||||
case 0x5: // RIP-relative
|
||||
insn->eaBase = EA_BASE_NONE;
|
||||
insn->eaDisplacement = EA_DISP_32;
|
||||
if (readDisplacement(insn))
|
||||
|
@ -1391,10 +1392,8 @@ static int readModRM(struct InternalInstruction* insn) {
|
|||
/* FALLTHROUGH */
|
||||
case 0x2:
|
||||
insn->eaDisplacement = (mod == 0x1 ? EA_DISP_8 : EA_DISP_32);
|
||||
switch (rm) {
|
||||
case 0x14:
|
||||
case 0x4:
|
||||
case 0xc: /* in case REXW.b is set */
|
||||
switch (rm & 7) {
|
||||
case 0x4: // SIB byte is present
|
||||
insn->eaBase = EA_BASE_sib;
|
||||
if (readSIB(insn) || readDisplacement(insn))
|
||||
return -1;
|
||||
|
|
|
@ -301,3 +301,41 @@
|
|||
|
||||
# CHECK: movq %rax, 1515870810
|
||||
0x67, 0x48 0xa3 0x5a 0x5a 0x5a 0x5a
|
||||
|
||||
# CHECK: addq 255(%rip), %rbx
|
||||
0x49, 0x03, 0x1d, 0xff, 0x00, 0x00, 0x00
|
||||
|
||||
# The following 4 encodings are equivalent, as confirmed by the 'xed64'
|
||||
# decoder tool provided by Intel, which we assume to be canonical even
|
||||
# if the real silicon does something different. If that should happen,
|
||||
# then we'll all have disassembler bugs to repair.
|
||||
|
||||
# Try all combinations of EVEX.x and REX.b:
|
||||
# CHECK: vaddps 287453952(%rip), %zmm20, %zmm15
|
||||
0x62 0x11 0x5c 0x40 0x58 0x3d 0x00 0x33 0x22 0x11
|
||||
# CHECK: vaddps 287453952(%rip), %zmm20, %zmm15
|
||||
0x62 0x31 0x5c 0x40 0x58 0x3d 0x00 0x33 0x22 0x11
|
||||
# CHECK: vaddps 287453952(%rip), %zmm20, %zmm15
|
||||
0x62 0x51 0x5c 0x40 0x58 0x3d 0x00 0x33 0x22 0x11
|
||||
# CHECK: vaddps 287453952(%rip), %zmm20, %zmm15
|
||||
0x62 0x71 0x5c 0x40 0x58 0x3d 0x00 0x33 0x22 0x11
|
||||
|
||||
# Known bugs: these use a SIB byte. The index register is incorrectly
|
||||
# printed as an xmm register. Indeed there are "gather" load instructions
|
||||
# taking a vector of indices, but ONLY those instructions can do that.
|
||||
# The CHECK lines test the current incorrect output; FIXME is desired.
|
||||
# CHECK: vaddps (%r10,%xmm9), %zmm20, %zmm15
|
||||
# FIXME: vaddps (%r10,%r9), %zmm20, %zmm15
|
||||
0x62 0x11 0x5c 0x40 0x58 0x3c 0x0a
|
||||
|
||||
# CHECK: vaddps (%rdx,%xmm9), %zmm20, %zmm15
|
||||
# FIXME: vaddps (%rdx,%r9), %zmm20, %zmm15
|
||||
0x62 0x31 0x5c 0x40 0x58 0x3c 0x0a
|
||||
|
||||
# CHECK: vaddps (%r10,%xmm1), %zmm20, %zmm15
|
||||
# FIXME: vaddps (%r10,%rcx), %zmm20, %zmm15
|
||||
0x62 0x51 0x5c 0x40 0x58 0x3c 0x0a
|
||||
|
||||
# CHECK: vaddps (%rdx,%xmm1), %zmm20, %zmm15
|
||||
# FIXME: vaddps (%rdx,%rcx), %zmm20, %zmm15
|
||||
0x62 0x71 0x5c 0x40 0x58 0x3c 0x0a
|
||||
|
|
Loading…
Reference in New Issue