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

Adhemerval Zanella adhemerval.zanella at linaro.org
Thu Mar 26 05:42:15 PDT 2015


Hi,

The powerpc HTM is defined in ISA 2.07 [1] and the builtins is modeled
using GCC
documentation [2].

[1] https://www.power.org/documentation/power-isa-version-2-07-2/
[2]
https://gcc.gnu.org/onlinedocs/gcc/PowerPC-Hardware-Transactional-Memory-Built-in-Functions.html

On Wed, Mar 25, 2015 at 10:08 PM, Sean Silva <chisophugis at gmail.com> wrote:

> Do any of the documents in
> http://llvm.org/docs/CompilerWriterInfo.html#powerpc cover this ISA
> extension? If not, could you add a link to docs/CompilerWriterInfo.rst ?
>
> -- Sean Silva
>
> On Wed, Mar 25, 2015 at 12:36 PM, Kit Barton <kbarton at ca.ibm.com> wrote:
>
>> 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.
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>


-- 
“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.”

― Albert Einstein
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150326/6f7d8c33/attachment.html>


More information about the llvm-commits mailing list