summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp5
-rw-r--r--llvm/lib/Target/Mips/MicroMipsInstrInfo.td26
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterInfo.cpp20
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterInfo.h12
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterInfo.td7
-rw-r--r--llvm/test/CodeGen/Mips/micromips-addiu.ll2
6 files changed, 58 insertions, 14 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index bff46886dc7..02922bccccf 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -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() &&
diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
index d552109b75a..35f5138701c 100644
--- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
@@ -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>;
diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
index 452400e5684..6981dd91cb8 100644
--- a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
@@ -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
diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.h b/llvm/lib/Target/Mips/MipsRegisterInfo.h
index 286fe8e3255..32f835e8310 100644
--- a/llvm/lib/Target/Mips/MipsRegisterInfo.h
+++ b/llvm/lib/Target/Mips/MipsRegisterInfo.h
@@ -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
diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td
index 939debcd956..cfce7c8e653 100644
--- a/llvm/lib/Target/Mips/MipsRegisterInfo.td
+++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td
@@ -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;
diff --git a/llvm/test/CodeGen/Mips/micromips-addiu.ll b/llvm/test/CodeGen/Mips/micromips-addiu.ll
index e0743c9c088..84ebc4349e1 100644
--- a/llvm/test/CodeGen/Mips/micromips-addiu.ll
+++ b/llvm/test/CodeGen/Mips/micromips-addiu.ll
@@ -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
OpenPOWER on IntegriCloud