[llvm] r233204 - Add Hardware Transactional Memory (HTM) Support

Kit Barton kbarton at ca.ibm.com
Wed Mar 25 12:36:24 PDT 2015


Author: kbarton
Date: Wed Mar 25 14:36:23 2015
New Revision: 233204

URL: http://llvm.org/viewvc/llvm-project?rev=233204&view=rev
Log:
Add Hardware Transactional Memory (HTM) Support

This patch adds Hardware Transaction Memory (HTM) support supported by ISA 2.07
(POWER8). The intrinsic support is based on GCC one [1], but currently only the
'PowerPC HTM Low Level Built-in Function' are implemented.

The HTM instructions follows the RC ones and the transaction initiation result
is set on RC0 (with exception of tcheck). Currently approach is to create a
register copy from CR0 to GPR and comapring. Although this is suboptimal, since
the branch could be taken directly by comparing the CR0 value, it generates code
correctly on both test and branch and just return value. A possible future
optimization could be elimitate the MFCR instruction to branch directly.

The HTM usage requires a recently newer kernel with PPC HTM enabled. Tested on
powerpc64 and powerpc64le.

This is send along a clang patch to enabled the builtins and option switch.

[1] https://gcc.gnu.org/onlinedocs/gcc/PowerPC-Hardware-Transactional-Memory-Built-in-Functions.html

Phabricator Review: http://reviews.llvm.org/D8247

Added:
    llvm/trunk/lib/Target/PowerPC/PPCInstrHTM.td
    llvm/trunk/test/CodeGen/PowerPC/htm.ll
    llvm/trunk/test/MC/PowerPC/htm.s
Modified:
    llvm/trunk/include/llvm/IR/IntrinsicsPowerPC.td
    llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
    llvm/trunk/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
    llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
    llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h
    llvm/trunk/lib/Target/PowerPC/PPC.td
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td
    llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td
    llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
    llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td
    llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp
    llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h
    llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td
    llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp
    llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h

Modified: llvm/trunk/include/llvm/IR/IntrinsicsPowerPC.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicsPowerPC.td?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/IntrinsicsPowerPC.td (original)
+++ llvm/trunk/include/llvm/IR/IntrinsicsPowerPC.td Wed Mar 25 14:36:23 2015
@@ -796,3 +796,62 @@ let TargetPrefix = "ppc" in {  // All in
                           [llvm_v4f64_ty], [llvm_i32_ty], [IntrNoMem]>;
 }
 
+//===----------------------------------------------------------------------===//
+// PowerPC HTM Intrinsic Definitions.
+
+let TargetPrefix = "ppc" in {  // All intrinsics start with "llvm.ppc.".
+
+def int_ppc_tbegin :
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+def int_ppc_tend :
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+
+def int_ppc_tabort : GCCBuiltin<"__builtin_tabort">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+def int_ppc_tabortwc :
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_ppc_tabortwci :
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_ppc_tabortdc :
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_ppc_tabortdci :
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+
+def int_ppc_tcheck : GCCBuiltin<"__builtin_tcheck">,
+      Intrinsic<[llvm_i32_ty], [], []>;
+def int_ppc_treclaim : GCCBuiltin<"__builtin_treclaim">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+def int_ppc_trechkpt : GCCBuiltin<"__builtin_trechkpt">,
+      Intrinsic<[llvm_i32_ty], [], []>;
+def int_ppc_tsr :
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+
+def int_ppc_get_texasr : GCCBuiltin<"__builtin_get_texasr">,
+      Intrinsic<[llvm_i64_ty], [], []>;
+def int_ppc_get_texasru : GCCBuiltin<"__builtin_get_texasru">,
+      Intrinsic<[llvm_i64_ty], [], []>;
+def int_ppc_get_tfhar : GCCBuiltin<"__builtin_get_tfhar">,
+      Intrinsic<[llvm_i64_ty], [], []>;
+def int_ppc_get_tfiar : GCCBuiltin<"__builtin_get_tfiar">,
+      Intrinsic<[llvm_i64_ty], [], []>;
+
+def int_ppc_set_texasr : GCCBuiltin<"__builtin_set_texasr">,
+      Intrinsic<[], [llvm_i64_ty], []>;
+def int_ppc_set_texasru : GCCBuiltin<"__builtin_set_texasru">,
+      Intrinsic<[], [llvm_i64_ty], []>;
+def int_ppc_set_tfhar : GCCBuiltin<"__builtin_set_tfhar">,
+      Intrinsic<[], [llvm_i64_ty], []>;
+def int_ppc_set_tfiar : GCCBuiltin<"__builtin_set_tfiar">,
+      Intrinsic<[], [llvm_i64_ty], []>;
+
+// Extended mnemonics
+def int_ppc_tendall : GCCBuiltin<"__builtin_tendall">,
+      Intrinsic<[llvm_i32_ty], [], []>;
+def int_ppc_tresume : GCCBuiltin<"__builtin_tresume">,
+      Intrinsic<[llvm_i32_ty], [], []>;
+def int_ppc_tsuspend : GCCBuiltin<"__builtin_tsuspend">,
+      Intrinsic<[llvm_i32_ty], [], []>;
+
+def int_ppc_ttest : GCCBuiltin<"__builtin_ttest">,
+      Intrinsic<[llvm_i64_ty], [], []>;
+}

Modified: llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp Wed Mar 25 14:36:23 2015
@@ -427,6 +427,7 @@ public:
   bool isImm() const override { return Kind == Immediate || Kind == Expression; }
   bool isU1Imm() const { return Kind == Immediate && isUInt<1>(getImm()); }
   bool isU2Imm() const { return Kind == Immediate && isUInt<2>(getImm()); }
+  bool isU3Imm() const { return Kind == Immediate && isUInt<3>(getImm()); }
   bool isU4Imm() const { return Kind == Immediate && isUInt<4>(getImm()); }
   bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); }
   bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); }

Modified: llvm/trunk/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp Wed Mar 25 14:36:23 2015
@@ -189,6 +189,12 @@ static DecodeStatus DecodeCRRCRegisterCl
   return decodeRegisterClass(Inst, RegNo, CRRegs);
 }
 
+static DecodeStatus DecodeCRRC0RegisterClass(MCInst &Inst, uint64_t RegNo,
+                                            uint64_t Address,
+                                            const void *Decoder) {
+  return decodeRegisterClass(Inst, RegNo, CRRegs);
+}
+
 static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo,
                                             uint64_t Address,
                                             const void *Decoder) {

Modified: llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp Wed Mar 25 14:36:23 2015
@@ -228,6 +228,13 @@ void PPCInstPrinter::printU2ImmOperand(c
   O << (unsigned int)Value;
 }
 
+void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo,
+                                       raw_ostream &O) {
+  unsigned int Value = MI->getOperand(OpNo).getImm();
+  assert(Value <= 8 && "Invalid u3imm argument!");
+  O << (unsigned int)Value;
+}
+
 void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
                                        raw_ostream &O) {
   unsigned int Value = MI->getOperand(OpNo).getImm();

Modified: llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h (original)
+++ llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h Wed Mar 25 14:36:23 2015
@@ -45,6 +45,7 @@ public:
 
   void printU1ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printU2ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+  void printU3ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printU4ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printS5ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printU5ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);

Modified: llvm/trunk/lib/Target/PowerPC/PPC.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPC.td?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPC.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPC.td Wed Mar 25 14:36:23 2015
@@ -125,6 +125,8 @@ def FeatureInvariantFunctionDescriptors
   SubtargetFeature<"invariant-function-descriptors",
                    "HasInvariantFunctionDescriptors", "true",
                    "Assume function descriptors are invariant">;
+def FeatureHTM : SubtargetFeature<"htm", "HasHTM", "true",
+                                  "Enable Hardware Transactional Memory instructions">;
 
 def DeprecatedMFTB   : SubtargetFeature<"", "DeprecatedMFTB", "true",
                                         "Treat mftb as deprecated">;
@@ -261,7 +263,7 @@ def ProcessorFeatures {
         [DirectivePwr8, FeatureAltivec, FeatureP8Altivec, FeatureVSX, 
         FeatureP8Vector, FeatureMFOCRF, FeatureFCPSGN, FeatureFSqrt, 
         FeatureFRE, FeatureFRES, FeatureFRSQRTE, FeatureFRSQRTES,
-        FeatureRecipPrec, FeatureSTFIWX, FeatureLFIWAX,
+        FeatureRecipPrec, FeatureSTFIWX, FeatureLFIWAX, FeatureHTM,
         FeatureFPRND, FeatureFPCVT, FeatureISEL,
         FeaturePOPCNTD, FeatureCMPB, FeatureLDBRX, FeatureP8Crypto,
         Feature64Bit /*, Feature64BitRegs */, FeatureICBT,

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Wed Mar 25 14:36:23 2015
@@ -8782,6 +8782,12 @@ PPCTargetLowering::EmitInstrWithCustomIn
     BuildMI(*BB, MI, dl, TII->get(TargetOpcode::COPY),
             MI->getOperand(0).getReg())
       .addReg(isEQ ? PPC::CR0EQ : PPC::CR0GT);
+  } else if (MI->getOpcode() == PPC::TCHECK_RET) {
+    DebugLoc Dl = MI->getDebugLoc();
+    MachineRegisterInfo &RegInfo = F->getRegInfo();
+    unsigned CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
+    BuildMI(*BB, MI, Dl, TII->get(PPC::TCHECK), CRReg);
+    return BB;
   } else {
     llvm_unreachable("Unexpected instr type to insert");
   }

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td Wed Mar 25 14:36:23 2015
@@ -329,6 +329,12 @@ let hasSideEffects = 1, isBarrier = 1, u
                           Requires<[In64BitMode]>;
 }
 
+def MFSPR8 : XFXForm_1<31, 339, (outs g8rc:$RT), (ins i32imm:$SPR),
+                       "mfspr $RT, $SPR", IIC_SprMFSPR>;
+def MTSPR8 : XFXForm_1<31, 467, (outs), (ins i32imm:$SPR, g8rc:$RT),
+                       "mtspr $SPR, $RT", IIC_SprMTSPR>;
+
+
 //===----------------------------------------------------------------------===//
 // 64-bit SPR manipulation instrs.
 

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td Wed Mar 25 14:36:23 2015
@@ -693,6 +693,60 @@ class XForm_16b<bits<6> opcode, bits<10>
   let A = 0;
 }
 
+class XForm_htm0<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
+                 string asmstr, InstrItinClass itin, list<dag> pattern>
+  : I<opcode, OOL, IOL, asmstr, itin> {
+  bit R;
+
+  bit RC = 1;
+
+  let Inst{6-9}   = 0;
+  let Inst{10}    = R;
+  let Inst{11-20} = 0;
+  let Inst{21-30} = xo;
+  let Inst{31}    = RC;
+}
+
+class XForm_htm1<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
+                 string asmstr, InstrItinClass itin, list<dag> pattern>
+  : I<opcode, OOL, IOL, asmstr, itin> {
+  bit A;
+
+  bit RC = 1;
+
+  let Inst{6}     = A;
+  let Inst{7-20}  = 0;
+  let Inst{21-30} = xo;
+  let Inst{31}    = RC;
+}
+
+class XForm_htm2<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, string asmstr,
+              InstrItinClass itin, list<dag> pattern>
+  : I<opcode, OOL, IOL, asmstr, itin> {
+  bit L;
+
+  bit RC = 0;    // set by isDOT
+
+  let Inst{7-9}   = 0;
+  let Inst{10}    = L;
+  let Inst{11-20} = 0;
+  let Inst{21-30} = xo;
+  let Inst{31}    = RC;
+}
+
+class XForm_htm3<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, string asmstr,
+              InstrItinClass itin, list<dag> pattern>
+  : I<opcode, OOL, IOL, asmstr, itin> {
+  bits<3> BF;
+
+  bit RC = 0;
+
+  let Inst{6-8}   = BF;
+  let Inst{9-20}  = 0;
+  let Inst{21-30} = xo;
+  let Inst{31}    = RC;
+}
+
 // XX*-Form (VSX)
 class XX1Form<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, 
               InstrItinClass itin, list<dag> pattern>

Added: llvm/trunk/lib/Target/PowerPC/PPCInstrHTM.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrHTM.td?rev=233204&view=auto
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrHTM.td (added)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrHTM.td Wed Mar 25 14:36:23 2015
@@ -0,0 +1,172 @@
+//===-- PPCInstrHTM.td - The PowerPC Hardware Transactional Memory  -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the Hardware Transactional Memory extension to the
+// PowerPC instruction set.
+//
+//===----------------------------------------------------------------------===//
+
+
+
+def HasHTM : Predicate<"PPCSubTarget->hasHTM()">;
+
+def HTM_get_imm : SDNodeXForm<imm, [{
+  return getI32Imm (N->getZExtValue());
+}]>;
+
+let hasSideEffects = 1, usesCustomInserter = 1  in {
+def TCHECK_RET : Pseudo<(outs crrc:$out), (ins), "#TCHECK_RET", []>;
+}
+
+
+let Predicates = [HasHTM] in {
+
+def TBEGIN : XForm_htm0 <31, 654,
+                         (outs crrc0:$ret), (ins u1imm:$R), "tbegin. $R", IIC_SprMTSPR, []>;
+
+def TEND : XForm_htm1 <31, 686,
+                       (outs crrc0:$ret), (ins u1imm:$A), "tend. $A", IIC_SprMTSPR, []>;
+
+def TABORT : XForm_base_r3xo <31, 910,
+                              (outs crrc0:$ret), (ins gprc:$A), "tabort. $A", IIC_SprMTSPR,
+                              []>, isDOT {
+  let RST = 0;
+  let B = 0;
+}
+
+def TABORTWC : XForm_base_r3xo <31, 782,
+                                (outs crrc0:$ret), (ins u5imm:$RTS, gprc:$A, gprc:$B),
+                                "tabortwc. $RTS, $A, $B", IIC_SprMTSPR, []>,
+                                isDOT;
+
+def TABORTWCI : XForm_base_r3xo <31, 846,
+                                 (outs crrc0:$ret), (ins u5imm:$RTS, gprc:$A, u5imm:$B),
+                                 "tabortwci. $RTS, $A, $B", IIC_SprMTSPR, []>,
+                                 isDOT;
+
+def TABORTDC : XForm_base_r3xo <31, 814,
+                                (outs crrc0:$ret), (ins u5imm:$RTS, gprc:$A, gprc:$B),
+                                "tabortdc. $RTS, $A, $B", IIC_SprMTSPR, []>,
+                                isDOT;
+
+def TABORTDCI : XForm_base_r3xo <31, 878,
+                                 (outs crrc0:$ret), (ins u5imm:$RTS, gprc:$A, u5imm:$B),
+                                 "tabortdci. $RTS, $A, $B", IIC_SprMTSPR, []>,
+                                 isDOT;
+
+def TSR : XForm_htm2 <31, 750,
+                      (outs crrc0:$ret), (ins u1imm:$L), "tsr. $L", IIC_SprMTSPR, []>,
+                      isDOT;
+
+def TCHECK : XForm_htm3 <31, 718,
+                        (outs), (ins crrc:$BF), "tcheck $BF", IIC_SprMTSPR, []>;
+
+
+def TRECLAIM : XForm_base_r3xo <31, 942,
+                                (outs crrc:$ret), (ins gprc:$A), "treclaim. $A",
+                                IIC_SprMTSPR, []>,
+                                isDOT {
+  let RST = 0;
+  let B = 0;
+}
+
+def TRECHKPT : XForm_base_r3xo <31, 1006,
+                                (outs crrc:$ret), (ins), "trechkpt.", IIC_SprMTSPR, []>,
+                                isDOT {
+  let RST = 0;
+  let A = 0;
+  let B = 0;
+}
+
+// Builtins
+
+// All HTM instructions, with the exception of tcheck, set CR0 with the
+// value of the MSR Transaction State (TS) bits that exist before the
+// instruction is executed.  For tbegin., the EQ bit in CR0 can be used
+// to determine whether the transaction was successfully started (0) or
+// failed (1).  We use an XORI pattern to 'flip' the bit to match the
+// tbegin builtin API which defines a return value of 1 as success.
+
+def : Pat<(int_ppc_tbegin i32:$R),
+           (XORI
+             (EXTRACT_SUBREG (
+               TBEGIN (HTM_get_imm imm:$R)), sub_eq),
+            1)>;
+
+def : Pat<(int_ppc_tend i32:$R),
+          (TEND (HTM_get_imm imm:$R))>;
+
+
+def : Pat<(int_ppc_tabort i32:$R),
+          (TABORT $R)>;
+
+def : Pat<(int_ppc_tabortwc i32:$TO, i32:$RA, i32:$RB),
+          (TABORTWC (HTM_get_imm imm:$TO), $RA, $RB)>;
+
+def : Pat<(int_ppc_tabortwci i32:$TO, i32:$RA, i32:$SI),
+          (TABORTWCI (HTM_get_imm imm:$TO), $RA, (HTM_get_imm imm:$SI))>;
+
+def : Pat<(int_ppc_tabortdc i32:$TO, i32:$RA, i32:$RB),
+          (TABORTDC (HTM_get_imm imm:$TO), $RA, $RB)>;
+
+def : Pat<(int_ppc_tabortdci i32:$TO, i32:$RA, i32:$SI),
+          (TABORTDCI (HTM_get_imm imm:$TO), $RA, (HTM_get_imm imm:$SI))>;
+
+def : Pat<(int_ppc_tcheck),
+          (TCHECK_RET)>;
+
+def : Pat<(int_ppc_treclaim i32:$RA),
+          (TRECLAIM $RA)>;
+
+def : Pat<(int_ppc_trechkpt),
+          (TRECHKPT)>;
+
+def : Pat<(int_ppc_tsr i32:$L),
+          (TSR (HTM_get_imm imm:$L))>;
+
+def : Pat<(int_ppc_get_texasr),
+          (MFSPR8 130)>;
+
+def : Pat<(int_ppc_get_texasru),
+          (MFSPR8 131)>;
+
+def : Pat<(int_ppc_get_tfhar),
+          (MFSPR8 128)>;
+
+def : Pat<(int_ppc_get_tfiar),
+          (MFSPR8 129)>;
+
+
+def : Pat<(int_ppc_set_texasr i64:$V),
+          (MTSPR8 130, $V)>;
+
+def : Pat<(int_ppc_set_texasru i64:$V),
+          (MTSPR8 131, $V)>;
+
+def : Pat<(int_ppc_set_tfhar i64:$V),
+          (MTSPR8 128, $V)>;
+
+def : Pat<(int_ppc_set_tfiar i64:$V),
+          (MTSPR8 129, $V)>;
+
+
+// Extended mnemonics
+def : Pat<(int_ppc_tendall),
+          (TEND 1)>;
+
+def : Pat<(int_ppc_tresume),
+          (TSR 1)>;
+
+def : Pat<(int_ppc_tsuspend),
+          (TSR 0)>;
+
+def : Pat<(i64 (int_ppc_ttest)),
+          (RLDICL (i64 (COPY (TABORTWCI 0, ZERO, 0))), 36, 28)>;
+
+} // [HasHTM]

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Wed Mar 25 14:36:23 2015
@@ -696,6 +696,33 @@ void PPCInstrInfo::insertSelect(MachineB
     .addReg(Cond[1].getReg(), 0, SubIdx);
 }
 
+static unsigned getCRBitValue(unsigned CRBit) {
+  unsigned Ret = 4;
+  if (CRBit == PPC::CR0LT || CRBit == PPC::CR1LT ||
+      CRBit == PPC::CR2LT || CRBit == PPC::CR3LT ||
+      CRBit == PPC::CR4LT || CRBit == PPC::CR5LT ||
+      CRBit == PPC::CR6LT || CRBit == PPC::CR7LT)
+    Ret = 3;
+  if (CRBit == PPC::CR0GT || CRBit == PPC::CR1GT ||
+      CRBit == PPC::CR2GT || CRBit == PPC::CR3GT ||
+      CRBit == PPC::CR4GT || CRBit == PPC::CR5GT ||
+      CRBit == PPC::CR6GT || CRBit == PPC::CR7GT)
+    Ret = 2;
+  if (CRBit == PPC::CR0EQ || CRBit == PPC::CR1EQ ||
+      CRBit == PPC::CR2EQ || CRBit == PPC::CR3EQ ||
+      CRBit == PPC::CR4EQ || CRBit == PPC::CR5EQ ||
+      CRBit == PPC::CR6EQ || CRBit == PPC::CR7EQ)
+    Ret = 1;
+  if (CRBit == PPC::CR0UN || CRBit == PPC::CR1UN ||
+      CRBit == PPC::CR2UN || CRBit == PPC::CR3UN ||
+      CRBit == PPC::CR4UN || CRBit == PPC::CR5UN ||
+      CRBit == PPC::CR6UN || CRBit == PPC::CR7UN)
+    Ret = 0;
+
+  assert(Ret != 4 && "Invalid CR bit register");
+  return Ret;
+}
+
 void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
                                MachineBasicBlock::iterator I, DebugLoc DL,
                                unsigned DestReg, unsigned SrcReg,
@@ -741,6 +768,32 @@ void PPCInstrInfo::copyPhysReg(MachineBa
     SrcReg = SuperReg;
   }
 
+  // Different class register copy
+  if (PPC::CRBITRCRegClass.contains(SrcReg) &&
+      PPC::GPRCRegClass.contains(DestReg)) {
+    unsigned CRReg = getCRFromCRBit(SrcReg);
+    BuildMI(MBB, I, DL, get(PPC::MFOCRF), DestReg)
+       .addReg(CRReg), getKillRegState(KillSrc);
+    // Rotate the CR bit in the CR fields to be the least significant bit and
+    // then mask with 0x1 (MB = ME = 31).
+    BuildMI(MBB, I, DL, get(PPC::RLWINM), DestReg)
+       .addReg(DestReg, RegState::Kill)
+       .addImm(TRI->getEncodingValue(CRReg) * 4 + (4 - getCRBitValue(SrcReg)))
+       .addImm(31)
+       .addImm(31);
+    return;
+  } else if (PPC::CRRCRegClass.contains(SrcReg) &&
+      PPC::G8RCRegClass.contains(DestReg)) {
+    BuildMI(MBB, I, DL, get(PPC::MFOCRF8), DestReg)
+       .addReg(SrcReg), getKillRegState(KillSrc);
+    return;
+  } else if (PPC::CRRCRegClass.contains(SrcReg) &&
+      PPC::GPRCRegClass.contains(DestReg)) {
+    BuildMI(MBB, I, DL, get(PPC::MFOCRF), DestReg)
+       .addReg(SrcReg), getKillRegState(KillSrc);
+    return;
+   }
+
   unsigned Opc;
   if (PPC::GPRCRegClass.contains(DestReg, SrcReg))
     Opc = PPC::OR;

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Wed Mar 25 14:36:23 2015
@@ -432,6 +432,9 @@ def PPCRegCRRCAsmOperand : AsmOperandCla
 def crrc : RegisterOperand<CRRC> {
   let ParserMatchClass = PPCRegCRRCAsmOperand;
 }
+def crrc0 : RegisterOperand<CRRC0> {
+  let ParserMatchClass = PPCRegCRRCAsmOperand;
+}
 
 def PPCU1ImmAsmOperand : AsmOperandClass {
   let Name = "U1Imm"; let PredicateMethod = "isU1Imm";
@@ -451,6 +454,15 @@ def u2imm   : Operand<i32> {
   let ParserMatchClass = PPCU2ImmAsmOperand;
 }
 
+def PPCU3ImmAsmOperand : AsmOperandClass {
+  let Name = "U3Imm"; let PredicateMethod = "isU3Imm";
+  let RenderMethod = "addImmOperands";
+}
+def u3imm   : Operand<i32> {
+  let PrintMethod = "printU3ImmOperand";
+  let ParserMatchClass = PPCU3ImmAsmOperand;
+}
+
 def PPCU4ImmAsmOperand : AsmOperandClass {
   let Name = "U4Imm"; let PredicateMethod = "isU4Imm";
   let RenderMethod = "addImmOperands";
@@ -2708,6 +2720,7 @@ include "PPCInstrSPE.td"
 include "PPCInstr64Bit.td"
 include "PPCInstrVSX.td"
 include "PPCInstrQPX.td"
+include "PPCInstrHTM.td"
 
 def crnot : OutPatFrag<(ops node:$in),
                        (CRNOR $in, $in)>;

Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Wed Mar 25 14:36:23 2015
@@ -524,37 +524,6 @@ void PPCRegisterInfo::lowerCRRestore(Mac
   MBB.erase(II);
 }
 
-static unsigned getCRFromCRBit(unsigned SrcReg) {
-  unsigned Reg = 0;
-  if (SrcReg == PPC::CR0LT || SrcReg == PPC::CR0GT ||
-      SrcReg == PPC::CR0EQ || SrcReg == PPC::CR0UN)
-    Reg = PPC::CR0;
-  else if (SrcReg == PPC::CR1LT || SrcReg == PPC::CR1GT ||
-           SrcReg == PPC::CR1EQ || SrcReg == PPC::CR1UN)
-    Reg = PPC::CR1;
-  else if (SrcReg == PPC::CR2LT || SrcReg == PPC::CR2GT ||
-           SrcReg == PPC::CR2EQ || SrcReg == PPC::CR2UN)
-    Reg = PPC::CR2;
-  else if (SrcReg == PPC::CR3LT || SrcReg == PPC::CR3GT ||
-           SrcReg == PPC::CR3EQ || SrcReg == PPC::CR3UN)
-    Reg = PPC::CR3;
-  else if (SrcReg == PPC::CR4LT || SrcReg == PPC::CR4GT ||
-           SrcReg == PPC::CR4EQ || SrcReg == PPC::CR4UN)
-    Reg = PPC::CR4;
-  else if (SrcReg == PPC::CR5LT || SrcReg == PPC::CR5GT ||
-           SrcReg == PPC::CR5EQ || SrcReg == PPC::CR5UN)
-    Reg = PPC::CR5;
-  else if (SrcReg == PPC::CR6LT || SrcReg == PPC::CR6GT ||
-           SrcReg == PPC::CR6EQ || SrcReg == PPC::CR6UN)
-    Reg = PPC::CR6;
-  else if (SrcReg == PPC::CR7LT || SrcReg == PPC::CR7GT ||
-           SrcReg == PPC::CR7EQ || SrcReg == PPC::CR7UN)
-    Reg = PPC::CR7;
-
-  assert(Reg != 0 && "Invalid CR bit register");
-  return Reg;
-}
-
 void PPCRegisterInfo::lowerCRBitSpilling(MachineBasicBlock::iterator II,
                                          unsigned FrameIndex) const {
   // Get the instruction.

Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h Wed Mar 25 14:36:23 2015
@@ -22,6 +22,39 @@
 #include "PPCGenRegisterInfo.inc"
 
 namespace llvm {
+
+inline static unsigned getCRFromCRBit(unsigned SrcReg) {
+  unsigned Reg = 0;
+  if (SrcReg == PPC::CR0LT || SrcReg == PPC::CR0GT ||
+      SrcReg == PPC::CR0EQ || SrcReg == PPC::CR0UN)
+    Reg = PPC::CR0;
+  else if (SrcReg == PPC::CR1LT || SrcReg == PPC::CR1GT ||
+           SrcReg == PPC::CR1EQ || SrcReg == PPC::CR1UN)
+    Reg = PPC::CR1;
+  else if (SrcReg == PPC::CR2LT || SrcReg == PPC::CR2GT ||
+           SrcReg == PPC::CR2EQ || SrcReg == PPC::CR2UN)
+    Reg = PPC::CR2;
+  else if (SrcReg == PPC::CR3LT || SrcReg == PPC::CR3GT ||
+           SrcReg == PPC::CR3EQ || SrcReg == PPC::CR3UN)
+    Reg = PPC::CR3;
+  else if (SrcReg == PPC::CR4LT || SrcReg == PPC::CR4GT ||
+           SrcReg == PPC::CR4EQ || SrcReg == PPC::CR4UN)
+    Reg = PPC::CR4;
+  else if (SrcReg == PPC::CR5LT || SrcReg == PPC::CR5GT ||
+           SrcReg == PPC::CR5EQ || SrcReg == PPC::CR5UN)
+    Reg = PPC::CR5;
+  else if (SrcReg == PPC::CR6LT || SrcReg == PPC::CR6GT ||
+           SrcReg == PPC::CR6EQ || SrcReg == PPC::CR6UN)
+    Reg = PPC::CR6;
+  else if (SrcReg == PPC::CR7LT || SrcReg == PPC::CR7GT ||
+           SrcReg == PPC::CR7EQ || SrcReg == PPC::CR7UN)
+    Reg = PPC::CR7;
+
+  assert(Reg != 0 && "Invalid CR bit register");
+  return Reg;
+}
+
+
 class PPCRegisterInfo : public PPCGenRegisterInfo {
   DenseMap<unsigned, unsigned> ImmToIdxMap;
   const PPCTargetMachine &TM;

Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td Wed Mar 25 14:36:23 2015
@@ -341,6 +341,8 @@ def CRBITRC : RegisterClass<"PPC", [i1],
 def CRRC : RegisterClass<"PPC", [i32], 32, (add CR0, CR1, CR5, CR6,
                                                 CR7, CR2, CR3, CR4)>;
 
+def CRRC0 : RegisterClass<"PPC", [i32], 32, (add CR0)>;
+
 // The CTR registers are not allocatable because they're used by the
 // decrement-and-branch instructions, and thus need to stay live across
 // multiple basic blocks.

Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp Wed Mar 25 14:36:23 2015
@@ -97,6 +97,7 @@ void PPCSubtarget::initializeEnvironment
   HasInvariantFunctionDescriptors = false;
   HasPartwordAtomics = false;
   IsQPXStackUnaligned = false;
+  HasHTM = false;
 }
 
 void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {

Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h?rev=233204&r1=233203&r2=233204&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h Wed Mar 25 14:36:23 2015
@@ -115,6 +115,7 @@ protected:
   bool HasICBT;
   bool HasInvariantFunctionDescriptors;
   bool HasPartwordAtomics;
+  bool HasHTM;
 
   /// When targeting QPX running a stock PPC64 Linux kernel where the stack
   /// alignment has not been changed, we need to keep the 16-byte alignment
@@ -246,6 +247,7 @@ public:
 
     return 16;
   }
+  bool hasHTM() const { return HasHTM; }
 
   const Triple &getTargetTriple() const { return TargetTriple; }
 

Added: llvm/trunk/test/CodeGen/PowerPC/htm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/htm.ll?rev=233204&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/htm.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/htm.ll Wed Mar 25 14:36:23 2015
@@ -0,0 +1,125 @@
+; RUN: llc -mcpu=pwr8 -mattr=+htm < %s | FileCheck %s
+target datalayout = "E-m:e-i64:64-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+define zeroext i32 @test1() {
+entry:
+  %0 = tail call i32 @llvm.ppc.tbegin(i32 0)
+  ret i32 %0
+
+; CHECK-LABEL: @test1
+; CHECK: tbegin. 0
+; CHECK: mfocrf  [[REGISTER1:[0-9]+]], 128
+; CHECK: rlwinm  [[REGISTER2:[0-9]+]], [[REGISTER1]], 3, 31, 31
+; CHECK: xori    {{[0-9]+}}, [[REGISTER2]], 1
+}
+
+declare i32 @llvm.ppc.tbegin(i32) #1
+
+
+define zeroext i32 @test2() {
+entry:
+  %0 = tail call i32 @llvm.ppc.tend(i32 0)
+  ret i32 %0
+; CHECK-LABEL: @test2
+; CHECK: tend. 0
+; CHECK: mfocrf  {{[0-9]+}}, 128
+}
+
+declare i32 @llvm.ppc.tend(i32)
+
+
+define void @test3() {
+entry:
+  %0 = tail call i32 @llvm.ppc.tabort(i32 0)
+  %1 = tail call i32 @llvm.ppc.tabortdc(i32 0, i32 1, i32 2)
+  %2 = tail call i32 @llvm.ppc.tabortdci(i32 0, i32 1, i32 2)
+  %3 = tail call i32 @llvm.ppc.tabortwc(i32 0, i32 1, i32 2)
+  %4 = tail call i32 @llvm.ppc.tabortwci(i32 0, i32 1, i32 2)
+  ret void
+; CHECK-LABEL: @test3
+; CHECK: tabort.    {{[0-9]+}}
+; CHECK: tabortdc.  0, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: tabortdci. 0, {{[0-9]+}}, 2
+; CHECK: tabortwc.  0, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: tabortwci. 0, {{[0-9]+}}, 2
+}
+
+declare i32 @llvm.ppc.tabort(i32)
+declare i32 @llvm.ppc.tabortdc(i32, i32, i32)
+declare i32 @llvm.ppc.tabortdci(i32, i32, i32)
+declare i32 @llvm.ppc.tabortwc(i32, i32, i32)
+declare i32 @llvm.ppc.tabortwci(i32, i32, i32)
+
+
+define void @test4() {
+entry:
+  %0 = tail call i32 @llvm.ppc.tendall()
+  %1 = tail call i32 @llvm.ppc.tresume()
+  %2 = tail call i32 @llvm.ppc.tsuspend()
+  ret void
+; CHECK-LABEL: @test4
+; CHECK: tend. 1
+; CHECK: tsr.  1
+; CHECK: tsr.  0
+}
+
+declare i32 @llvm.ppc.tendall()
+declare i32 @llvm.ppc.tresume()
+declare i32 @llvm.ppc.tsuspend()
+
+
+define void @test5(i64 %v) {
+entry:
+  tail call void @llvm.ppc.set.texasr(i64 %v)
+  tail call void @llvm.ppc.set.texasru(i64 %v)
+  tail call void @llvm.ppc.set.tfhar(i64 %v)
+  tail call void @llvm.ppc.set.tfiar(i64 %v)
+  ret void
+; CHECK-LABEL: @test5
+; CHECK: mtspr 130, [[REG1:[0-9]+]]
+; CHECK: mtspr 131, [[REG2:[0-9]+]]
+; CHECK: mtspr 128, [[REG3:[0-9]+]]
+; CHECK: mtspr 129, [[REG4:[0-9]+]]
+}
+
+define i64 @test6() {
+entry:
+  %0 = tail call i64 @llvm.ppc.get.texasr()
+  ret i64 %0
+; CHECK-LABEL: @test6
+; CHECK: mfspr [[REG1:[0-9]+]], 130
+}
+
+define i64 @test7() {
+entry:
+  %0 = tail call i64 @llvm.ppc.get.texasru()
+  ret i64 %0
+; CHECK-LABEL: @test7
+; CHECK: mfspr [[REG1:[0-9]+]], 131
+}
+
+define i64 @test8() {
+entry:
+  %0 = tail call i64 @llvm.ppc.get.tfhar()
+  ret i64 %0
+; CHECK-LABEL: @test8
+; CHECK: mfspr [[REG1:[0-9]+]], 128
+}
+
+define i64 @test9() {
+entry:
+  %0 = tail call i64 @llvm.ppc.get.tfiar()
+  ret i64 %0
+; CHECK-LABEL: @test9
+; CHECK: mfspr [[REG1:[0-9]+]], 129
+}
+
+declare void @llvm.ppc.set.texasr(i64)
+declare void @llvm.ppc.set.texasru(i64)
+declare void @llvm.ppc.set.tfhar(i64)
+declare void @llvm.ppc.set.tfiar(i64)
+declare i64 @llvm.ppc.get.texasr()
+declare i64 @llvm.ppc.get.texasru()
+declare i64 @llvm.ppc.get.tfhar()
+declare i64 @llvm.ppc.get.tfiar()

Added: llvm/trunk/test/MC/PowerPC/htm.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/htm.s?rev=233204&view=auto
==============================================================================
--- llvm/trunk/test/MC/PowerPC/htm.s (added)
+++ llvm/trunk/test/MC/PowerPC/htm.s Wed Mar 25 14:36:23 2015
@@ -0,0 +1,53 @@
+# RUN: llvm-mc -triple powerpc64-unknown-linux-gnu --show-encoding %s | FileCheck -check-prefix=CHECK-BE %s
+# RUN: llvm-mc -triple powerpc64le-unknown-linux-gnu --show-encoding %s | FileCheck -check-prefix=CHECK-LE %s
+
+# CHECK-BE: tbegin. 0                      # encoding: [0x7c,0x00,0x05,0x1d]
+# CHECK-LE: tbegin. 0                      # encoding: [0x1d,0x05,0x00,0x7c]
+            tbegin. 0
+# CHECK-BE: tbegin. 1                      # encoding: [0x7c,0x20,0x05,0x1d]
+# CHECK-LE: tbegin. 1                      # encoding: [0x1d,0x05,0x20,0x7c]
+            tbegin. 1
+
+# CHECK-BE: tend. 0                        # encoding: [0x7c,0x00,0x05,0x5d]
+# CHECK-LE: tend. 0                        # encoding: [0x5d,0x05,0x00,0x7c]
+            tend. 0
+# CHECK-BE: tend. 1                        # encoding: [0x7e,0x00,0x05,0x5d]
+# CHECK-LE: tend. 1                        # encoding: [0x5d,0x05,0x00,0x7e]
+            tend. 1
+
+# CHECK-BE: tabort. 9                      # encoding: [0x7c,0x09,0x07,0x1d]
+# CHECK-LE: tabort. 9                      # encoding: [0x1d,0x07,0x09,0x7c]
+            tabort. 9
+# CHECK-BE: tabortdc. 0, 9, 9              # encoding: [0x7c,0x09,0x4e,0x5d]
+# CHECK-LE: tabortdc. 0, 9, 9              # encoding: [0x5d,0x4e,0x09,0x7c]
+            tabortdc. 0, 9, 9
+# CHECK-BE: tabortdci. 0, 9, 0             # encoding: [0x7c,0x09,0x06,0xdd]
+# CHECK-LE: tabortdci. 0, 9, 0             # encoding: [0xdd,0x06,0x09,0x7c]
+            tabortdci. 0, 9, 0
+# CHECK-BE: tabortwc. 0, 9, 9              # encoding: [0x7c,0x09,0x4e,0x1d]
+# CHECK-LE: tabortwc. 0, 9, 9              # encoding: [0x1d,0x4e,0x09,0x7c]
+            tabortwc. 0, 9, 9
+# CHECK-BE: tabortwci. 0, 9, 0             # encoding: [0x7c,0x09,0x06,0x9d]
+# CHECK-LE: tabortwci. 0, 9, 0             # encoding: [0x9d,0x06,0x09,0x7c]
+            tabortwci. 0, 9, 0
+
+# CHECK-BE: tsr. 0                         # encoding: [0x7c,0x00,0x05,0xdd]
+# CHECK-LE: tsr. 0                         # encoding: [0xdd,0x05,0x00,0x7c]
+            tsr. 0
+# CHECK-BE: tsr. 1                         # encoding: [0x7c,0x20,0x05,0xdd]
+# CHECK-LE: tsr. 1                         # encoding: [0xdd,0x05,0x20,0x7c]
+            tsr. 1
+
+# CHECK-BE: tcheck 0                       # encoding: [0x7c,0x00,0x05,0x9c]
+# CHECK-LE: tcheck 0                       # encoding: [0x9c,0x05,0x00,0x7c]
+            tcheck 0
+# CHECK-BE: tcheck 3                       # encoding: [0x7d,0x80,0x05,0x9c]
+# CHECK-LE: tcheck 3                       # encoding: [0x9c,0x05,0x80,0x7d]
+            tcheck 3
+
+# CHECK-BE: treclaim. 9                    # encoding: [0x7c,0x09,0x07,0x5d]
+# CHECK-LE: treclaim. 9                    # encoding: [0x5d,0x07,0x09,0x7c]
+            treclaim. 9
+# CHECK-BE: trechkpt.                      # encoding: [0x7c,0x00,0x07,0xdd]
+# CHECK-LE: trechkpt.                      # encoding: [0xdd,0x07,0x00,0x7c]
+            trechkpt.





More information about the llvm-commits mailing list