mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
[mips][microMIPS] Implement SWP and LWP instructions
Differential Revision: http://reviews.llvm.org/D5667 llvm-svn: 224338
This commit is contained in:
parent
d1ab012d86
commit
d72dae73a8
@ -146,6 +146,9 @@ class MipsAsmParser : public MCTargetAsmParser {
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
parseRegisterPair (OperandVector &Operands);
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
parseRegisterList (OperandVector &Operands);
|
||||
|
||||
@ -428,7 +431,8 @@ private:
|
||||
k_PhysRegister, /// A physical register from the Mips namespace
|
||||
k_RegisterIndex, /// A register index in one or more RegKind.
|
||||
k_Token, /// A simple token
|
||||
k_RegList /// A physical register list
|
||||
k_RegList, /// A physical register list
|
||||
k_RegPair /// A pair of physical register
|
||||
} Kind;
|
||||
|
||||
public:
|
||||
@ -781,6 +785,13 @@ public:
|
||||
Inst.addOperand(MCOperand::CreateReg(RegNo));
|
||||
}
|
||||
|
||||
void addRegPairOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 2 && "Invalid number of operands!");
|
||||
unsigned RegNo = getRegPair();
|
||||
Inst.addOperand(MCOperand::CreateReg(RegNo++));
|
||||
Inst.addOperand(MCOperand::CreateReg(RegNo));
|
||||
}
|
||||
|
||||
bool isReg() const override {
|
||||
// As a special case until we sort out the definition of div/divu, pretend
|
||||
// that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
|
||||
@ -845,6 +856,7 @@ public:
|
||||
assert(Kind == k_Token && "Invalid access!");
|
||||
return StringRef(Tok.Data, Tok.Length);
|
||||
}
|
||||
bool isRegPair() const { return Kind == k_RegPair; }
|
||||
|
||||
unsigned getReg() const override {
|
||||
// As a special case until we sort out the definition of div/divu, pretend
|
||||
@ -886,6 +898,11 @@ public:
|
||||
return *(RegList.List);
|
||||
}
|
||||
|
||||
unsigned getRegPair() const {
|
||||
assert((Kind == k_RegPair) && "Invalid access!");
|
||||
return RegIdx.Index;
|
||||
}
|
||||
|
||||
static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
|
||||
MipsAsmParser &Parser) {
|
||||
auto Op = make_unique<MipsOperand>(k_Token, Parser);
|
||||
@ -995,6 +1012,15 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static std::unique_ptr<MipsOperand>
|
||||
CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
|
||||
auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
|
||||
Op->RegIdx.Index = RegNo;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
return Op;
|
||||
}
|
||||
|
||||
bool isGPRAsmReg() const {
|
||||
return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
|
||||
}
|
||||
@ -1061,6 +1087,7 @@ public:
|
||||
case k_PhysRegister:
|
||||
case k_RegisterIndex:
|
||||
case k_Token:
|
||||
case k_RegPair:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1094,6 +1121,9 @@ public:
|
||||
OS << Reg << " ";
|
||||
OS << ">";
|
||||
break;
|
||||
case k_RegPair:
|
||||
OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}; // class MipsOperand
|
||||
@ -2723,6 +2753,22 @@ MipsAsmParser::parseRegisterList(OperandVector &Operands) {
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
|
||||
MCAsmParser &Parser = getParser();
|
||||
|
||||
SMLoc S = Parser.getTok().getLoc();
|
||||
if (parseAnyRegister(Operands) != MatchOperand_Success)
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
SMLoc E = Parser.getTok().getLoc();
|
||||
MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
|
||||
unsigned Reg = Op.getGPR32Reg();
|
||||
Operands.pop_back();
|
||||
Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
|
||||
|
||||
MCSymbolRefExpr::VariantKind VK =
|
||||
|
@ -1222,6 +1222,9 @@ static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
|
||||
// fallthrough
|
||||
default:
|
||||
Inst.addOperand(MCOperand::CreateReg(Reg));
|
||||
if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
|
||||
Inst.addOperand(MCOperand::CreateReg(Reg+1));
|
||||
|
||||
Inst.addOperand(MCOperand::CreateReg(Base));
|
||||
Inst.addOperand(MCOperand::CreateImm(Offset));
|
||||
}
|
||||
|
@ -261,6 +261,11 @@ printFCCOperand(const MCInst *MI, int opNum, raw_ostream &O) {
|
||||
O << MipsFCCToString((Mips::CondCode)MO.getImm());
|
||||
}
|
||||
|
||||
void MipsInstPrinter::
|
||||
printRegisterPair(const MCInst *MI, int opNum, raw_ostream &O) {
|
||||
printRegName(O, MI->getOperand(opNum).getReg());
|
||||
}
|
||||
|
||||
void MipsInstPrinter::
|
||||
printSHFMask(const MCInst *MI, int opNum, raw_ostream &O) {
|
||||
llvm_unreachable("TODO");
|
||||
|
@ -99,6 +99,7 @@ private:
|
||||
void printMemOperand(const MCInst *MI, int opNum, raw_ostream &O);
|
||||
void printMemOperandEA(const MCInst *MI, int opNum, raw_ostream &O);
|
||||
void printFCCOperand(const MCInst *MI, int opNum, raw_ostream &O);
|
||||
void printRegisterPair(const MCInst *MI, int opNum, raw_ostream &O);
|
||||
void printSHFMask(const MCInst *MI, int opNum, raw_ostream &O);
|
||||
|
||||
bool printAlias(const char *Str, const MCInst &MI, unsigned OpNo,
|
||||
|
@ -862,4 +862,11 @@ MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
|
||||
return (MI.getNumOperands() - 4);
|
||||
}
|
||||
|
||||
unsigned
|
||||
MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
|
||||
}
|
||||
|
||||
#include "MipsGenMCCodeEmitter.inc"
|
||||
|
@ -184,6 +184,10 @@ public:
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
|
||||
unsigned getRegisterPairOpValue(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
|
||||
unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
|
||||
|
@ -148,6 +148,36 @@ class StoreLeftRightMM<string opstr, SDNode OpNode, RegisterOperand RO,
|
||||
let DecoderMethod = "DecodeMemMMImm12";
|
||||
}
|
||||
|
||||
/// A register pair used by load/store pair instructions.
|
||||
def RegPairAsmOperand : AsmOperandClass {
|
||||
let Name = "RegPair";
|
||||
let ParserMethod = "parseRegisterPair";
|
||||
}
|
||||
|
||||
def regpair : Operand<i32> {
|
||||
let EncoderMethod = "getRegisterPairOpValue";
|
||||
let ParserMatchClass = RegPairAsmOperand;
|
||||
let PrintMethod = "printRegisterPair";
|
||||
let DecoderMethod = "DecodeRegPairOperand";
|
||||
let MIOperandInfo = (ops GPR32Opnd, GPR32Opnd);
|
||||
}
|
||||
|
||||
class StorePairMM<string opstr, InstrItinClass Itin = NoItinerary,
|
||||
ComplexPattern Addr = addr> :
|
||||
InstSE<(outs), (ins regpair:$rt, mem_mm_12:$addr),
|
||||
!strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> {
|
||||
let DecoderMethod = "DecodeMemMMImm12";
|
||||
let mayStore = 1;
|
||||
}
|
||||
|
||||
class LoadPairMM<string opstr, InstrItinClass Itin = NoItinerary,
|
||||
ComplexPattern Addr = addr> :
|
||||
InstSE<(outs regpair:$rt), (ins mem_mm_12:$addr),
|
||||
!strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> {
|
||||
let DecoderMethod = "DecodeMemMMImm12";
|
||||
let mayLoad = 1;
|
||||
}
|
||||
|
||||
class LLBaseMM<string opstr, RegisterOperand RO> :
|
||||
InstSE<(outs RO:$rt), (ins mem_mm_12:$addr),
|
||||
!strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
|
||||
@ -555,6 +585,10 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
|
||||
def SWM16_MM : StoreMultMM16<"swm16">, LWM_FM_MM16<0x5>;
|
||||
def LWM16_MM : LoadMultMM16<"lwm16">, LWM_FM_MM16<0x4>;
|
||||
|
||||
/// Load and Store Pair Instructions
|
||||
def SWP_MM : StorePairMM<"swp">, LWM_FM_MM<0x9>;
|
||||
def LWP_MM : LoadPairMM<"lwp">, LWM_FM_MM<0x1>;
|
||||
|
||||
/// Move Conditional
|
||||
def MOVZ_I_MM : MMRel, CMov_I_I_FT<"movz", GPR32Opnd, GPR32Opnd,
|
||||
NoItinerary>, ADD_FM_MM<0, 0x58>;
|
||||
|
@ -343,6 +343,12 @@
|
||||
# CHECK: swm32 $16, $17, 8($4)
|
||||
0x20 0x44 0xd0 0x08
|
||||
|
||||
# CHECK: swp $16, 8($4)
|
||||
0x22 0x04 0x90 0x08
|
||||
|
||||
# CHECK: lwp $16, 8($4)
|
||||
0x22 0x04 0x10 0x08
|
||||
|
||||
# CHECK: nop
|
||||
0x00 0x00 0x00 0x00
|
||||
|
||||
|
@ -343,6 +343,12 @@
|
||||
# CHECK: swm32 $16, $17, 8($4)
|
||||
0x44 0x20 0x08 0xd0
|
||||
|
||||
# CHECK: swp $16, 8($4)
|
||||
0x04 0x22 0x08 0x90
|
||||
|
||||
# CHECK: lwp $16, 8($4)
|
||||
0x04 0x22 0x08 0x10
|
||||
|
||||
# CHECK: nop
|
||||
0x00 0x00 0x00 0x00
|
||||
|
||||
|
@ -31,6 +31,8 @@
|
||||
# CHECK-EL: swm32 $16, $17, $18, $19, 8($4) # encoding: [0x84,0x20,0x08,0xd0]
|
||||
# CHECK-EL: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x12,0x45]
|
||||
# CHECK-EL: swm16 $16, $17, $ra, 8($sp) # encoding: [0x52,0x45]
|
||||
# CHECK-EL: swp $16, 8($4) # encoding: [0x04,0x22,0x08,0x90]
|
||||
# CHECK-EL: lwp $16, 8($4) # encoding: [0x04,0x22,0x08,0x10]
|
||||
#------------------------------------------------------------------------------
|
||||
# Big endian
|
||||
#------------------------------------------------------------------------------
|
||||
@ -56,6 +58,8 @@
|
||||
# CHECK-EB: swm32 $16, $17, $18, $19, 8($4) # encoding: [0x20,0x84,0xd0,0x08]
|
||||
# CHECK-EB: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x12]
|
||||
# CHECK-EB: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x52]
|
||||
# CHECK-EB: swp $16, 8($4) # encoding: [0x22,0x04,0x90,0x08]
|
||||
# CHECK-EB: lwp $16, 8($4) # encoding: [0x22,0x04,0x10,0x08]
|
||||
lb $5, 8($4)
|
||||
lbu $6, 8($4)
|
||||
lh $2, 8($4)
|
||||
@ -78,3 +82,5 @@
|
||||
swm32 $16 - $19, 8($4)
|
||||
lwm16 $16, $17, $ra, 8($sp)
|
||||
swm16 $16, $17, $ra, 8($sp)
|
||||
swp $16, 8($4)
|
||||
lwp $16, 8($4)
|
||||
|
Loading…
Reference in New Issue
Block a user