forked from OSchip/llvm-project
40 Commits
Author | SHA1 | Message | Date |
---|---|---|---|
Ulrich Weigand | 84404f30b3 |
[SystemZ] Support execution hint instructions
This adds assembler support for the instructions provided by the execution-hint facility (NIAI and BP(R)P). This required adding support for the new relocation types for 12-bit and 24-bit PC- relative offsets used by the BP(R)P instructions. llvm-svn: 288031 |
|
Ulrich Weigand | 2d9e3d9d3b |
[SystemZ] Support load-and-trap instructions
This adds support for the instructions provided with the load-and-trap facility. llvm-svn: 288030 |
|
Ulrich Weigand | 524f276c74 |
[SystemZ] Improve use of conditional instructions
This patch moves formation of LOC-type instructions from (late) IfConversion to the early if-conversion pass, and in some cases additionally creates them directly from select instructions during DAG instruction selection. To make early if-conversion work, the patch implements the canInsertSelect / insertSelect callbacks. It also implements the commuteInstructionImpl and FoldImmediate callbacks to enable generation of the full range of LOC instructions. Finally, the patch adds support for all instructions of the load-store-on-condition-2 facility, which allows using LOC instructions also for high registers. Due to the use of the GRX32 register class to enable high registers, we now also have to handle the cases where there are still no single hardware instructions (conditional move from a low register to a high register or vice versa). These are converted back to a branch sequence after register allocation. Since the expandRAPseudos callback is not allowed to create new basic blocks, this requires a simple new pass, modelled after the ARM/AArch64 ExpandPseudos pass. Overall, this patch causes significantly more LOC-type instructions to be used, and results in a measurable performance improvement. llvm-svn: 288028 |
|
Ulrich Weigand | 92c2c672e5 |
[SystemZ] Support load-and-zero-rightmost-byte facility
This adds support for the LZRF/LZRG/LLZRGF instructions that were added on z13, and uses them for code generation were appropriate. SystemZDAGToDAGISel::tryRISBGZero is updated again to prefer LLZRGF over RISBG where both would be possible. llvm-svn: 286586 |
|
Zhan Jun Liau | def708a0f9 |
[SystemZ] Recognize Load On Condition Immediate (LOCHI/LOGHI) opportunities
Summary: Add support for the z13 instructions LOCHI and LOCGHI which conditionally load immediate values. Add target instruction info hooks so that if conversion will allow predication of LHI/LGHI. Author: RolandF Reviewers: uweigand Subscribers: zhanjunl Commiting on behalf of Roland. Differential Revision: http://reviews.llvm.org/D22117 llvm-svn: 275086 |
|
Rafael Espindola | 3beef8d6db |
Move shouldAssumeDSOLocal to Target.
Should fix the shared library build. llvm-svn: 273958 |
|
Benjamin Kramer | f9172fd4ac |
Rename TargetSelectionDAGInfo into SelectionDAGTargetInfo and move it to CodeGen/
It's a SelectionDAG thing, not a Target thing. llvm-svn: 258939 |
|
Daniel Sanders | a73f1fdb19 |
Replace string GNU Triples with llvm::Triple in MCSubtargetInfo and create*MCSubtargetInfo(). NFC.
Summary: This continues the patch series to eliminate StringRef forms of GNU triples from the internals of LLVM that began in r239036. Reviewers: rafael Reviewed By: rafael Subscribers: rafael, ted, jfb, llvm-commits, rengolin, jholewinski Differential Revision: http://reviews.llvm.org/D10311 llvm-svn: 239467 |
|
Ulrich Weigand | a8b04e1cbc |
[SystemZ] Add z13 vector facility and MC support
This patch adds support for the z13 processor type and its vector facility, and adds MC support for all new instructions provided by that facilily. Apart from defining the new instructions, the main changes are: - Adding VR128, VR64 and VR32 register classes. - Making FP64 a subclass of VR64 and FP32 a subclass of VR32. - Adding a D(V,B) addressing mode for scatter/gather operations - Adding 1-, 2-, and 3-bit immediate operands for some 4-bit fields. Until now all immediate operands have been the same width as the underlying field (hence the assert->return change in decode[SU]ImmOperand). In addition, sys::getHostCPUName is extended to detect running natively on a z13 machine. Based on a patch by Richard Sandiford. llvm-svn: 236520 |
|
Ulrich Weigand | 57c85f53ba |
[SystemZ] Support transactional execution on zEC12
The zEC12 provides the transactional-execution facility. This is exposed to users via a set of builtin routines on other compilers. This patch adds LLVM support to enable those builtins. In partciular, the patch: - adds the transactional-execution and processor-assist facilities - adds MC support for all instructions provided by those facilities - adds LLVM intrinsics for those instructions and hooks them up for CodeGen - adds CodeGen support to optimize CC return value checking Since this is first use of target-specific intrinsics on the platform, the patch creates the include/llvm/IR/IntrinsicsSystemZ.td file and hooks it up in Intrinsics.td. I've also changed Triple::getArchTypePrefix to return "s390" instead of "systemz", since the naming convention for GCC intrinsics uses "s390" on the platform, and it neemed more straight- forward to use the same convention for LLVM IR intrinsics. An associated clang patch makes the intrinsics (and command line switches) available at the source-language level. For reference, the transactional-execution instructions are documented in the z/Architecture Principles of Operation for the zEC12: http://publibfp.boulder.ibm.com/cgi-bin/bookmgr/download/DZ9ZR009.pdf The associated builtins are documented in the GCC manual: http://gcc.gnu.org/onlinedocs/gcc/S_002f390-System-z-Built-in-Functions.html Index: llvm-head/lib/Target/SystemZ/SystemZOperators.td =================================================================== --- llvm-head.orig/lib/Target/SystemZ/SystemZOperators.td +++ llvm-head/lib/Target/SystemZ/SystemZOperators.td @@ -79,6 +79,9 @@ def SDT_ZI32Intrinsic : SDTypeProf def SDT_ZPrefetch : SDTypeProfile<0, 2, [SDTCisVT<0, i32>, SDTCisPtrTy<1>]>; +def SDT_ZTBegin : SDTypeProfile<0, 2, + [SDTCisPtrTy<0>, + SDTCisVT<1, i32>]>; //===----------------------------------------------------------------------===// // Node definitions @@ -180,6 +183,15 @@ def z_prefetch : SDNode<"System [SDNPHasChain, SDNPMayLoad, SDNPMayStore, SDNPMemOperand]>; +def z_tbegin : SDNode<"SystemZISD::TBEGIN", SDT_ZTBegin, + [SDNPHasChain, SDNPOutGlue, SDNPMayStore, + SDNPSideEffect]>; +def z_tbegin_nofloat : SDNode<"SystemZISD::TBEGIN_NOFLOAT", SDT_ZTBegin, + [SDNPHasChain, SDNPOutGlue, SDNPMayStore, + SDNPSideEffect]>; +def z_tend : SDNode<"SystemZISD::TEND", SDTNone, + [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>; + //===----------------------------------------------------------------------===// // Pattern fragments //===----------------------------------------------------------------------===// Index: llvm-head/lib/Target/SystemZ/SystemZInstrFormats.td =================================================================== --- llvm-head.orig/lib/Target/SystemZ/SystemZInstrFormats.td +++ llvm-head/lib/Target/SystemZ/SystemZInstrFormats.td @@ -473,6 +473,17 @@ class InstSS<bits<8> op, dag outs, dag i let Inst{15-0} = BD2; } +class InstS<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<4, outs, ins, asmstr, pattern> { + field bits<32> Inst; + field bits<32> SoftFail = 0; + + bits<16> BD2; + + let Inst{31-16} = op; + let Inst{15-0} = BD2; +} + //===----------------------------------------------------------------------===// // Instruction definitions with semantics //===----------------------------------------------------------------------===// Index: llvm-head/lib/Target/SystemZ/SystemZInstrInfo.td =================================================================== --- llvm-head.orig/lib/Target/SystemZ/SystemZInstrInfo.td +++ llvm-head/lib/Target/SystemZ/SystemZInstrInfo.td @@ -1362,6 +1362,60 @@ let Defs = [CC] in { } //===----------------------------------------------------------------------===// +// Transactional execution +//===----------------------------------------------------------------------===// + +let Predicates = [FeatureTransactionalExecution] in { + // Transaction Begin + let hasSideEffects = 1, mayStore = 1, + usesCustomInserter = 1, Defs = [CC] in { + def TBEGIN : InstSIL<0xE560, + (outs), (ins bdaddr12only:$BD1, imm32zx16:$I2), + "tbegin\t$BD1, $I2", + [(z_tbegin bdaddr12only:$BD1, imm32zx16:$I2)]>; + def TBEGIN_nofloat : Pseudo<(outs), (ins bdaddr12only:$BD1, imm32zx16:$I2), + [(z_tbegin_nofloat bdaddr12only:$BD1, + imm32zx16:$I2)]>; + def TBEGINC : InstSIL<0xE561, + (outs), (ins bdaddr12only:$BD1, imm32zx16:$I2), + "tbeginc\t$BD1, $I2", + [(int_s390_tbeginc bdaddr12only:$BD1, + imm32zx16:$I2)]>; + } + + // Transaction End + let hasSideEffects = 1, Defs = [CC], BD2 = 0 in + def TEND : InstS<0xB2F8, (outs), (ins), "tend", [(z_tend)]>; + + // Transaction Abort + let hasSideEffects = 1, isTerminator = 1, isBarrier = 1 in + def TABORT : InstS<0xB2FC, (outs), (ins bdaddr12only:$BD2), + "tabort\t$BD2", + [(int_s390_tabort bdaddr12only:$BD2)]>; + + // Nontransactional Store + let hasSideEffects = 1 in + def NTSTG : StoreRXY<"ntstg", 0xE325, int_s390_ntstg, GR64, 8>; + + // Extract Transaction Nesting Depth + let hasSideEffects = 1 in + def ETND : InherentRRE<"etnd", 0xB2EC, GR32, (int_s390_etnd)>; +} + +//===----------------------------------------------------------------------===// +// Processor assist +//===----------------------------------------------------------------------===// + +let Predicates = [FeatureProcessorAssist] in { + let hasSideEffects = 1, R4 = 0 in + def PPA : InstRRF<0xB2E8, (outs), (ins GR64:$R1, GR64:$R2, imm32zx4:$R3), + "ppa\t$R1, $R2, $R3", []>; + def : Pat<(int_s390_ppa_txassist GR32:$src), + (PPA (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_l32), + 0, 1)>; +} + +//===----------------------------------------------------------------------===// // Miscellaneous Instructions. //===----------------------------------------------------------------------===// Index: llvm-head/lib/Target/SystemZ/SystemZProcessors.td =================================================================== --- llvm-head.orig/lib/Target/SystemZ/SystemZProcessors.td +++ llvm-head/lib/Target/SystemZ/SystemZProcessors.td @@ -60,6 +60,16 @@ def FeatureMiscellaneousExtensions : Sys "Assume that the miscellaneous-extensions facility is installed" >; +def FeatureTransactionalExecution : SystemZFeature< + "transactional-execution", "TransactionalExecution", + "Assume that the transactional-execution facility is installed" +>; + +def FeatureProcessorAssist : SystemZFeature< + "processor-assist", "ProcessorAssist", + "Assume that the processor-assist facility is installed" +>; + def : Processor<"generic", NoItineraries, []>; def : Processor<"z10", NoItineraries, []>; def : Processor<"z196", NoItineraries, @@ -70,4 +80,5 @@ def : Processor<"zEC12", NoItineraries, [FeatureDistinctOps, FeatureLoadStoreOnCond, FeatureHighWord, FeatureFPExtension, FeaturePopulationCount, FeatureFastSerialization, FeatureInterlockedAccess1, - FeatureMiscellaneousExtensions]>; + FeatureMiscellaneousExtensions, + FeatureTransactionalExecution, FeatureProcessorAssist]>; Index: llvm-head/lib/Target/SystemZ/SystemZSubtarget.cpp =================================================================== --- llvm-head.orig/lib/Target/SystemZ/SystemZSubtarget.cpp +++ llvm-head/lib/Target/SystemZ/SystemZSubtarget.cpp @@ -40,6 +40,7 @@ SystemZSubtarget::SystemZSubtarget(const HasLoadStoreOnCond(false), HasHighWord(false), HasFPExtension(false), HasPopulationCount(false), HasFastSerialization(false), HasInterlockedAccess1(false), HasMiscellaneousExtensions(false), + HasTransactionalExecution(false), HasProcessorAssist(false), TargetTriple(TT), InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this), TSInfo(*TM.getDataLayout()), FrameLowering() {} Index: llvm-head/lib/Target/SystemZ/SystemZSubtarget.h =================================================================== --- llvm-head.orig/lib/Target/SystemZ/SystemZSubtarget.h +++ llvm-head/lib/Target/SystemZ/SystemZSubtarget.h @@ -42,6 +42,8 @@ protected: bool HasFastSerialization; bool HasInterlockedAccess1; bool HasMiscellaneousExtensions; + bool HasTransactionalExecution; + bool HasProcessorAssist; private: Triple TargetTriple; @@ -102,6 +104,12 @@ public: return HasMiscellaneousExtensions; } + // Return true if the target has the transactional-execution facility. + bool hasTransactionalExecution() const { return HasTransactionalExecution; } + + // Return true if the target has the processor-assist facility. + bool hasProcessorAssist() const { return HasProcessorAssist; } + // Return true if GV can be accessed using LARL for reloc model RM // and code model CM. bool isPC32DBLSymbol(const GlobalValue *GV, Reloc::Model RM, Index: llvm-head/lib/Support/Triple.cpp =================================================================== --- llvm-head.orig/lib/Support/Triple.cpp +++ llvm-head/lib/Support/Triple.cpp @@ -92,7 +92,7 @@ const char *Triple::getArchTypePrefix(Ar case sparcv9: case sparc: return "sparc"; - case systemz: return "systemz"; + case systemz: return "s390"; case x86: case x86_64: return "x86"; Index: llvm-head/include/llvm/IR/Intrinsics.td =================================================================== --- llvm-head.orig/include/llvm/IR/Intrinsics.td +++ llvm-head/include/llvm/IR/Intrinsics.td @@ -634,3 +634,4 @@ include "llvm/IR/IntrinsicsNVVM.td" include "llvm/IR/IntrinsicsMips.td" include "llvm/IR/IntrinsicsR600.td" include "llvm/IR/IntrinsicsBPF.td" +include "llvm/IR/IntrinsicsSystemZ.td" Index: llvm-head/include/llvm/IR/IntrinsicsSystemZ.td =================================================================== --- /dev/null +++ llvm-head/include/llvm/IR/IntrinsicsSystemZ.td @@ -0,0 +1,46 @@ +//===- IntrinsicsSystemZ.td - Defines SystemZ intrinsics ---*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines all of the SystemZ-specific intrinsics. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// +// Transactional-execution intrinsics +// +//===----------------------------------------------------------------------===// + +let TargetPrefix = "s390" in { + def int_s390_tbegin : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty], + [IntrNoDuplicate]>; + + def int_s390_tbegin_nofloat : Intrinsic<[llvm_i32_ty], + [llvm_ptr_ty, llvm_i32_ty], + [IntrNoDuplicate]>; + + def int_s390_tbeginc : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], + [IntrNoDuplicate]>; + + def int_s390_tabort : Intrinsic<[], [llvm_i64_ty], + [IntrNoReturn, Throws]>; + + def int_s390_tend : GCCBuiltin<"__builtin_tend">, + Intrinsic<[llvm_i32_ty], []>; + + def int_s390_etnd : GCCBuiltin<"__builtin_tx_nesting_depth">, + Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>; + + def int_s390_ntstg : Intrinsic<[], [llvm_i64_ty, llvm_ptr64_ty], + [IntrReadWriteArgMem]>; + + def int_s390_ppa_txassist : GCCBuiltin<"__builtin_tx_assist">, + Intrinsic<[], [llvm_i32_ty]>; +} + Index: llvm-head/lib/Target/SystemZ/SystemZ.h =================================================================== --- llvm-head.orig/lib/Target/SystemZ/SystemZ.h +++ llvm-head/lib/Target/SystemZ/SystemZ.h @@ -68,6 +68,18 @@ const unsigned CCMASK_TM_MSB_0 = C const unsigned CCMASK_TM_MSB_1 = CCMASK_2 | CCMASK_3; const unsigned CCMASK_TM = CCMASK_ANY; +// Condition-code mask assignments for TRANSACTION_BEGIN. +const unsigned CCMASK_TBEGIN_STARTED = CCMASK_0; +const unsigned CCMASK_TBEGIN_INDETERMINATE = CCMASK_1; +const unsigned CCMASK_TBEGIN_TRANSIENT = CCMASK_2; +const unsigned CCMASK_TBEGIN_PERSISTENT = CCMASK_3; +const unsigned CCMASK_TBEGIN = CCMASK_ANY; + +// Condition-code mask assignments for TRANSACTION_END. +const unsigned CCMASK_TEND_TX = CCMASK_0; +const unsigned CCMASK_TEND_NOTX = CCMASK_2; +const unsigned CCMASK_TEND = CCMASK_TEND_TX | CCMASK_TEND_NOTX; + // The position of the low CC bit in an IPM result. const unsigned IPM_CC = 28; Index: llvm-head/lib/Target/SystemZ/SystemZISelLowering.h =================================================================== --- llvm-head.orig/lib/Target/SystemZ/SystemZISelLowering.h +++ llvm-head/lib/Target/SystemZ/SystemZISelLowering.h @@ -146,6 +146,15 @@ enum { // Perform a serialization operation. (BCR 15,0 or BCR 14,0.) SERIALIZE, + // Transaction begin. The first operand is the chain, the second + // the TDB pointer, and the third the immediate control field. + // Returns chain and glue. + TBEGIN, + TBEGIN_NOFLOAT, + + // Transaction end. Just the chain operand. Returns chain and glue. + TEND, + // Wrappers around the inner loop of an 8- or 16-bit ATOMIC_SWAP or // ATOMIC_LOAD_<op>. // @@ -318,6 +327,7 @@ private: SDValue lowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const; SDValue lowerPREFETCH(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const; // If the last instruction before MBBI in MBB was some form of COMPARE, // try to replace it with a COMPARE AND BRANCH just before MBBI. @@ -355,6 +365,10 @@ private: MachineBasicBlock *emitStringWrapper(MachineInstr *MI, MachineBasicBlock *BB, unsigned Opcode) const; + MachineBasicBlock *emitTransactionBegin(MachineInstr *MI, + MachineBasicBlock *MBB, + unsigned Opcode, + bool NoFloat) const; }; } // end namespace llvm Index: llvm-head/lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- llvm-head.orig/lib/Target/SystemZ/SystemZISelLowering.cpp +++ llvm-head/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -20,6 +20,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" +#include "llvm/IR/Intrinsics.h" #include <cctype> using namespace llvm; @@ -304,6 +305,9 @@ SystemZTargetLowering::SystemZTargetLowe // Codes for which we want to perform some z-specific combinations. setTargetDAGCombine(ISD::SIGN_EXTEND); + // Handle intrinsics. + setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); + // We want to use MVC in preference to even a single load/store pair. MaxStoresPerMemcpy = 0; MaxStoresPerMemcpyOptSize = 0; @@ -1031,6 +1035,53 @@ prepareVolatileOrAtomicLoad(SDValue Chai return DAG.getNode(SystemZISD::SERIALIZE, DL, MVT::Other, Chain); } +// Return true if Op is an intrinsic node with chain that returns the CC value +// as its only (other) argument. Provide the associated SystemZISD opcode and +// the mask of valid CC values if so. +static bool isIntrinsicWithCCAndChain(SDValue Op, unsigned &Opcode, + unsigned &CCValid) { + unsigned Id = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); + switch (Id) { + case Intrinsic::s390_tbegin: + Opcode = SystemZISD::TBEGIN; + CCValid = SystemZ::CCMASK_TBEGIN; + return true; + + case Intrinsic::s390_tbegin_nofloat: + Opcode = SystemZISD::TBEGIN_NOFLOAT; + CCValid = SystemZ::CCMASK_TBEGIN; + return true; + + case Intrinsic::s390_tend: + Opcode = SystemZISD::TEND; + CCValid = SystemZ::CCMASK_TEND; + return true; + + default: + return false; + } +} + +// Emit an intrinsic with chain with a glued value instead of its CC result. +static SDValue emitIntrinsicWithChainAndGlue(SelectionDAG &DAG, SDValue Op, + unsigned Opcode) { + // Copy all operands except the intrinsic ID. + unsigned NumOps = Op.getNumOperands(); + SmallVector<SDValue, 6> Ops; + Ops.reserve(NumOps - 1); + Ops.push_back(Op.getOperand(0)); + for (unsigned I = 2; I < NumOps; ++I) + Ops.push_back(Op.getOperand(I)); + + assert(Op->getNumValues() == 2 && "Expected only CC result and chain"); + SDVTList RawVTs = DAG.getVTList(MVT::Other, MVT::Glue); + SDValue Intr = DAG.getNode(Opcode, SDLoc(Op), RawVTs, Ops); + SDValue OldChain = SDValue(Op.getNode(), 1); + SDValue NewChain = SDValue(Intr.getNode(), 0); + DAG.ReplaceAllUsesOfValueWith(OldChain, NewChain); + return Intr; +} + // CC is a comparison that will be implemented using an integer or // floating-point comparison. Return the condition code mask for // a branch on true. In the integer case, CCMASK_CMP_UO is set for @@ -1588,9 +1639,53 @@ static void adjustForTestUnderMask(Selec C.CCMask = NewCCMask; } +// Return a Comparison that tests the condition-code result of intrinsic +// node Call against constant integer CC using comparison code Cond. +// Opcode is the opcode of the SystemZISD operation for the intrinsic +// and CCValid is the set of possible condition-code results. +static Comparison getIntrinsicCmp(SelectionDAG &DAG, unsigned Opcode, + SDValue Call, unsigned CCValid, uint64_t CC, + ISD::CondCode Cond) { + Comparison C(Call, SDValue()); + C.Opcode = Opcode; + C.CCValid = CCValid; + if (Cond == ISD::SETEQ) + // bit 3 for CC==0, bit 0 for CC==3, always false for CC>3. + C.CCMask = CC < 4 ? 1 << (3 - CC) : 0; + else if (Cond == ISD::SETNE) + // ...and the inverse of that. + C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1; + else if (Cond == ISD::SETLT || Cond == ISD::SETULT) + // bits above bit 3 for CC==0 (always false), bits above bit 0 for CC==3, + // always true for CC>3. + C.CCMask = CC < 4 ? -1 << (4 - CC) : -1; + else if (Cond == ISD::SETGE || Cond == ISD::SETUGE) + // ...and the inverse of that. + C.CCMask = CC < 4 ? ~(-1 << (4 - CC)) : 0; + else if (Cond == ISD::SETLE || Cond == ISD::SETULE) + // bit 3 and above for CC==0, bit 0 and above for CC==3 (always true), + // always true for CC>3. + C.CCMask = CC < 4 ? -1 << (3 - CC) : -1; + else if (Cond == ISD::SETGT || Cond == ISD::SETUGT) + // ...and the inverse of that. + C.CCMask = CC < 4 ? ~(-1 << (3 - CC)) : 0; + else + llvm_unreachable("Unexpected integer comparison type"); + C.CCMask &= CCValid; + return C; +} + // Decide how to implement a comparison of type Cond between CmpOp0 with CmpOp1. static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, ISD::CondCode Cond) { + if (CmpOp1.getOpcode() == ISD::Constant) { + uint64_t Constant = cast<ConstantSDNode>(CmpOp1)->getZExtValue(); + unsigned Opcode, CCValid; + if (CmpOp0.getOpcode() == ISD::INTRINSIC_W_CHAIN && + CmpOp0.getResNo() == 0 && CmpOp0->hasNUsesOfValue(1, 0) && + isIntrinsicWithCCAndChain(CmpOp0, Opcode, CCValid)) + return getIntrinsicCmp(DAG, Opcode, CmpOp0, CCValid, Constant, Cond); + } Comparison C(CmpOp0, CmpOp1); C.CCMask = CCMaskForCondCode(Cond); if (C.Op0.getValueType().isFloatingPoint()) { @@ -1632,6 +1727,17 @@ static Comparison getCmp(SelectionDAG &D // Emit the comparison instruction described by C. static SDValue emitCmp(SelectionDAG &DAG, SDLoc DL, Comparison &C) { + if (!C.Op1.getNode()) { + SDValue Op; + switch (C.Op0.getOpcode()) { + case ISD::INTRINSIC_W_CHAIN: + Op = emitIntrinsicWithChainAndGlue(DAG, C.Op0, C.Opcode); + break; + default: + llvm_unreachable("Invalid comparison operands"); + } + return SDValue(Op.getNode(), Op->getNumValues() - 1); + } if (C.Opcode == SystemZISD::ICMP) return DAG.getNode(SystemZISD::ICMP, DL, MVT::Glue, C.Op0, C.Op1, DAG.getConstant(C.ICmpType, MVT::i32)); @@ -1713,7 +1819,6 @@ SDValue SystemZTargetLowering::lowerSETC } SDValue SystemZTargetLowering::lowerBR_CC(SDValue Op, SelectionDAG &DAG) const { - SDValue Chain = Op.getOperand(0); ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); SDValue CmpOp0 = Op.getOperand(2); SDValue CmpOp1 = Op.getOperand(3); @@ -1723,7 +1828,7 @@ SDValue SystemZTargetLowering::lowerBR_C Comparison C(getCmp(DAG, CmpOp0, CmpOp1, CC)); SDValue Glue = emitCmp(DAG, DL, C); return DAG.getNode(SystemZISD::BR_CCMASK, DL, Op.getValueType(), - Chain, DAG.getConstant(C.CCValid, MVT::i32), + Op.getOperand(0), DAG.getConstant(C.CCValid, MVT::i32), DAG.getConstant(C.CCMask, MVT::i32), Dest, Glue); } @@ -2561,6 +2666,30 @@ SDValue SystemZTargetLowering::lowerPREF Node->getMemoryVT(), Node->getMemOperand()); } +// Return an i32 that contains the value of CC immediately after After, +// whose final operand must be MVT::Glue. +static SDValue getCCResult(SelectionDAG &DAG, SDNode *After) { + SDValue Glue = SDValue(After, After->getNumValues() - 1); + SDValue IPM = DAG.getNode(SystemZISD::IPM, SDLoc(After), MVT::i32, Glue); + return DAG.getNode(ISD::SRL, SDLoc(After), MVT::i32, IPM, + DAG.getConstant(SystemZ::IPM_CC, MVT::i32)); +} + +SDValue +SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op, + SelectionDAG &DAG) const { + unsigned Opcode, CCValid; + if (isIntrinsicWithCCAndChain(Op, Opcode, CCValid)) { + assert(Op->getNumValues() == 2 && "Expected only CC result and chain"); + SDValue Glued = emitIntrinsicWithChainAndGlue(DAG, Op, Opcode); + SDValue CC = getCCResult(DAG, Glued.getNode()); + DAG.ReplaceAllUsesOfValueWith(SDValue(Op.getNode(), 0), CC); + return SDValue(); + } + + return SDValue(); +} + SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { @@ -2634,6 +2763,8 @@ SDValue SystemZTargetLowering::LowerOper return lowerSTACKRESTORE(Op, DAG); case ISD::PREFETCH: return lowerPREFETCH(Op, DAG); + case ISD::INTRINSIC_W_CHAIN: + return lowerINTRINSIC_W_CHAIN(Op, DAG); default: llvm_unreachable("Unexpected node to lower"); } @@ -2674,6 +2805,9 @@ const char *SystemZTargetLowering::getTa OPCODE(SEARCH_STRING); OPCODE(IPM); OPCODE(SERIALIZE); + OPCODE(TBEGIN); + OPCODE(TBEGIN_NOFLOAT); + OPCODE(TEND); OPCODE(ATOMIC_SWAPW); OPCODE(ATOMIC_LOADW_ADD); OPCODE(ATOMIC_LOADW_SUB); @@ -3501,6 +3635,50 @@ SystemZTargetLowering::emitStringWrapper return DoneMBB; } +// Update TBEGIN instruction with final opcode and register clobbers. +MachineBasicBlock * +SystemZTargetLowering::emitTransactionBegin(MachineInstr *MI, + MachineBasicBlock *MBB, + unsigned Opcode, + bool NoFloat) const { + MachineFunction &MF = *MBB->getParent(); + const TargetFrameLowering *TFI = Subtarget.getFrameLowering(); + const SystemZInstrInfo *TII = Subtarget.getInstrInfo(); + + // Update opcode. + MI->setDesc(TII->get(Opcode)); + + // We cannot handle a TBEGIN that clobbers the stack or frame pointer. + // Make sure to add the corresponding GRSM bits if they are missing. + uint64_t Control = MI->getOperand(2).getImm(); + static const unsigned GPRControlBit[16] = { + 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000, + 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100 + }; + Control |= GPRControlBit[15]; + if (TFI->hasFP(MF)) + Control |= GPRControlBit[11]; + MI->getOperand(2).setImm(Control); + + // Add GPR clobbers. + for (int I = 0; I < 16; I++) { + if ((Control & GPRControlBit[I]) == 0) { + unsigned Reg = SystemZMC::GR64Regs[I]; + MI->addOperand(MachineOperand::CreateReg(Reg, true, true)); + } + } + + // Add FPR clobbers. + if (!NoFloat && (Control & 4) != 0) { + for (int I = 0; I < 16; I++) { + unsigned Reg = SystemZMC::FP64Regs[I]; + MI->addOperand(MachineOperand::CreateReg(Reg, true, true)); + } + } + + return MBB; +} + MachineBasicBlock *SystemZTargetLowering:: EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const { switch (MI->getOpcode()) { @@ -3742,6 +3920,12 @@ EmitInstrWithCustomInserter(MachineInstr return emitStringWrapper(MI, MBB, SystemZ::MVST); case SystemZ::SRSTLoop: return emitStringWrapper(MI, MBB, SystemZ::SRST); + case SystemZ::TBEGIN: + return emitTransactionBegin(MI, MBB, SystemZ::TBEGIN, false); + case SystemZ::TBEGIN_nofloat: + return emitTransactionBegin(MI, MBB, SystemZ::TBEGIN, true); + case SystemZ::TBEGINC: + return emitTransactionBegin(MI, MBB, SystemZ::TBEGINC, true); default: llvm_unreachable("Unexpected instr type to insert"); } Index: llvm-head/test/CodeGen/SystemZ/htm-intrinsics.ll =================================================================== --- /dev/null +++ llvm-head/test/CodeGen/SystemZ/htm-intrinsics.ll @@ -0,0 +1,352 @@ +; Test transactional-execution intrinsics. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=zEC12 | FileCheck %s + +declare i32 @llvm.s390.tbegin(i8 *, i32) +declare i32 @llvm.s390.tbegin.nofloat(i8 *, i32) +declare void @llvm.s390.tbeginc(i8 *, i32) +declare i32 @llvm.s390.tend() +declare void @llvm.s390.tabort(i64) +declare void @llvm.s390.ntstg(i64, i64 *) +declare i32 @llvm.s390.etnd() +declare void @llvm.s390.ppa.txassist(i32) + +; TBEGIN. +define void @test_tbegin() { +; CHECK-LABEL: test_tbegin: +; CHECK-NOT: stmg +; CHECK: std %f8, +; CHECK: std %f9, +; CHECK: std %f10, +; CHECK: std %f11, +; CHECK: std %f12, +; CHECK: std %f13, +; CHECK: std %f14, +; CHECK: std %f15, +; CHECK: tbegin 0, 65292 +; CHECK: ld %f8, +; CHECK: ld %f9, +; CHECK: ld %f10, +; CHECK: ld %f11, +; CHECK: ld %f12, +; CHECK: ld %f13, +; CHECK: ld %f14, +; CHECK: ld %f15, +; CHECK: br %r14 + call i32 @llvm.s390.tbegin(i8 *null, i32 65292) + ret void +} + +; TBEGIN (nofloat). +define void @test_tbegin_nofloat1() { +; CHECK-LABEL: test_tbegin_nofloat1: +; CHECK-NOT: stmg +; CHECK-NOT: std +; CHECK: tbegin 0, 65292 +; CHECK: br %r14 + call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 65292) + ret void +} + +; TBEGIN (nofloat) with integer CC return value. +define i32 @test_tbegin_nofloat2() { +; CHECK-LABEL: test_tbegin_nofloat2: +; CHECK-NOT: stmg +; CHECK-NOT: std +; CHECK: tbegin 0, 65292 +; CHECK: ipm %r2 +; CHECK: srl %r2, 28 +; CHECK: br %r14 + %res = call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 65292) + ret i32 %res +} + +; TBEGIN (nofloat) with implicit CC check. +define void @test_tbegin_nofloat3(i32 *%ptr) { +; CHECK-LABEL: test_tbegin_nofloat3: +; CHECK-NOT: stmg +; CHECK-NOT: std +; CHECK: tbegin 0, 65292 +; CHECK: jnh {{\.L*}} +; CHECK: mvhi 0(%r2), 0 +; CHECK: br %r14 + %res = call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 65292) + %cmp = icmp eq i32 %res, 2 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + store i32 0, i32* %ptr, align 4 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret void +} + +; TBEGIN (nofloat) with dual CC use. +define i32 @test_tbegin_nofloat4(i32 %pad, i32 *%ptr) { +; CHECK-LABEL: test_tbegin_nofloat4: +; CHECK-NOT: stmg +; CHECK-NOT: std +; CHECK: tbegin 0, 65292 +; CHECK: ipm %r2 +; CHECK: srl %r2, 28 +; CHECK: cijlh %r2, 2, {{\.L*}} +; CHECK: mvhi 0(%r3), 0 +; CHECK: br %r14 + %res = call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 65292) + %cmp = icmp eq i32 %res, 2 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + store i32 0, i32* %ptr, align 4 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret i32 %res +} + +; TBEGIN (nofloat) with register. +define void @test_tbegin_nofloat5(i8 *%ptr) { +; CHECK-LABEL: test_tbegin_nofloat5: +; CHECK-NOT: stmg +; CHECK-NOT: std +; CHECK: tbegin 0(%r2), 65292 +; CHECK: br %r14 + call i32 @llvm.s390.tbegin.nofloat(i8 *%ptr, i32 65292) + ret void +} + +; TBEGIN (nofloat) with GRSM 0x0f00. +define void @test_tbegin_nofloat6() { +; CHECK-LABEL: test_tbegin_nofloat6: +; CHECK: stmg %r6, %r15, +; CHECK-NOT: std +; CHECK: tbegin 0, 3840 +; CHECK: br %r14 + call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 3840) + ret void +} + +; TBEGIN (nofloat) with GRSM 0xf100. +define void @test_tbegin_nofloat7() { +; CHECK-LABEL: test_tbegin_nofloat7: +; CHECK: stmg %r8, %r15, +; CHECK-NOT: std +; CHECK: tbegin 0, 61696 +; CHECK: br %r14 + call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 61696) + ret void +} + +; TBEGIN (nofloat) with GRSM 0xfe00 -- stack pointer added automatically. +define void @test_tbegin_nofloat8() { +; CHECK-LABEL: test_tbegin_nofloat8: +; CHECK-NOT: stmg +; CHECK-NOT: std +; CHECK: tbegin 0, 65280 +; CHECK: br %r14 + call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 65024) + ret void +} + +; TBEGIN (nofloat) with GRSM 0xfb00 -- no frame pointer needed. +define void @test_tbegin_nofloat9() { +; CHECK-LABEL: test_tbegin_nofloat9: +; CHECK: stmg %r10, %r15, +; CHECK-NOT: std +; CHECK: tbegin 0, 64256 +; CHECK: br %r14 + call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 64256) + ret void +} + +; TBEGIN (nofloat) with GRSM 0xfb00 -- frame pointer added automatically. +define void @test_tbegin_nofloat10(i64 %n) { +; CHECK-LABEL: test_tbegin_nofloat10: +; CHECK: stmg %r11, %r15, +; CHECK-NOT: std +; CHECK: tbegin 0, 65280 +; CHECK: br %r14 + %buf = alloca i8, i64 %n + call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 64256) + ret void +} + +; TBEGINC. +define void @test_tbeginc() { +; CHECK-LABEL: test_tbeginc: +; CHECK-NOT: stmg +; CHECK-NOT: std +; CHECK: tbeginc 0, 65288 +; CHECK: br %r14 + call void @llvm.s390.tbeginc(i8 *null, i32 65288) + ret void +} + +; TEND with integer CC return value. +define i32 @test_tend1() { +; CHECK-LABEL: test_tend1: +; CHECK: tend +; CHECK: ipm %r2 +; CHECK: srl %r2, 28 +; CHECK: br %r14 + %res = call i32 @llvm.s390.tend() + ret i32 %res +} + +; TEND with implicit CC check. +define void @test_tend3(i32 *%ptr) { +; CHECK-LABEL: test_tend3: +; CHECK: tend +; CHECK: je {{\.L*}} +; CHECK: mvhi 0(%r2), 0 +; CHECK: br %r14 + %res = call i32 @llvm.s390.tend() + %cmp = icmp eq i32 %res, 2 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + store i32 0, i32* %ptr, align 4 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret void +} + +; TEND with dual CC use. +define i32 @test_tend2(i32 %pad, i32 *%ptr) { +; CHECK-LABEL: test_tend2: +; CHECK: tend +; CHECK: ipm %r2 +; CHECK: srl %r2, 28 +; CHECK: cijlh %r2, 2, {{\.L*}} +; CHECK: mvhi 0(%r3), 0 +; CHECK: br %r14 + %res = call i32 @llvm.s390.tend() + %cmp = icmp eq i32 %res, 2 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + store i32 0, i32* %ptr, align 4 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret i32 %res +} + +; TABORT with register only. +define void @test_tabort1(i64 %val) { +; CHECK-LABEL: test_tabort1: +; CHECK: tabort 0(%r2) +; CHECK: br %r14 + call void @llvm.s390.tabort(i64 %val) + ret void +} + +; TABORT with immediate only. +define void @test_tabort2(i64 %val) { +; CHECK-LABEL: test_tabort2: +; CHECK: tabort 1234 +; CHECK: br %r14 + call void @llvm.s390.tabort(i64 1234) + ret void +} + +; TABORT with register + immediate. +define void @test_tabort3(i64 %val) { +; CHECK-LABEL: test_tabort3: +; CHECK: tabort 1234(%r2) +; CHECK: br %r14 + %sum = add i64 %val, 1234 + call void @llvm.s390.tabort(i64 %sum) + ret void +} + +; TABORT with out-of-range immediate. +define void @test_tabort4(i64 %val) { +; CHECK-LABEL: test_tabort4: +; CHECK: tabort 0({{%r[1-5]}}) +; CHECK: br %r14 + call void @llvm.s390.tabort(i64 4096) + ret void +} + +; NTSTG with base pointer only. +define void @test_ntstg1(i64 *%ptr, i64 %val) { +; CHECK-LABEL: test_ntstg1: +; CHECK: ntstg %r3, 0(%r2) +; CHECK: br %r14 + call void @llvm.s390.ntstg(i64 %val, i64 *%ptr) + ret void +} + +; NTSTG with base and index. +; Check that VSTL doesn't allow an index. +define void @test_ntstg2(i64 *%base, i64 %index, i64 %val) { +; CHECK-LABEL: test_ntstg2: +; CHECK: sllg [[REG:%r[1-5]]], %r3, 3 +; CHECK: ntstg %r4, 0([[REG]],%r2) +; CHECK: br %r14 + %ptr = getelementptr i64, i64 *%base, i64 %index + call void @llvm.s390.ntstg(i64 %val, i64 *%ptr) + ret void +} + +; NTSTG with the highest in-range displacement. +define void @test_ntstg3(i64 *%base, i64 %val) { +; CHECK-LABEL: test_ntstg3: +; CHECK: ntstg %r3, 524280(%r2) +; CHECK: br %r14 + %ptr = getelementptr i64, i64 *%base, i64 65535 + call void @llvm.s390.ntstg(i64 %val, i64 *%ptr) + ret void +} + +; NTSTG with an out-of-range positive displacement. +define void @test_ntstg4(i64 *%base, i64 %val) { +; CHECK-LABEL: test_ntstg4: +; CHECK: ntstg %r3, 0({{%r[1-5]}}) +; CHECK: br %r14 + %ptr = getelementptr i64, i64 *%base, i64 65536 + call void @llvm.s390.ntstg(i64 %val, i64 *%ptr) + ret void +} + +; NTSTG with the lowest in-range displacement. +define void @test_ntstg5(i64 *%base, i64 %val) { +; CHECK-LABEL: test_ntstg5: +; CHECK: ntstg %r3, -524288(%r2) +; CHECK: br %r14 + %ptr = getelementptr i64, i64 *%base, i64 -65536 + call void @llvm.s390.ntstg(i64 %val, i64 *%ptr) + ret void +} + +; NTSTG with an out-of-range negative displacement. +define void @test_ntstg6(i64 *%base, i64 %val) { +; CHECK-LABEL: test_ntstg6: +; CHECK: ntstg %r3, 0({{%r[1-5]}}) +; CHECK: br %r14 + %ptr = getelementptr i64, i64 *%base, i64 -65537 + call void @llvm.s390.ntstg(i64 %val, i64 *%ptr) + ret void +} + +; ETND. +define i32 @test_etnd() { +; CHECK-LABEL: test_etnd: +; CHECK: etnd %r2 +; CHECK: br %r14 + %res = call i32 @llvm.s390.etnd() + ret i32 %res +} + +; PPA (Transaction-Abort Assist) +define void @test_ppa_txassist(i32 %val) { +; CHECK-LABEL: test_ppa_txassist: +; CHECK: ppa %r2, 0, 1 +; CHECK: br %r14 + call void @llvm.s390.ppa.txassist(i32 %val) + ret void +} + Index: llvm-head/test/MC/SystemZ/insn-bad-zEC12.s =================================================================== --- llvm-head.orig/test/MC/SystemZ/insn-bad-zEC12.s +++ llvm-head/test/MC/SystemZ/insn-bad-zEC12.s @@ -3,6 +3,22 @@ # RUN: FileCheck < %t %s #CHECK: error: invalid operand +#CHECK: ntstg %r0, -524289 +#CHECK: error: invalid operand +#CHECK: ntstg %r0, 524288 + + ntstg %r0, -524289 + ntstg %r0, 524288 + +#CHECK: error: invalid operand +#CHECK: ppa %r0, %r0, -1 +#CHECK: error: invalid operand +#CHECK: ppa %r0, %r0, 16 + + ppa %r0, %r0, -1 + ppa %r0, %r0, 16 + +#CHECK: error: invalid operand #CHECK: risbgn %r0,%r0,0,0,-1 #CHECK: error: invalid operand #CHECK: risbgn %r0,%r0,0,0,64 @@ -22,3 +38,47 @@ risbgn %r0,%r0,-1,0,0 risbgn %r0,%r0,256,0,0 +#CHECK: error: invalid operand +#CHECK: tabort -1 +#CHECK: error: invalid operand +#CHECK: tabort 4096 +#CHECK: error: invalid use of indexed addressing +#CHECK: tabort 0(%r1,%r2) + + tabort -1 + tabort 4096 + tabort 0(%r1,%r2) + +#CHECK: error: invalid operand +#CHECK: tbegin -1, 0 +#CHECK: error: invalid operand +#CHECK: tbegin 4096, 0 +#CHECK: error: invalid use of indexed addressing +#CHECK: tbegin 0(%r1,%r2), 0 +#CHECK: error: invalid operand +#CHECK: tbegin 0, -1 +#CHECK: error: invalid operand +#CHECK: tbegin 0, 65536 + + tbegin -1, 0 + tbegin 4096, 0 + tbegin 0(%r1,%r2), 0 + tbegin 0, -1 + tbegin 0, 65536 + +#CHECK: error: invalid operand +#CHECK: tbeginc -1, 0 +#CHECK: error: invalid operand +#CHECK: tbeginc 4096, 0 +#CHECK: error: invalid use of indexed addressing +#CHECK: tbeginc 0(%r1,%r2), 0 +#CHECK: error: invalid operand +#CHECK: tbeginc 0, -1 +#CHECK: error: invalid operand +#CHECK: tbeginc 0, 65536 + + tbeginc -1, 0 + tbeginc 4096, 0 + tbeginc 0(%r1,%r2), 0 + tbeginc 0, -1 + tbeginc 0, 65536 Index: llvm-head/test/MC/SystemZ/insn-good-zEC12.s =================================================================== --- llvm-head.orig/test/MC/SystemZ/insn-good-zEC12.s +++ llvm-head/test/MC/SystemZ/insn-good-zEC12.s @@ -1,6 +1,48 @@ # For zEC12 and above. # RUN: llvm-mc -triple s390x-linux-gnu -mcpu=zEC12 -show-encoding %s | FileCheck %s +#CHECK: etnd %r0 # encoding: [0xb2,0xec,0x00,0x00] +#CHECK: etnd %r15 # encoding: [0xb2,0xec,0x00,0xf0] +#CHECK: etnd %r7 # encoding: [0xb2,0xec,0x00,0x70] + + etnd %r0 + etnd %r15 + etnd %r7 + +#CHECK: ntstg %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0x25] +#CHECK: ntstg %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0x25] +#CHECK: ntstg %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0x25] +#CHECK: ntstg %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0x25] +#CHECK: ntstg %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0x25] +#CHECK: ntstg %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0x25] +#CHECK: ntstg %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0x25] +#CHECK: ntstg %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0x25] +#CHECK: ntstg %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0x25] +#CHECK: ntstg %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0x25] + + ntstg %r0, -524288 + ntstg %r0, -1 + ntstg %r0, 0 + ntstg %r0, 1 + ntstg %r0, 524287 + ntstg %r0, 0(%r1) + ntstg %r0, 0(%r15) + ntstg %r0, 524287(%r1,%r15) + ntstg %r0, 524287(%r15,%r1) + ntstg %r15, 0 + +#CHECK: ppa %r0, %r0, 0 # encoding: [0xb2,0xe8,0x00,0x00] +#CHECK: ppa %r0, %r0, 15 # encoding: [0xb2,0xe8,0xf0,0x00] +#CHECK: ppa %r0, %r15, 0 # encoding: [0xb2,0xe8,0x00,0x0f] +#CHECK: ppa %r4, %r6, 7 # encoding: [0xb2,0xe8,0x70,0x46] +#CHECK: ppa %r15, %r0, 0 # encoding: [0xb2,0xe8,0x00,0xf0] + + ppa %r0, %r0, 0 + ppa %r0, %r0, 15 + ppa %r0, %r15, 0 + ppa %r4, %r6, 7 + ppa %r15, %r0, 0 + #CHECK: risbgn %r0, %r0, 0, 0, 0 # encoding: [0xec,0x00,0x00,0x00,0x00,0x59] #CHECK: risbgn %r0, %r0, 0, 0, 63 # encoding: [0xec,0x00,0x00,0x00,0x3f,0x59] #CHECK: risbgn %r0, %r0, 0, 255, 0 # encoding: [0xec,0x00,0x00,0xff,0x00,0x59] @@ -17,3 +59,68 @@ risbgn %r15,%r0,0,0,0 risbgn %r4,%r5,6,7,8 +#CHECK: tabort 0 # encoding: [0xb2,0xfc,0x00,0x00] +#CHECK: tabort 0(%r1) # encoding: [0xb2,0xfc,0x10,0x00] +#CHECK: tabort 0(%r15) # encoding: [0xb2,0xfc,0xf0,0x00] +#CHECK: tabort 4095 # encoding: [0xb2,0xfc,0x0f,0xff] +#CHECK: tabort 4095(%r1) # encoding: [0xb2,0xfc,0x1f,0xff] +#CHECK: tabort 4095(%r15) # encoding: [0xb2,0xfc,0xff,0xff] + + tabort 0 + tabort 0(%r1) + tabort 0(%r15) + tabort 4095 + tabort 4095(%r1) + tabort 4095(%r15) + +#CHECK: tbegin 0, 0 # encoding: [0xe5,0x60,0x00,0x00,0x00,0x00] +#CHECK: tbegin 4095, 0 # encoding: [0xe5,0x60,0x0f,0xff,0x00,0x00] +#CHECK: tbegin 0, 0 # encoding: [0xe5,0x60,0x00,0x00,0x00,0x00] +#CHECK: tbegin 0, 1 # encoding: [0xe5,0x60,0x00,0x00,0x00,0x01] +#CHECK: tbegin 0, 32767 # encoding: [0xe5,0x60,0x00,0x00,0x7f,0xff] +#CHECK: tbegin 0, 32768 # encoding: [0xe5,0x60,0x00,0x00,0x80,0x00] +#CHECK: tbegin 0, 65535 # encoding: [0xe5,0x60,0x00,0x00,0xff,0xff] +#CHECK: tbegin 0(%r1), 42 # encoding: [0xe5,0x60,0x10,0x00,0x00,0x2a] +#CHECK: tbegin 0(%r15), 42 # encoding: [0xe5,0x60,0xf0,0x00,0x00,0x2a] +#CHECK: tbegin 4095(%r1), 42 # encoding: [0xe5,0x60,0x1f,0xff,0x00,0x2a] +#CHECK: tbegin 4095(%r15), 42 # encoding: [0xe5,0x60,0xff,0xff,0x00,0x2a] + + tbegin 0, 0 + tbegin 4095, 0 + tbegin 0, 0 + tbegin 0, 1 + tbegin 0, 32767 + tbegin 0, 32768 + tbegin 0, 65535 + tbegin 0(%r1), 42 + tbegin 0(%r15), 42 + tbegin 4095(%r1), 42 + tbegin 4095(%r15), 42 + +#CHECK: tbeginc 0, 0 # encoding: [0xe5,0x61,0x00,0x00,0x00,0x00] +#CHECK: tbeginc 4095, 0 # encoding: [0xe5,0x61,0x0f,0xff,0x00,0x00] +#CHECK: tbeginc 0, 0 # encoding: [0xe5,0x61,0x00,0x00,0x00,0x00] +#CHECK: tbeginc 0, 1 # encoding: [0xe5,0x61,0x00,0x00,0x00,0x01] +#CHECK: tbeginc 0, 32767 # encoding: [0xe5,0x61,0x00,0x00,0x7f,0xff] +#CHECK: tbeginc 0, 32768 # encoding: [0xe5,0x61,0x00,0x00,0x80,0x00] +#CHECK: tbeginc 0, 65535 # encoding: [0xe5,0x61,0x00,0x00,0xff,0xff] +#CHECK: tbeginc 0(%r1), 42 # encoding: [0xe5,0x61,0x10,0x00,0x00,0x2a] +#CHECK: tbeginc 0(%r15), 42 # encoding: [0xe5,0x61,0xf0,0x00,0x00,0x2a] +#CHECK: tbeginc 4095(%r1), 42 # encoding: [0xe5,0x61,0x1f,0xff,0x00,0x2a] +#CHECK: tbeginc 4095(%r15), 42 # encoding: [0xe5,0x61,0xff,0xff,0x00,0x2a] + + tbeginc 0, 0 + tbeginc 4095, 0 + tbeginc 0, 0 + tbeginc 0, 1 + tbeginc 0, 32767 + tbeginc 0, 32768 + tbeginc 0, 65535 + tbeginc 0(%r1), 42 + tbeginc 0(%r15), 42 + tbeginc 4095(%r1), 42 + tbeginc 4095(%r15), 42 + +#CHECK: tend # encoding: [0xb2,0xf8,0x00,0x00] + + tend Index: llvm-head/test/MC/SystemZ/insn-bad-z196.s =================================================================== --- llvm-head.orig/test/MC/SystemZ/insn-bad-z196.s +++ llvm-head/test/MC/SystemZ/insn-bad-z196.s @@ -244,6 +244,11 @@ cxlgbr %f0, 16, %r0, 0 cxlgbr %f2, 0, %r0, 0 +#CHECK: error: {{(instruction requires: transactional-execution)?}} +#CHECK: etnd %r7 + + etnd %r7 + #CHECK: error: invalid operand #CHECK: fidbra %f0, 0, %f0, -1 #CHECK: error: invalid operand @@ -546,6 +551,16 @@ locr %r0,%r0,-1 locr %r0,%r0,16 +#CHECK: error: {{(instruction requires: transactional-execution)?}} +#CHECK: ntstg %r0, 524287(%r1,%r15) + + ntstg %r0, 524287(%r1,%r15) + +#CHECK: error: {{(instruction requires: processor-assist)?}} +#CHECK: ppa %r4, %r6, 7 + + ppa %r4, %r6, 7 + #CHECK: error: {{(instruction requires: miscellaneous-extensions)?}} #CHECK: risbgn %r1, %r2, 0, 0, 0 @@ -690,3 +705,24 @@ stocg %r0,-524289,1 stocg %r0,524288,1 stocg %r0,0(%r1,%r2),1 + +#CHECK: error: {{(instruction requires: transactional-execution)?}} +#CHECK: tabort 4095(%r1) + + tabort 4095(%r1) + +#CHECK: error: {{(instruction requires: transactional-execution)?}} +#CHECK: tbegin 4095(%r1), 42 + + tbegin 4095(%r1), 42 + +#CHECK: error: {{(instruction requires: transactional-execution)?}} +#CHECK: tbeginc 4095(%r1), 42 + + tbeginc 4095(%r1), 42 + +#CHECK: error: {{(instruction requires: transactional-execution)?}} +#CHECK: tend + + tend + Index: llvm-head/test/MC/Disassembler/SystemZ/insns.txt =================================================================== --- llvm-head.orig/test/MC/Disassembler/SystemZ/insns.txt +++ llvm-head/test/MC/Disassembler/SystemZ/insns.txt @@ -2503,6 +2503,15 @@ # CHECK: ear %r15, %a15 0xb2 0x4f 0x00 0xff +# CHECK: etnd %r0 +0xb2 0xec 0x00 0x00 + +# CHECK: etnd %r15 +0xb2 0xec 0x00 0xf0 + +# CHECK: etnd %r7 +0xb2 0xec 0x00 0x70 + # CHECK: fidbr %f0, 0, %f0 0xb3 0x5f 0x00 0x00 @@ -6034,6 +6043,36 @@ # CHECK: ny %r15, 0 0xe3 0xf0 0x00 0x00 0x00 0x54 +# CHECK: ntstg %r0, -524288 +0xe3 0x00 0x00 0x00 0x80 0x25 + +# CHECK: ntstg %r0, -1 +0xe3 0x00 0x0f 0xff 0xff 0x25 + +# CHECK: ntstg %r0, 0 +0xe3 0x00 0x00 0x00 0x00 0x25 + +# CHECK: ntstg %r0, 1 +0xe3 0x00 0x00 0x01 0x00 0x25 + +# CHECK: ntstg %r0, 524287 +0xe3 0x00 0x0f 0xff 0x7f 0x25 + +# CHECK: ntstg %r0, 0(%r1) +0xe3 0x00 0x10 0x00 0x00 0x25 + +# CHECK: ntstg %r0, 0(%r15) +0xe3 0x00 0xf0 0x00 0x00 0x25 + +# CHECK: ntstg %r0, 524287(%r1,%r15) +0xe3 0x01 0xff 0xff 0x7f 0x25 + +# CHECK: ntstg %r0, 524287(%r15,%r1) +0xe3 0x0f 0x1f 0xff 0x7f 0x25 + +# CHECK: ntstg %r15, 0 +0xe3 0xf0 0x00 0x00 0x00 0x25 + # CHECK: oc 0(1), 0 0xd6 0x00 0x00 0x00 0x00 0x00 @@ -6346,6 +6385,21 @@ # CHECK: popcnt %r7, %r8 0xb9 0xe1 0x00 0x78 +# CHECK: ppa %r0, %r0, 0 +0xb2 0xe8 0x00 0x00 + +# CHECK: ppa %r0, %r0, 15 +0xb2 0xe8 0xf0 0x00 + +# CHECK: ppa %r0, %r15, 0 +0xb2 0xe8 0x00 0x0f + +# CHECK: ppa %r4, %r6, 7 +0xb2 0xe8 0x70 0x46 + +# CHECK: ppa %r15, %r0, 0 +0xb2 0xe8 0x00 0xf0 + # CHECK: risbg %r0, %r0, 0, 0, 0 0xec 0x00 0x00 0x00 0x00 0x55 @@ -8062,6 +8116,93 @@ # CHECK: sy %r15, 0 0xe3 0xf0 0x00 0x00 0x00 0x5b +# CHECK: tabort 0 +0xb2 0xfc 0x00 0x00 + +# CHECK: tabort 0(%r1) +0xb2 0xfc 0x10 0x00 + +# CHECK: tabort 0(%r15) +0xb2 0xfc 0xf0 0x00 + +# CHECK: tabort 4095 +0xb2 0xfc 0x0f 0xff + +# CHECK: tabort 4095(%r1) +0xb2 0xfc 0x1f 0xff + +# CHECK: tabort 4095(%r15) +0xb2 0xfc 0xff 0xff + +# CHECK: tbegin 0, 0 +0xe5 0x60 0x00 0x00 0x00 0x00 + +# CHECK: tbegin 4095, 0 +0xe5 0x60 0x0f 0xff 0x00 0x00 + +# CHECK: tbegin 0, 0 +0xe5 0x60 0x00 0x00 0x00 0x00 + +# CHECK: tbegin 0, 1 +0xe5 0x60 0x00 0x00 0x00 0x01 + +# CHECK: tbegin 0, 32767 +0xe5 0x60 0x00 0x00 0x7f 0xff + +# CHECK: tbegin 0, 32768 +0xe5 0x60 0x00 0x00 0x80 0x00 + +# CHECK: tbegin 0, 65535 +0xe5 0x60 0x00 0x00 0xff 0xff + +# CHECK: tbegin 0(%r1), 42 +0xe5 0x60 0x10 0x00 0x00 0x2a + +# CHECK: tbegin 0(%r15), 42 +0xe5 0x60 0xf0 0x00 0x00 0x2a + +# CHECK: tbegin 4095(%r1), 42 +0xe5 0x60 0x1f 0xff 0x00 0x2a + +# CHECK: tbegin 4095(%r15), 42 +0xe5 0x60 0xff 0xff 0x00 0x2a + +# CHECK: tbeginc 0, 0 +0xe5 0x61 0x00 0x00 0x00 0x00 + +# CHECK: tbeginc 4095, 0 +0xe5 0x61 0x0f 0xff 0x00 0x00 + +# CHECK: tbeginc 0, 0 +0xe5 0x61 0x00 0x00 0x00 0x00 + +# CHECK: tbeginc 0, 1 +0xe5 0x61 0x00 0x00 0x00 0x01 + +# CHECK: tbeginc 0, 32767 +0xe5 0x61 0x00 0x00 0x7f 0xff + +# CHECK: tbeginc 0, 32768 +0xe5 0x61 0x00 0x00 0x80 0x00 + +# CHECK: tbeginc 0, 65535 +0xe5 0x61 0x00 0x00 0xff 0xff + +# CHECK: tbeginc 0(%r1), 42 +0xe5 0x61 0x10 0x00 0x00 0x2a + +# CHECK: tbeginc 0(%r15), 42 +0xe5 0x61 0xf0 0x00 0x00 0x2a + +# CHECK: tbeginc 4095(%r1), 42 +0xe5 0x61 0x1f 0xff 0x00 0x2a + +# CHECK: tbeginc 4095(%r15), 42 +0xe5 0x61 0xff 0xff 0x00 0x2a + +# CHECK: tend +0xb2 0xf8 0x00 0x00 + # CHECK: tm 0, 0 0x91 0x00 0x00 0x00 llvm-svn: 233803 |
|
Ulrich Weigand | 371d10a4eb |
[SystemZ] Support RISBGN instruction on zEC12
So far, we do not yet support any instruction specific to zEC12. Most of the facilities added with zEC12 are indeed not very useful to compiler code generation, but there is one exception: the miscellaneous-extensions facility provides the RISBGN instruction, which is a variant of RISBG that does not set the condition code. Add support for this facility, MC support for RISBGN, and CodeGen support for prefering RISBGN over RISBG on zEC12, unless we can actually make use of the condition code set by RISBG. llvm-svn: 233690 |
|
Ulrich Weigand | b401218ca2 |
[SystemZ] Use POPCNT instruction on z196
We already exploit a number of instructions specific to z196, but not yet POPCNT. Add support for the population-count facility, MC support for the POPCNT instruction, CodeGen support for using POPCNT, and implement the getPopcntSupport TargetTransformInfo hook. llvm-svn: 233689 |
|
Eric Christopher | 8b7706517c |
Move DataLayout back to the TargetMachine from TargetSubtargetInfo
derived classes. Since global data alignment, layout, and mangling is often based on the DataLayout, move it to the TargetMachine. This ensures that global data is going to be layed out and mangled consistently if the subtarget changes on a per function basis. Prior to this all targets(*) have had subtarget dependent code moved out and onto the TargetMachine. *One target hasn't been migrated as part of this change: R600. The R600 port has, as a subtarget feature, the size of pointers and this affects global data layout. I've currently hacked in a FIXME to enable progress, but the port needs to be updated to either pass the 64-bitness to the TargetMachine, or fix the DataLayout to avoid subtarget dependent features. llvm-svn: 227113 |
|
Benjamin Kramer | a7c40ef022 |
Canonicalize header guards into a common format.
Add header guards to files that were missing guards. Remove #endif comments as they don't seem common in LLVM (we can easily add them back if we decide they're useful) Changes made by clang-tidy with minor tweaks. llvm-svn: 215558 |
|
Eric Christopher | d913448b38 |
Remove the TargetMachine forwards for TargetSubtargetInfo based
information and update all callers. No functional change. llvm-svn: 214781 |
|
Eric Christopher | 5234995e80 |
Move the subtarget dependent features from SystemZTargetMachine
down to the subtarget. Add an initialization routine to assist. llvm-svn: 212124 |
|
Richard Sandiford | b4d67b593e |
[SystemZ] Remove "virtual" from override methods
Also fix a couple of cases where "override" was missing. No behavioural change intended. llvm-svn: 203110 |
|
Craig Topper | 73156025e0 |
Switch all uses of LLVM_OVERRIDE to just use 'override' directly.
llvm-svn: 202621 |
|
Richard Sandiford | 45645a2c1c |
[SystemZ] Add MC support for interlocked-access 1 instructions
llvm-svn: 197984 |
|
Richard Sandiford | 9afe613d12 |
Add TargetLowering::prepareVolatileOrAtomicLoad
One unusual feature of the z architecture is that the result of a previous load can be reused indefinitely for subsequent loads, even if a cache-coherent store to that location is performed by another CPU. A special serializing instruction must be used if you want to force a load to be reattempted. Since volatile loads are not supposed to be omitted in this way, we should insert a serializing instruction before each such load. The same goes for atomic loads. The patch implements this at the IR->DAG boundary, in a similar way to atomic fences. It is a no-op for targets other than SystemZ. llvm-svn: 196905 |
|
Juergen Ributzka | d12ccbd343 |
[weak vtables] Remove a bunch of weak vtables
This patch removes most of the trivial cases of weak vtables by pinning them to a single object file. The memory leaks in this version have been fixed. Thanks Alexey for pointing them out. Differential Revision: http://llvm-reviews.chandlerc.com/D2068 Reviewed by Andy llvm-svn: 195064 |
|
Alexey Samsonov | 49109a279c |
Revert r194865 and r194874.
This change is incorrect. If you delete virtual destructor of both a base class and a subclass, then the following code: Base *foo = new Child(); delete foo; will not cause the destructor for members of Child class. As a result, I observe plently of memory leaks. Notable examples I investigated are: ObjectBuffer and ObjectBufferStream, AttributeImpl and StringSAttributeImpl. llvm-svn: 194997 |
|
Juergen Ributzka | dbedae89b9 |
[weak vtables] Remove a bunch of weak vtables
This patch removes most of the trivial cases of weak vtables by pinning them to a single object file. Differential Revision: http://llvm-reviews.chandlerc.com/D2068 Reviewed by Andy llvm-svn: 194865 |
|
Richard Sandiford | 094e609716 |
[SystemZ] Set usaAA to true
useAA significantly improves the handling of vector code that has TBAA information attached. It also helps other cases, as shown by the testsuite changes here. The only real downside I've seen is that it interferes with MergeConsecutiveStores. The problem is that that optimization works top down, starting at the first store in the chain, and looks for cases where the chain result is only used by a single related store. These related stores don't alias, so useAA will have rewritten all the later stores to use a different chain input (typically the same one as the first store). I think the advantages outweigh the disadvantages though, so for now I've just disabled alias analysis for the unaligned-01.ll test. llvm-svn: 193521 |
|
Richard Sandiford | 8e92c389e4 |
[SystemZ] Add FI[EDX]BRA
These are extensions of the existing FI[EDX]BR instructions, but use a spare bit to suppress inexact conditions. llvm-svn: 188894 |
|
Richard Sandiford | 6cf80b3ec0 |
[SystemZ] Add RISBLG and RISBHG instruction definitions
The next patch will make use of RISBLG for codegen. llvm-svn: 187490 |
|
Richard Sandiford | a68e6f5660 |
[SystemZ] Add STOC and STOCG
These instructions are allowed to trap even if the condition is false, so for now they are only used for "*ptr = (cond ? x : *ptr)"-style constructs. llvm-svn: 187111 |
|
Richard Sandiford | 27d1cfe3d4 |
[SystemZ] Start adding z196 and zEC12 support
This first step just adds definitions for SLLK, SRLK and SRAK. The next patch will actually make use of them during codegen. insn-bad.s tests that some form of error is reported when using these instructions on z10. More work is needed to get the "instruction requires: distinct-ops" that we'd ideally like, so I've stubbed that part out for now. I'll come back and make it mandatory once the necessary changes are in. llvm-svn: 186680 |
|
Ulrich Weigand | 5f613dfd1f |
[SystemZ] Add back end
This adds the actual lib/Target/SystemZ target files necessary to implement the SystemZ target. Note that at this point, the target cannot yet be built since the configure bits are missing. Those will be provided shortly by a follow-on patch. This version of the patch incorporates feedback from reviews by Chris Lattner and Anton Korobeynikov. Thanks to all reviewers! Patch by Richard Sandiford. llvm-svn: 181203 |
|
Dan Gohman | dfc96aea90 |
Remove the SystemZ backend.
llvm-svn: 142878 |
|
Evan Cheng | 1a72add615 |
Compute feature bits at time of MCSubtargetInfo initialization.
llvm-svn: 134606 |
|
Evan Cheng | c9c090d7a5 |
Rename XXXGenSubtarget.inc to XXXGenSubtargetInfo.inc for consistency.
llvm-svn: 134281 |
|
Evan Cheng | 0d639a28aa |
Rename TargetSubtarget to TargetSubtargetInfo for consistency.
llvm-svn: 134259 |
|
Evan Cheng | 54b68e3432 |
- Added MCSubtargetInfo to capture subtarget features and scheduling
itineraries. - Refactor TargetSubtarget to be based on MCSubtargetInfo. - Change tablegen generated subtarget info to initialize MCSubtargetInfo and hide more details from targets. llvm-svn: 134257 |
|
Evan Cheng | fe6e405e8c |
Fix the ridiculous SubtargetFeatures API where it implicitly expects CPU name to
be the first encoded as the first feature. It then uses the CPU name to look up features / scheduling itineray even though clients know full well the CPU name being used to query these properties. The fix is to just have the clients explictly pass the CPU name! llvm-svn: 134127 |
|
Daniel Dunbar | 31b44e8f6c |
Normalize Subtarget constructors to take a target triple string instead of
Module*. Also, dropped uses of TargetMachine where unnecessary. The only target which still takes a TargetMachine& is Mips, I would appreciate it if someone would normalize this to match other targets. llvm-svn: 77918 |
|
Anton Korobeynikov | 091872cb37 |
Implement 'large' PIC model
llvm-svn: 76006 |
|
Anton Korobeynikov | 2d218394c6 |
Add z9 and z10 target processors. Mark z10-only instructions as such.
llvm-svn: 75977 |
|
Anton Korobeynikov | 31e9a53d17 |
Unbreak due to mainline api change
llvm-svn: 75952 |
|
Anton Korobeynikov | c334c28b3b |
Let's start another backend :)
llvm-svn: 75909 |