Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 43d2886

Browse files
committed
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268918 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 0c06716 commit 43d2886

File tree

6 files changed

+58
-14
lines changed

6 files changed

+58
-14
lines changed

lib/Target/Mips/AsmParser/MipsAsmParser.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,11 @@ class MipsOperand : public MCParsedAsmOperand {
10921092
&& (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
10931093
&& (getMemBase()->getGPR32Reg() == Mips::SP);
10941094
}
1095+
template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1096+
return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1097+
&& (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1098+
&& (getMemBase()->getGPR32Reg() == Mips::GP);
1099+
}
10951100
template <unsigned Bits, unsigned ShiftLeftAmount>
10961101
bool isScaledUImm() const {
10971102
return isConstantImm() &&

lib/Target/Mips/MicroMipsInstrInfo.td

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,15 @@ def MicroMipsMemGPRMM16AsmOperand : AsmOperandClass {
4747
let PredicateMethod = "isMemWithGRPMM16Base";
4848
}
4949

50+
// Define the classes of pointers used by microMIPS.
51+
// The numbers must match those in MipsRegisterInfo::MipsPtrClass.
52+
def ptr_gpr16mm_rc : PointerLikeRegClass<1>;
53+
def ptr_sp_rc : PointerLikeRegClass<2>;
54+
def ptr_gp_rc : PointerLikeRegClass<3>;
55+
5056
class mem_mm_4_generic : Operand<i32> {
5157
let PrintMethod = "printMemOperand";
52-
let MIOperandInfo = (ops ptr_rc, simm4);
58+
let MIOperandInfo = (ops ptr_gpr16mm_rc, simm4);
5359
let OperandType = "OPERAND_MEMORY";
5460
let ParserMatchClass = MicroMipsMemGPRMM16AsmOperand;
5561
}
@@ -73,18 +79,26 @@ def MicroMipsMemSPAsmOperand : AsmOperandClass {
7379
let PredicateMethod = "isMemWithUimmWordAlignedOffsetSP<7>";
7480
}
7581

82+
def MicroMipsMemGPAsmOperand : AsmOperandClass {
83+
let Name = "MicroMipsMemGP";
84+
let RenderMethod = "addMemOperands";
85+
let ParserMethod = "parseMemOperand";
86+
let PredicateMethod = "isMemWithSimmWordAlignedOffsetGP<9>";
87+
}
88+
7689
def mem_mm_sp_imm5_lsl2 : Operand<i32> {
7790
let PrintMethod = "printMemOperand";
78-
let MIOperandInfo = (ops ptr_rc:$base, simm5:$offset);
91+
let MIOperandInfo = (ops ptr_sp_rc:$base, simm5:$offset);
7992
let OperandType = "OPERAND_MEMORY";
8093
let ParserMatchClass = MicroMipsMemSPAsmOperand;
8194
let EncoderMethod = "getMemEncodingMMSPImm5Lsl2";
8295
}
8396

84-
def mem_mm_gp_imm7_lsl2 : Operand<i32> {
97+
def mem_mm_gp_simm7_lsl2 : Operand<i32> {
8598
let PrintMethod = "printMemOperand";
86-
let MIOperandInfo = (ops GPRMM16:$base, simm7_lsl2:$offset);
99+
let MIOperandInfo = (ops ptr_gp_rc:$base, simm7_lsl2:$offset);
87100
let OperandType = "OPERAND_MEMORY";
101+
let ParserMatchClass = MicroMipsMemGPAsmOperand;
88102
let EncoderMethod = "getMemEncodingMMGPImm7Lsl2";
89103
}
90104

@@ -122,7 +136,7 @@ def MipsMemUimm4AsmOperand : AsmOperandClass {
122136

123137
def mem_mm_4sp : Operand<i32> {
124138
let PrintMethod = "printMemOperand";
125-
let MIOperandInfo = (ops ptr_rc, uimm8);
139+
let MIOperandInfo = (ops ptr_sp_rc, uimm8);
126140
let EncoderMethod = "getMemEncodingMMImm4sp";
127141
let ParserMatchClass = MipsMemUimm4AsmOperand;
128142
let OperandType = "OPERAND_MEMORY";
@@ -618,7 +632,7 @@ def SH16_MM : StoreMM16<"sh16", GPRMM16OpndZero, GPRMM16Opnd, truncstorei16,
618632
LOAD_STORE_FM_MM16<0x2a>;
619633
def SW16_MM : StoreMM16<"sw16", GPRMM16OpndZero, GPRMM16Opnd, store, II_SW,
620634
mem_mm_4_lsl2>, LOAD_STORE_FM_MM16<0x3a>;
621-
def LWGP_MM : LoadGPMM16<"lw", GPRMM16Opnd, II_LW, mem_mm_gp_imm7_lsl2>,
635+
def LWGP_MM : LoadGPMM16<"lw", GPRMM16Opnd, II_LW, mem_mm_gp_simm7_lsl2>,
622636
LOAD_GP_FM_MM16<0x19>;
623637
def LWSP_MM : LoadSPMM16<"lw", GPR32Opnd, II_LW, mem_mm_sp_imm5_lsl2>,
624638
LOAD_STORE_SP_FM_MM16<0x12>;

lib/Target/Mips/MipsRegisterInfo.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,19 @@ const TargetRegisterClass *
5050
MipsRegisterInfo::getPointerRegClass(const MachineFunction &MF,
5151
unsigned Kind) const {
5252
MipsABIInfo ABI = MF.getSubtarget<MipsSubtarget>().getABI();
53-
bool inMicroMips = MF.getSubtarget<MipsSubtarget>().inMicroMipsMode();
54-
55-
return ABI.ArePtrs64bit() ?
56-
inMicroMips ?
57-
&Mips::GPRMM16_64RegClass : &Mips::GPR64RegClass
58-
: inMicroMips ?
59-
&Mips::GPRMM16RegClass : &Mips::GPR32RegClass;
53+
MipsPtrClass PtrClassKind = static_cast<MipsPtrClass>(Kind);
54+
55+
switch (PtrClassKind) {
56+
case MipsPtrClass::Default:
57+
return ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
58+
case MipsPtrClass::GPR16MM:
59+
return ABI.ArePtrs64bit() ? &Mips::GPRMM16_64RegClass
60+
: &Mips::GPRMM16RegClass;
61+
case MipsPtrClass::StackPointer:
62+
return ABI.ArePtrs64bit() ? &Mips::SP64RegClass : &Mips::SP32RegClass;
63+
case MipsPtrClass::GlobalPointer:
64+
return ABI.ArePtrs64bit() ? &Mips::GP64RegClass : &Mips::GP32RegClass;
65+
}
6066
}
6167

6268
unsigned

lib/Target/Mips/MipsRegisterInfo.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@
2323
namespace llvm {
2424
class MipsRegisterInfo : public MipsGenRegisterInfo {
2525
public:
26+
enum class MipsPtrClass {
27+
/// The default register class for integer values.
28+
Default = 0,
29+
/// The subset of registers permitted in certain microMIPS instructions
30+
/// such as lw16.
31+
GPR16MM = 1,
32+
/// The stack pointer only.
33+
StackPointer = 2,
34+
/// The global pointer only.
35+
GlobalPointer = 3,
36+
};
37+
2638
MipsRegisterInfo();
2739

2840
/// Get PIC indirect call register

lib/Target/Mips/MipsRegisterInfo.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,13 @@ def COP2 : RegisterClass<"Mips", [i32], 32, (sequence "COP2%u", 0, 31)>,
453453
def COP3 : RegisterClass<"Mips", [i32], 32, (sequence "COP3%u", 0, 31)>,
454454
Unallocatable;
455455

456+
// Stack pointer and global pointer classes for instructions that are limited
457+
// to a single register such as lwgp/lwsp in microMIPS.
458+
def SP32 : RegisterClass<"Mips", [i32], 32, (add SP)>, Unallocatable;
459+
def SP64 : RegisterClass<"Mips", [i64], 64, (add SP_64)>, Unallocatable;
460+
def GP32 : RegisterClass<"Mips", [i32], 32, (add GP)>, Unallocatable;
461+
def GP64 : RegisterClass<"Mips", [i64], 64, (add GP_64)>, Unallocatable;
462+
456463
// Octeon multiplier and product registers
457464
def OCTEON_MPL : RegisterClass<"Mips", [i64], 64, (add MPL0, MPL1, MPL2)>,
458465
Unallocatable;

test/CodeGen/Mips/micromips-addiu.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+micromips \
1+
; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+micromips -verify-machineinstrs \
22
; RUN: -relocation-model=pic -O3 < %s | FileCheck %s
33

44
@x = global i32 65504, align 4

0 commit comments

Comments
 (0)