[mips] Define register class FGRH32 for the high half of the 64-bit floating

point registers. We will need this register class later when we add
definitions for instructions mfhc1 and mthc1. Also, remove sub-register indices
sub_fpeven and sub_fpodd and use sub_lo and sub_hi instead.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188842 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Akira Hatanaka 2013-08-20 22:58:56 +00:00
parent 5f560af541
commit 3531db14c6
6 changed files with 60 additions and 16 deletions

View File

@ -109,6 +109,9 @@ class MipsAsmParser : public MCTargetAsmParser {
MipsAsmParser::OperandMatchResultTy
parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
MipsAsmParser::OperandMatchResultTy
parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
MipsAsmParser::OperandMatchResultTy
parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
@ -224,6 +227,7 @@ public:
Kind_GPR64,
Kind_HWRegs,
Kind_FGR32Regs,
Kind_FGRH32Regs,
Kind_FGR64Regs,
Kind_AFGR64Regs,
Kind_CCRRegs,
@ -408,6 +412,10 @@ public:
return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
}
bool isFGRH32Asm() const {
return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
}
bool isFCCRegsAsm() const {
return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
}
@ -893,6 +901,7 @@ int MipsAsmParser::regKindToRegClass(int RegKind) {
case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID;
case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
@ -1310,6 +1319,7 @@ MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
case MipsOperand::Kind_AFGR64Regs:
case MipsOperand::Kind_FGR64Regs:
case MipsOperand::Kind_FGR32Regs:
case MipsOperand::Kind_FGRH32Regs:
RegNum = matchFPURegisterName(RegName);
if (RegKind == MipsOperand::Kind_AFGR64Regs)
RegNum /= 2;
@ -1415,6 +1425,11 @@ MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
}
MipsAsmParser::OperandMatchResultTy
MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs);
}
MipsAsmParser::OperandMatchResultTy
MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);

View File

@ -118,6 +118,11 @@ static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
@ -390,6 +395,18 @@ static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
return MCDisassembler::Success;
}
static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder) {
if (RegNo > 31)
return MCDisassembler::Fail;
unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
Inst.addOperand(MCOperand::CreateReg(Reg));
return MCDisassembler::Success;
}
static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,

View File

@ -576,7 +576,7 @@ let Predicates = [IsFP64bit, HasStdEnc] in {
def : MipsPat<(f64 (sint_to_fp GPR32Opnd:$src)),
(PseudoCVT_D64_W GPR32Opnd:$src)>;
def : MipsPat<(f32 (sint_to_fp GPR64Opnd:$src)),
(EXTRACT_SUBREG (PseudoCVT_S_L GPR64Opnd:$src), sub_32)>;
(EXTRACT_SUBREG (PseudoCVT_S_L GPR64Opnd:$src), sub_lo)>;
def : MipsPat<(f64 (sint_to_fp GPR64Opnd:$src)),
(PseudoCVT_D64_L GPR64Opnd:$src)>;

View File

@ -11,8 +11,6 @@
// Declarations that describe the MIPS register file
//===----------------------------------------------------------------------===//
let Namespace = "Mips" in {
def sub_fpeven : SubRegIndex<32>;
def sub_fpodd : SubRegIndex<32, 32>;
def sub_32 : SubRegIndex<32>;
def sub_64 : SubRegIndex<64>;
def sub_lo : SubRegIndex<32>;
@ -55,13 +53,13 @@ class FPR<bits<16> Enc, string n> : MipsReg<Enc, n>;
// Mips 64-bit (aliased) FPU Registers
class AFPR<bits<16> Enc, string n, list<Register> subregs>
: MipsRegWithSubRegs<Enc, n, subregs> {
let SubRegIndices = [sub_fpeven, sub_fpodd];
let SubRegIndices = [sub_lo, sub_hi];
let CoveredBySubRegs = 1;
}
class AFPR64<bits<16> Enc, string n, list<Register> subregs>
: MipsRegWithSubRegs<Enc, n, subregs> {
let SubRegIndices = [sub_32];
let SubRegIndices = [sub_lo, sub_hi];
}
// Mips 128-bit (aliased) MSA Registers
@ -157,6 +155,10 @@ let Namespace = "Mips" in {
foreach I = 0-31 in
def F#I : FPR<I, "f"#I>, DwarfRegNum<[!add(I, 32)]>;
// Higher half of 64-bit FP registers.
foreach I = 0-31 in
def F_HI#I : FPR<I, "f"#I>, DwarfRegNum<[!add(I, 32)]>;
/// Mips Double point precision FPU Registers (aliased
/// with the single precision to hold 64 bit values)
foreach I = 0-15 in
@ -166,7 +168,7 @@ let Namespace = "Mips" in {
/// Mips Double point precision FPU Registers in MFP64 mode.
foreach I = 0-31 in
def D#I#_64 : AFPR64<I, "f"#I, [!cast<FPR>("F"#I)]>,
def D#I#_64 : AFPR64<I, "f"#I, [!cast<FPR>("F"#I), !cast<FPR>("F_HI"#I)]>,
DwarfRegNum<[!add(I, 32)]>;
/// Mips MSA registers
@ -321,6 +323,8 @@ def CPUSPReg : RegisterClass<"Mips", [i32], 32, (add SP)>, Unallocatable;
// * FGR32 - 32 32-bit registers (single float only mode)
def FGR32 : RegisterClass<"Mips", [f32], 32, (sequence "F%u", 0, 31)>;
def FGRH32 : RegisterClass<"Mips", [f32], 32, (sequence "F_HI%u", 0, 31)>;
def AFGR64 : RegisterClass<"Mips", [f64], 64, (add
// Return Values and Arguments
D0, D1,
@ -423,6 +427,11 @@ def FGR32AsmOperand : MipsAsmRegOperand {
let ParserMethod = "parseFGR32Regs";
}
def FGRH32AsmOperand : MipsAsmRegOperand {
let Name = "FGRH32Asm";
let ParserMethod = "parseFGRH32Regs";
}
def FCCRegsAsmOperand : MipsAsmRegOperand {
let Name = "FCCRegsAsm";
let ParserMethod = "parseFCCRegs";
@ -465,6 +474,10 @@ def FGR32Opnd : RegisterOperand<FGR32> {
let ParserMatchClass = FGR32AsmOperand;
}
def FGRH32Opnd : RegisterOperand<FGRH32> {
let ParserMatchClass = FGRH32AsmOperand;
}
def FCCRegsOpnd : RegisterOperand<FCC> {
let ParserMatchClass = FCCRegsAsmOperand;
}

View File

@ -313,9 +313,9 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
// one for each of the paired single precision registers.
if (Mips::AFGR64RegClass.contains(Reg)) {
unsigned Reg0 =
MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpeven), true);
MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_lo), true);
unsigned Reg1 =
MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpodd), true);
MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_hi), true);
if (!STI.isLittle())
std::swap(Reg0, Reg1);

View File

@ -404,16 +404,15 @@ void MipsSEInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB,
unsigned DstReg = Dst.getReg(), SrcReg = Src.getReg(), TmpReg = DstReg;
unsigned KillSrc = getKillRegState(Src.isKill());
DebugLoc DL = I->getDebugLoc();
unsigned SubIdx = (IsI64 ? Mips::sub_32 : Mips::sub_fpeven);
bool DstIsLarger, SrcIsLarger;
tie(DstIsLarger, SrcIsLarger) = compareOpndSize(CvtOpc, *MBB.getParent());
if (DstIsLarger)
TmpReg = getRegisterInfo().getSubReg(DstReg, SubIdx);
TmpReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);
if (SrcIsLarger)
DstReg = getRegisterInfo().getSubReg(DstReg, SubIdx);
DstReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);
BuildMI(MBB, I, DL, MovDesc, TmpReg).addReg(SrcReg, KillSrc);
BuildMI(MBB, I, DL, CvtDesc, DstReg).addReg(TmpReg, RegState::Kill);
@ -428,7 +427,7 @@ void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB,
DebugLoc dl = I->getDebugLoc();
assert(N < 2 && "Invalid immediate");
unsigned SubIdx = N ? Mips::sub_fpodd : Mips::sub_fpeven;
unsigned SubIdx = N ? Mips::sub_hi : Mips::sub_lo;
unsigned SubReg = getRegisterInfo().getSubReg(SrcReg, SubIdx);
BuildMI(MBB, I, dl, Mfc1Tdd, DstReg).addReg(SubReg);
@ -444,9 +443,9 @@ void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB,
// mtc1 Lo, $fp
// mtc1 Hi, $fp + 1
BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_fpeven))
BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_lo))
.addReg(LoReg);
BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_fpodd))
BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_hi))
.addReg(HiReg);
}
@ -482,8 +481,8 @@ void MipsSEInstrInfo::expandDPLoadStore(MachineBasicBlock &MBB,
const TargetRegisterInfo &TRI = getRegisterInfo();
const MachineOperand &ValReg = I->getOperand(0);
unsigned LoReg = TRI.getSubReg(ValReg.getReg(), Mips::sub_fpeven);
unsigned HiReg = TRI.getSubReg(ValReg.getReg(), Mips::sub_fpodd);
unsigned LoReg = TRI.getSubReg(ValReg.getReg(), Mips::sub_lo);
unsigned HiReg = TRI.getSubReg(ValReg.getReg(), Mips::sub_hi);
if (!TM.getSubtarget<MipsSubtarget>().isLittle())
std::swap(LoReg, HiReg);