diff --git a/lib/Target/X86/Disassembler/X86Disassembler.cpp b/lib/Target/X86/Disassembler/X86Disassembler.cpp index 51ff5d96941..46b70b71d7e 100644 --- a/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -28,6 +28,8 @@ #define GET_REGINFO_ENUM #include "X86GenRegisterInfo.inc" +#define GET_INSTRINFO_ENUM +#include "X86GenInstrInfo.inc" #include "X86GenEDInfo.inc" using namespace llvm; @@ -184,6 +186,38 @@ static void translateImmediate(MCInst &mcInst, uint64_t immediate, break; } } + // By default sign-extend all X86 immediates based on their encoding. + else if (type == TYPE_IMM8 || type == TYPE_IMM16 || type == TYPE_IMM32 || + type == TYPE_IMM64) { + uint32_t Opcode = mcInst.getOpcode(); + switch (operand.encoding) { + default: + break; + case ENCODING_IB: + // Special case those X86 instructions that use the imm8 as a set of + // bits, bit count, etc. and are not sign-extend. + if (Opcode != X86::BLENDPSrri && Opcode != X86::BLENDPDrri && + Opcode != X86::PBLENDWrri && Opcode != X86::MPSADBWrri && + Opcode != X86::DPPSrri && Opcode != X86::DPPDrri && + Opcode != X86::INSERTPSrr && Opcode != X86::VBLENDPSYrri && + Opcode != X86::VBLENDPSYrmi && Opcode != X86::VBLENDPDYrri && + Opcode != X86::VBLENDPDYrmi && Opcode != X86::VPBLENDWrri && + Opcode != X86::VMPSADBWrri && Opcode != X86::VDPPSYrri && + Opcode != X86::VDPPSYrmi && Opcode != X86::VDPPDrri && + Opcode != X86::VINSERTPSrr) + type = TYPE_MOFFS8; + break; + case ENCODING_IW: + type = TYPE_MOFFS16; + break; + case ENCODING_ID: + type = TYPE_MOFFS32; + break; + case ENCODING_IO: + type = TYPE_MOFFS64; + break; + } + } switch (type) { case TYPE_MOFFS8: diff --git a/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp index c37d8797b39..591b5838310 100644 --- a/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp +++ b/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp @@ -90,7 +90,8 @@ void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, if (Op.isReg()) { O << '%' << getRegisterName(Op.getReg()); } else if (Op.isImm()) { - O << '$' << Op.getImm(); + // Print X86 immediates as signed values. + O << '$' << (int64_t)Op.getImm(); if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256)) *CommentStream << format("imm = 0x%llX\n", (long long)Op.getImm()); diff --git a/test/MC/Disassembler/X86/simple-tests.txt b/test/MC/Disassembler/X86/simple-tests.txt index a8a1099d4bc..ef36a6b80d0 100644 --- a/test/MC/Disassembler/X86/simple-tests.txt +++ b/test/MC/Disassembler/X86/simple-tests.txt @@ -102,3 +102,59 @@ # CHECK: vmovapd %xmm0, %xmm2 0xc5 0xf9 0x28 0xd0 + +# Check X86 immediates print as signed values by default. radr://8795217 +# CHECK: andq $-16, %rsp +0x48 0x83 0xe4 0xf0 + +# Check these special case instructions that the immediate is not sign-extend. +# CHECK: blendps $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x0c 0xca 0x81 + +# CHECK: blendpd $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x0d 0xca 0x81 + +# CHECK: pblendw $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x0e 0xca 0x81 + +# CHECK: mpsadbw $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x42 0xca 0x81 + +# CHECK: dpps $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x40 0xca 0x81 + +# CHECK: dppd $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x41 0xca 0x81 + +# CHECK: insertps $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x21 0xca 0x81 + +# CHECK: vblendps $129, %ymm2, %ymm5, %ymm1 +0xc4 0xe3 0x55 0x0c 0xca 0x81 + +# CHECK: vblendps $129, (%rax), %ymm5, %ymm1 +0xc4 0xe3 0x55 0x0c 0x08 0x81 + +# CHECK: vblendpd $129, %ymm2, %ymm5, %ymm1 +0xc4 0xe3 0x55 0x0d 0xca 0x81 + +# CHECK: vblendpd $129, (%rax), %ymm5, %ymm1 +0xc4 0xe3 0x55 0x0d 0x08 0x81 + +# CHECK: vpblendw $129, %xmm2, %xmm5, %xmm1 +0xc4 0xe3 0x51 0x0e 0xca 0x81 + +# CHECK: vmpsadbw $129, %xmm2, %xmm5, %xmm1 +0xc4 0xe3 0x51 0x42 0xca 0x81 + +# CHECK: vdpps $129, %ymm2, %ymm5, %ymm1 +0xc4 0xe3 0x55 0x40 0xca 0x81 + +# CHECK: vdpps $129, (%rax), %ymm5, %ymm1 +0xc4 0xe3 0x55 0x40 0x08 0x81 + +# CHECK: vdppd $129, %xmm2, %xmm5, %xmm1 +0xc4 0xe3 0x51 0x41 0xca 0x81 + +# CHECK: vinsertps $129, %xmm3, %xmm2, %xmm1 +0xc4 0xe3 0x69 0x21 0xcb 0x81