def int_ppc_dcbst : Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty],
[IntrReadWriteArgMem, NoCapture<0>]>;
- def int_ppc_dcbtst: Intrinsic<[], [llvm_ptr_ty], []>;
+ def int_ppc_dcbtst: Intrinsic<[], [llvm_ptr_ty],
+ [IntrReadWriteArgMem, NoCapture<0>]>;
def int_ppc_dcbz : Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbzl : Intrinsic<[], [llvm_ptr_ty], []>;
const OperandVector &Operands) {
int Opcode = Inst.getOpcode();
switch (Opcode) {
+ case PPC::DCBTx:
+ case PPC::DCBTT:
+ case PPC::DCBTSTx:
+ case PPC::DCBTSTT: {
+ MCInst TmpInst;
+ TmpInst.setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?
+ PPC::DCBT : PPC::DCBTST);
+ TmpInst.addOperand(MCOperand::CreateImm(
+ (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));
+ TmpInst.addOperand(Inst.getOperand(0));
+ TmpInst.addOperand(Inst.getOperand(1));
+ Inst = TmpInst;
+ break;
+ }
+ case PPC::DCBTCT:
+ case PPC::DCBTDS: {
+ MCInst TmpInst;
+ TmpInst.setOpcode(PPC::DCBT);
+ TmpInst.addOperand(Inst.getOperand(2));
+ TmpInst.addOperand(Inst.getOperand(0));
+ TmpInst.addOperand(Inst.getOperand(1));
+ Inst = TmpInst;
+ break;
+ }
+ case PPC::DCBTSTCT:
+ case PPC::DCBTSTDS: {
+ MCInst TmpInst;
+ TmpInst.setOpcode(PPC::DCBTST);
+ TmpInst.addOperand(Inst.getOperand(2));
+ TmpInst.addOperand(Inst.getOperand(0));
+ TmpInst.addOperand(Inst.getOperand(1));
+ Inst = TmpInst;
+ break;
+ }
case PPC::LAx: {
MCInst TmpInst;
TmpInst.setOpcode(PPC::LA);
return true;
}
+ // We'll now deal with an unfortunate special case: the syntax for the dcbt
+ // and dcbtst instructions differs for server vs. embedded cores.
+ // The syntax for dcbt is:
+ // dcbt ra, rb, th [server]
+ // dcbt th, ra, rb [embedded]
+ // where th can be omitted when it is 0. dcbtst is the same. We take the
+ // server form to be the default, so swap the operands if we're parsing for
+ // an embedded core (they'll be swapped again upon printing).
+ if ((STI.getFeatureBits() & PPC::FeatureBookE) != 0 &&
+ Operands.size() == 4 &&
+ (Name == "dcbt" || Name == "dcbtst")) {
+ std::swap(Operands[1], Operands[3]);
+ std::swap(Operands[2], Operands[1]);
+ }
+
return false;
}
return;
}
}
+
+ // dcbt[st] is printed manually here because:
+ // 1. The assembly syntax is different between embedded and server targets
+ // 2. We must print the short mnemonics for TH == 0 because the
+ // embedded/server syntax default will not be stable across assemblers
+ // The syntax for dcbt is:
+ // dcbt ra, rb, th [server]
+ // dcbt th, ra, rb [embedded]
+ // where th can be omitted when it is 0. dcbtst is the same.
+ if (MI->getOpcode() == PPC::DCBT || MI->getOpcode() == PPC::DCBTST) {
+ unsigned char TH = MI->getOperand(0).getImm();
+ O << "\tdcbt";
+ if (MI->getOpcode() == PPC::DCBTST)
+ O << "st";
+ if (TH == 16)
+ O << "t";
+ O << " ";
+
+ bool IsBookE = (STI.getFeatureBits() & PPC::FeatureBookE) != 0;
+ if (IsBookE && TH != 0 && TH != 16)
+ O << (unsigned int) TH << ", ";
+
+ printOperand(MI, 1, O);
+ O << ", ";
+ printOperand(MI, 2, O);
+
+ if (!IsBookE && TH != 0 && TH != 16)
+ O << ", " << (unsigned int) TH;
+
+ printAnnotation(O, Annot);
+ return;
+ }
// For fast-isel, a COPY_TO_REGCLASS may survive this long. This is
// used when converting a 32-bit float to a 64-bit float as part of
let Inst{31} = 0;
}
+class DCB_Form_hint<bits<10> xo, dag OOL, dag IOL, string asmstr,
+ InstrItinClass itin, list<dag> pattern>
+ : I<31, OOL, IOL, asmstr, itin> {
+ bits<5> TH;
+ bits<5> A;
+ bits<5> B;
+
+ let Pattern = pattern;
+
+ let Inst{6-10} = TH;
+ let Inst{11-15} = A;
+ let Inst{16-20} = B;
+ let Inst{21-30} = xo;
+ let Inst{31} = 0;
+}
// DSS_Form - Form X instruction, used for altivec dss* instructions.
class DSS_Form<bits<1> T, bits<10> xo, dag OOL, dag IOL, string asmstr,
def DCBST : DCB_Form<54, 0, (outs), (ins memrr:$dst), "dcbst $dst",
IIC_LdStDCBF, [(int_ppc_dcbst xoaddr:$dst)]>,
PPC970_DGroup_Single;
-def DCBT : DCB_Form<278, 0, (outs), (ins memrr:$dst), "dcbt $dst",
- IIC_LdStDCBF, [(int_ppc_dcbt xoaddr:$dst)]>,
- PPC970_DGroup_Single;
-def DCBTST : DCB_Form<246, 0, (outs), (ins memrr:$dst), "dcbtst $dst",
- IIC_LdStDCBF, [(int_ppc_dcbtst xoaddr:$dst)]>,
- PPC970_DGroup_Single;
def DCBZ : DCB_Form<1014, 0, (outs), (ins memrr:$dst), "dcbz $dst",
IIC_LdStDCBF, [(int_ppc_dcbz xoaddr:$dst)]>,
PPC970_DGroup_Single;
IIC_LdStDCBF, [(int_ppc_dcbzl xoaddr:$dst)]>,
PPC970_DGroup_Single;
+let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in {
+def DCBT : DCB_Form_hint<278, (outs), (ins u5imm:$TH, memrr:$dst),
+ "dcbt $dst, $TH", IIC_LdStDCBF, []>,
+ PPC970_DGroup_Single;
+def DCBTST : DCB_Form_hint<246, (outs), (ins u5imm:$TH, memrr:$dst),
+ "dcbtst $dst, $TH", IIC_LdStDCBF, []>,
+ PPC970_DGroup_Single;
+} // hasSideEffects = 0
+
def ICBT : XForm_icbt<31, 22, (outs), (ins u4imm:$CT, memrr:$src),
"icbt $CT, $src", IIC_LdStLoad>, Requires<[HasICBT]>;
+def : Pat<(int_ppc_dcbt xoaddr:$dst),
+ (DCBT 0, xoaddr:$dst)>;
+def : Pat<(int_ppc_dcbtst xoaddr:$dst),
+ (DCBTST 0, xoaddr:$dst)>;
+
def : Pat<(prefetch xoaddr:$dst, (i32 0), imm, (i32 1)),
- (DCBT xoaddr:$dst)>; // data prefetch for loads
+ (DCBT 0, xoaddr:$dst)>; // data prefetch for loads
def : Pat<(prefetch xoaddr:$dst, (i32 1), imm, (i32 1)),
- (DCBTST xoaddr:$dst)>; // data prefetch for stores
+ (DCBTST 0, xoaddr:$dst)>; // data prefetch for stores
def : Pat<(prefetch xoaddr:$dst, (i32 0), imm, (i32 0)),
(ICBT 0, xoaddr:$dst)>, Requires<[HasICBT]>; // inst prefetch (for read)
def : InstAlias<"mbar", (MBAR 0)>, Requires<[IsBookE]>;
+def DCBTx : PPCAsmPseudo<"dcbt $dst", (ins memrr:$dst)>;
+def DCBTSTx : PPCAsmPseudo<"dcbtst $dst", (ins memrr:$dst)>;
+
+def DCBTCT : PPCAsmPseudo<"dcbtct $dst, $TH", (ins memrr:$dst, u5imm:$TH)>;
+def DCBTDS : PPCAsmPseudo<"dcbtds $dst, $TH", (ins memrr:$dst, u5imm:$TH)>;
+def DCBTT : PPCAsmPseudo<"dcbtt $dst", (ins memrr:$dst)>;
+
+def DCBTSTCT : PPCAsmPseudo<"dcbtstct $dst, $TH", (ins memrr:$dst, u5imm:$TH)>;
+def DCBTSTDS : PPCAsmPseudo<"dcbtstds $dst, $TH", (ins memrr:$dst, u5imm:$TH)>;
+def DCBTSTT : PPCAsmPseudo<"dcbtstt $dst", (ins memrr:$dst)>;
+
def : InstAlias<"crset $bx", (CREQV crbitrc:$bx, crbitrc:$bx, crbitrc:$bx)>;
def : InstAlias<"crclr $bx", (CRXOR crbitrc:$bx, crbitrc:$bx, crbitrc:$bx)>;
def : InstAlias<"crmove $bx, $by", (CROR crbitrc:$bx, crbitrc:$by, crbitrc:$by)>;
--- /dev/null
+# RUN: llvm-mc --disassemble %s -triple powerpc64-unknown-unknown -mcpu=pwr7 | FileCheck %s -check-prefix=SERVER
+# RUN: llvm-mc --disassemble %s -triple powerpc64-unknown-unknown -mcpu=a2 | FileCheck %s -check-prefix=EMBEDDED
+
+# SERVER: dcbt 2, 3
+# EMBEDDED: dcbt 2, 3
+0x7c 0x02 0x1a 0x2c
+
+# SERVER: dcbtst 2, 3
+# EMBEDDED: dcbtst 2, 3
+0x7c 0x02 0x19 0xec
+
+# SERVER: dcbt 2, 3, 10
+# EMBEDDED: dcbt 10, 2, 3
+0x7d 0x42 0x1a 0x2c
+
+# SERVER: dcbtst 2, 3, 10
+# EMBEDDED: dcbtst 10, 2, 3
+0x7d 0x42 0x19 0xec
+
+
# CHECK: dcbtst 2, 3
0x7c 0x02 0x19 0xec
+# CHECK: dcbt 2, 3, 10
+0x7d 0x42 0x1a 0x2c
+
+# CHECK: dcbtst 2, 3, 10
+0x7d 0x42 0x19 0xec
+
# CHECK: dcbz 2, 3
0x7c 0x02 0x1f 0xec
--- /dev/null
+# RUN: llvm-mc -triple powerpc64-unknown-unknown --show-encoding %s | FileCheck -check-prefix=SERVER %s
+# RUN: llvm-mc -mcpu=a2 -triple powerpc64-unknown-unknown --show-encoding %s | FileCheck -check-prefix=EMBEDDED %s
+
+# SERVER: dcbt 2, 3, 10 # encoding: [0x7d,0x42,0x1a,0x2c]
+ dcbt 2, 3, 10
+# SERVER: dcbtst 2, 3, 10 # encoding: [0x7d,0x42,0x19,0xec]
+ dcbtst 2, 3, 10
+
+# EMBEDDED: dcbt 10, 2, 3 # encoding: [0x7d,0x42,0x1a,0x2c]
+ dcbt 10, 2, 3
+# EMBEDDED: dcbtst 10, 2, 3 # encoding: [0x7d,0x42,0x19,0xec]
+ dcbtst 10, 2, 3
+
# CHECK-LE: icbt 0, 5, 31 # encoding: [0x2c,0xf8,0x05,0x7c]
icbt 0, 5, 31
-# FIXME: dcbt 2, 3, 10
+# CHECK-BE: dcbt 2, 3, 10 # encoding: [0x7d,0x42,0x1a,0x2c]
+# CHECK-LE: dcbt 2, 3, 10 # encoding: [0x2c,0x1a,0x42,0x7d]
+ dcbt 2, 3, 10
+# CHECK-BE: dcbt 2, 3, 10 # encoding: [0x7d,0x42,0x1a,0x2c]
+# CHECK-LE: dcbt 2, 3, 10 # encoding: [0x2c,0x1a,0x42,0x7d]
+ dcbtct 2, 3, 10
+# CHECK-BE: dcbt 2, 3, 10 # encoding: [0x7d,0x42,0x1a,0x2c]
+# CHECK-LE: dcbt 2, 3, 10 # encoding: [0x2c,0x1a,0x42,0x7d]
+ dcbtds 2, 3, 10
# CHECK-BE: dcbt 2, 3 # encoding: [0x7c,0x02,0x1a,0x2c]
# CHECK-LE: dcbt 2, 3 # encoding: [0x2c,0x1a,0x02,0x7c]
dcbt 2, 3
-# FIXME: dcbtst 2, 3, 10
+# CHECK-BE: dcbt 2, 3 # encoding: [0x7c,0x02,0x1a,0x2c]
+# CHECK-LE: dcbt 2, 3 # encoding: [0x2c,0x1a,0x02,0x7c]
+ dcbt 2, 3, 0
+# CHECK-BE: dcbtt 2, 3 # encoding: [0x7e,0x02,0x1a,0x2c]
+# CHECK-LE: dcbtt 2, 3 # encoding: [0x2c,0x1a,0x02,0x7e]
+ dcbtt 2, 3
+# CHECK-BE: dcbtt 2, 3 # encoding: [0x7e,0x02,0x1a,0x2c]
+# CHECK-LE: dcbtt 2, 3 # encoding: [0x2c,0x1a,0x02,0x7e]
+ dcbt 2, 3, 16
+# CHECK-BE: dcbtst 2, 3, 10 # encoding: [0x7d,0x42,0x19,0xec]
+# CHECK-LE: dcbtst 2, 3, 10 # encoding: [0xec,0x19,0x42,0x7d]
+ dcbtst 2, 3, 10
+# CHECK-BE: dcbtst 2, 3, 10 # encoding: [0x7d,0x42,0x19,0xec]
+# CHECK-LE: dcbtst 2, 3, 10 # encoding: [0xec,0x19,0x42,0x7d]
+ dcbtstct 2, 3, 10
+# CHECK-BE: dcbtst 2, 3, 10 # encoding: [0x7d,0x42,0x19,0xec]
+# CHECK-LE: dcbtst 2, 3, 10 # encoding: [0xec,0x19,0x42,0x7d]
+ dcbtstds 2, 3, 10
# CHECK-BE: dcbtst 2, 3 # encoding: [0x7c,0x02,0x19,0xec]
# CHECK-LE: dcbtst 2, 3 # encoding: [0xec,0x19,0x02,0x7c]
dcbtst 2, 3
+# CHECK-BE: dcbtst 2, 3 # encoding: [0x7c,0x02,0x19,0xec]
+# CHECK-LE: dcbtst 2, 3 # encoding: [0xec,0x19,0x02,0x7c]
+ dcbtst 2, 3, 0
+# CHECK-BE: dcbtstt 2, 3 # encoding: [0x7e,0x02,0x19,0xec]
+# CHECK-LE: dcbtstt 2, 3 # encoding: [0xec,0x19,0x02,0x7e]
+ dcbtstt 2, 3
+# CHECK-BE: dcbtstt 2, 3 # encoding: [0x7e,0x02,0x19,0xec]
+# CHECK-LE: dcbtstt 2, 3 # encoding: [0xec,0x19,0x02,0x7e]
+ dcbtst 2, 3, 16
# CHECK-BE: dcbz 2, 3 # encoding: [0x7c,0x02,0x1f,0xec]
# CHECK-LE: dcbz 2, 3 # encoding: [0xec,0x1f,0x02,0x7c]
dcbz 2, 3