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:
parent
af070e4f0c
commit
76aeb9f378
@ -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() &&
|
||||
|
@ -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>;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user