[mips] Use ptr_rc to simplify definitions of base+index load/store instructions.

Also, fix predicates.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189432 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Akira Hatanaka 2013-08-28 00:55:15 +00:00
parent bf19dba2d4
commit a796d90c0e
13 changed files with 232 additions and 50 deletions

View File

@ -88,6 +88,11 @@ class MipsAsmParser : public MCTargetAsmParser {
MipsAsmParser::OperandMatchResultTy
parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind);
MipsAsmParser::OperandMatchResultTy
parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
MipsAsmParser::OperandMatchResultTy
parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
@ -179,6 +184,10 @@ class MipsAsmParser : public MCTargetAsmParser {
return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
}
bool isN64() const {
return STI.getFeatureBits() & Mips::FeatureN64;
}
int matchRegisterName(StringRef Symbol, bool is64BitReg);
int matchCPURegisterName(StringRef Symbol);
@ -245,6 +254,7 @@ private:
k_Memory,
k_PostIndexRegister,
k_Register,
k_PtrReg,
k_Token
} Kind;
@ -284,6 +294,11 @@ public:
Inst.addOperand(MCOperand::CreateReg(getReg()));
}
void addPtrRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
}
void addExpr(MCInst &Inst, const MCExpr *Expr) const{
// Add as immediate when possible. Null MCExpr = 0.
if (Expr == 0)
@ -313,6 +328,7 @@ public:
bool isImm() const { return Kind == k_Immediate; }
bool isToken() const { return Kind == k_Token; }
bool isMem() const { return Kind == k_Memory; }
bool isPtrReg() const { return Kind == k_PtrReg; }
StringRef getToken() const {
assert(Kind == k_Token && "Invalid access!");
@ -324,8 +340,13 @@ public:
return Reg.RegNum;
}
unsigned getPtrReg() const {
assert((Kind == k_PtrReg) && "Invalid access!");
return Reg.RegNum;
}
void setRegKind(RegisterKind RegKind) {
assert((Kind == k_Register) && "Invalid access!");
assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Reg.Kind = RegKind;
}
@ -361,6 +382,14 @@ public:
return Op;
}
static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
MipsOperand *Op = new MipsOperand(k_PtrReg);
Op->Reg.RegNum = RegNum;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
}
static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
MipsOperand *Op = new MipsOperand(k_Immediate);
Op->Imm.Val = Val;
@ -1289,6 +1318,68 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
return MatchOperand_Success;
}
bool
MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
int RegKind) {
// If the first token is not '$' we have an error.
if (Parser.getTok().isNot(AsmToken::Dollar))
return false;
SMLoc S = Parser.getTok().getLoc();
Parser.Lex();
AsmToken::TokenKind TkKind = getLexer().getKind();
int Reg;
if (TkKind == AsmToken::Integer) {
Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
regKindToRegClass(RegKind));
if (Reg == -1)
return false;
} else if (TkKind == AsmToken::Identifier) {
if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
return false;
Reg = getReg(regKindToRegClass(RegKind), Reg);
} else {
return false;
}
MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
Op->setRegKind((MipsOperand::RegisterKind)RegKind);
Operands.push_back(Op);
Parser.Lex();
return true;
}
MipsAsmParser::OperandMatchResultTy
MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 :
MipsOperand::Kind_GPR32;
// Parse index register.
if (!parsePtrReg(Operands, RegKind))
return MatchOperand_NoMatch;
// Parse '('.
if (Parser.getTok().isNot(AsmToken::LParen))
return MatchOperand_NoMatch;
Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
Parser.Lex();
// Parse base register.
if (!parsePtrReg(Operands, RegKind))
return MatchOperand_NoMatch;
// Parse ')'.
if (Parser.getTok().isNot(AsmToken::RParen))
return MatchOperand_NoMatch;
Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
Parser.Lex();
return MatchOperand_Success;
}
MipsAsmParser::OperandMatchResultTy
MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
int RegKind) {

View File

@ -35,14 +35,18 @@ public:
///
MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
bool bigEndian) :
MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {}
MCDisassembler(STI), RegInfo(Info),
IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {}
virtual ~MipsDisassemblerBase() {}
const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
bool isN64() const { return IsN64; }
private:
OwningPtr<const MCRegisterInfo> RegInfo;
bool IsN64;
protected:
bool isBigEndian;
};
@ -103,6 +107,11 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
unsigned Insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
@ -364,6 +373,16 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
return MCDisassembler::Success;
}
static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder) {
if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
}
static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,

View File

@ -348,10 +348,9 @@ class SHLL_QB_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
class LX_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
InstrItinClass itin> {
dag OutOperandList = (outs GPR32Opnd:$rd);
dag InOperandList = (ins GPR32Opnd:$base, GPR32Opnd:$index);
dag InOperandList = (ins PtrRC:$base, PtrRC:$index);
string AsmString = !strconcat(instr_asm, "\t$rd, ${index}(${base})");
list<dag> Pattern = [(set GPR32Opnd:$rd,
(OpNode GPR32Opnd:$base, GPR32Opnd:$index))];
list<dag> Pattern = [(set GPR32Opnd:$rd, (OpNode iPTR:$base, iPTR:$index))];
InstrItinClass Itinerary = itin;
bit mayLoad = 1;
}

View File

@ -171,19 +171,19 @@ class NMADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
[(set RC:$fd, (fsub fpimm0, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr)))],
Itin, FrmFR>;
class LWXC1_FT<string opstr, RegisterOperand DRC, RegisterOperand PRC,
class LWXC1_FT<string opstr, RegisterOperand DRC,
InstrItinClass Itin, SDPatternOperator OpNode = null_frag> :
InstSE<(outs DRC:$fd), (ins PRC:$base, PRC:$index),
InstSE<(outs DRC:$fd), (ins PtrRC:$base, PtrRC:$index),
!strconcat(opstr, "\t$fd, ${index}(${base})"),
[(set DRC:$fd, (OpNode (add PRC:$base, PRC:$index)))], Itin, FrmFI> {
[(set DRC:$fd, (OpNode (add iPTR:$base, iPTR:$index)))], Itin, FrmFI> {
let AddedComplexity = 20;
}
class SWXC1_FT<string opstr, RegisterOperand DRC, RegisterOperand PRC,
class SWXC1_FT<string opstr, RegisterOperand DRC,
InstrItinClass Itin, SDPatternOperator OpNode = null_frag> :
InstSE<(outs), (ins DRC:$fs, PRC:$base, PRC:$index),
InstSE<(outs), (ins DRC:$fs, PtrRC:$base, PtrRC:$index),
!strconcat(opstr, "\t$fs, ${index}(${base})"),
[(OpNode DRC:$fs, (add PRC:$base, PRC:$index))], Itin, FrmFI> {
[(OpNode DRC:$fs, (add iPTR:$base, iPTR:$index))], Itin, FrmFI> {
let AddedComplexity = 20;
}
@ -378,52 +378,30 @@ let Predicates = [NotFP64bit, HasStdEnc] in {
// Indexed loads and stores.
let Predicates = [HasFPIdx, HasStdEnc] in {
def LWXC1 : LWXC1_FT<"lwxc1", FGR32Opnd, GPR32Opnd, IIFLoad, load>,
LWXC1_FM<0>;
def SWXC1 : SWXC1_FT<"swxc1", FGR32Opnd, GPR32Opnd, IIFStore, store>,
SWXC1_FM<8>;
def LWXC1 : LWXC1_FT<"lwxc1", FGR32Opnd, IIFLoad, load>, LWXC1_FM<0>;
def SWXC1 : SWXC1_FT<"swxc1", FGR32Opnd, IIFStore, store>, SWXC1_FM<8>;
}
let Predicates = [HasMips32r2, NotMips64, HasStdEnc] in {
def LDXC1 : LWXC1_FT<"ldxc1", AFGR64Opnd, GPR32Opnd, IIFLoad, load>,
LWXC1_FM<1>;
def SDXC1 : SWXC1_FT<"sdxc1", AFGR64Opnd, GPR32Opnd, IIFStore, store>,
SWXC1_FM<9>;
let Predicates = [HasFPIdx, NotFP64bit, HasStdEnc] in {
def LDXC1 : LWXC1_FT<"ldxc1", AFGR64Opnd, IIFLoad, load>, LWXC1_FM<1>;
def SDXC1 : SWXC1_FT<"sdxc1", AFGR64Opnd, IIFStore, store>, SWXC1_FM<9>;
}
let Predicates = [HasMips64, NotN64, HasStdEnc], DecoderNamespace="Mips64" in {
def LDXC164 : LWXC1_FT<"ldxc1", FGR64Opnd, GPR32Opnd, IIFLoad, load>,
LWXC1_FM<1>;
def SDXC164 : SWXC1_FT<"sdxc1", FGR64Opnd, GPR32Opnd, IIFStore, store>,
SWXC1_FM<9>;
}
// n64
let Predicates = [IsN64, HasStdEnc], isCodeGenOnly=1 in {
def LWXC1_P8 : LWXC1_FT<"lwxc1", FGR32Opnd, GPR64Opnd, IIFLoad, load>,
LWXC1_FM<0>;
def LDXC164_P8 : LWXC1_FT<"ldxc1", FGR64Opnd, GPR64Opnd, IIFLoad,
load>, LWXC1_FM<1>;
def SWXC1_P8 : SWXC1_FT<"swxc1", FGR32Opnd, GPR64Opnd, IIFStore,
store>, SWXC1_FM<8>;
def SDXC164_P8 : SWXC1_FT<"sdxc1", FGR64Opnd, GPR64Opnd, IIFStore,
store>, SWXC1_FM<9>;
let Predicates = [HasFPIdx, IsFP64bit, HasStdEnc],
DecoderNamespace="Mips64" in {
def LDXC164 : LWXC1_FT<"ldxc1", FGR64Opnd, IIFLoad, load>, LWXC1_FM<1>;
def SDXC164 : SWXC1_FT<"sdxc1", FGR64Opnd, IIFStore, store>, SWXC1_FM<9>;
}
// Load/store doubleword indexed unaligned.
let Predicates = [NotMips64, HasStdEnc] in {
def LUXC1 : LWXC1_FT<"luxc1", AFGR64Opnd, GPR32Opnd, IIFLoad>,
LWXC1_FM<0x5>;
def SUXC1 : SWXC1_FT<"suxc1", AFGR64Opnd, GPR32Opnd, IIFStore>,
SWXC1_FM<0xd>;
let Predicates = [NotFP64bit, HasStdEnc] in {
def LUXC1 : LWXC1_FT<"luxc1", AFGR64Opnd, IIFLoad>, LWXC1_FM<0x5>;
def SUXC1 : SWXC1_FT<"suxc1", AFGR64Opnd, IIFStore>, SWXC1_FM<0xd>;
}
let Predicates = [HasMips64, HasStdEnc],
DecoderNamespace="Mips64" in {
def LUXC164 : LWXC1_FT<"luxc1", FGR64Opnd, GPR32Opnd, IIFLoad>,
LWXC1_FM<0x5>;
def SUXC164 : SWXC1_FT<"suxc1", FGR64Opnd, GPR32Opnd, IIFStore>,
SWXC1_FM<0xd>;
let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace="Mips64" in {
def LUXC164 : LWXC1_FT<"luxc1", FGR64Opnd, IIFLoad>, LWXC1_FM<0x5>;
def SUXC164 : SWXC1_FT<"suxc1", FGR64Opnd, IIFStore>, SWXC1_FM<0xd>;
}
/// Floating-point Aritmetic

View File

@ -279,6 +279,11 @@ def MipsMemAsmOperand : AsmOperandClass {
let ParserMethod = "parseMemOperand";
}
def PtrRegAsmOperand : AsmOperandClass {
let Name = "PtrReg";
let ParserMethod = "parsePtrReg";
}
// Address operand
def mem : Operand<iPTR> {
let PrintMethod = "printMemOperand";
@ -297,6 +302,8 @@ def mem_ea : Operand<iPTR> {
def PtrRC : Operand<iPTR> {
let MIOperandInfo = (ops ptr_rc);
let DecoderMethod = "DecodePtrRegisterClass";
let ParserMatchClass = PtrRegAsmOperand;
}
// size operand of ext instruction

View File

@ -11,3 +11,12 @@
# CHECK: mtlo $21, $ac3
0x13 0x18 0xa0 0x02
# CHECK: lbux $10, $20($26)
0x8a 0x51 0x54 0x7f
# CHECK: lhx $11, $21($27)
0x0a 0x59 0x75 0x7f
# CHECK: lwx $12, $22($gp)
0x0a 0x60 0x96 0x7f

View File

@ -242,6 +242,9 @@
# CHECK: lui $6, 17767
0x3c 0x06 0x45 0x67
# CHECK: luxc1 $f0, $6($5)
0x4c 0xa6 0x00 0x05
# CHECK: lw $4, 24($5)
0x8c 0xa4 0x00 0x18
@ -254,6 +257,9 @@
# CHECK: lwr $3, 16($5)
0x98 0xa3 0x00 0x10
# CHECK: lwxc1 $f20, $12($14)
0x4d 0xcc 0x05 0x00
# CHECK: madd $6, $7
0x70 0xc7 0x00 0x00
@ -404,6 +410,9 @@
# CHECK: subu $4, $3, $5
0x00 0x65 0x20 0x23
# CHECK: suxc1 $f4, $24($5)
0x4c 0xb8 0x20 0x0d
# CHECK: sw $4, 24($5)
0xac 0xa4 0x00 0x18
@ -416,6 +425,9 @@
# CHECK: swr $6, 16($7)
0xb8 0xe6 0x00 0x10
# CHECK: swxc1 $f26, $18($22)
0x4e 0xd2 0xd0 0x08
# CHECK: sync 7
0x00 0x00 0x01 0xcf

View File

@ -242,6 +242,9 @@
# CHECK: lui $6, 17767
0x67 0x45 0x06 0x3c
# CHECK: luxc1 $f0, $6($5)
0x05 0x00 0xa6 0x4c
# CHECK: lw $4, 24($5)
0x18 0x00 0xa4 0x8c
@ -254,6 +257,9 @@
# CHECK: lwr $3, 16($5)
0x10 0x00 0xa3 0x98
# CHECK: lwxc1 $f20, $12($14)
0x00 0x05 0xcc 0x4d
# CHECK: madd $6, $7
0x00 0x00 0xc7 0x70
@ -404,6 +410,9 @@
# CHECK: subu $4, $3, $5
0x23 0x20 0x65 0x00
# CHECK: suxc1 $f4, $24($5)
0x0d 0x20 0xb8 0x4c
# CHECK: sw $4, 24($5)
0x18 0x00 0xa4 0xac
@ -416,6 +425,9 @@
# CHECK: swr $6, 16($7)
0x10 0x00 0xe6 0xb8
# CHECK: swxc1 $f26, $18($22)
0x08 0xd0 0xd2 0x4e
# CHECK: sync 7
0xcf 0x01 0x00 0x00

View File

@ -64,3 +64,21 @@
# CHECK: sd $6, 17767($zero)
0xfc 0x06 0x45 0x67
# CHECK: luxc1 $f0, $6($5)
0x4c 0xa6 0x00 0x05
# CHECK: lwxc1 $f20, $12($14)
0x4d 0xcc 0x05 0x00
# CHECK: suxc1 $f4, $24($5)
0x4c 0xb8 0x20 0x0d
# CHECK: swxc1 $f26, $18($22)
0x4e 0xd2 0xd0 0x08
# CHECK: ldxc1 $f2, $2($10)
0x4d 0x42 0x00 0x81
# CHECK: sdxc1 $f8, $4($25)
0x4f 0x24 0x40 0x09

View File

@ -64,3 +64,21 @@
# CHECK: sd $6, 17767($zero)
0x67 0x45 0x06 0xfc
# CHECK: luxc1 $f0, $6($5)
0x05 0x00 0xa6 0x4c
# CHECK: lwxc1 $f20, $12($14)
0x00 0x05 0xcc 0x4d
# CHECK: suxc1 $f4, $24($5)
0x0d 0x20 0xb8 0x4c
# CHECK: swxc1 $f26, $18($22)
0x08 0xd0 0xd2 0x4e
# CHECK: ldxc1 $f2, $2($10)
0x81 0x00 0x42 0x4d
# CHECK: sdxc1 $f8, $4($25)
0x09 0x40 0x24 0x4f

View File

@ -22,6 +22,10 @@
# CHECK: precr_sra_r.ph.w $25, $26, 0 # encoding: [0x7f,0x59,0x07,0xd1]
# CHECK: precr_sra_r.ph.w $25, $26, 31 # encoding: [0x7f,0x59,0xff,0xd1]
# CHECK: lbux $10, $20($26) # encoding: [0x7f,0x54,0x51,0x8a]
# CHECK: lhx $11, $21($27) # encoding: [0x7f,0x75,0x59,0x0a]
# CHECK: lwx $12, $22($gp) # encoding: [0x7f,0x96,0x60,0x0a]
# CHECK: mult $ac3, $2, $3 # encoding: [0x00,0x43,0x18,0x18]
# CHECK: multu $ac2, $4, $5 # encoding: [0x00,0x85,0x10,0x19]
# CHECK: madd $ac1, $6, $7 # encoding: [0x70,0xc7,0x08,0x00]
@ -50,6 +54,10 @@
precr_sra_r.ph.w $25,$26,0
precr_sra_r.ph.w $25,$26,31
lbux $10, $s4($26)
lhx $11, $s5($27)
lwx $12, $s6($28)
mult $ac3, $2, $3
multu $ac2, $4, $5
madd $ac1, $6, $7

View File

@ -165,6 +165,8 @@
# CHECK: movf.s $f4, $f6, $fcc5 # encoding: [0x11,0x31,0x14,0x46]
# CHECK: luxc1 $f0, $6($5) # encoding: [0x05,0x00,0xa6,0x4c]
# CHECK: suxc1 $f4, $24($5) # encoding: [0x0d,0x20,0xb8,0x4c]
# CHECK: lwxc1 $f20, $12($14) # encoding: [0x00,0x05,0xcc,0x4d]
# CHECK: swxc1 $f26, $18($22) # encoding: [0x08,0xd0,0xd2,0x4e]
cfc1 $a2,$0
ctc1 $10,$31
@ -190,5 +192,7 @@
movt $4, $5, $fcc4
movf.d $f4, $f6, $fcc2
movf.s $f4, $f6, $fcc5
luxc1 $f0, $a2($a1)
suxc1 $f4, $t8($a1)
luxc1 $f0, $a2($a1)
suxc1 $f4, $t8($a1)
lwxc1 $f20, $12($14)
swxc1 $f26, $s2($s6)

View File

@ -0,0 +1,7 @@
# RUN: llvm-mc %s -triple=mips64el-unknown-linux -show-encoding -mcpu=mips64r2 | FileCheck %s
# CHECK: ldxc1 $f2, $2($10) # encoding: [0x81,0x00,0x42,0x4d]
# CHECK: sdxc1 $f8, $4($25) # encoding: [0x09,0x40,0x24,0x4f]
ldxc1 $f2, $2($10)
sdxc1 $f8, $a0($t9)