]>;
def SDT_PPCcondbr : SDTypeProfile<0, 3, [
- SDTCisVT<1, i32>, SDTCisVT<2, OtherVT>
+ SDTCisVT<0, i32>, SDTCisVT<2, OtherVT>
]>;
def SDT_PPClbrx : SDTypeProfile<1, 3, [
def PPClbrx : SDNode<"PPCISD::LBRX", SDT_PPClbrx, [SDNPHasChain]>;
def PPCstbrx : SDNode<"PPCISD::STBRX", SDT_PPCstbrx, [SDNPHasChain]>;
+// Instructions to support dynamic alloca.
+def SDTDynOp : SDTypeProfile<1, 2, []>;
+def PPCdynalloc : SDNode<"PPCISD::DYNALLOC", SDTDynOp, [SDNPHasChain]>;
+
//===----------------------------------------------------------------------===//
// PowerPC specific transformation functions and pattern fragments.
//
class RegConstraint<string C> {
string Constraints = C;
}
+class NoEncode<string E> {
+ string DisableEncoding = E;
+}
//===----------------------------------------------------------------------===//
}
def memrix : Operand<iPTR> { // memri where the imm is shifted 2 bits.
let PrintMethod = "printMemRegImmShifted";
- let MIOperandInfo = (ops i32imm, ptr_rc);
+ let MIOperandInfo = (ops i32imm:$imm, ptr_rc:$reg);
}
// PowerPC Predicate operand. 20 = (0<<5)|20 = always, CR0 is a dummy reg
def xoaddr : ComplexPattern<iPTR, 2, "SelectAddrIdxOnly",[], []>;
def ixaddr : ComplexPattern<iPTR, 2, "SelectAddrImmShift", [], []>; // "std"
+/// This is just the offset part of iaddr, used for preinc.
+def iaddroff : ComplexPattern<iPTR, 1, "SelectAddrImmOffs", [], []>;
//===----------------------------------------------------------------------===//
// PowerPC Instruction Predicate Definitions.
def UPDATE_VRSAVE : Pseudo<(ops GPRC:$rD, GPRC:$rS),
"UPDATE_VRSAVE $rD, $rS", []>;
}
+
+def DYNALLOC : Pseudo<(ops GPRC:$result, GPRC:$negsize, memri:$fpsi),
+ "${:comment} DYNALLOC $result, $negsize, $fpsi",
+ [(set GPRC:$result,
+ (PPCdynalloc GPRC:$negsize, iaddr:$fpsi))]>,
+ Imp<[R1],[R1]>;
+
def IMPLICIT_DEF_GPRC: Pseudo<(ops GPRC:$rD),"${:comment}IMPLICIT_DEF_GPRC $rD",
[(set GPRC:$rD, (undef))]>;
def IMPLICIT_DEF_F8 : Pseudo<(ops F8RC:$rD), "${:comment} IMPLICIT_DEF_F8 $rD",
let isTerminator = 1, isBarrier = 1, noResults = 1, PPC970_Unit = 7 in {
let isReturn = 1 in
- def BLR : XLForm_2_br<19, 16, 0,
- (ops pred:$p),
+ def BLR : XLForm_2_br<19, 16, 0, (ops pred:$p),
"b${p:cc}lr ${p:reg}", BrB,
[(retflag)]>;
def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr", BrB, []>;
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1,
noResults = 1, PPC970_Unit = 7 in {
- // COND_BRANCH is formed before branch selection, it is turned into Bcc below.
- def COND_BRANCH : Pseudo<(ops CRRC:$crS, u16imm:$opc, target:$dst),
- "${:comment} COND_BRANCH $crS, $opc, $dst",
- [(PPCcondbranch CRRC:$crS, imm:$opc, bb:$dst)]>;
let isBarrier = 1 in {
def B : IForm<18, 0, 0, (ops target:$dst),
"b $dst", BrB,
[(br bb:$dst)]>;
}
- def BLT : BForm<16, 0, 0, 12, 0, (ops CRRC:$crS, target:$block),
- "blt $crS, $block", BrB>;
- def BLE : BForm<16, 0, 0, 4, 1, (ops CRRC:$crS, target:$block),
- "ble $crS, $block", BrB>;
- def BEQ : BForm<16, 0, 0, 12, 2, (ops CRRC:$crS, target:$block),
- "beq $crS, $block", BrB>;
- def BGE : BForm<16, 0, 0, 4, 0, (ops CRRC:$crS, target:$block),
- "bge $crS, $block", BrB>;
- def BGT : BForm<16, 0, 0, 12, 1, (ops CRRC:$crS, target:$block),
- "bgt $crS, $block", BrB>;
- def BNE : BForm<16, 0, 0, 4, 2, (ops CRRC:$crS, target:$block),
- "bne $crS, $block", BrB>;
- def BUN : BForm<16, 0, 0, 12, 3, (ops CRRC:$crS, target:$block),
- "bun $crS, $block", BrB>;
- def BNU : BForm<16, 0, 0, 4, 3, (ops CRRC:$crS, target:$block),
- "bnu $crS, $block", BrB>;
+ // BCC represents an arbitrary conditional branch on a predicate.
+ // FIXME: should be able to write a pattern for PPCcondbranch, but can't use
+ // a two-value operand where a dag node expects two operands. :(
+ def BCC : BForm<16, 0, 0, (ops pred:$cond, target:$dst),
+ "b${cond:cc} ${cond:reg}, $dst"
+ /*[(PPCcondbranch CRRC:$crS, imm:$opc, bb:$dst)]*/>;
}
let isCall = 1, noResults = 1, PPC970_Unit = 7,
// Unindexed (r+i) Loads with Update (preinc).
def LBZU : DForm_1<35, (ops GPRC:$rD, ptr_rc:$ea_result, memri:$addr),
"lbzu $rD, $addr", LdStGeneral,
- []>, RegConstraint<"$addr.reg = $ea_result">;
+ []>, RegConstraint<"$addr.reg = $ea_result">,
+ NoEncode<"$ea_result">;
def LHAU : DForm_1<43, (ops GPRC:$rD, ptr_rc:$ea_result, memri:$addr),
"lhau $rD, $addr", LdStGeneral,
- []>, RegConstraint<"$addr.reg = $ea_result">;
+ []>, RegConstraint<"$addr.reg = $ea_result">,
+ NoEncode<"$ea_result">;
def LHZU : DForm_1<41, (ops GPRC:$rD, ptr_rc:$ea_result, memri:$addr),
"lhzu $rD, $addr", LdStGeneral,
- []>, RegConstraint<"$addr.reg = $ea_result">;
+ []>, RegConstraint<"$addr.reg = $ea_result">,
+ NoEncode<"$ea_result">;
def LWZU : DForm_1<33, (ops GPRC:$rD, ptr_rc:$ea_result, memri:$addr),
"lwzu $rD, $addr", LdStGeneral,
- []>, RegConstraint<"$addr.reg = $ea_result">;
+ []>, RegConstraint<"$addr.reg = $ea_result">,
+ NoEncode<"$ea_result">;
def LFSU : DForm_1<49, (ops F4RC:$rD, ptr_rc:$ea_result, memri:$addr),
"lfs $rD, $addr", LdStLFDU,
- []>, RegConstraint<"$addr.reg = $ea_result">;
+ []>, RegConstraint<"$addr.reg = $ea_result">,
+ NoEncode<"$ea_result">;
+
def LFDU : DForm_1<51, (ops F8RC:$rD, ptr_rc:$ea_result, memri:$addr),
"lfd $rD, $addr", LdStLFD,
- []>, RegConstraint<"$addr.reg = $ea_result">;
+ []>, RegConstraint<"$addr.reg = $ea_result">,
+ NoEncode<"$ea_result">;
}
// Indexed (r+r) Loads.
// Unindexed (r+i) Stores.
let isStore = 1, noResults = 1, PPC970_Unit = 2 in {
-def STB : DForm_3<38, (ops GPRC:$rS, memri:$src),
+def STB : DForm_1<38, (ops GPRC:$rS, memri:$src),
"stb $rS, $src", LdStGeneral,
[(truncstorei8 GPRC:$rS, iaddr:$src)]>;
-def STH : DForm_3<44, (ops GPRC:$rS, memri:$src),
+def STH : DForm_1<44, (ops GPRC:$rS, memri:$src),
"sth $rS, $src", LdStGeneral,
[(truncstorei16 GPRC:$rS, iaddr:$src)]>;
-def STW : DForm_3<36, (ops GPRC:$rS, memri:$src),
+def STW : DForm_1<36, (ops GPRC:$rS, memri:$src),
"stw $rS, $src", LdStGeneral,
[(store GPRC:$rS, iaddr:$src)]>;
def STFS : DForm_1<52, (ops F4RC:$rS, memri:$dst),
// Unindexed (r+i) Stores with Update (preinc).
let isStore = 1, PPC970_Unit = 2 in {
-def STBU : DForm_3<39, (ops ptr_rc:$ea_res, GPRC:$rS, memri:$addr),
- "stbu $rS, $addr", LdStGeneral,
- [/*(set ptr_rc:$ea_res,
- (pre_truncsti8 GPRC:$rS, iaddr:$addr))*/]>,
- RegConstraint<"$addr.reg = $ea_res">;
-def STHU : DForm_3<37, (ops ptr_rc:$ea_res, GPRC:$rS, memri:$addr),
- "sthu $rS, $addr", LdStGeneral,
- [/*(set ptr_rc:$ea_res,
- (pre_truncsti16 GPRC:$rS, iaddr:$addr))*/]>,
- RegConstraint<"$addr.reg = $ea_res">;
-def STWU : DForm_3<37, (ops ptr_rc:$ea_res, GPRC:$rS, memri:$addr),
- "stwu $rS, $addr", LdStGeneral,
- [/*(set ptr_rc:$ea_res, (pre_store GPRC:$rS, iaddr:$addr))*/]>,
- RegConstraint<"$addr.reg = $ea_res">;
-def STFSU : DForm_3<37, (ops ptr_rc:$ea_res, F4RC:$rS, memri:$addr),
- "stfsu $rS, $addr", LdStGeneral,
- [/*(set ptr_rc:$ea_res, (pre_store F4RC:$rS, iaddr:$addr))*/]>,
- RegConstraint<"$addr.reg = $ea_res">;
-def STFDU : DForm_3<37, (ops ptr_rc:$ea_res, F8RC:$rS, memri:$addr),
- "stfdu $rS, $addr", LdStGeneral,
- [/*(set ptr_rc:$ea_res, (pre_store F8RC:$rS, iaddr:$addr))*/]>,
- RegConstraint<"$addr.reg = $ea_res">;
+def STBU : DForm_1<39, (ops ptr_rc:$ea_res, GPRC:$rS,
+ symbolLo:$ptroff, ptr_rc:$ptrreg),
+ "stbu $rS, $ptroff($ptrreg)", LdStGeneral,
+ [(set ptr_rc:$ea_res,
+ (pre_truncsti8 GPRC:$rS, ptr_rc:$ptrreg,
+ iaddroff:$ptroff))]>,
+ RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
+def STHU : DForm_1<45, (ops ptr_rc:$ea_res, GPRC:$rS,
+ symbolLo:$ptroff, ptr_rc:$ptrreg),
+ "sthu $rS, $ptroff($ptrreg)", LdStGeneral,
+ [(set ptr_rc:$ea_res,
+ (pre_truncsti16 GPRC:$rS, ptr_rc:$ptrreg,
+ iaddroff:$ptroff))]>,
+ RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
+def STWU : DForm_1<37, (ops ptr_rc:$ea_res, GPRC:$rS,
+ symbolLo:$ptroff, ptr_rc:$ptrreg),
+ "stwu $rS, $ptroff($ptrreg)", LdStGeneral,
+ [(set ptr_rc:$ea_res, (pre_store GPRC:$rS, ptr_rc:$ptrreg,
+ iaddroff:$ptroff))]>,
+ RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
+def STFSU : DForm_1<37, (ops ptr_rc:$ea_res, F4RC:$rS,
+ symbolLo:$ptroff, ptr_rc:$ptrreg),
+ "stfsu $rS, $ptroff($ptrreg)", LdStGeneral,
+ [(set ptr_rc:$ea_res, (pre_store F4RC:$rS, ptr_rc:$ptrreg,
+ iaddroff:$ptroff))]>,
+ RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
+def STFDU : DForm_1<37, (ops ptr_rc:$ea_res, F8RC:$rS,
+ symbolLo:$ptroff, ptr_rc:$ptrreg),
+ "stfdu $rS, $ptroff($ptrreg)", LdStGeneral,
+ [(set ptr_rc:$ea_res, (pre_store F8RC:$rS, ptr_rc:$ptrreg,
+ iaddroff:$ptroff))]>,
+ RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
}
let PPC970_Unit = 1 in { // FXU Operations.
// M-Form instructions. rotate and mask instructions.
//
-let isTwoAddress = 1, isCommutable = 1 in {
+let isCommutable = 1 in {
// RLWIMI can be commuted if the rotate amount is zero.
def RLWIMI : MForm_2<20,
(ops GPRC:$rA, GPRC:$rSi, GPRC:$rS, u5imm:$SH, u5imm:$MB,
u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME", IntRotate,
- []>, PPC970_DGroup_Cracked;
+ []>, PPC970_DGroup_Cracked, RegConstraint<"$rSi = $rA">,
+ NoEncode<"$rSi">;
}
def RLWINM : MForm_2<21,
(ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
[(dwarf_loc (i32 imm:$line), (i32 imm:$col),
(i32 imm:$file))]>;
-def DWARF_LABEL : Pseudo<(ops i32imm:$id),
- "\n${:private}debug_loc$id:",
- [(dwarf_label (i32 imm:$id))]>;
-
//===----------------------------------------------------------------------===//
// PowerPC Instruction Patterns
//