summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-07-31 20:53:16 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-07-31 20:53:16 +0000
commit022e2a84a867ba73fd0e6b89f61e56396f22620d (patch)
tree1f4c1f50ea9e86c1c943d1aed46d7e785fdb8166
parentf581213bfb3c35c4cf6a2ec85f15ad27bf1bc95d (diff)
downloadexternal_llvm-022e2a84a867ba73fd0e6b89f61e56396f22620d.zip
external_llvm-022e2a84a867ba73fd0e6b89f61e56396f22620d.tar.gz
external_llvm-022e2a84a867ba73fd0e6b89f61e56396f22620d.tar.bz2
llvm-mc/X86: Sketch match functions for immediates and memory operands.
Also, change scale value to always be 1 when unspecified to machine MachineInst encoding. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77728 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp149
-rw-r--r--test/MC/AsmParser/x86_instructions.s16
2 files changed, 126 insertions, 39 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 1f00f16..1c55c3f 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -95,6 +95,32 @@ struct X86Operand {
return Reg.RegNo;
}
+ const MCValue &getImm() const {
+ assert(Kind == Immediate && "Invalid access!");
+ return Imm.Val;
+ }
+
+ const MCValue &getMemDisp() const {
+ assert(Kind == Memory && "Invalid access!");
+ return Mem.Disp;
+ }
+ unsigned getMemSegReg() const {
+ assert(Kind == Memory && "Invalid access!");
+ return Mem.SegReg;
+ }
+ unsigned getMemBaseReg() const {
+ assert(Kind == Memory && "Invalid access!");
+ return Mem.BaseReg;
+ }
+ unsigned getMemIndexReg() const {
+ assert(Kind == Memory && "Invalid access!");
+ return Mem.IndexReg;
+ }
+ unsigned getMemScale() const {
+ assert(Kind == Memory && "Invalid access!");
+ return Mem.Scale;
+ }
+
static X86Operand CreateReg(unsigned RegNo) {
X86Operand Res;
Res.Kind = Register;
@@ -109,11 +135,8 @@ struct X86Operand {
}
static X86Operand CreateMem(unsigned SegReg, MCValue Disp, unsigned BaseReg,
unsigned IndexReg, unsigned Scale) {
- // If there is no index register, we should never have a scale, and we
- // should always have a scale (in {1,2,4,8}) if we do.
- assert(((Scale == 0 && !IndexReg) ||
- (IndexReg && (Scale == 1 || Scale == 2 ||
- Scale == 4 || Scale == 8))) &&
+ // The scale should always be one of {1,2,4,8}.
+ assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
"Invalid scale!");
X86Operand Res;
Res.Kind = Memory;
@@ -193,7 +216,7 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
// After parsing the base expression we could either have a parenthesized
// memory address or not. If not, return now. If so, eat the (.
if (getLexer().isNot(AsmToken::LParen)) {
- Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0);
+ Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
return false;
}
@@ -215,7 +238,7 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
// After parsing the base expression we could either have a parenthesized
// memory address or not. If not, return now. If so, eat the (.
if (getLexer().isNot(AsmToken::LParen)) {
- Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0);
+ Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
return false;
}
@@ -226,7 +249,7 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
// If we reached here, then we just ate the ( of the memory operand. Process
// the rest of the memory operand.
- unsigned BaseReg = 0, IndexReg = 0, Scale = 0;
+ unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
if (getLexer().is(AsmToken::Register)) {
if (ParseRegister(Op))
@@ -247,7 +270,6 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
if (ParseRegister(Op))
return true;
IndexReg = Op.getReg();
- Scale = 1; // If not specified, the scale defaults to 1.
if (getLexer().isNot(AsmToken::RParen)) {
// Parse the scale amount:
@@ -329,11 +351,10 @@ extern "C" void LLVMInitializeX86AsmParser() {
RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target);
}
-// FIXME: These should come from tblgen.
+// FIXME: These should come from tblgen?
-// Match_X86_Op_GR8
static bool
-Match_X86_Op_GR8(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
+Match_X86_Op_REG(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
assert(NumOps == 1 && "Invalid number of ops!");
// FIXME: Match correct registers.
@@ -344,6 +365,85 @@ Match_X86_Op_GR8(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
return false;
}
+static bool
+Match_X86_Op_IMM(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
+ assert(NumOps == 1 && "Invalid number of ops!");
+
+ // FIXME: We need to check widths.
+ if (Op.Kind != X86Operand::Immediate)
+ return true;
+
+ MCOps[0].MakeMCValue(Op.getImm());
+ return false;
+}
+
+static bool Match_X86_Op_MEM(const X86Operand &Op,
+ MCOperand *MCOps,
+ unsigned NumMCOps) {
+ assert(NumMCOps == 5 && "Invalid number of ops!");
+
+ if (Op.Kind != X86Operand::Memory)
+ return true;
+
+ MCOps[0].MakeReg(Op.getMemBaseReg());
+ MCOps[1].MakeImm(Op.getMemScale());
+ MCOps[2].MakeReg(Op.getMemIndexReg());
+ MCOps[3].MakeMCValue(Op.getMemDisp());
+ MCOps[4].MakeReg(Op.getMemSegReg());
+
+ return false;
+}
+
+#define REG(name) \
+ static bool Match_X86_Op_##name(const X86Operand &Op, \
+ MCOperand *MCOps, \
+ unsigned NumMCOps) { \
+ return Match_X86_Op_REG(Op, MCOps, NumMCOps); \
+ }
+
+REG(GR64)
+REG(GR32)
+REG(GR16)
+REG(GR8)
+
+#define IMM(name) \
+ static bool Match_X86_Op_##name(const X86Operand &Op, \
+ MCOperand *MCOps, \
+ unsigned NumMCOps) { \
+ return Match_X86_Op_IMM(Op, MCOps, NumMCOps); \
+ }
+
+IMM(i16i8imm)
+IMM(i16imm)
+IMM(i32i8imm)
+IMM(i32imm)
+IMM(i64i32imm)
+IMM(i64i8imm)
+IMM(i64imm)
+IMM(i8imm)
+
+#define MEM(name) \
+ static bool Match_X86_Op_##name(const X86Operand &Op, \
+ MCOperand *MCOps, \
+ unsigned NumMCOps) { \
+ return Match_X86_Op_MEM(Op, MCOps, NumMCOps); \
+ }
+
+MEM(f128mem)
+MEM(f32mem)
+MEM(f64mem)
+MEM(f80mem)
+MEM(i128mem)
+MEM(i16mem)
+MEM(i32mem)
+MEM(i64mem)
+MEM(i8mem)
+MEM(lea32mem)
+MEM(lea64_32mem)
+MEM(lea64mem)
+MEM(sdmem)
+MEM(ssmem)
+
#define DUMMY(name) \
static bool Match_X86_Op_##name(const X86Operand &Op, \
MCOperand *MCOps, \
@@ -353,40 +453,15 @@ Match_X86_Op_GR8(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
DUMMY(FR32)
DUMMY(FR64)
-DUMMY(GR16)
-DUMMY(GR32)
DUMMY(GR32_NOREX)
-DUMMY(GR64)
DUMMY(GR8_NOREX)
DUMMY(RST)
DUMMY(VR128)
DUMMY(VR64)
DUMMY(brtarget)
DUMMY(brtarget8)
-DUMMY(f128mem)
-DUMMY(f32mem)
-DUMMY(f64mem)
-DUMMY(f80mem)
-DUMMY(i128mem)
-DUMMY(i16i8imm)
-DUMMY(i16imm)
-DUMMY(i16mem)
-DUMMY(i32i8imm)
DUMMY(i32imm_pcrel)
-DUMMY(i32imm)
-DUMMY(i32mem)
DUMMY(i64i32imm_pcrel)
-DUMMY(i64i32imm)
-DUMMY(i64i8imm)
-DUMMY(i64imm)
-DUMMY(i64mem)
-DUMMY(i8imm)
DUMMY(i8mem_NOREX)
-DUMMY(i8mem)
-DUMMY(lea32mem)
-DUMMY(lea64_32mem)
-DUMMY(lea64mem)
-DUMMY(sdmem)
-DUMMY(ssmem)
#include "X86GenAsmMatcher.inc"
diff --git a/test/MC/AsmParser/x86_instructions.s b/test/MC/AsmParser/x86_instructions.s
index acffd57..7dbe939 100644
--- a/test/MC/AsmParser/x86_instructions.s
+++ b/test/MC/AsmParser/x86_instructions.s
@@ -2,6 +2,18 @@
// RUN: llvm-mc -triple i386-unknown-unknown %s > %t
-# Simple instructions
- subb %al, %al
// RUN: grep {MCInst(opcode=.*, operands=.reg:2, reg:0, reg:2.)} %t
+ subb %al, %al
+
+// RUN: grep {MCInst(opcode=.*, operands=.reg:19, reg:0, val:24.)} %t
+ addl $24, %eax
+
+// RUN: grep {MCInst(opcode=.*, operands=.reg:20, imm:1, reg:0, val:10, reg:0, reg:19.)} %t
+ movl %eax, 10(%ebp)
+// RUN: grep {MCInst(opcode=.*, operands=.reg:20, imm:1, reg:21, val:10, reg:0, reg:19.)} %t
+ movl %eax, 10(%ebp, %ebx)
+// RUN: grep {MCInst(opcode=.*, operands=.reg:20, imm:4, reg:21, val:10, reg:0, reg:19.)} %t
+ movl %eax, 10(%ebp, %ebx, 4)
+// RUN: grep {MCInst(opcode=.*, operands=.reg:0, imm:4, reg:21, val:10, reg:0, reg:19.)} %t
+ movl %eax, 10(, %ebx, 4)
+ \ No newline at end of file