diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 43 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h | 3 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td | 32 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td | 75 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MicroMipsInstrFPU.td | 31 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MicroMipsInstrInfo.td | 18 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 12 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsISelDAGToDAG.h | 8 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsInstrFPU.td | 60 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.td | 19 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 26 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h | 13 |
15 files changed, 324 insertions, 58 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 53a3cf08a38..b51d0200b0b 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1063,10 +1063,17 @@ public: // and determine whether a Value is a constant or not. template <unsigned Bits, unsigned ShiftAmount = 0> bool isMemWithSimmOffset() const { - return isMem() && getMemBase()->isGPRAsmReg() && - (isa<MCTargetExpr>(getMemOff()) || - (isConstantMemOff() && - isShiftedInt<Bits, ShiftAmount>(getConstantMemOff()))); + if (!isMem()) + return false; + if (!getMemBase()->isGPRAsmReg()) + return false; + if (isa<MCTargetExpr>(getMemOff()) || + (isConstantMemOff() && + isShiftedInt<Bits, ShiftAmount>(getConstantMemOff()))) + return true; + MCValue Res; + bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); + return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant()); } bool isMemWithGRPMM16Base() const { return isMem() && getMemBase()->isMM16AsmReg(); diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 9124d87286d..aebb4ef419d 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -354,6 +354,10 @@ static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); @@ -366,6 +370,10 @@ static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1704,6 +1712,24 @@ static DecodeStatus DecodeFMem(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + // This function is the same as DecodeFMem but with the Reg and Base fields + // swapped according to microMIPS spec. + int Offset = SignExtend32<16>(Insn & 0xffff); + unsigned Base = fieldFromInstruction(Insn, 16, 5); + unsigned Reg = fieldFromInstruction(Insn, 21, 5); + + Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + + Inst.addOperand(MCOperand::createReg(Reg)); + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); + + return MCDisassembler::Success; +} + static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1757,6 +1783,23 @@ static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, return MCDisassembler::Success; } + +static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + int Offset = SignExtend32<11>(Insn & 0x07ff); + unsigned Reg = fieldFromInstruction(Insn, 21, 5); + unsigned Base = fieldFromInstruction(Insn, 16, 5); + + Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); + Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + + Inst.addOperand(MCOperand::createReg(Reg)); + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); + + return MCDisassembler::Success; +} + static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, unsigned Insn, uint64_t Address, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 61b53788bf3..401c7d42c4c 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -878,6 +878,19 @@ getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, } unsigned MipsMCCodeEmitter:: +getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + // Base register is encoded in bits 20-16, offset is encoded in bits 10-0. + assert(MI.getOperand(OpNo).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, + STI) << 16; + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); + + return (OffBits & 0x07FF) | RegBits; +} + +unsigned MipsMCCodeEmitter:: getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 6bc9a1b1c28..0f4dfe1200c 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -204,6 +204,9 @@ public: unsigned getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; + unsigned getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; unsigned getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td b/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td index c229fe68ddc..2f0933277e8 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -1060,3 +1060,35 @@ class POOL32I_BRANCH_COP_1_2_FM_MMR6<string instr_asm, bits<5> funct> let Inst{20-16} = rt; let Inst{15-0} = offset; } + +class LDWC1_SDWC1_FM_MMR6<string instr_asm, bits<6> funct> + : MMR6Arch<instr_asm> { + bits<5> ft; + bits<21> addr; + bits<5> base = addr{20-16}; + bits<16> offset = addr{15-0}; + + bits<32> Inst; + + let Inst{31-26} = funct; + let Inst{25-21} = ft; + let Inst{20-16} = base; + let Inst{15-0} = offset; +} + +class POOL32B_LDWC2_SDWC2_FM_MMR6<string instr_asm, bits<4> funct> + : MMR6Arch<instr_asm>, MipsR6Inst { + bits<5> rt; + bits<21> addr; + bits<5> base = addr{20-16}; + bits<11> offset = addr{10-0}; + + bits<32> Inst; + + let Inst{31-26} = 0b001000; + let Inst{25-21} = rt; + let Inst{20-16} = base; + let Inst{15-12} = funct; + let Inst{11} = 0; + let Inst{10-0} = offset; +} diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td index 04852dacd65..2b636cfe3bf 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -223,6 +223,12 @@ class BC1EQZC_MMR6_ENC : POOL32I_BRANCH_COP_1_2_FM_MMR6<"bc1eqzc", 0b01000>; class BC1NEZC_MMR6_ENC : POOL32I_BRANCH_COP_1_2_FM_MMR6<"bc1nezc", 0b01001>; class BC2EQZC_MMR6_ENC : POOL32I_BRANCH_COP_1_2_FM_MMR6<"bc2eqzc", 0b01010>; class BC2NEZC_MMR6_ENC : POOL32I_BRANCH_COP_1_2_FM_MMR6<"bc2nezc", 0b01011>; +class LDC1_MMR6_ENC : LDWC1_SDWC1_FM_MMR6<"ldc1", 0b101111>; +class SDC1_MMR6_ENC : LDWC1_SDWC1_FM_MMR6<"sdc1", 0b101110>; +class LDC2_MMR6_ENC : POOL32B_LDWC2_SDWC2_FM_MMR6<"ldc2", 0b0010>; +class SDC2_MMR6_ENC : POOL32B_LDWC2_SDWC2_FM_MMR6<"sdc2", 0b1010>; +class LWC2_MMR6_ENC : POOL32B_LDWC2_SDWC2_FM_MMR6<"lwc2", 0b0000>; +class SWC2_MMR6_ENC : POOL32B_LDWC2_SDWC2_FM_MMR6<"swc2", 0b1000>; class CMP_CBR_RT_Z_MMR6_DESC_BASE<string instr_asm, DAGOperand opnd, RegisterOperand GPROpnd> @@ -756,6 +762,58 @@ class MFHC1_D64_MMR6_DESC : MFC1_MMR6_DESC_BASE<"mfhc1", GPR32Opnd, FGR64Opnd, II_MFHC1>, HARDFLOAT, FGR_64; class MFHC2_MMR6_DESC : MFC2_MMR6_DESC_BASE<"mfhc2", GPR32Opnd, COP2Opnd>; +class LDC1_D64_MMR6_DESC : MipsR6Inst, HARDFLOAT, FGR_64 { + dag InOperandList = (ins mem_mm_16:$addr); + dag OutOperandList = (outs FGR64Opnd:$ft); + string AsmString = !strconcat("ldc1", "\t$ft, $addr"); + list<dag> Pattern = [(set FGR64Opnd:$ft, (load addrimm16:$addr))]; + Format f = FrmFI; + InstrItinClass Itinerary = II_LDC1; + string BaseOpcode = "ldc1"; + bit mayLoad = 1; + let DecoderMethod = "DecodeFMemMMR2"; +} + +class SDC1_D64_MMR6_DESC : MipsR6Inst, HARDFLOAT, FGR_64 { + dag InOperandList = (ins FGR64Opnd:$ft, mem_mm_16:$addr); + dag OutOperandList = (outs); + string AsmString = !strconcat("sdc1", "\t$ft, $addr"); + list<dag> Pattern = [(store FGR64Opnd:$ft, addrimm16:$addr)]; + Format f = FrmFI; + InstrItinClass Itinerary = II_SDC1; + string BaseOpcode = "sdc1"; + bit mayStore = 1; + let DecoderMethod = "DecodeFMemMMR2"; +} + +class LDC2_LWC2_MMR6_DESC_BASE<string opstr> { + dag OutOperandList = (outs COP2Opnd:$rt); + dag InOperandList = (ins mem_mm_11:$addr); + string AsmString = !strconcat(opstr, "\t$rt, $addr"); + list<dag> Pattern = [(set COP2Opnd:$rt, (load addrimm11:$addr))]; + Format f = FrmFI; + InstrItinClass Itinerary = NoItinerary; + string BaseOpcode = opstr; + bit mayLoad = 1; + string DecoderMethod = "DecodeFMemCop2MMR6"; +} +class LDC2_MMR6_DESC : LDC2_LWC2_MMR6_DESC_BASE<"ldc2">; +class LWC2_MMR6_DESC : LDC2_LWC2_MMR6_DESC_BASE<"lwc2">; + +class SDC2_SWC2_MMR6_DESC_BASE<string opstr> { + dag OutOperandList = (outs); + dag InOperandList = (ins COP2Opnd:$rt, mem_mm_11:$addr); + string AsmString = !strconcat(opstr, "\t$rt, $addr"); + list<dag> Pattern = [(store COP2Opnd:$rt, addrimm11:$addr)]; + Format f = FrmFI; + InstrItinClass Itinerary = NoItinerary; + string BaseOpcode = opstr; + bit mayStore = 1; + string DecoderMethod = "DecodeFMemCop2MMR6"; +} +class SDC2_MMR6_DESC : SDC2_SWC2_MMR6_DESC_BASE<"sdc2">; +class SWC2_MMR6_DESC : SDC2_SWC2_MMR6_DESC_BASE<"swc2">; + /// Floating Point Instructions class FARITH_MMR6_DESC_BASE<string instr_asm, RegisterOperand RC, InstrItinClass Itin, bit isComm, @@ -1577,6 +1635,18 @@ def BC2EQZC_MMR6 : R6MMR6Rel, MipsR6Inst, BC2EQZC_MMR6_ENC, BC2EQZC_MMR6_DESC, ISA_MICROMIPS32R6; def BC2NEZC_MMR6 : R6MMR6Rel, MipsR6Inst, BC2NEZC_MMR6_ENC, BC2NEZC_MMR6_DESC, ISA_MICROMIPS32R6; +let DecoderNamespace = "MicroMips32r6FP64" in { + def LDC1_D64_MMR6 : StdMMR6Rel, LDC1_D64_MMR6_DESC, LDC1_MMR6_ENC, + ISA_MICROMIPS32R6 { + let BaseOpcode = "LDC164"; + } + def SDC1_D64_MMR6 : StdMMR6Rel, SDC1_D64_MMR6_DESC, SDC1_MMR6_ENC, + ISA_MICROMIPS32R6; +} +def LDC2_MMR6 : StdMMR6Rel, LDC2_MMR6_ENC, LDC2_MMR6_DESC, ISA_MICROMIPS32R6; +def SDC2_MMR6 : StdMMR6Rel, SDC2_MMR6_ENC, SDC2_MMR6_DESC, ISA_MICROMIPS32R6; +def LWC2_MMR6 : StdMMR6Rel, LWC2_MMR6_ENC, LWC2_MMR6_DESC, ISA_MICROMIPS32R6; +def SWC2_MMR6 : StdMMR6Rel, SWC2_MMR6_ENC, SWC2_MMR6_DESC, ISA_MICROMIPS32R6; } def BOVC_MMR6 : R6MMR6Rel, BOVC_MMR6_ENC, BOVC_MMR6_DESC, ISA_MICROMIPS32R6, @@ -1697,3 +1767,8 @@ def : MipsPat<(not GPRMM16:$in), (NOT16_MMR6 GPRMM16:$in)>, ISA_MICROMIPS32R6; def : MipsPat<(not GPR32:$in), (NOR_MMR6 GPR32Opnd:$in, ZERO)>, ISA_MICROMIPS32R6; +// Patterns for load with a reg+imm operand. +let AddedComplexity = 41 in { + def : LoadRegImmPat<LDC1_D64_MMR6, f64, load>, FGR_64, ISA_MICROMIPS32R6; + def : StoreRegImmPat<SDC1_D64_MMR6, f64>, FGR_64, ISA_MICROMIPS32R6; +} diff --git a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td index 3208f2b9f89..7b0e00bd1c3 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td @@ -17,12 +17,6 @@ def FMUL_MM : MMRel, ADDS_FT<"mul.d", AFGR64Opnd, II_MUL_D, 1, fmul>, def FSUB_MM : MMRel, ADDS_FT<"sub.d", AFGR64Opnd, II_SUB_D, 0, fsub>, ADDS_FM_MM<1, 0x70>; -def LWC1_MM : MMRel, LW_FT<"lwc1", FGR32Opnd, II_LWC1, load>, LW_FM_MM<0x27>; -def SWC1_MM : MMRel, SW_FT<"swc1", FGR32Opnd, II_SWC1, store>, - LW_FM_MM<0x26>; -def LDC1_MM : MMRel, LW_FT<"ldc1", AFGR64Opnd, II_LDC1, load>, LW_FM_MM<0x2f>; -def SDC1_MM : MMRel, SW_FT<"sdc1", AFGR64Opnd, II_SDC1, store>, - LW_FM_MM<0x2e>; def LWXC1_MM : MMRel, LWXC1_FT<"lwxc1", FGR32Opnd, II_LWXC1, load>, LWXC1_FM_MM<0x48>, INSN_MIPS4_32R2_NOT_32R6_64R6; def SWXC1_MM : MMRel, SWXC1_FT<"swxc1", FGR32Opnd, II_SWXC1, store>, @@ -147,4 +141,29 @@ let AdditionalPredicates = [InMicroMips] in { MFC1_FM_MM<0xe0>, ISA_MIPS32R2, FGR_32; def MFHC1_MM : MMRel, MFC1_FT<"mfhc1", GPR32Opnd, AFGR64Opnd, II_MFHC1>, MFC1_FM_MM<0xc0>, ISA_MIPS32R2, FGR_32; + let DecoderNamespace = "MicroMips", DecoderMethod = "DecodeFMemMMR2" in { + def LDC1_MM : MMRel, LW_FT<"ldc1", AFGR64Opnd, mem_mm_16, II_LDC1, load>, + LW_FM_MM<0x2f>, FGR_32 { + let BaseOpcode = "LDC132"; + } + def SDC1_MM : MMRel, SW_FT<"sdc1", AFGR64Opnd, mem_mm_16, II_SDC1, store>, + LW_FM_MM<0x2e>, FGR_32; + def LWC1_MM : MMRel, LW_FT<"lwc1", FGR32Opnd, mem_mm_16, II_LWC1, load>, + LW_FM_MM<0x27>; + def SWC1_MM : MMRel, SW_FT<"swc1", FGR32Opnd, mem_mm_16, II_SWC1, store>, + LW_FM_MM<0x26>; + } +} + +//===----------------------------------------------------------------------===// +// Floating Point Patterns +//===----------------------------------------------------------------------===// +let AdditionalPredicates = [InMicroMips] in { + // Patterns for loads/stores with a reg+imm operand. + let AddedComplexity = 40 in { + def : LoadRegImmPat<LDC1_MM, f64, load>, FGR_32; + def : StoreRegImmPat<SDC1_MM, f64>, FGR_32; + def : LoadRegImmPat<LWC1_MM, f32, load>; + def : StoreRegImmPat<SWC1_MM, f32>; + } } diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td index 00ca54a8cc1..f27370f57fa 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td @@ -1,4 +1,6 @@ -def addrimm12 : ComplexPattern<iPTR, 2, "selectIntAddrMM", [frameindex]>; +def addrimm11 : ComplexPattern<iPTR, 2, "selectIntAddr11MM", [frameindex]>; +def addrimm12 : ComplexPattern<iPTR, 2, "selectIntAddr12MM", [frameindex]>; +def addrimm16 : ComplexPattern<iPTR, 2, "selectIntAddr16MM", [frameindex]>; def addrimm4lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrLSL2MM", [frameindex]>; def simm9_addiusp : Operand<i32> { @@ -106,6 +108,14 @@ def mem_mm_9 : Operand<i32> { let OperandType = "OPERAND_MEMORY"; } +def mem_mm_11 : Operand<i32> { + let PrintMethod = "printMemOperand"; + let MIOperandInfo = (ops GPR32, simm11); + let EncoderMethod = "getMemEncodingMMImm11"; + let ParserMatchClass = MipsMemSimm11AsmOperand; + let OperandType = "OPERAND_MEMORY"; +} + def mem_mm_12 : Operand<i32> { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops ptr_rc, simm12); @@ -118,7 +128,7 @@ def mem_mm_16 : Operand<i32> { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops ptr_rc, simm16); let EncoderMethod = "getMemEncodingMMImm16"; - let ParserMatchClass = MipsMemAsmOperand; + let ParserMatchClass = MipsMemSimm16AsmOperand; let OperandType = "OPERAND_MEMORY"; } @@ -740,8 +750,8 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { /// Load and Store Instructions - aligned let DecoderMethod = "DecodeMemMMImm16" in { - def LB_MM : Load<"lb", GPR32Opnd>, MMRel, LW_FM_MM<0x7>; - def LBu_MM : Load<"lbu", GPR32Opnd>, MMRel, LW_FM_MM<0x5>; + def LB_MM : LoadMemory<"lb", GPR32Opnd, mem_mm_16>, MMRel, LW_FM_MM<0x7>; + def LBu_MM : LoadMemory<"lbu", GPR32Opnd, mem_mm_16>, MMRel, LW_FM_MM<0x5>; def LH_MM : LoadMemory<"lh", GPR32Opnd, mem_simm16, sextloadi16, II_LH, addrDefault>, MMRel, LW_FM_MM<0xf>; def LHu_MM : LoadMemory<"lhu", GPR32Opnd, mem_simm16, zextloadi16, II_LHU>, diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td index cee169e6c5e..f552f8d37af 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td @@ -793,12 +793,14 @@ let AdditionalPredicates = [NotInMicroMips] in { def JIALC : R6MMR6Rel, JIALC_ENC, JIALC_DESC, ISA_MIPS32R6; def JIC : R6MMR6Rel, JIC_ENC, JIC_DESC, ISA_MIPS32R6; def JR_HB_R6 : JR_HB_R6_ENC, JR_HB_R6_DESC, ISA_MIPS32R6; -def LDC2_R6 : LDC2_R6_ENC, LDC2_R6_DESC, ISA_MIPS32R6; let AdditionalPredicates = [NotInMicroMips] in { + def LDC2_R6 : LDC2_R6_ENC, LDC2_R6_DESC, ISA_MIPS32R6; def LL_R6 : LL_R6_ENC, LL_R6_DESC, PTR_32, ISA_MIPS32R6; } def LSA_R6 : R6MMR6Rel, LSA_R6_ENC, LSA_R6_DESC, ISA_MIPS32R6; -def LWC2_R6 : LWC2_R6_ENC, LWC2_R6_DESC, ISA_MIPS32R6; +let AdditionalPredicates = [NotInMicroMips] in { + def LWC2_R6 : LWC2_R6_ENC, LWC2_R6_DESC, ISA_MIPS32R6; +} def LWPC : R6MMR6Rel, LWPC_ENC, LWPC_DESC, ISA_MIPS32R6; def LWUPC : LWUPC_ENC, LWUPC_DESC, ISA_MIPS32R6; let AdditionalPredicates = [NotInMicroMips] in { @@ -831,9 +833,6 @@ let AdditionalPredicates = [NotInMicroMips] in { def RINT_S : RINT_S_ENC, RINT_S_DESC, ISA_MIPS32R6, HARDFLOAT; def SC_R6 : SC_R6_ENC, SC_R6_DESC, PTR_32, ISA_MIPS32R6; def SDBBP_R6 : SDBBP_R6_ENC, SDBBP_R6_DESC, ISA_MIPS32R6; -} -def SDC2_R6 : SDC2_R6_ENC, SDC2_R6_DESC, ISA_MIPS32R6; -let AdditionalPredicates = [NotInMicroMips] in { def SELEQZ : R6MMR6Rel, SELEQZ_ENC, SELEQZ_DESC, ISA_MIPS32R6, GPR_32; def SELNEZ : R6MMR6Rel, SELNEZ_ENC, SELNEZ_DESC, ISA_MIPS32R6, GPR_32; def SELEQZ_D : R6MMR6Rel, SELEQZ_D_ENC, SELEQZ_D_DESC, ISA_MIPS32R6, @@ -846,8 +845,9 @@ let AdditionalPredicates = [NotInMicroMips] in { HARDFLOAT; def SEL_D : R6MMR6Rel, SEL_D_ENC, SEL_D_DESC, ISA_MIPS32R6, HARDFLOAT; def SEL_S : R6MMR6Rel, SEL_S_ENC, SEL_S_DESC, ISA_MIPS32R6, HARDFLOAT; + def SDC2_R6 : SDC2_R6_ENC, SDC2_R6_DESC, ISA_MIPS32R6; + def SWC2_R6 : SWC2_R6_ENC, SWC2_R6_DESC, ISA_MIPS32R6; } -def SWC2_R6 : SWC2_R6_ENC, SWC2_R6_DESC, ISA_MIPS32R6; //===----------------------------------------------------------------------===// // diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp index 9d8feaa5594..83763a64ab6 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -84,7 +84,19 @@ bool MipsDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base, return false; } -bool MipsDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base, +bool MipsDAGToDAGISel::selectIntAddr11MM(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + +bool MipsDAGToDAGISel::selectIntAddr12MM(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + +bool MipsDAGToDAGISel::selectIntAddr16MM(SDValue Addr, SDValue &Base, SDValue &Offset) const { llvm_unreachable("Unimplemented function."); return false; diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h index 2cca7fe26fd..84e09611e16 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h @@ -65,9 +65,15 @@ private: virtual bool selectIntAddr(SDValue Addr, SDValue &Base, SDValue &Offset) const; - virtual bool selectIntAddrMM(SDValue Addr, SDValue &Base, + virtual bool selectIntAddr11MM(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + + virtual bool selectIntAddr12MM(SDValue Addr, SDValue &Base, SDValue &Offset) const; + virtual bool selectIntAddr16MM(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + virtual bool selectIntAddrLSL2MM(SDValue Addr, SDValue &Base, SDValue &Offset) const; diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td index 2639588f059..87b02bdfdfd 100644 --- a/llvm/lib/Target/Mips/MipsInstrFPU.td +++ b/llvm/lib/Target/Mips/MipsInstrFPU.td @@ -160,18 +160,18 @@ class MTC1_64_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC, let Constraints = "$fs = $fs_in"; } -class LW_FT<string opstr, RegisterOperand RC, InstrItinClass Itin, - SDPatternOperator OpNode= null_frag> : - InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"), +class LW_FT<string opstr, RegisterOperand RC, DAGOperand MO, + InstrItinClass Itin, SDPatternOperator OpNode = null_frag> : + InstSE<(outs RC:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr>, HARDFLOAT { let DecoderMethod = "DecodeFMem"; let mayLoad = 1; } -class SW_FT<string opstr, RegisterOperand RC, InstrItinClass Itin, - SDPatternOperator OpNode= null_frag> : - InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), +class SW_FT<string opstr, RegisterOperand RC, DAGOperand MO, + InstrItinClass Itin, SDPatternOperator OpNode = null_frag> : + InstSE<(outs), (ins RC:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr>, HARDFLOAT { let DecoderMethod = "DecodeFMem"; let mayStore = 1; @@ -400,20 +400,30 @@ def FMOV_D64 : ABSS_FT<"mov.d", FGR64Opnd, FGR64Opnd, II_MOV_D>, } /// Floating Point Memory Instructions -def LWC1 : MMRel, LW_FT<"lwc1", FGR32Opnd, II_LWC1, load>, LW_FM<0x31>; -def SWC1 : MMRel, SW_FT<"swc1", FGR32Opnd, II_SWC1, store>, LW_FM<0x39>; +let AdditionalPredicates = [NotInMicroMips] in { + def LWC1 : MMRel, LW_FT<"lwc1", FGR32Opnd, mem_simm16, II_LWC1, load>, + LW_FM<0x31>; + def SWC1 : MMRel, SW_FT<"swc1", FGR32Opnd, mem_simm16, II_SWC1, store>, + LW_FM<0x39>; +} -let DecoderNamespace = "Mips64" in { - def LDC164 : LW_FT<"ldc1", FGR64Opnd, II_LDC1, load>, LW_FM<0x35>, ISA_MIPS2, - FGR_64; - def SDC164 : SW_FT<"sdc1", FGR64Opnd, II_SDC1, store>, LW_FM<0x3d>, ISA_MIPS2, - FGR_64; +let DecoderNamespace = "Mips64", AdditionalPredicates = [NotInMicroMips] in { + def LDC164 : StdMMR6Rel, LW_FT<"ldc1", FGR64Opnd, mem_simm16, II_LDC1, load>, + LW_FM<0x35>, ISA_MIPS2, FGR_64 { + let BaseOpcode = "LDC164"; + } + def SDC164 : StdMMR6Rel, SW_FT<"sdc1", FGR64Opnd, mem_simm16, II_SDC1, store>, + LW_FM<0x3d>, ISA_MIPS2, FGR_64; } -def LDC1 : MMRel, LW_FT<"ldc1", AFGR64Opnd, II_LDC1, load>, LW_FM<0x35>, - ISA_MIPS2, FGR_32; -def SDC1 : MMRel, SW_FT<"sdc1", AFGR64Opnd, II_SDC1, store>, LW_FM<0x3d>, - ISA_MIPS2, FGR_32; +let AdditionalPredicates = [NotInMicroMips] in { + def LDC1 : MMRel, StdMMR6Rel, LW_FT<"ldc1", AFGR64Opnd, mem_simm16, II_LDC1, + load>, LW_FM<0x35>, ISA_MIPS2, FGR_32 { + let BaseOpcode = "LDC132"; + } + def SDC1 : MMRel, SW_FT<"sdc1", AFGR64Opnd, mem_simm16, II_SDC1, store>, + LW_FM<0x3d>, ISA_MIPS2, FGR_32; +} // Indexed loads and stores. // Base register + offset register addressing mode (indicated by "x" in the @@ -632,13 +642,15 @@ def : MipsPat<(f64 (fextend FGR32Opnd:$src)), (CVT_D64_S FGR32Opnd:$src)>, FGR_64; // Patterns for loads/stores with a reg+imm operand. -let AddedComplexity = 40 in { - def : LoadRegImmPat<LWC1, f32, load>; - def : StoreRegImmPat<SWC1, f32>; +let AdditionalPredicates = [NotInMicroMips] in { + let AddedComplexity = 40 in { + def : LoadRegImmPat<LWC1, f32, load>; + def : StoreRegImmPat<SWC1, f32>; - def : LoadRegImmPat<LDC164, f64, load>, FGR_64; - def : StoreRegImmPat<SDC164, f64>, FGR_64; + def : LoadRegImmPat<LDC164, f64, load>, FGR_64; + def : StoreRegImmPat<SDC164, f64>, FGR_64; - def : LoadRegImmPat<LDC1, f64, load>, FGR_32; - def : StoreRegImmPat<SDC1, f64>, FGR_32; + def : LoadRegImmPat<LDC1, f64, load>, FGR_32; + def : StoreRegImmPat<SDC1, f64>, FGR_32; + } } diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 0d7abbf7b9f..296f6e9b08b 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -1742,9 +1742,10 @@ let AdditionalPredicates = [NotInMicroMips] in { /// Load and Store Instructions /// aligned -def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>; -def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel, - LW_FM<0x24>; +def LB : LoadMemory<"lb", GPR32Opnd, mem_simm16, sextloadi8, II_LB>, MMRel, + LW_FM<0x20>; +def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simm16, zextloadi8, II_LBU, + addrDefault>, MMRel, LW_FM<0x24>; let AdditionalPredicates = [NotInMicroMips] in { def LH : LoadMemory<"lh", GPR32Opnd, mem_simm16, sextloadi16, II_LH, addrDefault>, MMRel, LW_FM<0x21>; @@ -1775,14 +1776,14 @@ def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>, let AdditionalPredicates = [NotInMicroMips] in { // COP2 Memory Instructions -def LWC2 : LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>, +def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>, ISA_MIPS1_NOT_32R6_64R6; -def SWC2 : SW_FT2<"swc2", COP2Opnd, II_SWC2, store>, LW_FM<0x3a>, - ISA_MIPS1_NOT_32R6_64R6; -def LDC2 : LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>, - ISA_MIPS2_NOT_32R6_64R6; -def SDC2 : SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>, LW_FM<0x3e>, +def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>, + LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6; +def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>, ISA_MIPS2_NOT_32R6_64R6; +def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>, + LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6; // COP3 Memory Instructions let DecoderNamespace = "COP3_" in { diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 96bd9cd5c1c..ff24e534e31 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -403,6 +403,18 @@ bool MipsSEDAGToDAGISel::selectAddrRegImm10(SDValue Addr, SDValue &Base, return false; } +/// Used on microMIPS LWC2, LDC2, SWC2 and SDC2 instructions (11-bit offset) +bool MipsSEDAGToDAGISel::selectAddrRegImm11(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + if (selectAddrFrameIndex(Addr, Base, Offset)) + return true; + + if (selectAddrFrameIndexOffset(Addr, Base, Offset, 11)) + return true; + + return false; +} + /// Used on microMIPS Load/Store unaligned instructions (12-bit offset) bool MipsSEDAGToDAGISel::selectAddrRegImm12(SDValue Addr, SDValue &Base, SDValue &Offset) const { @@ -426,12 +438,24 @@ bool MipsSEDAGToDAGISel::selectAddrRegImm16(SDValue Addr, SDValue &Base, return false; } -bool MipsSEDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base, +bool MipsSEDAGToDAGISel::selectIntAddr11MM(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + return selectAddrRegImm11(Addr, Base, Offset) || + selectAddrDefault(Addr, Base, Offset); +} + +bool MipsSEDAGToDAGISel::selectIntAddr12MM(SDValue Addr, SDValue &Base, SDValue &Offset) const { return selectAddrRegImm12(Addr, Base, Offset) || selectAddrDefault(Addr, Base, Offset); } +bool MipsSEDAGToDAGISel::selectIntAddr16MM(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + return selectAddrRegImm16(Addr, Base, Offset) || + selectAddrDefault(Addr, Base, Offset); +} + bool MipsSEDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base, SDValue &Offset) const { if (selectAddrFrameIndexOffset(Addr, Base, Offset, 7)) { diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h index 4dbcb2bc21d..6a09e516ece 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -60,14 +60,23 @@ private: bool selectAddrRegImm10(SDValue Addr, SDValue &Base, SDValue &Offset) const; + bool selectAddrRegImm11(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + bool selectAddrRegImm12(SDValue Addr, SDValue &Base, SDValue &Offset) const; bool selectAddrRegImm16(SDValue Addr, SDValue &Base, SDValue &Offset) const; - bool selectIntAddrMM(SDValue Addr, SDValue &Base, - SDValue &Offset) const override; + bool selectIntAddr11MM(SDValue Addr, SDValue &Base, + SDValue &Offset) const override; + + bool selectIntAddr12MM(SDValue Addr, SDValue &Base, + SDValue &Offset) const override; + + bool selectIntAddr16MM(SDValue Addr, SDValue &Base, + SDValue &Offset) const override; bool selectIntAddrLSL2MM(SDValue Addr, SDValue &Base, SDValue &Offset) const override; |