summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2010-05-20 20:20:39 +0000
committerDaniel Dunbar <daniel@zuster.org>2010-05-20 20:20:39 +0000
commit1fe591da3e83ae95f6e97d7cd432cfbb25e680e8 (patch)
treebd8f4315172a31203a605244995bf22fb6396046
parent0306e3ddbf626a5ea8477358ee6ba07c0ef41a8f (diff)
downloadexternal_llvm-1fe591da3e83ae95f6e97d7cd432cfbb25e680e8.zip
external_llvm-1fe591da3e83ae95f6e97d7cd432cfbb25e680e8.tar.gz
external_llvm-1fe591da3e83ae95f6e97d7cd432cfbb25e680e8.tar.bz2
X86: Model i64i32imm properly, as a subclass of all immediates.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104272 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp20
-rw-r--r--lib/Target/X86/X86Instr64bit.td4
-rw-r--r--lib/Target/X86/X86InstrInfo.td7
3 files changed, 29 insertions, 2 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index e6d546b..479f4e4 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -200,6 +200,20 @@ struct X86Operand : public MCParsedAsmOperand {
return true;
}
+ bool isImmSExt32() const {
+ // Accept immediates which fit in 32 bits when sign extended, and
+ // non-absolute immediates.
+ if (!isImm())
+ return false;
+
+ if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
+ int64_t Value = CE->getValue();
+ return Value == (int64_t) (int32_t) Value;
+ }
+
+ return true;
+ }
+
bool isMem() const { return Kind == Memory; }
bool isAbsMem() const {
@@ -237,6 +251,12 @@ struct X86Operand : public MCParsedAsmOperand {
addExpr(Inst, getImm());
}
+ void addImmSExt32Operands(MCInst &Inst, unsigned N) const {
+ // FIXME: Support user customization of the render method.
+ assert(N == 1 && "Invalid number of operands!");
+ addExpr(Inst, getImm());
+ }
+
void addMemOperands(MCInst &Inst, unsigned N) const {
assert((N == 5) && "Invalid number of operands!");
Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td
index 3693281..3cbb2f5 100644
--- a/lib/Target/X86/X86Instr64bit.td
+++ b/lib/Target/X86/X86Instr64bit.td
@@ -18,7 +18,9 @@
//
// 64-bits but only 32 bits are significant.
-def i64i32imm : Operand<i64>;
+def i64i32imm : Operand<i64> {
+ let ParserMatchClass = ImmSExt32AsmOperand;
+}
// 64-bits but only 32 bits are significant, and those bits are treated as being
// pc relative.
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 5029216..803ca2f 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -270,9 +270,14 @@ def SSECC : Operand<i8> {
let PrintMethod = "printSSECC";
}
+def ImmSExt32AsmOperand : AsmOperandClass {
+ let Name = "ImmSExt32";
+ let SuperClass = ImmAsmOperand;
+}
+
def ImmSExt8AsmOperand : AsmOperandClass {
let Name = "ImmSExt8";
- let SuperClass = ImmAsmOperand;
+ let SuperClass = ImmSExt32AsmOperand;
}
// A couple of more descriptive operand definitions.