Process instructions after match to select alternative encoding which may be more desirable.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148431 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel 2012-01-18 22:42:29 +00:00
parent 5aa5368ccd
commit b8ba13f009
2 changed files with 111 additions and 16 deletions

View File

@ -60,6 +60,9 @@ private:
bool ParseDirectiveWord(unsigned Size, SMLoc L);
bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
bool processInstruction(MCInst &Inst,
const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
bool MatchAndEmitInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCStreamer &Out);
@ -112,6 +115,31 @@ static unsigned MatchRegisterName(StringRef Name);
/// }
static bool isImmSExti16i8Value(uint64_t Value) {
return (( Value <= 0x000000000000007FULL)||
(0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
(0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
}
static bool isImmSExti32i8Value(uint64_t Value) {
return (( Value <= 0x000000000000007FULL)||
(0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
(0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
}
static bool isImmZExtu32u8Value(uint64_t Value) {
return (Value <= 0x00000000000000FFULL);
}
static bool isImmSExti64i8Value(uint64_t Value) {
return (( Value <= 0x000000000000007FULL)||
(0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
}
static bool isImmSExti64i32Value(uint64_t Value) {
return (( Value <= 0x000000007FFFFFFFULL)||
(0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
}
namespace {
/// X86Operand - Instances of this class represent a parsed X86 machine
@ -219,10 +247,7 @@ struct X86Operand : public MCParsedAsmOperand {
// Otherwise, check the value is in a range that makes sense for this
// extension.
uint64_t Value = CE->getValue();
return (( Value <= 0x000000000000007FULL)||
(0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
(0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
return isImmSExti16i8Value(CE->getValue());
}
bool isImmSExti32i8() const {
if (!isImm())
@ -236,10 +261,7 @@ struct X86Operand : public MCParsedAsmOperand {
// Otherwise, check the value is in a range that makes sense for this
// extension.
uint64_t Value = CE->getValue();
return (( Value <= 0x000000000000007FULL)||
(0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
(0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
return isImmSExti32i8Value(CE->getValue());
}
bool isImmZExtu32u8() const {
if (!isImm())
@ -253,8 +275,7 @@ struct X86Operand : public MCParsedAsmOperand {
// Otherwise, check the value is in a range that makes sense for this
// extension.
uint64_t Value = CE->getValue();
return (Value <= 0x00000000000000FFULL);
return isImmZExtu32u8Value(CE->getValue());
}
bool isImmSExti64i8() const {
if (!isImm())
@ -268,9 +289,7 @@ struct X86Operand : public MCParsedAsmOperand {
// Otherwise, check the value is in a range that makes sense for this
// extension.
uint64_t Value = CE->getValue();
return (( Value <= 0x000000000000007FULL)||
(0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
return isImmSExti64i8Value(CE->getValue());
}
bool isImmSExti64i32() const {
if (!isImm())
@ -284,9 +303,7 @@ struct X86Operand : public MCParsedAsmOperand {
// Otherwise, check the value is in a range that makes sense for this
// extension.
uint64_t Value = CE->getValue();
return (( Value <= 0x000000007FFFFFFFULL)||
(0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
return isImmSExti64i32Value(CE->getValue());
}
bool isMem() const { return Kind == Memory; }
@ -1156,6 +1173,54 @@ ParseInstruction(StringRef Name, SMLoc NameLoc,
return false;
}
bool X86AsmParser::
processInstruction(MCInst &Inst,
const SmallVectorImpl<MCParsedAsmOperand*> &Ops) {
switch (Inst.getOpcode()) {
default: return false;
case X86::AND16i16: {
if (!Inst.getOperand(0).isImm() ||
!isImmSExti16i8Value(Inst.getOperand(0).getImm()))
return false;
MCInst TmpInst;
TmpInst.setOpcode(X86::AND16ri8);
TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
TmpInst.addOperand(Inst.getOperand(0));
Inst = TmpInst;
return true;
}
case X86::AND32i32: {
if (!Inst.getOperand(0).isImm() ||
!isImmSExti32i8Value(Inst.getOperand(0).getImm()))
return false;
MCInst TmpInst;
TmpInst.setOpcode(X86::AND32ri8);
TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
TmpInst.addOperand(Inst.getOperand(0));
Inst = TmpInst;
return true;
}
case X86::AND64i32: {
if (!Inst.getOperand(0).isImm() ||
!isImmSExti64i8Value(Inst.getOperand(0).getImm()))
return false;
MCInst TmpInst;
TmpInst.setOpcode(X86::AND64ri8);
TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
TmpInst.addOperand(Inst.getOperand(0));
Inst = TmpInst;
return true;
}
}
return false;
}
bool X86AsmParser::
MatchAndEmitInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
@ -1201,6 +1266,12 @@ MatchAndEmitInstruction(SMLoc IDLoc,
getParser().getAssemblerDialect())) {
default: break;
case Match_Success:
// Some instructions need post-processing to, for example, tweak which
// encoding is selected. Loop on it while changes happen so the
// individual transformations can chain off each other.
while (processInstruction(Inst, Operands))
;
Out.EmitInstruction(Inst);
return false;
case Match_MissingFeature:

View File

@ -29,4 +29,28 @@ _main:
movzx EDI, WORD PTR [RCX + 2]
// CHECK: callq _test
call _test
// CHECK: andw $12, %ax
and ax, 12
// CHECK: andw $-12, %ax
and ax, -12
// CHECK: andw $257, %ax
and ax, 257
// CHECK: andw $-257, %ax
and ax, -257
// CHECK: andl $12, %eax
and eax, 12
// CHECK: andl $-12, %eax
and eax, -12
// CHECK: andl $257, %eax
and eax, 257
// CHECK: andl $-257, %eax
and eax, -257
// CHECK: andq $12, %rax
and rax, 12
// CHECK: andq $-12, %rax
and rax, -12
// CHECK: andq $257, %rax
and rax, 257
// CHECK: andq $-257, %rax
and rax, -257
ret