<div dir="ltr">Hi,<div><br></div><div>The powerpc HTM is defined in ISA 2.07 [1] and the builtins is modeled using GCC</div><div>documentation [2].</div><div><br></div><div>[1] <a href="https://www.power.org/documentation/power-isa-version-2-07-2/">https://www.power.org/documentation/power-isa-version-2-07-2/</a></div><div>[2] <a href="https://gcc.gnu.org/onlinedocs/gcc/PowerPC-Hardware-Transactional-Memory-Built-in-Functions.html" target="_blank" style="font-size:12.8000001907349px">https://gcc.gnu.org/onlinedocs/gcc/PowerPC-Hardware-Transactional-Memory-Built-in-Functions.html</a></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 25, 2015 at 10:08 PM, Sean Silva <span dir="ltr"><<a href="mailto:chisophugis@gmail.com" target="_blank">chisophugis@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Do any of the documents in <a href="http://llvm.org/docs/CompilerWriterInfo.html#powerpc" target="_blank">http://llvm.org/docs/CompilerWriterInfo.html#powerpc</a> cover this ISA extension? If not, could you add a link to docs/CompilerWriterInfo.rst ?<span class="HOEnZb"><font color="#888888"><div><br></div><div>-- Sean Silva</div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 25, 2015 at 12:36 PM, Kit Barton <span dir="ltr"><<a href="mailto:kbarton@ca.ibm.com" target="_blank">kbarton@ca.ibm.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: kbarton<br>
Date: Wed Mar 25 14:36:23 2015<br>
New Revision: 233204<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=233204&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=233204&view=rev</a><br>
Log:<br>
Add Hardware Transactional Memory (HTM) Support<br>
<br>
This patch adds Hardware Transaction Memory (HTM) support supported by ISA 2.07<br>
(POWER8). The intrinsic support is based on GCC one [1], but currently only the<br>
'PowerPC HTM Low Level Built-in Function' are implemented.<br>
<br>
The HTM instructions follows the RC ones and the transaction initiation result<br>
is set on RC0 (with exception of tcheck). Currently approach is to create a<br>
register copy from CR0 to GPR and comapring. Although this is suboptimal, since<br>
the branch could be taken directly by comparing the CR0 value, it generates code<br>
correctly on both test and branch and just return value. A possible future<br>
optimization could be elimitate the MFCR instruction to branch directly.<br>
<br>
The HTM usage requires a recently newer kernel with PPC HTM enabled. Tested on<br>
powerpc64 and powerpc64le.<br>
<br>
This is send along a clang patch to enabled the builtins and option switch.<br>
<br>
[1] <a href="https://gcc.gnu.org/onlinedocs/gcc/PowerPC-Hardware-Transactional-Memory-Built-in-Functions.html" target="_blank">https://gcc.gnu.org/onlinedocs/gcc/PowerPC-Hardware-Transactional-Memory-Built-in-Functions.html</a><br>
<br>
Phabricator Review: <a href="http://reviews.llvm.org/D8247" target="_blank">http://reviews.llvm.org/D8247</a><br>
<br>
Added:<br>
    llvm/trunk/lib/Target/PowerPC/PPCInstrHTM.td<br>
    llvm/trunk/test/CodeGen/PowerPC/htm.ll<br>
    llvm/trunk/test/MC/PowerPC/htm.s<br>
Modified:<br>
    llvm/trunk/include/llvm/IR/IntrinsicsPowerPC.td<br>
    llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp<br>
    llvm/trunk/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp<br>
    llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp<br>
    llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h<br>
    llvm/trunk/lib/Target/PowerPC/PPC.td<br>
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp<br>
    llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td<br>
    llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td<br>
    llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp<br>
    llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td<br>
    llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp<br>
    llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h<br>
    llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td<br>
    llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp<br>
    llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h<br>
<br>
Modified: llvm/trunk/include/llvm/IR/IntrinsicsPowerPC.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicsPowerPC.td?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicsPowerPC.td?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/IntrinsicsPowerPC.td (original)<br>
+++ llvm/trunk/include/llvm/IR/IntrinsicsPowerPC.td Wed Mar 25 14:36:23 2015<br>
@@ -796,3 +796,62 @@ let TargetPrefix = "ppc" in {  // All in<br>
                           [llvm_v4f64_ty], [llvm_i32_ty], [IntrNoMem]>;<br>
 }<br>
<br>
+//===----------------------------------------------------------------------===//<br>
+// PowerPC HTM Intrinsic Definitions.<br>
+<br>
+let TargetPrefix = "ppc" in {  // All intrinsics start with "llvm.ppc.".<br>
+<br>
+def int_ppc_tbegin :<br>
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;<br>
+def int_ppc_tend :<br>
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;<br>
+<br>
+def int_ppc_tabort : GCCBuiltin<"__builtin_tabort">,<br>
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;<br>
+def int_ppc_tabortwc :<br>
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;<br>
+def int_ppc_tabortwci :<br>
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;<br>
+def int_ppc_tabortdc :<br>
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;<br>
+def int_ppc_tabortdci :<br>
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;<br>
+<br>
+def int_ppc_tcheck : GCCBuiltin<"__builtin_tcheck">,<br>
+      Intrinsic<[llvm_i32_ty], [], []>;<br>
+def int_ppc_treclaim : GCCBuiltin<"__builtin_treclaim">,<br>
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;<br>
+def int_ppc_trechkpt : GCCBuiltin<"__builtin_trechkpt">,<br>
+      Intrinsic<[llvm_i32_ty], [], []>;<br>
+def int_ppc_tsr :<br>
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;<br>
+<br>
+def int_ppc_get_texasr : GCCBuiltin<"__builtin_get_texasr">,<br>
+      Intrinsic<[llvm_i64_ty], [], []>;<br>
+def int_ppc_get_texasru : GCCBuiltin<"__builtin_get_texasru">,<br>
+      Intrinsic<[llvm_i64_ty], [], []>;<br>
+def int_ppc_get_tfhar : GCCBuiltin<"__builtin_get_tfhar">,<br>
+      Intrinsic<[llvm_i64_ty], [], []>;<br>
+def int_ppc_get_tfiar : GCCBuiltin<"__builtin_get_tfiar">,<br>
+      Intrinsic<[llvm_i64_ty], [], []>;<br>
+<br>
+def int_ppc_set_texasr : GCCBuiltin<"__builtin_set_texasr">,<br>
+      Intrinsic<[], [llvm_i64_ty], []>;<br>
+def int_ppc_set_texasru : GCCBuiltin<"__builtin_set_texasru">,<br>
+      Intrinsic<[], [llvm_i64_ty], []>;<br>
+def int_ppc_set_tfhar : GCCBuiltin<"__builtin_set_tfhar">,<br>
+      Intrinsic<[], [llvm_i64_ty], []>;<br>
+def int_ppc_set_tfiar : GCCBuiltin<"__builtin_set_tfiar">,<br>
+      Intrinsic<[], [llvm_i64_ty], []>;<br>
+<br>
+// Extended mnemonics<br>
+def int_ppc_tendall : GCCBuiltin<"__builtin_tendall">,<br>
+      Intrinsic<[llvm_i32_ty], [], []>;<br>
+def int_ppc_tresume : GCCBuiltin<"__builtin_tresume">,<br>
+      Intrinsic<[llvm_i32_ty], [], []>;<br>
+def int_ppc_tsuspend : GCCBuiltin<"__builtin_tsuspend">,<br>
+      Intrinsic<[llvm_i32_ty], [], []>;<br>
+<br>
+def int_ppc_ttest : GCCBuiltin<"__builtin_ttest">,<br>
+      Intrinsic<[llvm_i64_ty], [], []>;<br>
+}<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp Wed Mar 25 14:36:23 2015<br>
@@ -427,6 +427,7 @@ public:<br>
   bool isImm() const override { return Kind == Immediate || Kind == Expression; }<br>
   bool isU1Imm() const { return Kind == Immediate && isUInt<1>(getImm()); }<br>
   bool isU2Imm() const { return Kind == Immediate && isUInt<2>(getImm()); }<br>
+  bool isU3Imm() const { return Kind == Immediate && isUInt<3>(getImm()); }<br>
   bool isU4Imm() const { return Kind == Immediate && isUInt<4>(getImm()); }<br>
   bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); }<br>
   bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); }<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp Wed Mar 25 14:36:23 2015<br>
@@ -189,6 +189,12 @@ static DecodeStatus DecodeCRRCRegisterCl<br>
   return decodeRegisterClass(Inst, RegNo, CRRegs);<br>
 }<br>
<br>
+static DecodeStatus DecodeCRRC0RegisterClass(MCInst &Inst, uint64_t RegNo,<br>
+                                            uint64_t Address,<br>
+                                            const void *Decoder) {<br>
+  return decodeRegisterClass(Inst, RegNo, CRRegs);<br>
+}<br>
+<br>
 static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo,<br>
                                             uint64_t Address,<br>
                                             const void *Decoder) {<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp Wed Mar 25 14:36:23 2015<br>
@@ -228,6 +228,13 @@ void PPCInstPrinter::printU2ImmOperand(c<br>
   O << (unsigned int)Value;<br>
 }<br>
<br>
+void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo,<br>
+                                       raw_ostream &O) {<br>
+  unsigned int Value = MI->getOperand(OpNo).getImm();<br>
+  assert(Value <= 8 && "Invalid u3imm argument!");<br>
+  O << (unsigned int)Value;<br>
+}<br>
+<br>
 void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,<br>
                                        raw_ostream &O) {<br>
   unsigned int Value = MI->getOperand(OpNo).getImm();<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h Wed Mar 25 14:36:23 2015<br>
@@ -45,6 +45,7 @@ public:<br>
<br>
   void printU1ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);<br>
   void printU2ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);<br>
+  void printU3ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);<br>
   void printU4ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);<br>
   void printS5ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);<br>
   void printU5ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPC.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPC.td?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPC.td?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPC.td (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPC.td Wed Mar 25 14:36:23 2015<br>
@@ -125,6 +125,8 @@ def FeatureInvariantFunctionDescriptors<br>
   SubtargetFeature<"invariant-function-descriptors",<br>
                    "HasInvariantFunctionDescriptors", "true",<br>
                    "Assume function descriptors are invariant">;<br>
+def FeatureHTM : SubtargetFeature<"htm", "HasHTM", "true",<br>
+                                  "Enable Hardware Transactional Memory instructions">;<br>
<br>
 def DeprecatedMFTB   : SubtargetFeature<"", "DeprecatedMFTB", "true",<br>
                                         "Treat mftb as deprecated">;<br>
@@ -261,7 +263,7 @@ def ProcessorFeatures {<br>
         [DirectivePwr8, FeatureAltivec, FeatureP8Altivec, FeatureVSX,<br>
         FeatureP8Vector, FeatureMFOCRF, FeatureFCPSGN, FeatureFSqrt,<br>
         FeatureFRE, FeatureFRES, FeatureFRSQRTE, FeatureFRSQRTES,<br>
-        FeatureRecipPrec, FeatureSTFIWX, FeatureLFIWAX,<br>
+        FeatureRecipPrec, FeatureSTFIWX, FeatureLFIWAX, FeatureHTM,<br>
         FeatureFPRND, FeatureFPCVT, FeatureISEL,<br>
         FeaturePOPCNTD, FeatureCMPB, FeatureLDBRX, FeatureP8Crypto,<br>
         Feature64Bit /*, Feature64BitRegs */, FeatureICBT,<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Wed Mar 25 14:36:23 2015<br>
@@ -8782,6 +8782,12 @@ PPCTargetLowering::EmitInstrWithCustomIn<br>
     BuildMI(*BB, MI, dl, TII->get(TargetOpcode::COPY),<br>
             MI->getOperand(0).getReg())<br>
       .addReg(isEQ ? PPC::CR0EQ : PPC::CR0GT);<br>
+  } else if (MI->getOpcode() == PPC::TCHECK_RET) {<br>
+    DebugLoc Dl = MI->getDebugLoc();<br>
+    MachineRegisterInfo &RegInfo = F->getRegInfo();<br>
+    unsigned CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);<br>
+    BuildMI(*BB, MI, Dl, TII->get(PPC::TCHECK), CRReg);<br>
+    return BB;<br>
   } else {<br>
     llvm_unreachable("Unexpected instr type to insert");<br>
   }<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td Wed Mar 25 14:36:23 2015<br>
@@ -329,6 +329,12 @@ let hasSideEffects = 1, isBarrier = 1, u<br>
                           Requires<[In64BitMode]>;<br>
 }<br>
<br>
+def MFSPR8 : XFXForm_1<31, 339, (outs g8rc:$RT), (ins i32imm:$SPR),<br>
+                       "mfspr $RT, $SPR", IIC_SprMFSPR>;<br>
+def MTSPR8 : XFXForm_1<31, 467, (outs), (ins i32imm:$SPR, g8rc:$RT),<br>
+                       "mtspr $SPR, $RT", IIC_SprMTSPR>;<br>
+<br>
+<br>
 //===----------------------------------------------------------------------===//<br>
 // 64-bit SPR manipulation instrs.<br>
<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td Wed Mar 25 14:36:23 2015<br>
@@ -693,6 +693,60 @@ class XForm_16b<bits<6> opcode, bits<10><br>
   let A = 0;<br>
 }<br>
<br>
+class XForm_htm0<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,<br>
+                 string asmstr, InstrItinClass itin, list<dag> pattern><br>
+  : I<opcode, OOL, IOL, asmstr, itin> {<br>
+  bit R;<br>
+<br>
+  bit RC = 1;<br>
+<br>
+  let Inst{6-9}   = 0;<br>
+  let Inst{10}    = R;<br>
+  let Inst{11-20} = 0;<br>
+  let Inst{21-30} = xo;<br>
+  let Inst{31}    = RC;<br>
+}<br>
+<br>
+class XForm_htm1<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,<br>
+                 string asmstr, InstrItinClass itin, list<dag> pattern><br>
+  : I<opcode, OOL, IOL, asmstr, itin> {<br>
+  bit A;<br>
+<br>
+  bit RC = 1;<br>
+<br>
+  let Inst{6}     = A;<br>
+  let Inst{7-20}  = 0;<br>
+  let Inst{21-30} = xo;<br>
+  let Inst{31}    = RC;<br>
+}<br>
+<br>
+class XForm_htm2<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, string asmstr,<br>
+              InstrItinClass itin, list<dag> pattern><br>
+  : I<opcode, OOL, IOL, asmstr, itin> {<br>
+  bit L;<br>
+<br>
+  bit RC = 0;    // set by isDOT<br>
+<br>
+  let Inst{7-9}   = 0;<br>
+  let Inst{10}    = L;<br>
+  let Inst{11-20} = 0;<br>
+  let Inst{21-30} = xo;<br>
+  let Inst{31}    = RC;<br>
+}<br>
+<br>
+class XForm_htm3<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, string asmstr,<br>
+              InstrItinClass itin, list<dag> pattern><br>
+  : I<opcode, OOL, IOL, asmstr, itin> {<br>
+  bits<3> BF;<br>
+<br>
+  bit RC = 0;<br>
+<br>
+  let Inst{6-8}   = BF;<br>
+  let Inst{9-20}  = 0;<br>
+  let Inst{21-30} = xo;<br>
+  let Inst{31}    = RC;<br>
+}<br>
+<br>
 // XX*-Form (VSX)<br>
 class XX1Form<bits<6> opcode, bits<10> xo, dag OOL, dag IOL, string asmstr,<br>
               InstrItinClass itin, list<dag> pattern><br>
<br>
Added: llvm/trunk/lib/Target/PowerPC/PPCInstrHTM.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrHTM.td?rev=233204&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrHTM.td?rev=233204&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCInstrHTM.td (added)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrHTM.td Wed Mar 25 14:36:23 2015<br>
@@ -0,0 +1,172 @@<br>
+//===-- PPCInstrHTM.td - The PowerPC Hardware Transactional Memory  -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file describes the Hardware Transactional Memory extension to the<br>
+// PowerPC instruction set.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+<br>
+<br>
+def HasHTM : Predicate<"PPCSubTarget->hasHTM()">;<br>
+<br>
+def HTM_get_imm : SDNodeXForm<imm, [{<br>
+  return getI32Imm (N->getZExtValue());<br>
+}]>;<br>
+<br>
+let hasSideEffects = 1, usesCustomInserter = 1  in {<br>
+def TCHECK_RET : Pseudo<(outs crrc:$out), (ins), "#TCHECK_RET", []>;<br>
+}<br>
+<br>
+<br>
+let Predicates = [HasHTM] in {<br>
+<br>
+def TBEGIN : XForm_htm0 <31, 654,<br>
+                         (outs crrc0:$ret), (ins u1imm:$R), "tbegin. $R", IIC_SprMTSPR, []>;<br>
+<br>
+def TEND : XForm_htm1 <31, 686,<br>
+                       (outs crrc0:$ret), (ins u1imm:$A), "tend. $A", IIC_SprMTSPR, []>;<br>
+<br>
+def TABORT : XForm_base_r3xo <31, 910,<br>
+                              (outs crrc0:$ret), (ins gprc:$A), "tabort. $A", IIC_SprMTSPR,<br>
+                              []>, isDOT {<br>
+  let RST = 0;<br>
+  let B = 0;<br>
+}<br>
+<br>
+def TABORTWC : XForm_base_r3xo <31, 782,<br>
+                                (outs crrc0:$ret), (ins u5imm:$RTS, gprc:$A, gprc:$B),<br>
+                                "tabortwc. $RTS, $A, $B", IIC_SprMTSPR, []>,<br>
+                                isDOT;<br>
+<br>
+def TABORTWCI : XForm_base_r3xo <31, 846,<br>
+                                 (outs crrc0:$ret), (ins u5imm:$RTS, gprc:$A, u5imm:$B),<br>
+                                 "tabortwci. $RTS, $A, $B", IIC_SprMTSPR, []>,<br>
+                                 isDOT;<br>
+<br>
+def TABORTDC : XForm_base_r3xo <31, 814,<br>
+                                (outs crrc0:$ret), (ins u5imm:$RTS, gprc:$A, gprc:$B),<br>
+                                "tabortdc. $RTS, $A, $B", IIC_SprMTSPR, []>,<br>
+                                isDOT;<br>
+<br>
+def TABORTDCI : XForm_base_r3xo <31, 878,<br>
+                                 (outs crrc0:$ret), (ins u5imm:$RTS, gprc:$A, u5imm:$B),<br>
+                                 "tabortdci. $RTS, $A, $B", IIC_SprMTSPR, []>,<br>
+                                 isDOT;<br>
+<br>
+def TSR : XForm_htm2 <31, 750,<br>
+                      (outs crrc0:$ret), (ins u1imm:$L), "tsr. $L", IIC_SprMTSPR, []>,<br>
+                      isDOT;<br>
+<br>
+def TCHECK : XForm_htm3 <31, 718,<br>
+                        (outs), (ins crrc:$BF), "tcheck $BF", IIC_SprMTSPR, []>;<br>
+<br>
+<br>
+def TRECLAIM : XForm_base_r3xo <31, 942,<br>
+                                (outs crrc:$ret), (ins gprc:$A), "treclaim. $A",<br>
+                                IIC_SprMTSPR, []>,<br>
+                                isDOT {<br>
+  let RST = 0;<br>
+  let B = 0;<br>
+}<br>
+<br>
+def TRECHKPT : XForm_base_r3xo <31, 1006,<br>
+                                (outs crrc:$ret), (ins), "trechkpt.", IIC_SprMTSPR, []>,<br>
+                                isDOT {<br>
+  let RST = 0;<br>
+  let A = 0;<br>
+  let B = 0;<br>
+}<br>
+<br>
+// Builtins<br>
+<br>
+// All HTM instructions, with the exception of tcheck, set CR0 with the<br>
+// value of the MSR Transaction State (TS) bits that exist before the<br>
+// instruction is executed.  For tbegin., the EQ bit in CR0 can be used<br>
+// to determine whether the transaction was successfully started (0) or<br>
+// failed (1).  We use an XORI pattern to 'flip' the bit to match the<br>
+// tbegin builtin API which defines a return value of 1 as success.<br>
+<br>
+def : Pat<(int_ppc_tbegin i32:$R),<br>
+           (XORI<br>
+             (EXTRACT_SUBREG (<br>
+               TBEGIN (HTM_get_imm imm:$R)), sub_eq),<br>
+            1)>;<br>
+<br>
+def : Pat<(int_ppc_tend i32:$R),<br>
+          (TEND (HTM_get_imm imm:$R))>;<br>
+<br>
+<br>
+def : Pat<(int_ppc_tabort i32:$R),<br>
+          (TABORT $R)>;<br>
+<br>
+def : Pat<(int_ppc_tabortwc i32:$TO, i32:$RA, i32:$RB),<br>
+          (TABORTWC (HTM_get_imm imm:$TO), $RA, $RB)>;<br>
+<br>
+def : Pat<(int_ppc_tabortwci i32:$TO, i32:$RA, i32:$SI),<br>
+          (TABORTWCI (HTM_get_imm imm:$TO), $RA, (HTM_get_imm imm:$SI))>;<br>
+<br>
+def : Pat<(int_ppc_tabortdc i32:$TO, i32:$RA, i32:$RB),<br>
+          (TABORTDC (HTM_get_imm imm:$TO), $RA, $RB)>;<br>
+<br>
+def : Pat<(int_ppc_tabortdci i32:$TO, i32:$RA, i32:$SI),<br>
+          (TABORTDCI (HTM_get_imm imm:$TO), $RA, (HTM_get_imm imm:$SI))>;<br>
+<br>
+def : Pat<(int_ppc_tcheck),<br>
+          (TCHECK_RET)>;<br>
+<br>
+def : Pat<(int_ppc_treclaim i32:$RA),<br>
+          (TRECLAIM $RA)>;<br>
+<br>
+def : Pat<(int_ppc_trechkpt),<br>
+          (TRECHKPT)>;<br>
+<br>
+def : Pat<(int_ppc_tsr i32:$L),<br>
+          (TSR (HTM_get_imm imm:$L))>;<br>
+<br>
+def : Pat<(int_ppc_get_texasr),<br>
+          (MFSPR8 130)>;<br>
+<br>
+def : Pat<(int_ppc_get_texasru),<br>
+          (MFSPR8 131)>;<br>
+<br>
+def : Pat<(int_ppc_get_tfhar),<br>
+          (MFSPR8 128)>;<br>
+<br>
+def : Pat<(int_ppc_get_tfiar),<br>
+          (MFSPR8 129)>;<br>
+<br>
+<br>
+def : Pat<(int_ppc_set_texasr i64:$V),<br>
+          (MTSPR8 130, $V)>;<br>
+<br>
+def : Pat<(int_ppc_set_texasru i64:$V),<br>
+          (MTSPR8 131, $V)>;<br>
+<br>
+def : Pat<(int_ppc_set_tfhar i64:$V),<br>
+          (MTSPR8 128, $V)>;<br>
+<br>
+def : Pat<(int_ppc_set_tfiar i64:$V),<br>
+          (MTSPR8 129, $V)>;<br>
+<br>
+<br>
+// Extended mnemonics<br>
+def : Pat<(int_ppc_tendall),<br>
+          (TEND 1)>;<br>
+<br>
+def : Pat<(int_ppc_tresume),<br>
+          (TSR 1)>;<br>
+<br>
+def : Pat<(int_ppc_tsuspend),<br>
+          (TSR 0)>;<br>
+<br>
+def : Pat<(i64 (int_ppc_ttest)),<br>
+          (RLDICL (i64 (COPY (TABORTWCI 0, ZERO, 0))), 36, 28)>;<br>
+<br>
+} // [HasHTM]<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Wed Mar 25 14:36:23 2015<br>
@@ -696,6 +696,33 @@ void PPCInstrInfo::insertSelect(MachineB<br>
     .addReg(Cond[1].getReg(), 0, SubIdx);<br>
 }<br>
<br>
+static unsigned getCRBitValue(unsigned CRBit) {<br>
+  unsigned Ret = 4;<br>
+  if (CRBit == PPC::CR0LT || CRBit == PPC::CR1LT ||<br>
+      CRBit == PPC::CR2LT || CRBit == PPC::CR3LT ||<br>
+      CRBit == PPC::CR4LT || CRBit == PPC::CR5LT ||<br>
+      CRBit == PPC::CR6LT || CRBit == PPC::CR7LT)<br>
+    Ret = 3;<br>
+  if (CRBit == PPC::CR0GT || CRBit == PPC::CR1GT ||<br>
+      CRBit == PPC::CR2GT || CRBit == PPC::CR3GT ||<br>
+      CRBit == PPC::CR4GT || CRBit == PPC::CR5GT ||<br>
+      CRBit == PPC::CR6GT || CRBit == PPC::CR7GT)<br>
+    Ret = 2;<br>
+  if (CRBit == PPC::CR0EQ || CRBit == PPC::CR1EQ ||<br>
+      CRBit == PPC::CR2EQ || CRBit == PPC::CR3EQ ||<br>
+      CRBit == PPC::CR4EQ || CRBit == PPC::CR5EQ ||<br>
+      CRBit == PPC::CR6EQ || CRBit == PPC::CR7EQ)<br>
+    Ret = 1;<br>
+  if (CRBit == PPC::CR0UN || CRBit == PPC::CR1UN ||<br>
+      CRBit == PPC::CR2UN || CRBit == PPC::CR3UN ||<br>
+      CRBit == PPC::CR4UN || CRBit == PPC::CR5UN ||<br>
+      CRBit == PPC::CR6UN || CRBit == PPC::CR7UN)<br>
+    Ret = 0;<br>
+<br>
+  assert(Ret != 4 && "Invalid CR bit register");<br>
+  return Ret;<br>
+}<br>
+<br>
 void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,<br>
                                MachineBasicBlock::iterator I, DebugLoc DL,<br>
                                unsigned DestReg, unsigned SrcReg,<br>
@@ -741,6 +768,32 @@ void PPCInstrInfo::copyPhysReg(MachineBa<br>
     SrcReg = SuperReg;<br>
   }<br>
<br>
+  // Different class register copy<br>
+  if (PPC::CRBITRCRegClass.contains(SrcReg) &&<br>
+      PPC::GPRCRegClass.contains(DestReg)) {<br>
+    unsigned CRReg = getCRFromCRBit(SrcReg);<br>
+    BuildMI(MBB, I, DL, get(PPC::MFOCRF), DestReg)<br>
+       .addReg(CRReg), getKillRegState(KillSrc);<br>
+    // Rotate the CR bit in the CR fields to be the least significant bit and<br>
+    // then mask with 0x1 (MB = ME = 31).<br>
+    BuildMI(MBB, I, DL, get(PPC::RLWINM), DestReg)<br>
+       .addReg(DestReg, RegState::Kill)<br>
+       .addImm(TRI->getEncodingValue(CRReg) * 4 + (4 - getCRBitValue(SrcReg)))<br>
+       .addImm(31)<br>
+       .addImm(31);<br>
+    return;<br>
+  } else if (PPC::CRRCRegClass.contains(SrcReg) &&<br>
+      PPC::G8RCRegClass.contains(DestReg)) {<br>
+    BuildMI(MBB, I, DL, get(PPC::MFOCRF8), DestReg)<br>
+       .addReg(SrcReg), getKillRegState(KillSrc);<br>
+    return;<br>
+  } else if (PPC::CRRCRegClass.contains(SrcReg) &&<br>
+      PPC::GPRCRegClass.contains(DestReg)) {<br>
+    BuildMI(MBB, I, DL, get(PPC::MFOCRF), DestReg)<br>
+       .addReg(SrcReg), getKillRegState(KillSrc);<br>
+    return;<br>
+   }<br>
+<br>
   unsigned Opc;<br>
   if (PPC::GPRCRegClass.contains(DestReg, SrcReg))<br>
     Opc = PPC::OR;<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Wed Mar 25 14:36:23 2015<br>
@@ -432,6 +432,9 @@ def PPCRegCRRCAsmOperand : AsmOperandCla<br>
 def crrc : RegisterOperand<CRRC> {<br>
   let ParserMatchClass = PPCRegCRRCAsmOperand;<br>
 }<br>
+def crrc0 : RegisterOperand<CRRC0> {<br>
+  let ParserMatchClass = PPCRegCRRCAsmOperand;<br>
+}<br>
<br>
 def PPCU1ImmAsmOperand : AsmOperandClass {<br>
   let Name = "U1Imm"; let PredicateMethod = "isU1Imm";<br>
@@ -451,6 +454,15 @@ def u2imm   : Operand<i32> {<br>
   let ParserMatchClass = PPCU2ImmAsmOperand;<br>
 }<br>
<br>
+def PPCU3ImmAsmOperand : AsmOperandClass {<br>
+  let Name = "U3Imm"; let PredicateMethod = "isU3Imm";<br>
+  let RenderMethod = "addImmOperands";<br>
+}<br>
+def u3imm   : Operand<i32> {<br>
+  let PrintMethod = "printU3ImmOperand";<br>
+  let ParserMatchClass = PPCU3ImmAsmOperand;<br>
+}<br>
+<br>
 def PPCU4ImmAsmOperand : AsmOperandClass {<br>
   let Name = "U4Imm"; let PredicateMethod = "isU4Imm";<br>
   let RenderMethod = "addImmOperands";<br>
@@ -2708,6 +2720,7 @@ include "PPCInstrSPE.td"<br>
 include "PPCInstr64Bit.td"<br>
 include "PPCInstrVSX.td"<br>
 include "PPCInstrQPX.td"<br>
+include "PPCInstrHTM.td"<br>
<br>
 def crnot : OutPatFrag<(ops node:$in),<br>
                        (CRNOR $in, $in)>;<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Wed Mar 25 14:36:23 2015<br>
@@ -524,37 +524,6 @@ void PPCRegisterInfo::lowerCRRestore(Mac<br>
   MBB.erase(II);<br>
 }<br>
<br>
-static unsigned getCRFromCRBit(unsigned SrcReg) {<br>
-  unsigned Reg = 0;<br>
-  if (SrcReg == PPC::CR0LT || SrcReg == PPC::CR0GT ||<br>
-      SrcReg == PPC::CR0EQ || SrcReg == PPC::CR0UN)<br>
-    Reg = PPC::CR0;<br>
-  else if (SrcReg == PPC::CR1LT || SrcReg == PPC::CR1GT ||<br>
-           SrcReg == PPC::CR1EQ || SrcReg == PPC::CR1UN)<br>
-    Reg = PPC::CR1;<br>
-  else if (SrcReg == PPC::CR2LT || SrcReg == PPC::CR2GT ||<br>
-           SrcReg == PPC::CR2EQ || SrcReg == PPC::CR2UN)<br>
-    Reg = PPC::CR2;<br>
-  else if (SrcReg == PPC::CR3LT || SrcReg == PPC::CR3GT ||<br>
-           SrcReg == PPC::CR3EQ || SrcReg == PPC::CR3UN)<br>
-    Reg = PPC::CR3;<br>
-  else if (SrcReg == PPC::CR4LT || SrcReg == PPC::CR4GT ||<br>
-           SrcReg == PPC::CR4EQ || SrcReg == PPC::CR4UN)<br>
-    Reg = PPC::CR4;<br>
-  else if (SrcReg == PPC::CR5LT || SrcReg == PPC::CR5GT ||<br>
-           SrcReg == PPC::CR5EQ || SrcReg == PPC::CR5UN)<br>
-    Reg = PPC::CR5;<br>
-  else if (SrcReg == PPC::CR6LT || SrcReg == PPC::CR6GT ||<br>
-           SrcReg == PPC::CR6EQ || SrcReg == PPC::CR6UN)<br>
-    Reg = PPC::CR6;<br>
-  else if (SrcReg == PPC::CR7LT || SrcReg == PPC::CR7GT ||<br>
-           SrcReg == PPC::CR7EQ || SrcReg == PPC::CR7UN)<br>
-    Reg = PPC::CR7;<br>
-<br>
-  assert(Reg != 0 && "Invalid CR bit register");<br>
-  return Reg;<br>
-}<br>
-<br>
 void PPCRegisterInfo::lowerCRBitSpilling(MachineBasicBlock::iterator II,<br>
                                          unsigned FrameIndex) const {<br>
   // Get the instruction.<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h Wed Mar 25 14:36:23 2015<br>
@@ -22,6 +22,39 @@<br>
 #include "PPCGenRegisterInfo.inc"<br>
<br>
 namespace llvm {<br>
+<br>
+inline static unsigned getCRFromCRBit(unsigned SrcReg) {<br>
+  unsigned Reg = 0;<br>
+  if (SrcReg == PPC::CR0LT || SrcReg == PPC::CR0GT ||<br>
+      SrcReg == PPC::CR0EQ || SrcReg == PPC::CR0UN)<br>
+    Reg = PPC::CR0;<br>
+  else if (SrcReg == PPC::CR1LT || SrcReg == PPC::CR1GT ||<br>
+           SrcReg == PPC::CR1EQ || SrcReg == PPC::CR1UN)<br>
+    Reg = PPC::CR1;<br>
+  else if (SrcReg == PPC::CR2LT || SrcReg == PPC::CR2GT ||<br>
+           SrcReg == PPC::CR2EQ || SrcReg == PPC::CR2UN)<br>
+    Reg = PPC::CR2;<br>
+  else if (SrcReg == PPC::CR3LT || SrcReg == PPC::CR3GT ||<br>
+           SrcReg == PPC::CR3EQ || SrcReg == PPC::CR3UN)<br>
+    Reg = PPC::CR3;<br>
+  else if (SrcReg == PPC::CR4LT || SrcReg == PPC::CR4GT ||<br>
+           SrcReg == PPC::CR4EQ || SrcReg == PPC::CR4UN)<br>
+    Reg = PPC::CR4;<br>
+  else if (SrcReg == PPC::CR5LT || SrcReg == PPC::CR5GT ||<br>
+           SrcReg == PPC::CR5EQ || SrcReg == PPC::CR5UN)<br>
+    Reg = PPC::CR5;<br>
+  else if (SrcReg == PPC::CR6LT || SrcReg == PPC::CR6GT ||<br>
+           SrcReg == PPC::CR6EQ || SrcReg == PPC::CR6UN)<br>
+    Reg = PPC::CR6;<br>
+  else if (SrcReg == PPC::CR7LT || SrcReg == PPC::CR7GT ||<br>
+           SrcReg == PPC::CR7EQ || SrcReg == PPC::CR7UN)<br>
+    Reg = PPC::CR7;<br>
+<br>
+  assert(Reg != 0 && "Invalid CR bit register");<br>
+  return Reg;<br>
+}<br>
+<br>
+<br>
 class PPCRegisterInfo : public PPCGenRegisterInfo {<br>
   DenseMap<unsigned, unsigned> ImmToIdxMap;<br>
   const PPCTargetMachine &TM;<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td Wed Mar 25 14:36:23 2015<br>
@@ -341,6 +341,8 @@ def CRBITRC : RegisterClass<"PPC", [i1],<br>
 def CRRC : RegisterClass<"PPC", [i32], 32, (add CR0, CR1, CR5, CR6,<br>
                                                 CR7, CR2, CR3, CR4)>;<br>
<br>
+def CRRC0 : RegisterClass<"PPC", [i32], 32, (add CR0)>;<br>
+<br>
 // The CTR registers are not allocatable because they're used by the<br>
 // decrement-and-branch instructions, and thus need to stay live across<br>
 // multiple basic blocks.<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp Wed Mar 25 14:36:23 2015<br>
@@ -97,6 +97,7 @@ void PPCSubtarget::initializeEnvironment<br>
   HasInvariantFunctionDescriptors = false;<br>
   HasPartwordAtomics = false;<br>
   IsQPXStackUnaligned = false;<br>
+  HasHTM = false;<br>
 }<br>
<br>
 void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h?rev=233204&r1=233203&r2=233204&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h?rev=233204&r1=233203&r2=233204&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h Wed Mar 25 14:36:23 2015<br>
@@ -115,6 +115,7 @@ protected:<br>
   bool HasICBT;<br>
   bool HasInvariantFunctionDescriptors;<br>
   bool HasPartwordAtomics;<br>
+  bool HasHTM;<br>
<br>
   /// When targeting QPX running a stock PPC64 Linux kernel where the stack<br>
   /// alignment has not been changed, we need to keep the 16-byte alignment<br>
@@ -246,6 +247,7 @@ public:<br>
<br>
     return 16;<br>
   }<br>
+  bool hasHTM() const { return HasHTM; }<br>
<br>
   const Triple &getTargetTriple() const { return TargetTriple; }<br>
<br>
<br>
Added: llvm/trunk/test/CodeGen/PowerPC/htm.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/htm.ll?rev=233204&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/htm.ll?rev=233204&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/PowerPC/htm.ll (added)<br>
+++ llvm/trunk/test/CodeGen/PowerPC/htm.ll Wed Mar 25 14:36:23 2015<br>
@@ -0,0 +1,125 @@<br>
+; RUN: llc -mcpu=pwr8 -mattr=+htm < %s | FileCheck %s<br>
+target datalayout = "E-m:e-i64:64-n32:64"<br>
+target triple = "powerpc64-unknown-linux-gnu"<br>
+<br>
+define zeroext i32 @test1() {<br>
+entry:<br>
+  %0 = tail call i32 @llvm.ppc.tbegin(i32 0)<br>
+  ret i32 %0<br>
+<br>
+; CHECK-LABEL: @test1<br>
+; CHECK: tbegin. 0<br>
+; CHECK: mfocrf  [[REGISTER1:[0-9]+]], 128<br>
+; CHECK: rlwinm  [[REGISTER2:[0-9]+]], [[REGISTER1]], 3, 31, 31<br>
+; CHECK: xori    {{[0-9]+}}, [[REGISTER2]], 1<br>
+}<br>
+<br>
+declare i32 @llvm.ppc.tbegin(i32) #1<br>
+<br>
+<br>
+define zeroext i32 @test2() {<br>
+entry:<br>
+  %0 = tail call i32 @llvm.ppc.tend(i32 0)<br>
+  ret i32 %0<br>
+; CHECK-LABEL: @test2<br>
+; CHECK: tend. 0<br>
+; CHECK: mfocrf  {{[0-9]+}}, 128<br>
+}<br>
+<br>
+declare i32 @llvm.ppc.tend(i32)<br>
+<br>
+<br>
+define void @test3() {<br>
+entry:<br>
+  %0 = tail call i32 @llvm.ppc.tabort(i32 0)<br>
+  %1 = tail call i32 @llvm.ppc.tabortdc(i32 0, i32 1, i32 2)<br>
+  %2 = tail call i32 @llvm.ppc.tabortdci(i32 0, i32 1, i32 2)<br>
+  %3 = tail call i32 @llvm.ppc.tabortwc(i32 0, i32 1, i32 2)<br>
+  %4 = tail call i32 @llvm.ppc.tabortwci(i32 0, i32 1, i32 2)<br>
+  ret void<br>
+; CHECK-LABEL: @test3<br>
+; CHECK: tabort.    {{[0-9]+}}<br>
+; CHECK: tabortdc.  0, {{[0-9]+}}, {{[0-9]+}}<br>
+; CHECK: tabortdci. 0, {{[0-9]+}}, 2<br>
+; CHECK: tabortwc.  0, {{[0-9]+}}, {{[0-9]+}}<br>
+; CHECK: tabortwci. 0, {{[0-9]+}}, 2<br>
+}<br>
+<br>
+declare i32 @llvm.ppc.tabort(i32)<br>
+declare i32 @llvm.ppc.tabortdc(i32, i32, i32)<br>
+declare i32 @llvm.ppc.tabortdci(i32, i32, i32)<br>
+declare i32 @llvm.ppc.tabortwc(i32, i32, i32)<br>
+declare i32 @llvm.ppc.tabortwci(i32, i32, i32)<br>
+<br>
+<br>
+define void @test4() {<br>
+entry:<br>
+  %0 = tail call i32 @llvm.ppc.tendall()<br>
+  %1 = tail call i32 @llvm.ppc.tresume()<br>
+  %2 = tail call i32 @llvm.ppc.tsuspend()<br>
+  ret void<br>
+; CHECK-LABEL: @test4<br>
+; CHECK: tend. 1<br>
+; CHECK: tsr.  1<br>
+; CHECK: tsr.  0<br>
+}<br>
+<br>
+declare i32 @llvm.ppc.tendall()<br>
+declare i32 @llvm.ppc.tresume()<br>
+declare i32 @llvm.ppc.tsuspend()<br>
+<br>
+<br>
+define void @test5(i64 %v) {<br>
+entry:<br>
+  tail call void @llvm.ppc.set.texasr(i64 %v)<br>
+  tail call void @llvm.ppc.set.texasru(i64 %v)<br>
+  tail call void @llvm.ppc.set.tfhar(i64 %v)<br>
+  tail call void @llvm.ppc.set.tfiar(i64 %v)<br>
+  ret void<br>
+; CHECK-LABEL: @test5<br>
+; CHECK: mtspr 130, [[REG1:[0-9]+]]<br>
+; CHECK: mtspr 131, [[REG2:[0-9]+]]<br>
+; CHECK: mtspr 128, [[REG3:[0-9]+]]<br>
+; CHECK: mtspr 129, [[REG4:[0-9]+]]<br>
+}<br>
+<br>
+define i64 @test6() {<br>
+entry:<br>
+  %0 = tail call i64 @llvm.ppc.get.texasr()<br>
+  ret i64 %0<br>
+; CHECK-LABEL: @test6<br>
+; CHECK: mfspr [[REG1:[0-9]+]], 130<br>
+}<br>
+<br>
+define i64 @test7() {<br>
+entry:<br>
+  %0 = tail call i64 @llvm.ppc.get.texasru()<br>
+  ret i64 %0<br>
+; CHECK-LABEL: @test7<br>
+; CHECK: mfspr [[REG1:[0-9]+]], 131<br>
+}<br>
+<br>
+define i64 @test8() {<br>
+entry:<br>
+  %0 = tail call i64 @llvm.ppc.get.tfhar()<br>
+  ret i64 %0<br>
+; CHECK-LABEL: @test8<br>
+; CHECK: mfspr [[REG1:[0-9]+]], 128<br>
+}<br>
+<br>
+define i64 @test9() {<br>
+entry:<br>
+  %0 = tail call i64 @llvm.ppc.get.tfiar()<br>
+  ret i64 %0<br>
+; CHECK-LABEL: @test9<br>
+; CHECK: mfspr [[REG1:[0-9]+]], 129<br>
+}<br>
+<br>
+declare void @llvm.ppc.set.texasr(i64)<br>
+declare void @llvm.ppc.set.texasru(i64)<br>
+declare void @llvm.ppc.set.tfhar(i64)<br>
+declare void @llvm.ppc.set.tfiar(i64)<br>
+declare i64 @llvm.ppc.get.texasr()<br>
+declare i64 @llvm.ppc.get.texasru()<br>
+declare i64 @llvm.ppc.get.tfhar()<br>
+declare i64 @llvm.ppc.get.tfiar()<br>
<br>
Added: llvm/trunk/test/MC/PowerPC/htm.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/htm.s?rev=233204&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/htm.s?rev=233204&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/MC/PowerPC/htm.s (added)<br>
+++ llvm/trunk/test/MC/PowerPC/htm.s Wed Mar 25 14:36:23 2015<br>
@@ -0,0 +1,53 @@<br>
+# RUN: llvm-mc -triple powerpc64-unknown-linux-gnu --show-encoding %s | FileCheck -check-prefix=CHECK-BE %s<br>
+# RUN: llvm-mc -triple powerpc64le-unknown-linux-gnu --show-encoding %s | FileCheck -check-prefix=CHECK-LE %s<br>
+<br>
+# CHECK-BE: tbegin. 0                      # encoding: [0x7c,0x00,0x05,0x1d]<br>
+# CHECK-LE: tbegin. 0                      # encoding: [0x1d,0x05,0x00,0x7c]<br>
+            tbegin. 0<br>
+# CHECK-BE: tbegin. 1                      # encoding: [0x7c,0x20,0x05,0x1d]<br>
+# CHECK-LE: tbegin. 1                      # encoding: [0x1d,0x05,0x20,0x7c]<br>
+            tbegin. 1<br>
+<br>
+# CHECK-BE: tend. 0                        # encoding: [0x7c,0x00,0x05,0x5d]<br>
+# CHECK-LE: tend. 0                        # encoding: [0x5d,0x05,0x00,0x7c]<br>
+            tend. 0<br>
+# CHECK-BE: tend. 1                        # encoding: [0x7e,0x00,0x05,0x5d]<br>
+# CHECK-LE: tend. 1                        # encoding: [0x5d,0x05,0x00,0x7e]<br>
+            tend. 1<br>
+<br>
+# CHECK-BE: tabort. 9                      # encoding: [0x7c,0x09,0x07,0x1d]<br>
+# CHECK-LE: tabort. 9                      # encoding: [0x1d,0x07,0x09,0x7c]<br>
+            tabort. 9<br>
+# CHECK-BE: tabortdc. 0, 9, 9              # encoding: [0x7c,0x09,0x4e,0x5d]<br>
+# CHECK-LE: tabortdc. 0, 9, 9              # encoding: [0x5d,0x4e,0x09,0x7c]<br>
+            tabortdc. 0, 9, 9<br>
+# CHECK-BE: tabortdci. 0, 9, 0             # encoding: [0x7c,0x09,0x06,0xdd]<br>
+# CHECK-LE: tabortdci. 0, 9, 0             # encoding: [0xdd,0x06,0x09,0x7c]<br>
+            tabortdci. 0, 9, 0<br>
+# CHECK-BE: tabortwc. 0, 9, 9              # encoding: [0x7c,0x09,0x4e,0x1d]<br>
+# CHECK-LE: tabortwc. 0, 9, 9              # encoding: [0x1d,0x4e,0x09,0x7c]<br>
+            tabortwc. 0, 9, 9<br>
+# CHECK-BE: tabortwci. 0, 9, 0             # encoding: [0x7c,0x09,0x06,0x9d]<br>
+# CHECK-LE: tabortwci. 0, 9, 0             # encoding: [0x9d,0x06,0x09,0x7c]<br>
+            tabortwci. 0, 9, 0<br>
+<br>
+# CHECK-BE: tsr. 0                         # encoding: [0x7c,0x00,0x05,0xdd]<br>
+# CHECK-LE: tsr. 0                         # encoding: [0xdd,0x05,0x00,0x7c]<br>
+            tsr. 0<br>
+# CHECK-BE: tsr. 1                         # encoding: [0x7c,0x20,0x05,0xdd]<br>
+# CHECK-LE: tsr. 1                         # encoding: [0xdd,0x05,0x20,0x7c]<br>
+            tsr. 1<br>
+<br>
+# CHECK-BE: tcheck 0                       # encoding: [0x7c,0x00,0x05,0x9c]<br>
+# CHECK-LE: tcheck 0                       # encoding: [0x9c,0x05,0x00,0x7c]<br>
+            tcheck 0<br>
+# CHECK-BE: tcheck 3                       # encoding: [0x7d,0x80,0x05,0x9c]<br>
+# CHECK-LE: tcheck 3                       # encoding: [0x9c,0x05,0x80,0x7d]<br>
+            tcheck 3<br>
+<br>
+# CHECK-BE: treclaim. 9                    # encoding: [0x7c,0x09,0x07,0x5d]<br>
+# CHECK-LE: treclaim. 9                    # encoding: [0x5d,0x07,0x09,0x7c]<br>
+            treclaim. 9<br>
+# CHECK-BE: trechkpt.                      # encoding: [0x7c,0x00,0x07,0xdd]<br>
+# CHECK-LE: trechkpt.                      # encoding: [0xdd,0x07,0x00,0x7c]<br>
+            trechkpt.<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div>“One thing I have learned in a long life: that all our science, measured against reality, is primitive and childlike -- and yet it is the most precious thing we have.”</div><div><br></div><div>― Albert Einstein</div></div></div>
</div>