diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-02-01 21:34:47 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-02-01 21:34:47 +0000 |
commit | 823f87a1f80708ce9ba318cc0b07632e76b74d43 (patch) | |
tree | 400cc7e5d4548d5f3829f7feea7f7942b4e62dd4 /lib/Target | |
parent | aac4ca60bc813a35242145a1f92f325303d5df6e (diff) | |
download | src-823f87a1f80708ce9ba318cc0b07632e76b74d43.tar.gz src-823f87a1f80708ce9ba318cc0b07632e76b74d43.zip |
Notes
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 17 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MicroMipsInstrFPU.td | 107 | ||||
-rw-r--r-- | lib/Target/Mips/MicroMipsInstrFormats.td | 7 | ||||
-rw-r--r-- | lib/Target/Mips/MipsAsmPrinter.cpp | 16 | ||||
-rw-r--r-- | lib/Target/Mips/MipsAsmPrinter.h | 1 | ||||
-rw-r--r-- | lib/Target/Mips/MipsFastISel.cpp | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrFPU.td | 211 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrFormats.td | 8 | ||||
-rw-r--r-- | lib/Target/Mips/MipsTargetObjectFile.cpp | 8 | ||||
-rw-r--r-- | lib/Target/Mips/MipsTargetObjectFile.h | 2 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstrInfo.td | 13 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCSchedule.td | 2 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCScheduleE500mc.td | 8 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCScheduleE5500.td | 10 |
15 files changed, 371 insertions, 47 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 97ca11ca501e..d054578deb67 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -413,6 +413,7 @@ public: Match_RequiresDifferentOperands, Match_RequiresNoZeroRegister, Match_RequiresSameSrcAndDst, + Match_NoFCCRegisterForCurrentISA, Match_NonZeroOperandForSync, #define GET_OPERAND_DIAGNOSTIC_TYPES #include "MipsGenAsmMatcher.inc" @@ -1461,8 +1462,6 @@ public: bool isFCCAsmReg() const { if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC)) return false; - if (!AsmParser.hasEightFccRegisters()) - return RegIdx.Index == 0; return RegIdx.Index <= 7; } bool isACCAsmReg() const { @@ -4053,6 +4052,7 @@ MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst, return Match_RequiresSameSrcAndDst; } } + unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { switch (Inst.getOpcode()) { // As described by the MIPSR6 spec, daui must not use the zero operand for @@ -4131,9 +4131,15 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) return Match_RequiresDifferentOperands; return Match_Success; - default: - return Match_Success; } + + uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags; + if ((TSFlags & MipsII::HasFCCRegOperand) && + (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters()) + return Match_NoFCCRegisterForCurrentISA; + + return Match_Success; + } static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, @@ -4191,6 +4197,9 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return Error(IDLoc, "invalid operand ($zero) for instruction"); case Match_RequiresSameSrcAndDst: return Error(IDLoc, "source and destination must match"); + case Match_NoFCCRegisterForCurrentISA: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "non-zero fcc register doesn't exist in current ISA level"); case Match_Immz: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'"); case Match_UImm1_0: diff --git a/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h b/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h index 35de7b27bf10..a90db2384c46 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h +++ b/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h @@ -123,7 +123,9 @@ namespace MipsII { HasForbiddenSlot = 1 << 5, /// IsPCRelativeLoad - A Load instruction with implicit source register /// ($pc) with explicit offset and destination register - IsPCRelativeLoad = 1 << 6 + IsPCRelativeLoad = 1 << 6, + /// HasFCCRegOperand - Instruction uses an $fcc<x> register. + HasFCCRegOperand = 1 << 7 }; } diff --git a/lib/Target/Mips/MicroMipsInstrFPU.td b/lib/Target/Mips/MicroMipsInstrFPU.td index fc83761e409b..5600f71ff68e 100644 --- a/lib/Target/Mips/MicroMipsInstrFPU.td +++ b/lib/Target/Mips/MicroMipsInstrFPU.td @@ -27,9 +27,20 @@ def SUXC1_MM : MMRel, SWXC1_FT<"suxc1", AFGR64Opnd, II_SUXC1>, SWXC1_FM_MM<0x188>, INSN_MIPS5_32R2_NOT_32R6_64R6; def FCMP_S32_MM : MMRel, CEQS_FT<"s", FGR32, II_C_CC_S, MipsFPCmp>, - CEQS_FM_MM<0>; + CEQS_FM_MM<0> { + // FIXME: This is a required to work around the fact that these instructions + // only use $fcc0. Ideally, MipsFPCmp nodes could be removed and the + // fcc register set is used directly. + bits<3> fcc = 0; +} + def FCMP_D32_MM : MMRel, CEQS_FT<"d", AFGR64, II_C_CC_D, MipsFPCmp>, - CEQS_FM_MM<1>; + CEQS_FM_MM<1> { + // FIXME: This is a required to work around the fact that these instructions + // only use $fcc0. Ideally, MipsFPCmp nodes could be removed and the + // fcc register set is used directly. + bits<3> fcc = 0; +} def BC1F_MM : MMRel, BC1F_FT<"bc1f", brtarget_mm, II_BC1F, MIPS_BRANCH_F>, BC1F_FM_MM<0x1c>, ISA_MIPS1_NOT_32R6_64R6; @@ -164,6 +175,98 @@ let AdditionalPredicates = [InMicroMips] in { def SWC1_MM : MMRel, SW_FT<"swc1", FGR32Opnd, mem_mm_16, II_SWC1, store>, LW_FM_MM<0x26>; } + + multiclass C_COND_MM<string TypeStr, RegisterOperand RC, bits<2> fmt, + InstrItinClass itin> { + def C_F_#NAME#_MM : MMRel, C_COND_FT<"f", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 0> { + let BaseOpcode = "c.f."#NAME; + let isCommutable = 1; + } + def C_UN_#NAME#_MM : MMRel, C_COND_FT<"un", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 1> { + let BaseOpcode = "c.un."#NAME; + let isCommutable = 1; + } + def C_EQ_#NAME#_MM : MMRel, C_COND_FT<"eq", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 2> { + let BaseOpcode = "c.eq."#NAME; + let isCommutable = 1; + } + def C_UEQ_#NAME#_MM : MMRel, C_COND_FT<"ueq", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 3> { + let BaseOpcode = "c.ueq."#NAME; + let isCommutable = 1; + } + def C_OLT_#NAME#_MM : MMRel, C_COND_FT<"olt", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 4> { + let BaseOpcode = "c.olt."#NAME; + } + def C_ULT_#NAME#_MM : MMRel, C_COND_FT<"ult", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 5> { + let BaseOpcode = "c.ult."#NAME; + } + def C_OLE_#NAME#_MM : MMRel, C_COND_FT<"ole", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 6> { + let BaseOpcode = "c.ole."#NAME; + } + def C_ULE_#NAME#_MM : MMRel, C_COND_FT<"ule", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 7> { + let BaseOpcode = "c.ule."#NAME; + } + def C_SF_#NAME#_MM : MMRel, C_COND_FT<"sf", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 8> { + let BaseOpcode = "c.sf."#NAME; + let isCommutable = 1; + } + def C_NGLE_#NAME#_MM : MMRel, C_COND_FT<"ngle", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 9> { + let BaseOpcode = "c.ngle."#NAME; + } + def C_SEQ_#NAME#_MM : MMRel, C_COND_FT<"seq", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 10> { + let BaseOpcode = "c.seq."#NAME; + let isCommutable = 1; + } + def C_NGL_#NAME#_MM : MMRel, C_COND_FT<"ngl", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 11> { + let BaseOpcode = "c.ngl."#NAME; + } + def C_LT_#NAME#_MM : MMRel, C_COND_FT<"lt", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 12> { + let BaseOpcode = "c.lt."#NAME; + } + def C_NGE_#NAME#_MM : MMRel, C_COND_FT<"nge", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 13> { + let BaseOpcode = "c.nge."#NAME; + } + def C_LE_#NAME#_MM : MMRel, C_COND_FT<"le", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 14> { + let BaseOpcode = "c.le."#NAME; + } + def C_NGT_#NAME#_MM : MMRel, C_COND_FT<"ngt", TypeStr, RC, itin>, + C_COND_FM_MM<fmt, 15> { + let BaseOpcode = "c.ngt."#NAME; + } + } + + defm S : C_COND_MM<"s", FGR32Opnd, 0b00, II_C_CC_S>, + ISA_MIPS1_NOT_32R6_64R6; + defm D32 : C_COND_MM<"d", AFGR64Opnd, 0b01, II_C_CC_D>, + ISA_MIPS1_NOT_32R6_64R6, FGR_32; + let DecoderNamespace = "Mips64" in + defm D64 : C_COND_MM<"d", FGR64Opnd, 0b01, II_C_CC_D>, + ISA_MIPS1_NOT_32R6_64R6, FGR_64; + + defm S_MM : C_COND_ALIASES<"s", FGR32Opnd>, HARDFLOAT, + ISA_MIPS1_NOT_32R6_64R6; + defm D32_MM : C_COND_ALIASES<"d", AFGR64Opnd>, HARDFLOAT, + ISA_MIPS1_NOT_32R6_64R6, FGR_32; + defm D64_MM : C_COND_ALIASES<"d", FGR64Opnd>, HARDFLOAT, + ISA_MIPS1_NOT_32R6_64R6, FGR_64; + + defm : BC1_ALIASES<BC1T_MM, "bc1t", BC1F_MM, "bc1f">, + ISA_MIPS1_NOT_32R6_64R6, HARDFLOAT; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td index 8b595f9e6c4c..774976828a0c 100644 --- a/lib/Target/Mips/MicroMipsInstrFormats.td +++ b/lib/Target/Mips/MicroMipsInstrFormats.td @@ -766,6 +766,7 @@ class SWXC1_FM_MM<bits<9> funct> : MMArch { class CEQS_FM_MM<bits<2> fmt> : MMArch { bits<5> fs; bits<5> ft; + bits<3> fcc; bits<4> cond; bits<32> Inst; @@ -773,13 +774,17 @@ class CEQS_FM_MM<bits<2> fmt> : MMArch { let Inst{31-26} = 0x15; let Inst{25-21} = ft; let Inst{20-16} = fs; - let Inst{15-13} = 0x0; // cc + let Inst{15-13} = fcc; let Inst{12} = 0; let Inst{11-10} = fmt; let Inst{9-6} = cond; let Inst{5-0} = 0x3c; } +class C_COND_FM_MM<bits <2> fmt, bits<4> c> : CEQS_FM_MM<fmt> { + let cond = c; +} + class BC1F_FM_MM<bits<5> tf> : MMArch { bits<16> offset; diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index 179695bc6988..04d6529a073d 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -1037,6 +1037,22 @@ void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, // TODO: implement } +// Emit .dtprelword or .dtpreldword directive +// and value for debug thread local expression. +void MipsAsmPrinter::EmitDebugValue(const MCExpr *Value, + unsigned Size) const { + switch (Size) { + case 4: + OutStreamer->EmitDTPRel32Value(Value); + break; + case 8: + OutStreamer->EmitDTPRel64Value(Value); + break; + default: + llvm_unreachable("Unexpected size of expression value."); + } +} + // Align all targets of indirect branches on bundle size. Used only if target // is NaCl. void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) { diff --git a/lib/Target/Mips/MipsAsmPrinter.h b/lib/Target/Mips/MipsAsmPrinter.h index 259e557e1283..c5cf5241c236 100644 --- a/lib/Target/Mips/MipsAsmPrinter.h +++ b/lib/Target/Mips/MipsAsmPrinter.h @@ -140,6 +140,7 @@ public: void EmitStartOfAsmFile(Module &M) override; void EmitEndOfAsmFile(Module &M) override; void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); + void EmitDebugValue(const MCExpr *Value, unsigned Size) const override; }; } diff --git a/lib/Target/Mips/MipsFastISel.cpp b/lib/Target/Mips/MipsFastISel.cpp index 29f3e2c07e04..a44192f57aa0 100644 --- a/lib/Target/Mips/MipsFastISel.cpp +++ b/lib/Target/Mips/MipsFastISel.cpp @@ -698,8 +698,8 @@ bool MipsFastISel::emitCmp(unsigned ResultReg, const CmpInst *CI) { unsigned RegWithOne = createResultReg(&Mips::GPR32RegClass); emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0); emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1); - emitInst(Opc).addReg(LeftReg).addReg(RightReg).addReg( - Mips::FCC0, RegState::ImplicitDefine); + emitInst(Opc).addReg(Mips::FCC0, RegState::Define).addReg(LeftReg) + .addReg(RightReg); emitInst(CondMovOpc, ResultReg) .addReg(RegWithOne) .addReg(Mips::FCC0) diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index ab7aa9dcdcae..df42d56d041b 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -219,6 +219,7 @@ class BC1F_FT<string opstr, DAGOperand opnd, InstrItinClass Itin, let isTerminator = 1; let hasDelaySlot = DelaySlot; let Defs = [AT]; + let hasFCCRegOperand = 1; } class CEQS_FT<string typestr, RegisterClass RC, InstrItinClass Itin, @@ -229,41 +230,106 @@ class CEQS_FT<string typestr, RegisterClass RC, InstrItinClass Itin, !strconcat("c.$cond.", typestr)>, HARDFLOAT { let Defs = [FCC0]; let isCodeGenOnly = 1; + let hasFCCRegOperand = 1; } + +// Note: MIPS-IV introduced $fcc1-$fcc7 and renamed FCSR31[23] $fcc0. Rather +// duplicating the instruction definition for MIPS1 - MIPS3, we expand +// c.cond.ft if necessary, and reject it after constructing the +// instruction if the ISA doesn't support it. class C_COND_FT<string CondStr, string Typestr, RegisterOperand RC, InstrItinClass itin> : - InstSE<(outs), (ins RC:$fs, RC:$ft), - !strconcat("c.", CondStr, ".", Typestr, "\t$fs, $ft"), [], itin, - FrmFR>, HARDFLOAT; + InstSE<(outs FCCRegsOpnd:$fcc), (ins RC:$fs, RC:$ft), + !strconcat("c.", CondStr, ".", Typestr, "\t$fcc, $fs, $ft"), [], itin, + FrmFR>, HARDFLOAT { + let isCompare = 1; + let hasFCCRegOperand = 1; +} + multiclass C_COND_M<string TypeStr, RegisterOperand RC, bits<5> fmt, InstrItinClass itin> { - def C_F_#NAME : C_COND_FT<"f", TypeStr, RC, itin>, C_COND_FM<fmt, 0>; - def C_UN_#NAME : C_COND_FT<"un", TypeStr, RC, itin>, C_COND_FM<fmt, 1>; - def C_EQ_#NAME : C_COND_FT<"eq", TypeStr, RC, itin>, C_COND_FM<fmt, 2>; - def C_UEQ_#NAME : C_COND_FT<"ueq", TypeStr, RC, itin>, C_COND_FM<fmt, 3>; - def C_OLT_#NAME : C_COND_FT<"olt", TypeStr, RC, itin>, C_COND_FM<fmt, 4>; - def C_ULT_#NAME : C_COND_FT<"ult", TypeStr, RC, itin>, C_COND_FM<fmt, 5>; - def C_OLE_#NAME : C_COND_FT<"ole", TypeStr, RC, itin>, C_COND_FM<fmt, 6>; - def C_ULE_#NAME : C_COND_FT<"ule", TypeStr, RC, itin>, C_COND_FM<fmt, 7>; - def C_SF_#NAME : C_COND_FT<"sf", TypeStr, RC, itin>, C_COND_FM<fmt, 8>; - def C_NGLE_#NAME : C_COND_FT<"ngle", TypeStr, RC, itin>, C_COND_FM<fmt, 9>; - def C_SEQ_#NAME : C_COND_FT<"seq", TypeStr, RC, itin>, C_COND_FM<fmt, 10>; - def C_NGL_#NAME : C_COND_FT<"ngl", TypeStr, RC, itin>, C_COND_FM<fmt, 11>; - def C_LT_#NAME : C_COND_FT<"lt", TypeStr, RC, itin>, C_COND_FM<fmt, 12>; - def C_NGE_#NAME : C_COND_FT<"nge", TypeStr, RC, itin>, C_COND_FM<fmt, 13>; - def C_LE_#NAME : C_COND_FT<"le", TypeStr, RC, itin>, C_COND_FM<fmt, 14>; - def C_NGT_#NAME : C_COND_FT<"ngt", TypeStr, RC, itin>, C_COND_FM<fmt, 15>; + def C_F_#NAME : MMRel, C_COND_FT<"f", TypeStr, RC, itin>, + C_COND_FM<fmt, 0> { + let BaseOpcode = "c.f."#NAME; + let isCommutable = 1; + } + def C_UN_#NAME : MMRel, C_COND_FT<"un", TypeStr, RC, itin>, + C_COND_FM<fmt, 1> { + let BaseOpcode = "c.un."#NAME; + let isCommutable = 1; + } + def C_EQ_#NAME : MMRel, C_COND_FT<"eq", TypeStr, RC, itin>, + C_COND_FM<fmt, 2> { + let BaseOpcode = "c.eq."#NAME; + let isCommutable = 1; + } + def C_UEQ_#NAME : MMRel, C_COND_FT<"ueq", TypeStr, RC, itin>, + C_COND_FM<fmt, 3> { + let BaseOpcode = "c.ueq."#NAME; + let isCommutable = 1; + } + def C_OLT_#NAME : MMRel, C_COND_FT<"olt", TypeStr, RC, itin>, + C_COND_FM<fmt, 4> { + let BaseOpcode = "c.olt."#NAME; + } + def C_ULT_#NAME : MMRel, C_COND_FT<"ult", TypeStr, RC, itin>, + C_COND_FM<fmt, 5> { + let BaseOpcode = "c.ult."#NAME; + } + def C_OLE_#NAME : MMRel, C_COND_FT<"ole", TypeStr, RC, itin>, + C_COND_FM<fmt, 6> { + let BaseOpcode = "c.ole."#NAME; + } + def C_ULE_#NAME : MMRel, C_COND_FT<"ule", TypeStr, RC, itin>, + C_COND_FM<fmt, 7> { + let BaseOpcode = "c.ule."#NAME; + } + def C_SF_#NAME : MMRel, C_COND_FT<"sf", TypeStr, RC, itin>, + C_COND_FM<fmt, 8> { + let BaseOpcode = "c.sf."#NAME; + let isCommutable = 1; + } + def C_NGLE_#NAME : MMRel, C_COND_FT<"ngle", TypeStr, RC, itin>, + C_COND_FM<fmt, 9> { + let BaseOpcode = "c.ngle."#NAME; + } + def C_SEQ_#NAME : MMRel, C_COND_FT<"seq", TypeStr, RC, itin>, + C_COND_FM<fmt, 10> { + let BaseOpcode = "c.seq."#NAME; + let isCommutable = 1; + } + def C_NGL_#NAME : MMRel, C_COND_FT<"ngl", TypeStr, RC, itin>, + C_COND_FM<fmt, 11> { + let BaseOpcode = "c.ngl."#NAME; + } + def C_LT_#NAME : MMRel, C_COND_FT<"lt", TypeStr, RC, itin>, + C_COND_FM<fmt, 12> { + let BaseOpcode = "c.lt."#NAME; + } + def C_NGE_#NAME : MMRel, C_COND_FT<"nge", TypeStr, RC, itin>, + C_COND_FM<fmt, 13> { + let BaseOpcode = "c.nge."#NAME; + } + def C_LE_#NAME : MMRel, C_COND_FT<"le", TypeStr, RC, itin>, + C_COND_FM<fmt, 14> { + let BaseOpcode = "c.le."#NAME; + } + def C_NGT_#NAME : MMRel, C_COND_FT<"ngt", TypeStr, RC, itin>, + C_COND_FM<fmt, 15> { + let BaseOpcode = "c.ngt."#NAME; + } } +let AdditionalPredicates = [NotInMicroMips] in { defm S : C_COND_M<"s", FGR32Opnd, 16, II_C_CC_S>, ISA_MIPS1_NOT_32R6_64R6; defm D32 : C_COND_M<"d", AFGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6, FGR_32; let DecoderNamespace = "Mips64" in defm D64 : C_COND_M<"d", FGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6, FGR_64; - +} //===----------------------------------------------------------------------===// // Floating Point Instructions //===----------------------------------------------------------------------===// @@ -549,13 +615,29 @@ def BC1TL : MMRel, BC1F_FT<"bc1tl", brtarget, II_BC1TL, MIPS_BRANCH_T, 0>, /// Floating Point Compare let AdditionalPredicates = [NotInMicroMips] in { def FCMP_S32 : MMRel, CEQS_FT<"s", FGR32, II_C_CC_S, MipsFPCmp>, CEQS_FM<16>, - ISA_MIPS1_NOT_32R6_64R6; + ISA_MIPS1_NOT_32R6_64R6 { + + // FIXME: This is a required to work around the fact that these instructions + // only use $fcc0. Ideally, MipsFPCmp nodes could be removed and the + // fcc register set is used directly. + bits<3> fcc = 0; + } def FCMP_D32 : MMRel, CEQS_FT<"d", AFGR64, II_C_CC_D, MipsFPCmp>, CEQS_FM<17>, - ISA_MIPS1_NOT_32R6_64R6, FGR_32; + ISA_MIPS1_NOT_32R6_64R6, FGR_32 { + // FIXME: This is a required to work around the fact that these instructions + // only use $fcc0. Ideally, MipsFPCmp nodes could be removed and the + // fcc register set is used directly. + bits<3> fcc = 0; + } } let DecoderNamespace = "Mips64" in def FCMP_D64 : CEQS_FT<"d", FGR64, II_C_CC_D, MipsFPCmp>, CEQS_FM<17>, - ISA_MIPS1_NOT_32R6_64R6, FGR_64; + ISA_MIPS1_NOT_32R6_64R6, FGR_64 { + // FIXME: This is a required to work around the fact that thiese instructions + // only use $fcc0. Ideally, MipsFPCmp nodes could be removed and the + // fcc register set is used directly. + bits<3> fcc = 0; +} //===----------------------------------------------------------------------===// // Floating Point Pseudo-Instructions @@ -602,15 +684,6 @@ def PseudoTRUNC_W_D : MipsAsmPseudoInst<(outs FGR32Opnd:$fd), //===----------------------------------------------------------------------===// // InstAliases. //===----------------------------------------------------------------------===// -def : MipsInstAlias<"bc1t $offset", (BC1T FCC0, brtarget:$offset)>, - ISA_MIPS1_NOT_32R6_64R6, HARDFLOAT; -def : MipsInstAlias<"bc1tl $offset", (BC1TL FCC0, brtarget:$offset)>, - ISA_MIPS2_NOT_32R6_64R6, HARDFLOAT; -def : MipsInstAlias<"bc1f $offset", (BC1F FCC0, brtarget:$offset)>, - ISA_MIPS1_NOT_32R6_64R6, HARDFLOAT; -def : MipsInstAlias<"bc1fl $offset", (BC1FL FCC0, brtarget:$offset)>, - ISA_MIPS2_NOT_32R6_64R6, HARDFLOAT; - def : MipsInstAlias <"s.s $fd, $addr", (SWC1 FGR32Opnd:$fd, mem_simm16:$addr), 0>, ISA_MIPS2, HARDFLOAT; @@ -630,6 +703,80 @@ def : MipsInstAlias def : MipsInstAlias <"l.d $fd, $addr", (LDC164 FGR64Opnd:$fd, mem_simm16:$addr), 0>, FGR_64, ISA_MIPS2, HARDFLOAT; + +multiclass C_COND_ALIASES<string TypeStr, RegisterOperand RC> { + def : MipsInstAlias<!strconcat("c.f.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_F_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.un.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_UN_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.eq.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_EQ_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.ueq.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_UEQ_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.olt.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_OLT_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.ult.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_ULT_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.ole.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_OLE_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.ule.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_ULE_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.sf.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_SF_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.ngle.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_NGLE_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.seq.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_SEQ_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.ngl.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_NGL_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.lt.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_LT_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.nge.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_NGE_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.le.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_LE_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; + def : MipsInstAlias<!strconcat("c.ngt.", TypeStr, " $fs, $ft"), + (!cast<Instruction>("C_NGT_"#NAME) FCC0, + RC:$fs, RC:$ft), 1>; +} + +multiclass BC1_ALIASES<Instruction BCTrue, string BCTrueString, + Instruction BCFalse, string BCFalseString> { + def : MipsInstAlias<!strconcat(BCTrueString, " $offset"), + (BCTrue FCC0, brtarget:$offset), 1>; + + def : MipsInstAlias<!strconcat(BCFalseString, " $offset"), + (BCFalse FCC0, brtarget:$offset), 1>; +} + +let AdditionalPredicates = [NotInMicroMips] in { + defm S : C_COND_ALIASES<"s", FGR32Opnd>, HARDFLOAT, + ISA_MIPS1_NOT_32R6_64R6; + defm D32 : C_COND_ALIASES<"d", AFGR64Opnd>, HARDFLOAT, + ISA_MIPS1_NOT_32R6_64R6, FGR_32; + defm D64 : C_COND_ALIASES<"d", FGR64Opnd>, HARDFLOAT, + ISA_MIPS1_NOT_32R6_64R6, FGR_64; + + defm : BC1_ALIASES<BC1T, "bc1t", BC1F, "bc1f">, ISA_MIPS1_NOT_32R6_64R6, + HARDFLOAT; + defm : BC1_ALIASES<BC1TL, "bc1tl", BC1FL, "bc1fl">, ISA_MIPS2_NOT_32R6_64R6, + HARDFLOAT; +} //===----------------------------------------------------------------------===// // Floating Point Patterns //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td index 1437fb75434a..817d9b44b9c2 100644 --- a/lib/Target/Mips/MipsInstrFormats.td +++ b/lib/Target/Mips/MipsInstrFormats.td @@ -101,12 +101,15 @@ class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern, bit IsPCRelativeLoad = 0; // Load instruction with implicit source register // ($pc) and with explicit offset and destination // register + bit hasFCCRegOperand = 0; // Instruction uses $fcc<X> register and is + // present in MIPS-I to MIPS-III. - // TSFlags layout should be kept in sync with MipsInstrInfo.h. + // TSFlags layout should be kept in sync with MCTargetDesc/MipsBaseInfo.h. let TSFlags{3-0} = FormBits; let TSFlags{4} = isCTI; let TSFlags{5} = hasForbiddenSlot; let TSFlags{6} = IsPCRelativeLoad; + let TSFlags{7} = hasFCCRegOperand; let DecoderNamespace = "Mips"; @@ -829,6 +832,7 @@ class BC1F_FM<bit nd, bit tf> : StdArch { class CEQS_FM<bits<5> fmt> : StdArch { bits<5> fs; bits<5> ft; + bits<3> fcc; bits<4> cond; bits<32> Inst; @@ -837,7 +841,7 @@ class CEQS_FM<bits<5> fmt> : StdArch { let Inst{25-21} = fmt; let Inst{20-16} = ft; let Inst{15-11} = fs; - let Inst{10-8} = 0; // cc + let Inst{10-8} = fcc; let Inst{7-4} = 0x3; let Inst{3-0} = cond; } diff --git a/lib/Target/Mips/MipsTargetObjectFile.cpp b/lib/Target/Mips/MipsTargetObjectFile.cpp index fadab7806120..c5d6a05d6611 100644 --- a/lib/Target/Mips/MipsTargetObjectFile.cpp +++ b/lib/Target/Mips/MipsTargetObjectFile.cpp @@ -148,3 +148,11 @@ MCSection *MipsTargetObjectFile::getSectionForConstant(const DataLayout &DL, // Otherwise, we work the same as ELF. return TargetLoweringObjectFileELF::getSectionForConstant(DL, Kind, C, Align); } + +const MCExpr * +MipsTargetObjectFile::getDebugThreadLocalSymbol(const MCSymbol *Sym) const { + const MCExpr *Expr = + MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); + return MCBinaryExpr::createAdd( + Expr, MCConstantExpr::create(0x8000, getContext()), getContext()); +} diff --git a/lib/Target/Mips/MipsTargetObjectFile.h b/lib/Target/Mips/MipsTargetObjectFile.h index e5423f9578a8..a37ec154ff79 100644 --- a/lib/Target/Mips/MipsTargetObjectFile.h +++ b/lib/Target/Mips/MipsTargetObjectFile.h @@ -42,6 +42,8 @@ class MipsTargetMachine; MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind, const Constant *C, unsigned &Align) const override; + /// Describe a TLS variable address within debug info. + const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const override; }; } // end namespace llvm diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 90111bbea07d..f615cc7cc974 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -1508,8 +1508,14 @@ def DCBTST : DCB_Form_hint<246, (outs), (ins u5imm:$TH, memrr:$dst), PPC970_DGroup_Single; } // hasSideEffects = 0 +def ICBLC : XForm_icbt<31, 230, (outs), (ins u4imm:$CT, memrr:$src), + "icblc $CT, $src", IIC_LdStStore>, Requires<[HasICBT]>; +def ICBLQ : XForm_icbt<31, 198, (outs), (ins u4imm:$CT, memrr:$src), + "icblq. $CT, $src", IIC_LdStLoad>, Requires<[HasICBT]>; def ICBT : XForm_icbt<31, 22, (outs), (ins u4imm:$CT, memrr:$src), "icbt $CT, $src", IIC_LdStLoad>, Requires<[HasICBT]>; +def ICBTLS : XForm_icbt<31, 486, (outs), (ins u4imm:$CT, memrr:$src), + "icbtls $CT, $src", IIC_LdStLoad>, Requires<[HasICBT]>; def : Pat<(int_ppc_dcbt xoaddr:$dst), (DCBT 0, xoaddr:$dst)>; @@ -2381,6 +2387,13 @@ def MTSPR : XFXForm_1<31, 467, (outs), (ins i32imm:$SPR, gprc:$RT), def MFTB : XFXForm_1<31, 371, (outs gprc:$RT), (ins i32imm:$SPR), "mftb $RT, $SPR", IIC_SprMFTB>; +def MFPMR : XFXForm_1<31, 334, (outs gprc:$RT), (ins i32imm:$SPR), + "mfpmr $RT, $SPR", IIC_SprMFPMR>; + +def MTPMR : XFXForm_1<31, 462, (outs), (ins i32imm:$SPR, gprc:$RT), + "mtpmr $SPR, $RT", IIC_SprMTPMR>; + + // A pseudo-instruction used to implement the read of the 64-bit cycle counter // on a 32-bit target. let hasSideEffects = 1, usesCustomInserter = 1 in diff --git a/lib/Target/PowerPC/PPCSchedule.td b/lib/Target/PowerPC/PPCSchedule.td index edabe7748673..d240529bc731 100644 --- a/lib/Target/PowerPC/PPCSchedule.td +++ b/lib/Target/PowerPC/PPCSchedule.td @@ -118,6 +118,8 @@ def IIC_SprTLBIE : InstrItinClass; def IIC_SprABORT : InstrItinClass; def IIC_SprMSGSYNC : InstrItinClass; def IIC_SprSTOP : InstrItinClass; +def IIC_SprMFPMR : InstrItinClass; +def IIC_SprMTPMR : InstrItinClass; //===----------------------------------------------------------------------===// // Processor instruction itineraries. diff --git a/lib/Target/PowerPC/PPCScheduleE500mc.td b/lib/Target/PowerPC/PPCScheduleE500mc.td index f687d326b52d..15d5991b938c 100644 --- a/lib/Target/PowerPC/PPCScheduleE500mc.td +++ b/lib/Target/PowerPC/PPCScheduleE500mc.td @@ -249,6 +249,10 @@ def PPCE500mcItineraries : ProcessorItineraries< InstrStage<5, [E500_SFX0]>], [8, 1], [E500_GPR_Bypass, E500_CR_Bypass]>, + InstrItinData<IIC_SprMFPMR, [InstrStage<1, [E500_DIS0, E500_DIS1], 0>, + InstrStage<4, [E500_SFX0]>], + [7, 1], // Latency = 4, Repeat rate = 4 + [E500_GPR_Bypass, E500_GPR_Bypass]>, InstrItinData<IIC_SprMFMSR, [InstrStage<1, [E500_DIS0, E500_DIS1], 0>, InstrStage<4, [E500_SFX0]>], [7, 1], // Latency = 4, Repeat rate = 4 @@ -257,6 +261,10 @@ def PPCE500mcItineraries : ProcessorItineraries< InstrStage<1, [E500_SFX0, E500_SFX1]>], [4, 1], // Latency = 1, Repeat rate = 1 [E500_GPR_Bypass, E500_CR_Bypass]>, + InstrItinData<IIC_SprMTPMR, [InstrStage<1, [E500_DIS0, E500_DIS1], 0>, + InstrStage<1, [E500_SFX0]>], + [4, 1], // Latency = 1, Repeat rate = 1 + [E500_CR_Bypass, E500_GPR_Bypass]>, InstrItinData<IIC_SprMFTB, [InstrStage<1, [E500_DIS0, E500_DIS1], 0>, InstrStage<4, [E500_SFX0]>], [7, 1], // Latency = 4, Repeat rate = 4 diff --git a/lib/Target/PowerPC/PPCScheduleE5500.td b/lib/Target/PowerPC/PPCScheduleE5500.td index 5db886cf8f94..32f8e652dd56 100644 --- a/lib/Target/PowerPC/PPCScheduleE5500.td +++ b/lib/Target/PowerPC/PPCScheduleE5500.td @@ -313,20 +313,24 @@ def PPCE5500Itineraries : ProcessorItineraries< InstrStage<5, [E5500_CFX_0]>], [9, 2], // Latency = 5, Repeat rate = 5 [E5500_GPR_Bypass, E5500_CR_Bypass]>, - InstrItinData<IIC_SprMFMSR, [InstrStage<1, [E5500_DIS0, E5500_DIS1], 0>, - InstrStage<4, [E5500_SFX0]>], + InstrItinData<IIC_SprMFPMR, [InstrStage<1, [E5500_DIS0, E5500_DIS1], 0>, + InstrStage<4, [E5500_CFX_0]>], [8, 2], // Latency = 4, Repeat rate = 4 [E5500_GPR_Bypass, E5500_GPR_Bypass]>, InstrItinData<IIC_SprMFSPR, [InstrStage<1, [E5500_DIS0, E5500_DIS1], 0>, InstrStage<1, [E5500_CFX_0]>], [5], // Latency = 1, Repeat rate = 1 [E5500_GPR_Bypass]>, + InstrItinData<IIC_SprMTPMR, [InstrStage<1, [E5500_DIS0, E5500_DIS1], 0>, + InstrStage<1, [E5500_CFX_0]>], + [5], // Latency = 1, Repeat rate = 1 + [E5500_GPR_Bypass]>, InstrItinData<IIC_SprMFTB, [InstrStage<1, [E5500_DIS0, E5500_DIS1], 0>, InstrStage<4, [E5500_CFX_0]>], [8, 2], // Latency = 4, Repeat rate = 4 [NoBypass, E5500_GPR_Bypass]>, InstrItinData<IIC_SprMTSPR, [InstrStage<1, [E5500_DIS0, E5500_DIS1], 0>, - InstrStage<1, [E5500_SFX0, E5500_SFX1]>], + InstrStage<1, [E5500_CFX_0]>], [5], // Latency = 1, Repeat rate = 1 [E5500_GPR_Bypass]>, InstrItinData<IIC_FPGeneral, [InstrStage<1, [E5500_DIS0, E5500_DIS1], 0>, |