summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/SystemZ
Commit message (Collapse)AuthorAgeFilesLines
...
* MC: Clean up method names in MCContext.Jim Grosbach2015-05-182-4/+4
| | | | | | | The naming was a mish-mash of old and new style. Update to be consistent with the new. NFC. llvm-svn: 237594
* Remove MCAssembler.h include from MCStreamer.h and fix users of MCStreamer.hPete Cooper2015-05-151-0/+1
| | | | llvm-svn: 237483
* Remove 3 includes from MCInstrDesc.h and explicitly include them where neededPete Cooper2015-05-153-0/+5
| | | | llvm-svn: 237481
* MC: MCCodeGenInfo naming update. NFC.Jim Grosbach2015-05-151-1/+1
| | | | | | s/InitMCCodeGenInfo/initMCCodeGenInfo/ llvm-svn: 237471
* MC: Update MCCodeEmitter naming. NFC.Jim Grosbach2015-05-151-2/+2
| | | | | | s/EncodeInstruction/encodeInstruction/ llvm-svn: 237469
* MC: Update MCFixup naming. NFC.Jim Grosbach2015-05-151-2/+2
| | | | | | s/MCFixup::Create/MCFixup::create/ llvm-svn: 237468
* MC: Modernize MCOperand API naming. NFC.Jim Grosbach2015-05-133-34/+34
| | | | | | MCOperand::Create*() methods renamed to MCOperand::create*(). llvm-svn: 237275
* Silencing an MSVC warning: '<<' : result of 32-bit shift implicitly ↵Aaron Ballman2015-05-111-1/+1
| | | | | | converted to 64 bits (was 64-bit shift intended?); NFC llvm-svn: 236987
* SystemZ: silence a GCC warningSaleem Abdulrasool2015-05-101-2/+2
| | | | | | | | warning: enumeral and non-enumeral type in conditional expression Cast the 0 to the appropriate type. NFC. Identified by GCC 4.9.2 llvm-svn: 236942
* Change getTargetNodeName() to produce compiler warnings for missing cases, ↵Matthias Braun2015-05-072-2/+3
| | | | | | fix them llvm-svn: 236775
* [SystemZ] Add vector intrinsicsUlrich Weigand2015-05-055-153/+497
| | | | | | | | | | | | | | | | | | | This adds intrinsics to allow access to all of the z13 vector instructions. Note that instructions whose semantics can be described by standard LLVM IR do not get any intrinsics. For each instructions whose semantics *cannot* (fully) be described, we define an LLVM IR target-specific intrinsic that directly maps to this instruction. For instructions that also set the condition code, the LLVM IR intrinsic returns the post-instruction CC value as a second result. Instruction selection will attempt to detect code that compares that CC value against constants and use the condition code directly instead. Based on a patch by Richard Sandiford. llvm-svn: 236527
* [SystemZ] Mark v1i128 and v1f128 as unsupportedUlrich Weigand2015-05-051-0/+32
| | | | | | | | | | | | The ABI specifies that <1 x i128> and <1 x fp128> are supposed to be passed in vector registers. We do not yet support those types, and some infrastructure is missing before we can do so. In order to prevent accidentally generating code violating the ABI, this patch adds checks to detect those types and error out if user code attempts to use them. llvm-svn: 236526
* [SystemZ] Handle sub-128 vectorsUlrich Weigand2015-05-056-27/+155
| | | | | | | | | | | | | | | | | | | | | The ABI allows sub-128 vectors to be passed and returned in registers, with the vector occupying the upper part of a register. We therefore want to legalize those types by widening the vector rather than promoting the elements. The patch includes some simple tests for sub-128 vectors and also tests that we can recognize various pack sequences, some of which use sub-128 vectors as temporary results. One of these forms is based on the pack sequences generated by llvmpipe when no intrinsics are used. Signed unpacks are recognized as BUILD_VECTORs whose elements are individually sign-extended. Unsigned unpacks can have the equivalent form with zero extension, but they also occur as shuffles in which some elements are zero. Based on a patch by Richard Sandiford. llvm-svn: 236525
* [SystemZ] Add CodeGen support for scalar f64 ops in vector registersUlrich Weigand2015-05-058-23/+261
| | | | | | | | | | | | The z13 vector facility includes some instructions that operate only on the high f64 in a v2f64, effectively extending the FP register set from 16 to 32 registers. It's still better to use the old instructions if the operands happen to fit though, since the older instructions have a shorter encoding. Based on a patch by Richard Sandiford. llvm-svn: 236524
* [SystemZ] Add CodeGen support for v4f32Ulrich Weigand2015-05-058-20/+231
| | | | | | | | | | | | | | | | The architecture doesn't really have any native v4f32 operations except v4f32->v2f64 and v2f64->v4f32 conversions, with only half of the v4f32 elements being used. Even so, using vector registers for <4 x float> and scalarising individual operations is much better than generating completely scalar code, since there's much less register pressure. It's also more efficient to do v4f32 comparisons by extending to 2 v2f64s, comparing those, then packing the result. This particularly helps with llvmpipe. Based on a patch by Richard Sandiford. llvm-svn: 236523
* [SystemZ] Add CodeGen support for v2f64Ulrich Weigand2015-05-056-37/+342
| | | | | | | | | This adds ABI and CodeGen support for the v2f64 type, which is natively supported by z13 instructions. Based on a patch by Richard Sandiford. llvm-svn: 236522
* [SystemZ] Add CodeGen support for integer vector typesUlrich Weigand2015-05-0514-146/+2138
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This the first of a series of patches to add CodeGen support exploiting the instructions of the z13 vector facility. This patch adds support for the native integer vector types (v16i8, v8i16, v4i32, v2i64). When the vector facility is present, we default to the new vector ABI. This is characterized by two major differences: - Vector types are passed/returned in vector registers (except for unnamed arguments of a variable-argument list function). - Vector types are at most 8-byte aligned. The reason for the choice of 8-byte vector alignment is that the hardware is able to efficiently load vectors at 8-byte alignment, and the ABI only guarantees 8-byte alignment of the stack pointer, so requiring any higher alignment for vectors would require dynamic stack re-alignment code. However, for compatibility with old code that may use vector types, when *not* using the vector facility, the old alignment rules (vector types are naturally aligned) remain in use. These alignment rules are not only implemented at the C language level (implemented in clang), but also at the LLVM IR level. This is done by selecting a different DataLayout string depending on whether the vector ABI is in effect or not. Based on a patch by Richard Sandiford. llvm-svn: 236521
* [SystemZ] Add z13 vector facility and MC supportUlrich Weigand2015-05-0515-116/+2051
| | | | | | | | | | | | | | | | | | | | | 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
* [ShrinkWrap] Add (a simplified version) of shrink-wrapping.Quentin Colombet2015-05-052-3/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch introduces a new pass that computes the safe point to insert the prologue and epilogue of the function. The interest is to find safe points that are cheaper than the entry and exits blocks. As an example and to avoid regressions to be introduce, this patch also implements the required bits to enable the shrink-wrapping pass for AArch64. ** Context ** Currently we insert the prologue and epilogue of the method/function in the entry and exits blocks. Although this is correct, we can do a better job when those are not immediately required and insert them at less frequently executed places. The job of the shrink-wrapping pass is to identify such places. ** Motivating example ** Let us consider the following function that perform a call only in one branch of a if: define i32 @f(i32 %a, i32 %b) { %tmp = alloca i32, align 4 %tmp2 = icmp slt i32 %a, %b br i1 %tmp2, label %true, label %false true: store i32 %a, i32* %tmp, align 4 %tmp4 = call i32 @doSomething(i32 0, i32* %tmp) br label %false false: %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] ret i32 %tmp.0 } On AArch64 this code generates (removing the cfi directives to ease readabilities): _f: ; @f ; BB#0: stp x29, x30, [sp, #-16]! mov x29, sp sub sp, sp, #16 ; =16 cmp w0, w1 b.ge LBB0_2 ; BB#1: ; %true stur w0, [x29, #-4] sub x1, x29, #4 ; =4 mov w0, wzr bl _doSomething LBB0_2: ; %false mov sp, x29 ldp x29, x30, [sp], #16 ret With shrink-wrapping we could generate: _f: ; @f ; BB#0: cmp w0, w1 b.ge LBB0_2 ; BB#1: ; %true stp x29, x30, [sp, #-16]! mov x29, sp sub sp, sp, #16 ; =16 stur w0, [x29, #-4] sub x1, x29, #4 ; =4 mov w0, wzr bl _doSomething add sp, x29, #16 ; =16 ldp x29, x30, [sp], #16 LBB0_2: ; %false ret Therefore, we would pay the overhead of setting up/destroying the frame only if we actually do the call. ** Proposed Solution ** This patch introduces a new machine pass that perform the shrink-wrapping analysis (See the comments at the beginning of ShrinkWrap.cpp for more details). It then stores the safe save and restore point into the MachineFrameInfo attached to the MachineFunction. This information is then used by the PrologEpilogInserter (PEI) to place the related code at the right place. This pass runs right before the PEI. Unlike the original paper of Chow from PLDI’88, this implementation of shrink-wrapping does not use expensive data-flow analysis and does not need hack to properly avoid frequently executed point. Instead, it relies on dominance and loop properties. The pass is off by default and each target can opt-in by setting the EnableShrinkWrap boolean to true in their derived class of TargetPassConfig. This setting can also be overwritten on the command line by using -enable-shrink-wrap. Before you try out the pass for your target, make sure you properly fix your emitProlog/emitEpilog/adjustForXXX method to cope with basic blocks that are not necessarily the entry block. ** Design Decisions ** 1. ShrinkWrap is its own pass right now. It could frankly be merged into PEI but for debugging and clarity I thought it was best to have its own file. 2. Right now, we only support one save point and one restore point. At some point we can expand this to several save point and restore point, the impacted component would then be: - The pass itself: New algorithm needed. - MachineFrameInfo: Hold a list or set of Save/Restore point instead of one pointer. - PEI: Should loop over the save point and restore point. Anyhow, at least for this first iteration, I do not believe this is interesting to support the complex cases. We should revisit that when we motivating examples. Differential Revision: http://reviews.llvm.org/D9210 <rdar://problem/3201744> llvm-svn: 236507
* [SystemZ] Reclassify f32 subregs of f64 registersUlrich Weigand2015-05-043-6/+8
| | | | | | | | | | | | | | | | | | | | | At the moment, all subregs defined by the SystemZ target can be modified independently of the wider register. E.g. writing to a GR32 does not change the upper 32 bits of the GR64. Writing to an FP32 does not change the lower 32 bits of the FP64. Hoewver, the upcoming support for the vector extension redefines FP64 as one half of a V128. Floating-point operations leave the other half of a V128 in an unpredictable state, so it's no longer the case that writing to an FP32 leaves the bits of the underlying register (the V128) alone. I'd prefer to have separate subreg_ names for this situation, so that it's obvious at a glance whether we're talking about a subreg that leaves the other parts of the register alone. No behavioral change intended. Patch originally by Richard Sandiford. llvm-svn: 236433
* [SystemZ] Clean up AsmParser isMem() handlingUlrich Weigand2015-05-041-35/+41
| | | | | | | | | | | | We know what MemoryKind an operand has at the time we construct it, so we might as well just record it in an unused part of the structure. This makes it easier to add scatter/gather addresses later. No behavioral change intended. Patch originally by Richard Sandiford. llvm-svn: 236432
* [SystemZ] Fix getTargetNodeNameUlrich Weigand2015-05-041-1/+5
| | | | | | | | It seems SystemZTargetLowering::getTargetNodeName got out of sync with some recent changes to the SystemZISD opcode list. Add back all the missing opcodes (and re-sort to the same order as SystemISelLowering.h). llvm-svn: 236430
* Reapply r235977 "[DebugInfo] Add debug locations to constant SD nodes"Sergey Dmitrouk2015-04-284-131/+149
| | | | | | | | | | | | | | | | | | | | | | | | | [DebugInfo] Add debug locations to constant SD nodes This adds debug location to constant nodes of Selection DAG and updates all places that create constants to pass debug locations (see PR13269). Can't guarantee that all locations are correct, but in a lot of cases choice is obvious, so most of them should be. At least all tests pass. Tests for these changes do not cover everything, instead just check it for SDNodes, ARM and AArch64 where it's easy to get incorrect locations on constants. This is not complete fix as FastISel contains workaround for wrong debug locations, which drops locations from instructions on processing constants, but there isn't currently a way to use debug locations from constants there as llvm::Constant doesn't cache it (yet). Although this is a bit different issue, not directly related to these changes. Differential Revision: http://reviews.llvm.org/D9084 llvm-svn: 235989
* Revert "[DebugInfo] Add debug locations to constant SD nodes"Daniel Jasper2015-04-284-149/+131
| | | | | | | This breaks a test: http://bb.pgr.jp/builders/cmake-llvm-x86_64-linux/builds/23870 llvm-svn: 235987
* [DebugInfo] Add debug locations to constant SD nodesSergey Dmitrouk2015-04-284-131/+149
| | | | | | | | | | | | | | | | | | | | | | | This adds debug location to constant nodes of Selection DAG and updates all places that create constants to pass debug locations (see PR13269). Can't guarantee that all locations are correct, but in a lot of cases choice is obvious, so most of them should be. At least all tests pass. Tests for these changes do not cover everything, instead just check it for SDNodes, ARM and AArch64 where it's easy to get incorrect locations on constants. This is not complete fix as FastISel contains workaround for wrong debug locations, which drops locations from instructions on processing constants, but there isn't currently a way to use debug locations from constants there as llvm::Constant doesn't cache it (yet). Although this is a bit different issue, not directly related to these changes. Differential Revision: http://reviews.llvm.org/D9084 llvm-svn: 235977
* [AsmPrinter] Make AsmPrinter's OutStreamer member a unique_ptr.Lang Hames2015-04-241-2/+2
| | | | | | | AsmPrinter owns the OutStreamer, so an owning pointer makes sense here. Using a reference for this is crufty. llvm-svn: 235752
* Use raw_pwrite_stream in the object writer/streamer.Rafael Espindola2015-04-143-3/+4
| | | | | | The ELF object writer will take advantage of that in the next commit. llvm-svn: 234950
* Allow memory intrinsics to be tail callsKrzysztof Parzyszek2015-04-131-0/+1
| | | | llvm-svn: 234764
* Use 'override/final' instead of 'virtual' for overridden methodsAlexander Kornienko2015-04-113-3/+3
| | | | | | | | | | | | | | The patch is generated using clang-tidy misc-use-override check. This command was used: tools/clang/tools/extra/clang-tidy/tool/run-clang-tidy.py \ -checks='-*,misc-use-override' -header-filter='llvm|clang' \ -j=32 -fix -format http://reviews.llvm.org/D8925 llvm-svn: 234679
* Refactor a lot of duplicated code for stub output.Rafael Espindola2015-04-072-24/+0
| | | | | | | This also moves it earlier so that it they are produced before we print an end symbol for the data section. llvm-svn: 234315
* [SystemZ] Support transactional execution on zEC12Ulrich Weigand2015-04-019-3/+310
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* [SystemZ] Address review comments for r233689Ulrich Weigand2015-03-311-4/+5
| | | | | | | | | | Change lowerCTPOP to: - Gracefully handle a known-zero input value - Simplify computation of significant bit size Thanks to Jay Foad for the review! llvm-svn: 233736
* [SystemZ] Add Analysis to required_libraries (fall-out from r233688)Ulrich Weigand2015-03-311-1/+1
| | | | | | Should fix build failures with cmake builds llvm-svn: 233700
* [SystemZ] Support RISBGN instruction on zEC12Ulrich Weigand2015-03-316-17/+48
| | | | | | | | | | | | | | 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
* [SystemZ] Use POPCNT instruction on z196Ulrich Weigand2015-03-319-6/+85
| | | | | | | | | | 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
* [SystemZ] Provide basic TargetTransformInfo implementationUlrich Weigand2015-03-317-0/+320
| | | | | | | | | | | | This hooks up the TargetTransformInfo machinery for SystemZ, and provides an implementation of getIntImmCost. In addition, the patch adds the isLegalICmpImmediate and isLegalAddImmediate TargetLowering overrides, and updates a couple of test cases where we now generate slightly better code. llvm-svn: 233688
* Replace the MCSubtargetInfo parameter with a Triple when creatingEric Christopher2015-03-311-3/+3
| | | | | | | an MCInstPrinter. Update all callers and use where we wanted a Triple previously. llvm-svn: 233648
* Remove unused Target argument from MCInstPrinter ctor functions.Eric Christopher2015-03-301-2/+1
| | | | llvm-svn: 233607
* [SystemZ] Fix LLVM crash on unoptimized codeUlrich Weigand2015-03-301-0/+2
| | | | | | | | | | | | | | Compiling the following function with -O0 would crash, since LLVM would hit an assertion in getTestUnderMaskCond: int test(unsigned long x) { return x >= 0 && x <= 15; } Fixed by detecting the case in the caller of getTestUnderMaskCond. llvm-svn: 233541
* [SystemZ] Remove TargetMachine CPU auto-detectionUlrich Weigand2015-03-301-5/+0
| | | | | | As was done for X86 in r206094. llvm-svn: 233540
* [MCInstPrinter] Enable MCInstPrinter to change its behavior based on theAkira Hatanaka2015-03-272-2/+4
| | | | | | | | | | | | | | | | | | | | per-function subtarget. Currently, code-gen passes the default or generic subtarget to the constructors of MCInstPrinter subclasses (see LLVMTargetMachine::addPassesToEmitFile), which enables some targets (AArch64, ARM, and X86) to change their instprinter's behavior based on the subtarget feature bits. Since the backend can now use different subtargets for each function, instprinter has to be changed to use the per-function subtarget rather than the default subtarget. This patch takes the first step towards enabling instprinter to change its behavior based on the per-function subtarget. It adds a bit "PassSubtarget" to AsmWriter which tells table-gen to pass a reference to MCSubtargetInfo to the various print methods table-gen auto-generates. I will follow up with changes to instprinters of AArch64, ARM, and X86. llvm-svn: 233411
* Remove the target independent TargetMachine::getSubtarget andEric Christopher2015-03-211-1/+2
| | | | | | | | | | | | | | | | | | | TargetMachine::getSubtargetImpl routines. This keeps the target independent code free of bare subtarget calls while the remainder of the backends are migrated, or not if they don't wish to support per-function subtargets as would be needed for function multiversioning or LTO of disparate cpu subarchitecture types, e.g. clang -msse4.2 -c foo.c -emit-llvm -o foo.bc clang -c bar.c -emit-llvm -o bar.bc llvm-link foo.bc bar.bc -o baz.bc llc baz.bc and get appropriate code for what the command lines requested. llvm-svn: 232885
* Add a default implementation of createObjectStreamer.Rafael Espindola2015-03-181-10/+0
| | | | | | | This removes duplicated code from backends that don't need to do anything fancy. llvm-svn: 232658
* [systemz] Distinguish the 'Q', 'R', 'S', and 'T' inline assembly memory ↵Daniel Sanders2015-03-172-15/+38
| | | | | | | | | | | | | | | | | | | | constraints. Summary: But still handle them the same way since I don't know how they differ on this target. No functional change intended. Reviewers: uweigand Reviewed By: uweigand Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8251 llvm-svn: 232495
* Pass in a "const Triple &T" instead of a raw StringRef.Rafael Espindola2015-03-161-4/+3
| | | | llvm-svn: 232429
* Remove unused argument. NFC.Rafael Espindola2015-03-161-3/+2
| | | | llvm-svn: 232428
* Make each target map all inline assembly memory constraints to ↵Daniel Sanders2015-03-161-0/+7
| | | | | | | | | | | | | | | | | | | InlineAsm::Constraint_m. NFC. Summary: This is instead of doing this in target independent code and is the last non-functional change before targets begin to distinguish between different memory constraints when selecting code for the ISD::INLINEASM node. Next, each target will individually move away from the idea that all memory constraints behave like 'm'. Subscribers: jholewinski, llvm-commits Differential Revision: http://reviews.llvm.org/D8173 llvm-svn: 232373
* Recommit r232027 with PR22883 fixed: Add infrastructure for support of ↵Daniel Sanders2015-03-131-3/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | multiple memory constraints. The operand flag word for ISD::INLINEASM nodes now contains a 15-bit memory constraint ID when the operand kind is Kind_Mem. This constraint ID is a numeric equivalent to the constraint code string and is converted with a target specific hook in TargetLowering. This patch maps all memory constraints to InlineAsm::Constraint_m so there is no functional change at this point. It just proves that using these previously unused bits in the encoding of the flag word doesn't break anything. The next patch will make each target preserve the current mapping of everything to Constraint_m for itself while changing the target independent implementation of the hook to return Constraint_Unknown appropriately. Each target will then be adapted in separate patches to use appropriate Constraint_* values. PR22883 was caused the matching operands copying the whole of the operand flags for the matched operand. This included the constraint id which needed to be replaced with the operand number. This has been fixed with a conversion function. Following on from this, matching operands also used the operand number as the constraint id. This has been fixed by looking up the matched operand and taking it from there. llvm-svn: 232165
* Revert "r232027 - Add infrastructure for support of multiple memory constraints"Hal Finkel2015-03-121-4/+3
| | | | | | | | | | | | | | | | | | | | | | | | This (r232027) has caused PR22883; so it seems those bits might be used by something else after all. Reverting until we can figure out what else to do. Original commit message: The operand flag word for ISD::INLINEASM nodes now contains a 15-bit memory constraint ID when the operand kind is Kind_Mem. This constraint ID is a numeric equivalent to the constraint code string and is converted with a target specific hook in TargetLowering. This patch maps all memory constraints to InlineAsm::Constraint_m so there is no functional change at this point. It just proves that using these previously unused bits in the encoding of the flag word doesn't break anything. The next patch will make each target preserve the current mapping of everything to Constraint_m for itself while changing the target independent implementation of the hook to return Constraint_Unknown appropriately. Each target will then be adapted in separate patches to use appropriate Constraint_* values. llvm-svn: 232093
* Add infrastructure for support of multiple memory constraints.Daniel Sanders2015-03-121-3/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: The operand flag word for ISD::INLINEASM nodes now contains a 15-bit memory constraint ID when the operand kind is Kind_Mem. This constraint ID is a numeric equivalent to the constraint code string and is converted with a target specific hook in TargetLowering. This patch maps all memory constraints to InlineAsm::Constraint_m so there is no functional change at this point. It just proves that using these previously unused bits in the encoding of the flag word doesn't break anything. The next patch will make each target preserve the current mapping of everything to Constraint_m for itself while changing the target independent implementation of the hook to return Constraint_Unknown appropriately. Each target will then be adapted in separate patches to use appropriate Constraint_* values. Reviewers: hfinkel Reviewed By: hfinkel Subscribers: hfinkel, jholewinski, llvm-commits Differential Revision: http://reviews.llvm.org/D8171 llvm-svn: 232027
OpenPOWER on IntegriCloud