1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[mips][micromips] Make getPointerRegClass() result depend on the instruction.

Summary:
Previously, it returned the GPR16MMRegClass for all instructions which was
incorrect for instructions like lwsp/lwgp and unnecesarily restricted the
permitted registers for instructions like lw32.

This fixes quite a few of the -verify-machineinstrs errors reported in PR27458.
I've only added -verify-machineinstrs to one test in this change since I
understand there is a plan to enable the verifier by default.

Reviewers: hvarga, zbuljan, zoran.jovanovic, sdardis

Subscribers: dsanders, llvm-commits, sdardis

Differential Revision: http://reviews.llvm.org/D19873

llvm-svn: 268918
This commit is contained in:
Daniel Sanders 2016-05-09 13:38:25 +00:00
parent af070e4f0c
commit 76aeb9f378
6 changed files with 58 additions and 14 deletions

View File

@ -1092,6 +1092,11 @@ public:
&& (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
&& (getMemBase()->getGPR32Reg() == Mips::SP);
}
template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
&& (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
&& (getMemBase()->getGPR32Reg() == Mips::GP);
}
template <unsigned Bits, unsigned ShiftLeftAmount>
bool isScaledUImm() const {
return isConstantImm() &&

View File

@ -47,9 +47,15 @@ def MicroMipsMemGPRMM16AsmOperand : AsmOperandClass {
let PredicateMethod = "isMemWithGRPMM16Base";
}
// Define the classes of pointers used by microMIPS.
// The numbers must match those in MipsRegisterInfo::MipsPtrClass.
def ptr_gpr16mm_rc : PointerLikeRegClass<1>;
def ptr_sp_rc : PointerLikeRegClass<2>;
def ptr_gp_rc : PointerLikeRegClass<3>;
class mem_mm_4_generic : Operand<i32> {
let PrintMethod = "printMemOperand";
let MIOperandInfo = (ops ptr_rc, simm4);
let MIOperandInfo = (ops ptr_gpr16mm_rc, simm4);
let OperandType = "OPERAND_MEMORY";
let ParserMatchClass = MicroMipsMemGPRMM16AsmOperand;
}
@ -73,18 +79,26 @@ def MicroMipsMemSPAsmOperand : AsmOperandClass {
let PredicateMethod = "isMemWithUimmWordAlignedOffsetSP<7>";
}
def MicroMipsMemGPAsmOperand : AsmOperandClass {
let Name = "MicroMipsMemGP";
let RenderMethod = "addMemOperands";
let ParserMethod = "parseMemOperand";
let PredicateMethod = "isMemWithSimmWordAlignedOffsetGP<9>";
}
def mem_mm_sp_imm5_lsl2 : Operand<i32> {
let PrintMethod = "printMemOperand";
let MIOperandInfo = (ops ptr_rc:$base, simm5:$offset);
let MIOperandInfo = (ops ptr_sp_rc:$base, simm5:$offset);
let OperandType = "OPERAND_MEMORY";
let ParserMatchClass = MicroMipsMemSPAsmOperand;
let EncoderMethod = "getMemEncodingMMSPImm5Lsl2";
}
def mem_mm_gp_imm7_lsl2 : Operand<i32> {
def mem_mm_gp_simm7_lsl2 : Operand<i32> {
let PrintMethod = "printMemOperand";
let MIOperandInfo = (ops GPRMM16:$base, simm7_lsl2:$offset);
let MIOperandInfo = (ops ptr_gp_rc:$base, simm7_lsl2:$offset);
let OperandType = "OPERAND_MEMORY";
let ParserMatchClass = MicroMipsMemGPAsmOperand;
let EncoderMethod = "getMemEncodingMMGPImm7Lsl2";
}
@ -122,7 +136,7 @@ def MipsMemUimm4AsmOperand : AsmOperandClass {
def mem_mm_4sp : Operand<i32> {
let PrintMethod = "printMemOperand";
let MIOperandInfo = (ops ptr_rc, uimm8);
let MIOperandInfo = (ops ptr_sp_rc, uimm8);
let EncoderMethod = "getMemEncodingMMImm4sp";
let ParserMatchClass = MipsMemUimm4AsmOperand;
let OperandType = "OPERAND_MEMORY";
@ -618,7 +632,7 @@ def SH16_MM : StoreMM16<"sh16", GPRMM16OpndZero, GPRMM16Opnd, truncstorei16,
LOAD_STORE_FM_MM16<0x2a>;
def SW16_MM : StoreMM16<"sw16", GPRMM16OpndZero, GPRMM16Opnd, store, II_SW,
mem_mm_4_lsl2>, LOAD_STORE_FM_MM16<0x3a>;
def LWGP_MM : LoadGPMM16<"lw", GPRMM16Opnd, II_LW, mem_mm_gp_imm7_lsl2>,
def LWGP_MM : LoadGPMM16<"lw", GPRMM16Opnd, II_LW, mem_mm_gp_simm7_lsl2>,
LOAD_GP_FM_MM16<0x19>;
def LWSP_MM : LoadSPMM16<"lw", GPR32Opnd, II_LW, mem_mm_sp_imm5_lsl2>,
LOAD_STORE_SP_FM_MM16<0x12>;

View File

@ -50,13 +50,19 @@ const TargetRegisterClass *
MipsRegisterInfo::getPointerRegClass(const MachineFunction &MF,
unsigned Kind) const {
MipsABIInfo ABI = MF.getSubtarget<MipsSubtarget>().getABI();
bool inMicroMips = MF.getSubtarget<MipsSubtarget>().inMicroMipsMode();
return ABI.ArePtrs64bit() ?
inMicroMips ?
&Mips::GPRMM16_64RegClass : &Mips::GPR64RegClass
: inMicroMips ?
&Mips::GPRMM16RegClass : &Mips::GPR32RegClass;
MipsPtrClass PtrClassKind = static_cast<MipsPtrClass>(Kind);
switch (PtrClassKind) {
case MipsPtrClass::Default:
return ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
case MipsPtrClass::GPR16MM:
return ABI.ArePtrs64bit() ? &Mips::GPRMM16_64RegClass
: &Mips::GPRMM16RegClass;
case MipsPtrClass::StackPointer:
return ABI.ArePtrs64bit() ? &Mips::SP64RegClass : &Mips::SP32RegClass;
case MipsPtrClass::GlobalPointer:
return ABI.ArePtrs64bit() ? &Mips::GP64RegClass : &Mips::GP32RegClass;
}
}
unsigned

View File

@ -23,6 +23,18 @@
namespace llvm {
class MipsRegisterInfo : public MipsGenRegisterInfo {
public:
enum class MipsPtrClass {
/// The default register class for integer values.
Default = 0,
/// The subset of registers permitted in certain microMIPS instructions
/// such as lw16.
GPR16MM = 1,
/// The stack pointer only.
StackPointer = 2,
/// The global pointer only.
GlobalPointer = 3,
};
MipsRegisterInfo();
/// Get PIC indirect call register

View File

@ -453,6 +453,13 @@ def COP2 : RegisterClass<"Mips", [i32], 32, (sequence "COP2%u", 0, 31)>,
def COP3 : RegisterClass<"Mips", [i32], 32, (sequence "COP3%u", 0, 31)>,
Unallocatable;
// Stack pointer and global pointer classes for instructions that are limited
// to a single register such as lwgp/lwsp in microMIPS.
def SP32 : RegisterClass<"Mips", [i32], 32, (add SP)>, Unallocatable;
def SP64 : RegisterClass<"Mips", [i64], 64, (add SP_64)>, Unallocatable;
def GP32 : RegisterClass<"Mips", [i32], 32, (add GP)>, Unallocatable;
def GP64 : RegisterClass<"Mips", [i64], 64, (add GP_64)>, Unallocatable;
// Octeon multiplier and product registers
def OCTEON_MPL : RegisterClass<"Mips", [i64], 64, (add MPL0, MPL1, MPL2)>,
Unallocatable;

View File

@ -1,4 +1,4 @@
; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+micromips \
; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+micromips -verify-machineinstrs \
; RUN: -relocation-model=pic -O3 < %s | FileCheck %s
@x = global i32 65504, align 4