From: Bill Schmidt Date: Fri, 22 May 2015 16:44:10 +0000 (+0000) Subject: [PPC64] Add support for clrbhrb, mfbhrbe, rfebb. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=490d207be4ba9a12cc677ad3cd20c0e1b0231446;p=oota-llvm.git [PPC64] Add support for clrbhrb, mfbhrbe, rfebb. This patch adds support for the ISA 2.07 additions involving the branch history rolling buffer and event-based branching. These will not be used by typical applications, so built-in support is not required. They will only be available via inline assembly. Assembly/disassembly tests are included in the patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238032 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp index 3aeb6f6f23e..15225049f56 100644 --- a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp @@ -460,6 +460,8 @@ public: bool isU8ImmX8() const { return Kind == Immediate && isUInt<8>(getImm()) && (getImm() & 7) == 0; } + + bool isU10Imm() const { return Kind == Immediate && isUInt<10>(getImm()); } bool isU12Imm() const { return Kind == Immediate && isUInt<12>(getImm()); } bool isU16Imm() const { switch (Kind) { diff --git a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp index d5b90f2bd5c..53223ed50fa 100644 --- a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp +++ b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp @@ -299,6 +299,13 @@ void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo, O << (unsigned int)Value; } +void PPCInstPrinter::printU10ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned short Value = MI->getOperand(OpNo).getImm(); + assert(Value <= 1023 && "Invalid u10imm argument!"); + O << (unsigned short)Value; +} + void PPCInstPrinter::printU12ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { unsigned short Value = MI->getOperand(OpNo).getImm(); diff --git a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h index 3d83c72e2be..8e187834430 100644 --- a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h +++ b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h @@ -55,6 +55,7 @@ public: void printS5ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printU5ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printU6ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printU10ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printU12ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printS16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printU16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 43ffef2dcff..f8ebae1d4dc 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1048,6 +1048,9 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { case PPCISD::ADDI_DTPREL_L: return "PPCISD::ADDI_DTPREL_L"; case PPCISD::VADD_SPLAT: return "PPCISD::VADD_SPLAT"; case PPCISD::SC: return "PPCISD::SC"; + case PPCISD::CLRBHRB: return "PPCISD::CLRBHRB"; + case PPCISD::MFBHRBE: return "PPCISD::MFBHRBE"; + case PPCISD::RFEBB: return "PPCISD::RFEBB"; case PPCISD::XXSWAPD: return "PPCISD::XXSWAPD"; case PPCISD::QVFPERM: return "PPCISD::QVFPERM"; case PPCISD::QVGPCI: return "PPCISD::QVGPCI"; diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index 81589c8307f..c93de430fd0 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -275,6 +275,16 @@ namespace llvm { /// operand identifies the operating system entry point. SC, + /// CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer. + CLRBHRB, + + /// GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch + /// history rolling buffer entry. + MFBHRBE, + + /// CHAIN = RFEBB CHAIN, State - Return from event-based branch. + RFEBB, + /// VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little /// endian. Maps to an xxswapd instruction that corrects an lxvd2x /// or stxvd2x instruction. The chain is necessary because the diff --git a/lib/Target/PowerPC/PPCInstrFormats.td b/lib/Target/PowerPC/PPCInstrFormats.td index 57ac0784bd7..4e03ed27653 100644 --- a/lib/Target/PowerPC/PPCInstrFormats.td +++ b/lib/Target/PowerPC/PPCInstrFormats.td @@ -1080,6 +1080,19 @@ class XLForm_4 opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, let Inst{31} = RC; } +class XLForm_S opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : I { + bits<1> S; + + let Pattern = pattern; + + let Inst{6-19} = 0; + let Inst{20} = S; + let Inst{21-30} = xo; + let Inst{31} = 0; +} + class XLForm_2_and_DSForm_1 opcode1, bits<10> xo1, bit lk, bits<6> opcode2, bits<2> xo2, dag OOL, dag IOL, string asmstr, @@ -1158,6 +1171,19 @@ class XFXForm_3 opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, let Inst{31} = 0; } +class XFXForm_3p opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : I { + bits<5> RT; + bits<10> Entry; + let Pattern = pattern; + + let Inst{6-10} = RT; + let Inst{11-20} = Entry; + let Inst{21-30} = xo; + let Inst{31} = 0; +} + class XFXForm_5 opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, InstrItinClass itin> : I { diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 15459f2780f..c5a044ce85f 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -201,6 +201,12 @@ def SDT_PPCsc : SDTypeProfile<0, 1, [SDTCisInt<0>]>; def PPCsc : SDNode<"PPCISD::SC", SDT_PPCsc, [SDNPHasChain, SDNPSideEffect]>; +def PPCclrbhrb : SDNode<"PPCISD::CLRBHRB", SDTNone, + [SDNPHasChain, SDNPSideEffect]>; +def PPCmfbhrbe : SDNode<"PPCISD::MFBHRBE", SDTIntBinOp, [SDNPHasChain]>; +def PPCrfebb : SDNode<"PPCISD::RFEBB", SDT_PPCsc, + [SDNPHasChain, SDNPSideEffect]>; + def PPCvcmp : SDNode<"PPCISD::VCMP" , SDT_PPCvcmp, []>; def PPCvcmp_o : SDNode<"PPCISD::VCMPo", SDT_PPCvcmp, [SDNPOutGlue]>; @@ -499,6 +505,15 @@ def u6imm : Operand { let ParserMatchClass = PPCU6ImmAsmOperand; let DecoderMethod = "decodeUImmOperand<6>"; } +def PPCU10ImmAsmOperand : AsmOperandClass { + let Name = "U10Imm"; let PredicateMethod = "isU10Imm"; + let RenderMethod = "addImmOperands"; +} +def u10imm : Operand { + let PrintMethod = "printU10ImmOperand"; + let ParserMatchClass = PPCU10ImmAsmOperand; + let DecoderMethod = "decodeUImmOperand<10>"; +} def PPCU12ImmAsmOperand : AsmOperandClass { let Name = "U12Imm"; let PredicateMethod = "isU12Imm"; let RenderMethod = "addImmOperands"; @@ -1357,6 +1372,24 @@ let PPC970_Unit = 7 in { "sc $lev", IIC_BrB, [(PPCsc (i32 imm:$lev))]>; } +// Branch history rolling buffer. +def CLRBHRB : XForm_0<31, 430, (outs), (ins), "clrbhrb", IIC_BrB, + [(PPCclrbhrb)]>, + PPC970_DGroup_Single; +// The $dmy argument used for MFBHRBE is not needed; however, including +// it avoids automatic generation of PPCFastISel::fastEmit_i(), which +// interferes with necessary special handling (see PPCFastISel.cpp). +def MFBHRBE : XFXForm_3p<31, 302, (outs gprc:$rD), + (ins u10imm:$imm, u10imm:$dmy), + "mfbhrbe $rD, $imm", IIC_BrB, + [(set i32:$rD, + (PPCmfbhrbe imm:$imm, imm:$dmy))]>, + PPC970_DGroup_First; + +def RFEBB : XLForm_S<19, 146, (outs), (ins u1imm:$imm), "rfebb $imm", + IIC_BrB, [(PPCrfebb (i32 imm:$imm))]>, + PPC970_DGroup_Single; + // DCB* instructions. def DCBA : DCB_Form<758, 0, (outs), (ins memrr:$dst), "dcba $dst", IIC_LdStDCBF, [(int_ppc_dcba xoaddr:$dst)]>, diff --git a/test/MC/Disassembler/PowerPC/ppc64-encoding.txt b/test/MC/Disassembler/PowerPC/ppc64-encoding.txt index 59a1c4908fe..f235c242fbc 100644 --- a/test/MC/Disassembler/PowerPC/ppc64-encoding.txt +++ b/test/MC/Disassembler/PowerPC/ppc64-encoding.txt @@ -73,6 +73,15 @@ # CHECK: sc 0x44 0x00 0x00 0x02 +# CHECK: clrbhrb +0x7c 0x00 0x03 0x5c + +# CHECK: mfbhrbe 9, 983 +0x7d 0x3e 0xba 0x5c + +# CHECK: rfebb 1 +0x4c 0x00 0x09 0x24 + # CHECK: lbz 2, 128(4) 0x88 0x44 0x00 0x80 diff --git a/test/MC/PowerPC/ppc64-encoding.s b/test/MC/PowerPC/ppc64-encoding.s index effbc94fb13..4a698adadda 100644 --- a/test/MC/PowerPC/ppc64-encoding.s +++ b/test/MC/PowerPC/ppc64-encoding.s @@ -112,6 +112,18 @@ # CHECK-LE: sc # encoding: [0x02,0x00,0x00,0x44] sc +# Branch history rolling buffer + +# CHECK-BE: clrbhrb # encoding: [0x7c,0x00,0x03,0x5c] +# CHECK-LE: clrbhrb # encoding: [0x5c,0x03,0x00,0x7c] + clrbhrb +# CHECK-BE: mfbhrbe 9, 983 # encoding: [0x7d,0x3e,0xba,0x5c] +# CHECK-LE: mfbhrbe 9, 983 # encoding: [0x5c,0xba,0x3e,0x7d] + mfbhrbe 9, 983 +# CHECK-BE: rfebb 1 # encoding: [0x4c,0x00,0x09,0x24] +# CHECK-LE: rfebb 1 # encoding: [0x24,0x09,0x00,0x4c] + rfebb 1 + # Fixed-point facility # Fixed-point load instructions