mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Add predicate method check match memory operand size, if available.
In att style asm syntax memory operand size is derived from suffix attached with mnemonic. In intel style asm syntax it is part of memory operand hence predicate method check is required to select appropriate instruction. llvm-svn: 148006
This commit is contained in:
parent
771a417c3f
commit
2096c1a697
@ -139,6 +139,7 @@ struct X86Operand : public MCParsedAsmOperand {
|
||||
unsigned BaseReg;
|
||||
unsigned IndexReg;
|
||||
unsigned Scale;
|
||||
unsigned Size;
|
||||
} Mem;
|
||||
};
|
||||
|
||||
@ -282,6 +283,27 @@ struct X86Operand : public MCParsedAsmOperand {
|
||||
}
|
||||
|
||||
bool isMem() const { return Kind == Memory; }
|
||||
bool isMem8() const {
|
||||
return Kind == Memory && (!Mem.Size || Mem.Size == 8);
|
||||
}
|
||||
bool isMem16() const {
|
||||
return Kind == Memory && (!Mem.Size || Mem.Size == 16);
|
||||
}
|
||||
bool isMem32() const {
|
||||
return Kind == Memory && (!Mem.Size || Mem.Size == 32);
|
||||
}
|
||||
bool isMem64() const {
|
||||
return Kind == Memory && (!Mem.Size || Mem.Size == 64);
|
||||
}
|
||||
bool isMem80() const {
|
||||
return Kind == Memory && (!Mem.Size || Mem.Size == 80);
|
||||
}
|
||||
bool isMem128() const {
|
||||
return Kind == Memory && (!Mem.Size || Mem.Size == 128);
|
||||
}
|
||||
bool isMem256() const {
|
||||
return Kind == Memory && (!Mem.Size || Mem.Size == 256);
|
||||
}
|
||||
|
||||
bool isAbsMem() const {
|
||||
return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
|
||||
@ -308,6 +330,28 @@ struct X86Operand : public MCParsedAsmOperand {
|
||||
addExpr(Inst, getImm());
|
||||
}
|
||||
|
||||
void addMem8Operands(MCInst &Inst, unsigned N) const {
|
||||
addMemOperands(Inst, N);
|
||||
}
|
||||
void addMem16Operands(MCInst &Inst, unsigned N) const {
|
||||
addMemOperands(Inst, N);
|
||||
}
|
||||
void addMem32Operands(MCInst &Inst, unsigned N) const {
|
||||
addMemOperands(Inst, N);
|
||||
}
|
||||
void addMem64Operands(MCInst &Inst, unsigned N) const {
|
||||
addMemOperands(Inst, N);
|
||||
}
|
||||
void addMem80Operands(MCInst &Inst, unsigned N) const {
|
||||
addMemOperands(Inst, N);
|
||||
}
|
||||
void addMem128Operands(MCInst &Inst, unsigned N) const {
|
||||
addMemOperands(Inst, N);
|
||||
}
|
||||
void addMem256Operands(MCInst &Inst, unsigned N) const {
|
||||
addMemOperands(Inst, N);
|
||||
}
|
||||
|
||||
void addMemOperands(MCInst &Inst, unsigned N) const {
|
||||
assert((N == 5) && "Invalid number of operands!");
|
||||
Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
|
||||
@ -344,20 +388,22 @@ struct X86Operand : public MCParsedAsmOperand {
|
||||
|
||||
/// Create an absolute memory operand.
|
||||
static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc,
|
||||
SMLoc EndLoc) {
|
||||
SMLoc EndLoc, unsigned Size = 0) {
|
||||
X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
|
||||
Res->Mem.SegReg = 0;
|
||||
Res->Mem.Disp = Disp;
|
||||
Res->Mem.BaseReg = 0;
|
||||
Res->Mem.IndexReg = 0;
|
||||
Res->Mem.Scale = 1;
|
||||
Res->Mem.Size = Size;
|
||||
return Res;
|
||||
}
|
||||
|
||||
/// Create a generalized memory operand.
|
||||
static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
|
||||
unsigned BaseReg, unsigned IndexReg,
|
||||
unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) {
|
||||
unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
|
||||
unsigned Size = 0) {
|
||||
// We should never just have a displacement, that should be parsed as an
|
||||
// absolute memory operand.
|
||||
assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
|
||||
@ -371,6 +417,7 @@ struct X86Operand : public MCParsedAsmOperand {
|
||||
Res->Mem.BaseReg = BaseReg;
|
||||
Res->Mem.IndexReg = IndexReg;
|
||||
Res->Mem.Scale = Scale;
|
||||
Res->Mem.Size = Size;
|
||||
return Res;
|
||||
}
|
||||
};
|
||||
@ -576,7 +623,7 @@ X86Operand *X86ATTAsmParser::ParseIntelOperand() {
|
||||
return 0;
|
||||
}
|
||||
return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
|
||||
Start, End);
|
||||
Start, End, Size);
|
||||
}
|
||||
|
||||
// immediate.
|
||||
|
@ -251,10 +251,31 @@ def ptr_rc_nosp : PointerLikeRegClass<1>;
|
||||
|
||||
// *mem - Operand definitions for the funky X86 addressing mode operands.
|
||||
//
|
||||
def X86MemAsmOperand : AsmOperandClass {
|
||||
let Name = "Mem";
|
||||
let SuperClasses = [];
|
||||
def X86MemAsmOperand : AsmOperandClass {
|
||||
let Name = "Mem"; let PredicateMethod = "isMem";
|
||||
}
|
||||
def X86Mem8AsmOperand : AsmOperandClass {
|
||||
let Name = "Mem8"; let PredicateMethod = "isMem8";
|
||||
}
|
||||
def X86Mem16AsmOperand : AsmOperandClass {
|
||||
let Name = "Mem16"; let PredicateMethod = "isMem16";
|
||||
}
|
||||
def X86Mem32AsmOperand : AsmOperandClass {
|
||||
let Name = "Mem32"; let PredicateMethod = "isMem32";
|
||||
}
|
||||
def X86Mem64AsmOperand : AsmOperandClass {
|
||||
let Name = "Mem64"; let PredicateMethod = "isMem64";
|
||||
}
|
||||
def X86Mem80AsmOperand : AsmOperandClass {
|
||||
let Name = "Mem80"; let PredicateMethod = "isMem80";
|
||||
}
|
||||
def X86Mem128AsmOperand : AsmOperandClass {
|
||||
let Name = "Mem128"; let PredicateMethod = "isMem128";
|
||||
}
|
||||
def X86Mem256AsmOperand : AsmOperandClass {
|
||||
let Name = "Mem256"; let PredicateMethod = "isMem256";
|
||||
}
|
||||
|
||||
def X86AbsMemAsmOperand : AsmOperandClass {
|
||||
let Name = "AbsMem";
|
||||
let SuperClasses = [X86MemAsmOperand];
|
||||
@ -271,17 +292,28 @@ def opaque48mem : X86MemOperand<"printopaquemem">;
|
||||
def opaque80mem : X86MemOperand<"printopaquemem">;
|
||||
def opaque512mem : X86MemOperand<"printopaquemem">;
|
||||
|
||||
def i8mem : X86MemOperand<"printi8mem">;
|
||||
def i16mem : X86MemOperand<"printi16mem">;
|
||||
def i32mem : X86MemOperand<"printi32mem">;
|
||||
def i64mem : X86MemOperand<"printi64mem">;
|
||||
def i128mem : X86MemOperand<"printi128mem">;
|
||||
def i256mem : X86MemOperand<"printi256mem">;
|
||||
def f32mem : X86MemOperand<"printf32mem">;
|
||||
def f64mem : X86MemOperand<"printf64mem">;
|
||||
def f80mem : X86MemOperand<"printf80mem">;
|
||||
def f128mem : X86MemOperand<"printf128mem">;
|
||||
def f256mem : X86MemOperand<"printf256mem">;
|
||||
def i8mem : X86MemOperand<"printi8mem"> {
|
||||
let ParserMatchClass = X86Mem8AsmOperand; }
|
||||
def i16mem : X86MemOperand<"printi16mem"> {
|
||||
let ParserMatchClass = X86Mem16AsmOperand; }
|
||||
def i32mem : X86MemOperand<"printi32mem"> {
|
||||
let ParserMatchClass = X86Mem32AsmOperand; }
|
||||
def i64mem : X86MemOperand<"printi64mem"> {
|
||||
let ParserMatchClass = X86Mem64AsmOperand; }
|
||||
def i128mem : X86MemOperand<"printi128mem"> {
|
||||
let ParserMatchClass = X86Mem128AsmOperand; }
|
||||
def i256mem : X86MemOperand<"printi256mem"> {
|
||||
let ParserMatchClass = X86Mem256AsmOperand; }
|
||||
def f32mem : X86MemOperand<"printf32mem"> {
|
||||
let ParserMatchClass = X86Mem32AsmOperand; }
|
||||
def f64mem : X86MemOperand<"printf64mem"> {
|
||||
let ParserMatchClass = X86Mem64AsmOperand; }
|
||||
def f80mem : X86MemOperand<"printf80mem"> {
|
||||
let ParserMatchClass = X86Mem80AsmOperand; }
|
||||
def f128mem : X86MemOperand<"printf128mem"> {
|
||||
let ParserMatchClass = X86Mem128AsmOperand; }
|
||||
def f256mem : X86MemOperand<"printf256mem">{
|
||||
let ParserMatchClass = X86Mem256AsmOperand; }
|
||||
}
|
||||
|
||||
// A version of i8mem for use on x86-64 that uses GR64_NOREX instead of
|
||||
|
Loading…
Reference in New Issue
Block a user