Index: lib/Target/PowerPC/PPCInstr64Bit.td =================================================================== --- lib/Target/PowerPC/PPCInstr64Bit.td +++ lib/Target/PowerPC/PPCInstr64Bit.td @@ -244,8 +244,8 @@ // Instructions to support atomic operations let mayLoad = 1, hasSideEffects = 0 in { -def LDARX : XForm_1<31, 84, (outs g8rc:$rD), (ins memrr:$ptr), - "ldarx $rD, $ptr", IIC_LdStLDARX, []>; +def LDARX : XForm_1_memOp<31, 84, (outs g8rc:$rD), (ins memrr:$ptr), + "ldarx $rD, $ptr", IIC_LdStLDARX, []>; // Instruction to support lock versions of atomics // (EH=1 - see Power ISA 2.07 Book II 4.4.2) @@ -259,8 +259,8 @@ } let Defs = [CR0], mayStore = 1, mayLoad = 0, hasSideEffects = 0 in -def STDCX : XForm_1<31, 214, (outs), (ins g8rc:$rS, memrr:$dst), - "stdcx. $rS, $dst", IIC_LdStSTDCX, []>, isDOT; +def STDCX : XForm_1_memOp<31, 214, (outs), (ins g8rc:$rS, memrr:$dst), + "stdcx. $rS, $dst", IIC_LdStSTDCX, []>, isDOT; let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in def STDAT : X_RD5_RS5_IM5<31, 742, (outs), (ins g8rc:$rS, g8rc:$rA, u5imm:$FC), @@ -837,11 +837,11 @@ (aligned4sextloadi32 ixaddr:$src))]>, isPPC64, PPC970_DGroup_Cracked; let Interpretation64Bit = 1, isCodeGenOnly = 1 in -def LHAX8: XForm_1<31, 343, (outs g8rc:$rD), (ins memrr:$src), +def LHAX8: XForm_1_memOp<31, 343, (outs g8rc:$rD), (ins memrr:$src), "lhax $rD, $src", IIC_LdStLHA, [(set i64:$rD, (sextloadi16 xaddr:$src))]>, PPC970_DGroup_Cracked; -def LWAX : XForm_1<31, 341, (outs g8rc:$rD), (ins memrr:$src), +def LWAX : XForm_1_memOp<31, 341, (outs g8rc:$rD), (ins memrr:$src), "lwax $rD, $src", IIC_LdStLHA, [(set i64:$rD, (sextloadi32 xaddr:$src))]>, isPPC64, PPC970_DGroup_Cracked; @@ -850,7 +850,7 @@ def LWA_32 : DSForm_1<58, 2, (outs gprc:$rD), (ins memrix:$src), "lwa $rD, $src", IIC_LdStLWA, []>, isPPC64, PPC970_DGroup_Cracked; -def LWAX_32 : XForm_1<31, 341, (outs gprc:$rD), (ins memrr:$src), +def LWAX_32 : XForm_1_memOp<31, 341, (outs gprc:$rD), (ins memrr:$src), "lwax $rD, $src", IIC_LdStLHA, []>, isPPC64, PPC970_DGroup_Cracked; } // end fast-isel isCodeGenOnly @@ -866,12 +866,12 @@ // NO LWAU! let Interpretation64Bit = 1, isCodeGenOnly = 1 in -def LHAUX8 : XForm_1<31, 375, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), +def LHAUX8 : XForm_1_memOp<31, 375, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), (ins memrr:$addr), "lhaux $rD, $addr", IIC_LdStLHAUX, []>, RegConstraint<"$addr.ptrreg = $ea_result">, NoEncode<"$ea_result">; -def LWAUX : XForm_1<31, 373, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), +def LWAUX : XForm_1_memOp<31, 373, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), (ins memrr:$addr), "lwaux $rD, $addr", IIC_LdStLHAUX, []>, RegConstraint<"$addr.ptrreg = $ea_result">, @@ -892,43 +892,46 @@ "lwz $rD, $src", IIC_LdStLoad, [(set i64:$rD, (zextloadi32 iaddr:$src))]>, isPPC64; -def LBZX8 : XForm_1<31, 87, (outs g8rc:$rD), (ins memrr:$src), +def LBZX8 : XForm_1_memOp<31, 87, (outs g8rc:$rD), (ins memrr:$src), "lbzx $rD, $src", IIC_LdStLoad, [(set i64:$rD, (zextloadi8 xaddr:$src))]>; -def LHZX8 : XForm_1<31, 279, (outs g8rc:$rD), (ins memrr:$src), +def LHZX8 : XForm_1_memOp<31, 279, (outs g8rc:$rD), (ins memrr:$src), "lhzx $rD, $src", IIC_LdStLoad, [(set i64:$rD, (zextloadi16 xaddr:$src))]>; -def LWZX8 : XForm_1<31, 23, (outs g8rc:$rD), (ins memrr:$src), +def LWZX8 : XForm_1_memOp<31, 23, (outs g8rc:$rD), (ins memrr:$src), "lwzx $rD, $src", IIC_LdStLoad, [(set i64:$rD, (zextloadi32 xaddr:$src))]>; // Update forms. let mayLoad = 1, hasSideEffects = 0 in { -def LBZU8 : DForm_1<35, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), (ins memri:$addr), +def LBZU8 : DForm_1<35, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), + (ins memri:$addr), "lbzu $rD, $addr", IIC_LdStLoadUpd, []>, RegConstraint<"$addr.reg = $ea_result">, NoEncode<"$ea_result">; -def LHZU8 : DForm_1<41, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), (ins memri:$addr), +def LHZU8 : DForm_1<41, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), + (ins memri:$addr), "lhzu $rD, $addr", IIC_LdStLoadUpd, []>, RegConstraint<"$addr.reg = $ea_result">, NoEncode<"$ea_result">; -def LWZU8 : DForm_1<33, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), (ins memri:$addr), +def LWZU8 : DForm_1<33, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), + (ins memri:$addr), "lwzu $rD, $addr", IIC_LdStLoadUpd, []>, RegConstraint<"$addr.reg = $ea_result">, NoEncode<"$ea_result">; -def LBZUX8 : XForm_1<31, 119, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), +def LBZUX8 : XForm_1_memOp<31, 119, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), (ins memrr:$addr), "lbzux $rD, $addr", IIC_LdStLoadUpdX, []>, RegConstraint<"$addr.ptrreg = $ea_result">, NoEncode<"$ea_result">; -def LHZUX8 : XForm_1<31, 311, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), +def LHZUX8 : XForm_1_memOp<31, 311, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), (ins memrr:$addr), "lhzux $rD, $addr", IIC_LdStLoadUpdX, []>, RegConstraint<"$addr.ptrreg = $ea_result">, NoEncode<"$ea_result">; -def LWZUX8 : XForm_1<31, 55, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), +def LWZUX8 : XForm_1_memOp<31, 55, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), (ins memrr:$addr), "lwzux $rD, $addr", IIC_LdStLoadUpdX, []>, RegConstraint<"$addr.ptrreg = $ea_result">, @@ -963,35 +966,36 @@ [(set i64:$rD, (PPCtoc_entry tblockaddress:$disp, i64:$reg))]>, isPPC64; -def LDX : XForm_1<31, 21, (outs g8rc:$rD), (ins memrr:$src), +def LDX : XForm_1_memOp<31, 21, (outs g8rc:$rD), (ins memrr:$src), "ldx $rD, $src", IIC_LdStLD, [(set i64:$rD, (load xaddr:$src))]>, isPPC64; -def LDBRX : XForm_1<31, 532, (outs g8rc:$rD), (ins memrr:$src), +def LDBRX : XForm_1_memOp<31, 532, (outs g8rc:$rD), (ins memrr:$src), "ldbrx $rD, $src", IIC_LdStLoad, [(set i64:$rD, (PPClbrx xoaddr:$src, i64))]>, isPPC64; let mayLoad = 1, hasSideEffects = 0, isCodeGenOnly = 1 in { -def LHBRX8 : XForm_1<31, 790, (outs g8rc:$rD), (ins memrr:$src), +def LHBRX8 : XForm_1_memOp<31, 790, (outs g8rc:$rD), (ins memrr:$src), "lhbrx $rD, $src", IIC_LdStLoad, []>; -def LWBRX8 : XForm_1<31, 534, (outs g8rc:$rD), (ins memrr:$src), +def LWBRX8 : XForm_1_memOp<31, 534, (outs g8rc:$rD), (ins memrr:$src), "lwbrx $rD, $src", IIC_LdStLoad, []>; } let mayLoad = 1, hasSideEffects = 0 in { -def LDU : DSForm_1<58, 1, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), (ins memrix:$addr), +def LDU : DSForm_1<58, 1, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), + (ins memrix:$addr), "ldu $rD, $addr", IIC_LdStLDU, []>, RegConstraint<"$addr.reg = $ea_result">, isPPC64, NoEncode<"$ea_result">; -def LDUX : XForm_1<31, 53, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), - (ins memrr:$addr), - "ldux $rD, $addr", IIC_LdStLDUX, - []>, RegConstraint<"$addr.ptrreg = $ea_result">, - NoEncode<"$ea_result">, isPPC64; +def LDUX : XForm_1_memOp<31, 53, (outs g8rc:$rD, ptr_rc_nor0:$ea_result), + (ins memrr:$addr), + "ldux $rD, $addr", IIC_LdStLDUX, + []>, RegConstraint<"$addr.ptrreg = $ea_result">, + NoEncode<"$ea_result">, isPPC64; def LDMX : XForm_1<31, 309, (outs g8rc:$rD), (ins memrr:$src), "ldmx $rD, $src", IIC_LdStLD, []>, isPPC64, - Requires<[IsISA3_0]>; + Requires<[IsISA3_0]>; } } @@ -1116,15 +1120,15 @@ def STW8 : DForm_1<36, (outs), (ins g8rc:$rS, memri:$src), "stw $rS, $src", IIC_LdStStore, [(truncstorei32 i64:$rS, iaddr:$src)]>; -def STBX8 : XForm_8<31, 215, (outs), (ins g8rc:$rS, memrr:$dst), +def STBX8 : XForm_8_memOp<31, 215, (outs), (ins g8rc:$rS, memrr:$dst), "stbx $rS, $dst", IIC_LdStStore, [(truncstorei8 i64:$rS, xaddr:$dst)]>, PPC970_DGroup_Cracked; -def STHX8 : XForm_8<31, 407, (outs), (ins g8rc:$rS, memrr:$dst), +def STHX8 : XForm_8_memOp<31, 407, (outs), (ins g8rc:$rS, memrr:$dst), "sthx $rS, $dst", IIC_LdStStore, [(truncstorei16 i64:$rS, xaddr:$dst)]>, PPC970_DGroup_Cracked; -def STWX8 : XForm_8<31, 151, (outs), (ins g8rc:$rS, memrr:$dst), +def STWX8 : XForm_8_memOp<31, 151, (outs), (ins g8rc:$rS, memrr:$dst), "stwx $rS, $dst", IIC_LdStStore, [(truncstorei32 i64:$rS, xaddr:$dst)]>, PPC970_DGroup_Cracked; @@ -1134,11 +1138,11 @@ def STD : DSForm_1<62, 0, (outs), (ins g8rc:$rS, memrix:$dst), "std $rS, $dst", IIC_LdStSTD, [(aligned4store i64:$rS, ixaddr:$dst)]>, isPPC64; -def STDX : XForm_8<31, 149, (outs), (ins g8rc:$rS, memrr:$dst), +def STDX : XForm_8_memOp<31, 149, (outs), (ins g8rc:$rS, memrr:$dst), "stdx $rS, $dst", IIC_LdStSTD, [(store i64:$rS, xaddr:$dst)]>, isPPC64, PPC970_DGroup_Cracked; -def STDBRX: XForm_8<31, 660, (outs), (ins g8rc:$rS, memrr:$dst), +def STDBRX: XForm_8_memOp<31, 660, (outs), (ins g8rc:$rS, memrr:$dst), "stdbrx $rS, $dst", IIC_LdStStore, [(PPCstbrx i64:$rS, xoaddr:$dst, i64)]>, isPPC64, PPC970_DGroup_Cracked; @@ -1157,29 +1161,38 @@ "stwu $rS, $dst", IIC_LdStStoreUpd, []>, RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">; -def STBUX8: XForm_8<31, 247, (outs ptr_rc_nor0:$ea_res), (ins g8rc:$rS, memrr:$dst), - "stbux $rS, $dst", IIC_LdStStoreUpd, []>, - RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, - PPC970_DGroup_Cracked; -def STHUX8: XForm_8<31, 439, (outs ptr_rc_nor0:$ea_res), (ins g8rc:$rS, memrr:$dst), - "sthux $rS, $dst", IIC_LdStStoreUpd, []>, - RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, - PPC970_DGroup_Cracked; -def STWUX8: XForm_8<31, 183, (outs ptr_rc_nor0:$ea_res), (ins g8rc:$rS, memrr:$dst), - "stwux $rS, $dst", IIC_LdStStoreUpd, []>, - RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, - PPC970_DGroup_Cracked; +def STBUX8: XForm_8_memOp<31, 247, (outs ptr_rc_nor0:$ea_res), + (ins g8rc:$rS, memrr:$dst), + "stbux $rS, $dst", IIC_LdStStoreUpd, []>, + RegConstraint<"$dst.ptrreg = $ea_res">, + NoEncode<"$ea_res">, + PPC970_DGroup_Cracked; +def STHUX8: XForm_8_memOp<31, 439, (outs ptr_rc_nor0:$ea_res), + (ins g8rc:$rS, memrr:$dst), + "sthux $rS, $dst", IIC_LdStStoreUpd, []>, + RegConstraint<"$dst.ptrreg = $ea_res">, + NoEncode<"$ea_res">, + PPC970_DGroup_Cracked; +def STWUX8: XForm_8_memOp<31, 183, (outs ptr_rc_nor0:$ea_res), + (ins g8rc:$rS, memrr:$dst), + "stwux $rS, $dst", IIC_LdStStoreUpd, []>, + RegConstraint<"$dst.ptrreg = $ea_res">, + NoEncode<"$ea_res">, + PPC970_DGroup_Cracked; } // Interpretation64Bit -def STDU : DSForm_1<62, 1, (outs ptr_rc_nor0:$ea_res), (ins g8rc:$rS, memrix:$dst), +def STDU : DSForm_1<62, 1, (outs ptr_rc_nor0:$ea_res), + (ins g8rc:$rS, memrix:$dst), "stdu $rS, $dst", IIC_LdStSTDU, []>, RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">, isPPC64; -def STDUX : XForm_8<31, 181, (outs ptr_rc_nor0:$ea_res), (ins g8rc:$rS, memrr:$dst), - "stdux $rS, $dst", IIC_LdStSTDUX, []>, - RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, - PPC970_DGroup_Cracked, isPPC64; +def STDUX : XForm_8_memOp<31, 181, (outs ptr_rc_nor0:$ea_res), + (ins g8rc:$rS, memrr:$dst), + "stdux $rS, $dst", IIC_LdStSTDUX, []>, + RegConstraint<"$dst.ptrreg = $ea_res">, + NoEncode<"$ea_res">, + PPC970_DGroup_Cracked, isPPC64; } // Patterns to match the pre-inc stores. We can't put the patterns on Index: lib/Target/PowerPC/PPCInstrAltivec.td =================================================================== --- lib/Target/PowerPC/PPCInstrAltivec.td +++ lib/Target/PowerPC/PPCInstrAltivec.td @@ -408,46 +408,46 @@ [(int_ppc_altivec_mtvscr v4i32:$vB)]>; let PPC970_Unit = 2, mayLoad = 1, mayStore = 0 in { // Loads. -def LVEBX: XForm_1<31, 7, (outs vrrc:$vD), (ins memrr:$src), +def LVEBX: XForm_1_memOp<31, 7, (outs vrrc:$vD), (ins memrr:$src), "lvebx $vD, $src", IIC_LdStLoad, [(set v16i8:$vD, (int_ppc_altivec_lvebx xoaddr:$src))]>; -def LVEHX: XForm_1<31, 39, (outs vrrc:$vD), (ins memrr:$src), +def LVEHX: XForm_1_memOp<31, 39, (outs vrrc:$vD), (ins memrr:$src), "lvehx $vD, $src", IIC_LdStLoad, [(set v8i16:$vD, (int_ppc_altivec_lvehx xoaddr:$src))]>; -def LVEWX: XForm_1<31, 71, (outs vrrc:$vD), (ins memrr:$src), +def LVEWX: XForm_1_memOp<31, 71, (outs vrrc:$vD), (ins memrr:$src), "lvewx $vD, $src", IIC_LdStLoad, [(set v4i32:$vD, (int_ppc_altivec_lvewx xoaddr:$src))]>; -def LVX : XForm_1<31, 103, (outs vrrc:$vD), (ins memrr:$src), +def LVX : XForm_1_memOp<31, 103, (outs vrrc:$vD), (ins memrr:$src), "lvx $vD, $src", IIC_LdStLoad, [(set v4i32:$vD, (int_ppc_altivec_lvx xoaddr:$src))]>; -def LVXL : XForm_1<31, 359, (outs vrrc:$vD), (ins memrr:$src), +def LVXL : XForm_1_memOp<31, 359, (outs vrrc:$vD), (ins memrr:$src), "lvxl $vD, $src", IIC_LdStLoad, [(set v4i32:$vD, (int_ppc_altivec_lvxl xoaddr:$src))]>; } -def LVSL : XForm_1<31, 6, (outs vrrc:$vD), (ins memrr:$src), +def LVSL : XForm_1_memOp<31, 6, (outs vrrc:$vD), (ins memrr:$src), "lvsl $vD, $src", IIC_LdStLoad, [(set v16i8:$vD, (int_ppc_altivec_lvsl xoaddr:$src))]>, PPC970_Unit_LSU; -def LVSR : XForm_1<31, 38, (outs vrrc:$vD), (ins memrr:$src), +def LVSR : XForm_1_memOp<31, 38, (outs vrrc:$vD), (ins memrr:$src), "lvsr $vD, $src", IIC_LdStLoad, [(set v16i8:$vD, (int_ppc_altivec_lvsr xoaddr:$src))]>, PPC970_Unit_LSU; let PPC970_Unit = 2, mayStore = 1, mayLoad = 0 in { // Stores. -def STVEBX: XForm_8<31, 135, (outs), (ins vrrc:$rS, memrr:$dst), +def STVEBX: XForm_8_memOp<31, 135, (outs), (ins vrrc:$rS, memrr:$dst), "stvebx $rS, $dst", IIC_LdStStore, [(int_ppc_altivec_stvebx v16i8:$rS, xoaddr:$dst)]>; -def STVEHX: XForm_8<31, 167, (outs), (ins vrrc:$rS, memrr:$dst), +def STVEHX: XForm_8_memOp<31, 167, (outs), (ins vrrc:$rS, memrr:$dst), "stvehx $rS, $dst", IIC_LdStStore, [(int_ppc_altivec_stvehx v8i16:$rS, xoaddr:$dst)]>; -def STVEWX: XForm_8<31, 199, (outs), (ins vrrc:$rS, memrr:$dst), +def STVEWX: XForm_8_memOp<31, 199, (outs), (ins vrrc:$rS, memrr:$dst), "stvewx $rS, $dst", IIC_LdStStore, [(int_ppc_altivec_stvewx v4i32:$rS, xoaddr:$dst)]>; -def STVX : XForm_8<31, 231, (outs), (ins vrrc:$rS, memrr:$dst), +def STVX : XForm_8_memOp<31, 231, (outs), (ins vrrc:$rS, memrr:$dst), "stvx $rS, $dst", IIC_LdStStore, [(int_ppc_altivec_stvx v4i32:$rS, xoaddr:$dst)]>; -def STVXL : XForm_8<31, 487, (outs), (ins vrrc:$rS, memrr:$dst), +def STVXL : XForm_8_memOp<31, 487, (outs), (ins vrrc:$rS, memrr:$dst), "stvxl $rS, $dst", IIC_LdStStore, [(int_ppc_altivec_stvxl v4i32:$rS, xoaddr:$dst)]>; } Index: lib/Target/PowerPC/PPCInstrFormats.td =================================================================== --- lib/Target/PowerPC/PPCInstrFormats.td +++ lib/Target/PowerPC/PPCInstrFormats.td @@ -46,6 +46,10 @@ bits<1> UseVSXReg = 0; let TSFlags{6} = UseVSXReg; + // Indicate that this instruction is of type X-Form Load or Store + bits<1> XFormMemOp = 0; + let TSFlags{7} = XFormMemOp; + // Fields used for relation models. string BaseName = ""; @@ -71,6 +75,7 @@ class PPC970_Unit_BRU { bits<3> PPC970_Unit = 7; } class UseVSXReg { bits<1> UseVSXReg = 1; } +class XFormMemOp { bits<1> XFormMemOp = 1; } // Two joined instructions; used to emit two adjacent instructions as one. // The itinerary from the first instruction is used for scheduling and @@ -109,6 +114,11 @@ bit Interpretation64Bit = 0; } +// Base class for all X-Form memory instructions +class IXFormMemOp opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin> + :I, XFormMemOp; + // 1.7.1 I-Form class IForm opcode, bit aa, bit lk, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list pattern> @@ -437,6 +447,11 @@ let Inst{31} = RC; } +class XForm_base_r3xo_memOp opcode, bits<10> xo, dag OOL, dag IOL, + string asmstr, InstrItinClass itin, + list pattern> + : XForm_base_r3xo, XFormMemOp; + class XForm_tlb xo, dag OOL, dag IOL, string asmstr, InstrItinClass itin> : XForm_base_r3xo<31, xo, OOL, IOL, asmstr, itin, []> { let RST = 0; @@ -469,9 +484,13 @@ class XForm_1 opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, - InstrItinClass itin, list pattern> + InstrItinClass itin, list pattern> : XForm_base_r3xo; +class XForm_1_memOp opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : XForm_base_r3xo_memOp; + class XForm_1a opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list pattern> : XForm_base_r3xo { @@ -511,6 +530,10 @@ InstrItinClass itin, list pattern> : XForm_base_r3xo; +class XForm_8_memOp opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : XForm_base_r3xo_memOp; + class XForm_10 opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list pattern> : XForm_base_r3xo_swapped { @@ -692,24 +715,34 @@ } class XForm_24_eieio opcode, bits<10> xo, dag OOL, dag IOL, - string asmstr, InstrItinClass itin, list pattern> + string asmstr, InstrItinClass itin, list pattern> : XForm_24_sync { let L = 0; } class XForm_25 opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, - InstrItinClass itin, list pattern> + InstrItinClass itin, list pattern> : XForm_base_r3xo { } +class XForm_25_memOp opcode, bits<10> xo, dag OOL, dag IOL, + string asmstr, InstrItinClass itin, list pattern> + : XForm_base_r3xo_memOp { +} + class XForm_26 opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list pattern> : XForm_base_r3xo { let A = 0; } +class XForm_28_memOp opcode, bits<10> xo, dag OOL, dag IOL, + string asmstr, InstrItinClass itin, list pattern> + : XForm_base_r3xo_memOp { +} + class XForm_28 opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, - InstrItinClass itin, list pattern> + InstrItinClass itin, list pattern> : XForm_base_r3xo { } @@ -980,7 +1013,7 @@ // to specify an SDAG pattern for matching. class X_RD5_RS5_IM5 opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, InstrItinClass itin> - : XForm_base_r3xo { + : XForm_base_r3xo_memOp { } class X_BF3 opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, @@ -1018,6 +1051,10 @@ let Inst{31} = XT{5}; } +class XX1Form_memOp opcode, bits<10> xo, dag OOL, dag IOL, + string asmstr, InstrItinClass itin, list pattern> + : XX1Form, XFormMemOp; + class XX1_RS6_RD5_XO opcode, bits<10> xo, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list pattern> : XX1Form { @@ -2103,3 +2140,7 @@ let Inst{31-0} = 0; let hasNoSchedulingInfo = 1; } + +class PseudoXFormMemOp pattern> + : Pseudo, XFormMemOp; + Index: lib/Target/PowerPC/PPCInstrInfo.h =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.h +++ lib/Target/PowerPC/PPCInstrInfo.h @@ -68,7 +68,9 @@ /// The VSX instruction that uses VSX register (vs0-vs63), instead of VMX /// register (v0-v31). - UseVSXReg = 0x1 << NewDef_Shift + UseVSXReg = 0x1 << NewDef_Shift, + /// This instruction is X-Form + XFormMemOp = 0x1 << (NewDef_Shift+1) }; } // end namespace PPCII @@ -114,20 +116,19 @@ PPCSubtarget &Subtarget; const PPCRegisterInfo RI; - bool StoreRegToStackSlot(MachineFunction &MF, - unsigned SrcReg, bool isKill, int FrameIdx, - const TargetRegisterClass *RC, - SmallVectorImpl &NewMIs, - bool &NonRI, bool &SpillsVRS) const; - bool LoadRegFromStackSlot(MachineFunction &MF, const DebugLoc &DL, + void StoreRegToStackSlot(MachineFunction &MF, unsigned SrcReg, bool isKill, + int FrameIdx, const TargetRegisterClass *RC, + SmallVectorImpl &NewMIs) const; + void LoadRegFromStackSlot(MachineFunction &MF, const DebugLoc &DL, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, - SmallVectorImpl &NewMIs, - bool &NonRI, bool &SpillsVRS) const; + SmallVectorImpl &NewMIs) const; bool transformToImmForm(MachineInstr &MI, const ImmInstrInfo &III, unsigned ConstantOpNo, int64_t Imm) const; MachineInstr *getConstantDefMI(MachineInstr &MI, unsigned &ConstOp, bool &SeenIntermediateUse) const; + const unsigned *getStoreOpcodesForSpillArray() const; + const unsigned *getLoadOpcodesForSpillArray() const; virtual void anchor(); protected: @@ -251,6 +252,12 @@ const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override; + unsigned getStoreOpcodeForSpill(unsigned Reg, + const TargetRegisterClass *RC = nullptr) const; + + unsigned getLoadOpcodeForSpill(unsigned Reg, + const TargetRegisterClass *RC = nullptr) const; + bool reverseBranchCondition(SmallVectorImpl &Cond) const override; Index: lib/Target/PowerPC/PPCInstrInfo.cpp =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.cpp +++ lib/Target/PowerPC/PPCInstrInfo.cpp @@ -71,6 +71,26 @@ UseOldLatencyCalc("ppc-old-latency-calc", cl::Hidden, cl::desc("Use the old (incorrect) instruction latency calculation")); +// Index into the OpcodesForSpill array +enum SpillOpcodeKey { + SOK_Int4Spill, + SOK_Int8Spill, + SOK_Float8Spill, + SOK_Float4Spill, + SOK_CRSpill, + SOK_CRBitSpill, + SOK_VRVectorSpill, + SOK_VSXVectorSpill, + SOK_VectorFloat8Spill, + SOK_VectorFloat4Spill, + SOK_VRSaveSpill, + SOK_QuadFloat8Spill, + SOK_QuadFloat4Spill, + SOK_QuadBitSpill, + SOK_SpillToVSR, + SOK_LastOpcodeSpill // This must be last on the enum +}; + // Pin the vtable to this file. void PPCInstrInfo::anchor() {} @@ -275,23 +295,11 @@ unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const { - // Note: This list must be kept consistent with LoadRegFromStackSlot. - switch (MI.getOpcode()) { - default: break; - case PPC::LD: - case PPC::LWZ: - case PPC::LFS: - case PPC::LFD: - case PPC::RESTORE_CR: - case PPC::RESTORE_CRBIT: - case PPC::LVX: - case PPC::LXVD2X: - case PPC::LXV: - case PPC::QVLFDX: - case PPC::QVLFSXs: - case PPC::QVLFDXb: - case PPC::RESTORE_VRSAVE: - case PPC::SPILLTOVSR_LD: + unsigned Opcode = MI.getOpcode(); + const unsigned *OpcodesForSpill = getLoadOpcodesForSpillArray(); + const unsigned *End = OpcodesForSpill + SOK_LastOpcodeSpill; + + if (End != std::find(OpcodesForSpill, End, Opcode)) { // Check for the operands added by addFrameReference (the immediate is the // offset which defaults to 0). if (MI.getOperand(1).isImm() && !MI.getOperand(1).getImm() && @@ -299,7 +307,6 @@ FrameIndex = MI.getOperand(2).getIndex(); return MI.getOperand(0).getReg(); } - break; } return 0; } @@ -329,31 +336,16 @@ unsigned PPCInstrInfo::isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const { - // Note: This list must be kept consistent with StoreRegToStackSlot. - switch (MI.getOpcode()) { - default: break; - case PPC::STD: - case PPC::STW: - case PPC::STFS: - case PPC::STFD: - case PPC::SPILL_CR: - case PPC::SPILL_CRBIT: - case PPC::STVX: - case PPC::STXVD2X: - case PPC::STXV: - case PPC::QVSTFDX: - case PPC::QVSTFSXs: - case PPC::QVSTFDXb: - case PPC::SPILL_VRSAVE: - case PPC::SPILLTOVSR_ST: - // Check for the operands added by addFrameReference (the immediate is the - // offset which defaults to 0). + unsigned Opcode = MI.getOpcode(); + const unsigned *OpcodesForSpill = getStoreOpcodesForSpillArray(); + const unsigned *End = OpcodesForSpill + SOK_LastOpcodeSpill; + + if (End != std::find(OpcodesForSpill, End, Opcode)) { if (MI.getOperand(1).isImm() && !MI.getOperand(1).getImm() && MI.getOperand(2).isFI()) { FrameIndex = MI.getOperand(2).getIndex(); return MI.getOperand(0).getReg(); } - break; } return 0; } @@ -1000,129 +992,204 @@ BuildMI(MBB, I, DL, MCID, DestReg).addReg(SrcReg, getKillRegState(KillSrc)); } -// This function returns true if a CR spill is necessary and false otherwise. -bool -PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, - unsigned SrcReg, bool isKill, - int FrameIdx, - const TargetRegisterClass *RC, - SmallVectorImpl &NewMIs, - bool &NonRI, bool &SpillsVRS) const{ - // Note: If additional store instructions are added here, - // update isStoreToStackSlot. - - DebugLoc DL; - if (PPC::GPRCRegClass.hasSubClassEq(RC) || - PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - } else if (PPC::G8RCRegClass.hasSubClassEq(RC) || - PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STD)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STFD)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STFS)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::SPILL_CR)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - return true; - } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::SPILL_CRBIT)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - return true; - } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STVX)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - NonRI = true; - } else if (PPC::VSRCRegClass.hasSubClassEq(RC)) { - unsigned Op = Subtarget.hasP9Vector() ? PPC::STXV : PPC::STXVD2X; - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(Op)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - NonRI = true; - } else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) { - unsigned Opc = Subtarget.hasP9Vector() ? PPC::DFSTOREf64 : PPC::STXSDX; - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(Opc)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - NonRI = true; - } else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) { - unsigned Opc = Subtarget.hasP9Vector() ? PPC::DFSTOREf32 : PPC::STXSSPX; - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(Opc)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - NonRI = true; - } else if (PPC::VRSAVERCRegClass.hasSubClassEq(RC)) { - assert(Subtarget.isDarwin() && - "VRSAVE only needs spill/restore on Darwin"); - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::SPILL_VRSAVE)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - SpillsVRS = true; - } else if (PPC::QFRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::QVSTFDX)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - NonRI = true; - } else if (PPC::QSRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::QVSTFSXs)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - NonRI = true; - } else if (PPC::QBRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::QVSTFDXb)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); - NonRI = true; - } else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::SPILLTOVSR_ST)) - .addReg(SrcReg, - getKillRegState(isKill)), - FrameIdx)); +unsigned PPCInstrInfo::getStoreOpcodeForSpill(unsigned Reg, + const TargetRegisterClass *RC) + const { + const unsigned *OpcodesForSpill = getStoreOpcodesForSpillArray(); + int OpcodeIndex = 0; + + if (RC != nullptr) { + if (PPC::GPRCRegClass.hasSubClassEq(RC) || + PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_Int4Spill; + } else if (PPC::G8RCRegClass.hasSubClassEq(RC) || + PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_Int8Spill; + } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_Float8Spill; + } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_Float4Spill; + } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_CRSpill; + } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_CRBitSpill; + } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_VRVectorSpill; + } else if (PPC::VSRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_VSXVectorSpill; + } else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_VectorFloat8Spill; + } else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_VectorFloat4Spill; + } else if (PPC::VRSAVERCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_VRSaveSpill; + } else if (PPC::QFRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_QuadFloat8Spill; + } else if (PPC::QSRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_QuadFloat4Spill; + } else if (PPC::QBRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_QuadBitSpill; + } else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_SpillToVSR; + } else { + llvm_unreachable("Unknown regclass!"); + } } else { - llvm_unreachable("Unknown regclass!"); + if (PPC::GPRCRegClass.contains(Reg) || + PPC::GPRC_NOR0RegClass.contains(Reg)) { + OpcodeIndex = SOK_Int4Spill; + } else if (PPC::G8RCRegClass.contains(Reg) || + PPC::G8RC_NOX0RegClass.contains(Reg)) { + OpcodeIndex = SOK_Int8Spill; + } else if (PPC::F8RCRegClass.contains(Reg)) { + OpcodeIndex = SOK_Float8Spill; + } else if (PPC::F4RCRegClass.contains(Reg)) { + OpcodeIndex = SOK_Float4Spill; + } else if (PPC::CRRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_CRSpill; + } else if (PPC::CRBITRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_CRBitSpill; + } else if (PPC::VRRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_VRVectorSpill; + } else if (PPC::VSRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_VSXVectorSpill; + } else if (PPC::VSFRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_VectorFloat8Spill; + } else if (PPC::VSSRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_VectorFloat4Spill; + } else if (PPC::VRSAVERCRegClass.contains(Reg)) { + OpcodeIndex = SOK_VRSaveSpill; + } else if (PPC::QFRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_QuadFloat8Spill; + } else if (PPC::QSRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_QuadFloat4Spill; + } else if (PPC::QBRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_QuadBitSpill; + } else if (PPC::SPILLTOVSRRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_SpillToVSR; + } else { + llvm_unreachable("Unknown regclass!"); + } } + return OpcodesForSpill[OpcodeIndex]; +} - return false; +unsigned PPCInstrInfo::getLoadOpcodeForSpill(unsigned Reg, + const TargetRegisterClass *RC) + const { + const unsigned *OpcodesForSpill = getLoadOpcodesForSpillArray(); + int OpcodeIndex = 0; + + if (RC != nullptr) { + if (PPC::GPRCRegClass.hasSubClassEq(RC) || + PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_Int4Spill; + } else if (PPC::G8RCRegClass.hasSubClassEq(RC) || + PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_Int8Spill; + } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_Float8Spill; + } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_Float4Spill; + } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_CRSpill; + } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_CRBitSpill; + } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_VRVectorSpill; + } else if (PPC::VSRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_VSXVectorSpill; + } else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_VectorFloat8Spill; + } else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_VectorFloat4Spill; + } else if (PPC::VRSAVERCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_VRSaveSpill; + } else if (PPC::QFRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_QuadFloat8Spill; + } else if (PPC::QSRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_QuadFloat4Spill; + } else if (PPC::QBRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_QuadBitSpill; + } else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) { + OpcodeIndex = SOK_SpillToVSR; + } else { + llvm_unreachable("Unknown regclass!"); + } + } else { + if (PPC::GPRCRegClass.contains(Reg) || + PPC::GPRC_NOR0RegClass.contains(Reg)) { + OpcodeIndex = SOK_Int4Spill; + } else if (PPC::G8RCRegClass.contains(Reg) || + PPC::G8RC_NOX0RegClass.contains(Reg)) { + OpcodeIndex = SOK_Int8Spill; + } else if (PPC::F8RCRegClass.contains(Reg)) { + OpcodeIndex = SOK_Float8Spill; + } else if (PPC::F4RCRegClass.contains(Reg)) { + OpcodeIndex = SOK_Float4Spill; + } else if (PPC::CRRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_CRSpill; + } else if (PPC::CRBITRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_CRBitSpill; + } else if (PPC::VRRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_VRVectorSpill; + } else if (PPC::VSRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_VSXVectorSpill; + } else if (PPC::VSFRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_VectorFloat8Spill; + } else if (PPC::VSSRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_VectorFloat4Spill; + } else if (PPC::VRSAVERCRegClass.contains(Reg)) { + OpcodeIndex = SOK_VRSaveSpill; + } else if (PPC::QFRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_QuadFloat8Spill; + } else if (PPC::QSRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_QuadFloat4Spill; + } else if (PPC::QBRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_QuadBitSpill; + } else if (PPC::SPILLTOVSRRCRegClass.contains(Reg)) { + OpcodeIndex = SOK_SpillToVSR; + } else { + llvm_unreachable("Unknown regclass!"); + } + } + return OpcodesForSpill[OpcodeIndex]; } -void -PPCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned SrcReg, bool isKill, int FrameIdx, - const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { - MachineFunction &MF = *MBB.getParent(); - SmallVector NewMIs; +void PPCInstrInfo::StoreRegToStackSlot( + MachineFunction &MF, unsigned SrcReg, bool isKill, int FrameIdx, + const TargetRegisterClass *RC, + SmallVectorImpl &NewMIs) const { + unsigned Opcode = getStoreOpcodeForSpill(PPC::NoRegister, RC); + DebugLoc DL; PPCFunctionInfo *FuncInfo = MF.getInfo(); FuncInfo->setHasSpills(); + NewMIs.push_back(addFrameReference( + BuildMI(MF, DL, get(Opcode)).addReg(SrcReg, getKillRegState(isKill)), + FrameIdx)); + + if (PPC::CRRCRegClass.hasSubClassEq(RC) || + PPC::CRBITRCRegClass.hasSubClassEq(RC)) + FuncInfo->setSpillsCR(); + + if (PPC::VRSAVERCRegClass.hasSubClassEq(RC)) + FuncInfo->setSpillsVRSAVE(); + + if (get(Opcode).TSFlags & PPCII::XFormMemOp) + FuncInfo->setHasNonRISpills(); +} + +void PPCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned SrcReg, bool isKill, + int FrameIdx, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const { + MachineFunction &MF = *MBB.getParent(); + SmallVector NewMIs; + // We need to avoid a situation in which the value from a VRRC register is // spilled using an Altivec instruction and reloaded into a VSRC register // using a VSX instruction. The issue with this is that the VSX @@ -1132,16 +1199,7 @@ // VSX instruction. RC = updatedRC(RC); - bool NonRI = false, SpillsVRS = false; - if (StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs, - NonRI, SpillsVRS)) - FuncInfo->setSpillsCR(); - - if (SpillsVRS) - FuncInfo->setSpillsVRSAVE(); - - if (NonRI) - FuncInfo->setHasNonRISpills(); + StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs); for (unsigned i = 0, e = NewMIs.size(); i != e; ++i) MBB.insert(MI, NewMIs[i]); @@ -1154,85 +1212,25 @@ NewMIs.back()->addMemOperand(MF, MMO); } -bool PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, const DebugLoc &DL, +void PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, const DebugLoc &DL, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, - SmallVectorImpl &NewMIs, - bool &NonRI, bool &SpillsVRS) const { - // Note: If additional load instructions are added here, - // update isLoadFromStackSlot. - - if (PPC::GPRCRegClass.hasSubClassEq(RC) || - PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), - DestReg), FrameIdx)); - } else if (PPC::G8RCRegClass.hasSubClassEq(RC) || - PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LD), DestReg), - FrameIdx)); - } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFD), DestReg), - FrameIdx)); - } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFS), DestReg), - FrameIdx)); - } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, - get(PPC::RESTORE_CR), DestReg), - FrameIdx)); - return true; - } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, - get(PPC::RESTORE_CRBIT), DestReg), - FrameIdx)); - return true; - } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LVX), DestReg), - FrameIdx)); - NonRI = true; - } else if (PPC::VSRCRegClass.hasSubClassEq(RC)) { - unsigned Op = Subtarget.hasP9Vector() ? PPC::LXV : PPC::LXVD2X; - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(Op), DestReg), - FrameIdx)); - NonRI = true; - } else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) { - unsigned Opc = Subtarget.hasP9Vector() ? PPC::DFLOADf64 : PPC::LXSDX; - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(Opc), - DestReg), FrameIdx)); - NonRI = true; - } else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) { - unsigned Opc = Subtarget.hasP9Vector() ? PPC::DFLOADf32 : PPC::LXSSPX; - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(Opc), - DestReg), FrameIdx)); - NonRI = true; - } else if (PPC::VRSAVERCRegClass.hasSubClassEq(RC)) { - assert(Subtarget.isDarwin() && - "VRSAVE only needs spill/restore on Darwin"); - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, - get(PPC::RESTORE_VRSAVE), - DestReg), - FrameIdx)); - SpillsVRS = true; - } else if (PPC::QFRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::QVLFDX), DestReg), - FrameIdx)); - NonRI = true; - } else if (PPC::QSRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::QVLFSXs), DestReg), - FrameIdx)); - NonRI = true; - } else if (PPC::QBRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::QVLFDXb), DestReg), - FrameIdx)); - NonRI = true; - } else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) { - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::SPILLTOVSR_LD), - DestReg), FrameIdx)); - } else { - llvm_unreachable("Unknown regclass!"); - } + SmallVectorImpl &NewMIs) + const { + unsigned Opcode = getLoadOpcodeForSpill(PPC::NoRegister, RC); + NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(Opcode), DestReg), + FrameIdx)); + PPCFunctionInfo *FuncInfo = MF.getInfo(); - return false; + if (PPC::CRRCRegClass.hasSubClassEq(RC) || + PPC::CRBITRCRegClass.hasSubClassEq(RC)) + FuncInfo->setSpillsCR(); + + if (PPC::VRSAVERCRegClass.hasSubClassEq(RC)) + FuncInfo->setSpillsVRSAVE(); + + if (get(Opcode).TSFlags & PPCII::XFormMemOp) + FuncInfo->setHasNonRISpills(); } void @@ -1259,16 +1257,7 @@ if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass) RC = &PPC::VSRCRegClass; - bool NonRI = false, SpillsVRS = false; - if (LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs, - NonRI, SpillsVRS)) - FuncInfo->setSpillsCR(); - - if (SpillsVRS) - FuncInfo->setSpillsVRSAVE(); - - if (NonRI) - FuncInfo->setHasNonRISpills(); + LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs); for (unsigned i = 0, e = NewMIs.size(); i != e; ++i) MBB.insert(MI, NewMIs[i]); @@ -2313,6 +2302,38 @@ return ConstOp == ~0U ? nullptr : DefMI; } +const unsigned *PPCInstrInfo::getStoreOpcodesForSpillArray() const { + static const unsigned OpcodesForSpill[2][SOK_LastOpcodeSpill] = { + // Power 8 + {PPC::STW, PPC::STD, PPC::STFD, PPC::STFS, PPC::SPILL_CR, + PPC::SPILL_CRBIT, PPC::STVX, PPC::STXVD2X, PPC::STXSDX, PPC::STXSSPX, + PPC::SPILL_VRSAVE, PPC::QVSTFDX, PPC::QVSTFSXs, PPC::QVSTFDXb, + PPC::SPILLTOVSR_ST}, + // Power 9 + {PPC::STW, PPC::STD, PPC::STFD, PPC::STFS, PPC::SPILL_CR, + PPC::SPILL_CRBIT, PPC::STVX, PPC::STXV, PPC::DFSTOREf64, PPC::DFSTOREf32, + PPC::SPILL_VRSAVE, PPC::QVSTFDX, PPC::QVSTFSXs, PPC::QVSTFDXb, + PPC::SPILLTOVSR_ST}}; + + return OpcodesForSpill[(Subtarget.hasP9Vector()) ? 1 : 0]; +} + +const unsigned *PPCInstrInfo::getLoadOpcodesForSpillArray() const { + static const unsigned OpcodesForSpill[2][SOK_LastOpcodeSpill] = { + // Power 8 + {PPC::LWZ, PPC::LD, PPC::LFD, PPC::LFS, PPC::RESTORE_CR, + PPC::RESTORE_CRBIT, PPC::LVX, PPC::LXVD2X, PPC::LXSDX, PPC::LXSSPX, + PPC::RESTORE_VRSAVE, PPC::QVLFDX, PPC::QVLFSXs, PPC::QVLFDXb, + PPC::SPILLTOVSR_LD}, + // Power 9 + {PPC::LWZ, PPC::LD, PPC::LFD, PPC::LFS, PPC::RESTORE_CR, + PPC::RESTORE_CRBIT, PPC::LVX, PPC::LXV, PPC::DFLOADf64, PPC::DFLOADf32, + PPC::RESTORE_VRSAVE, PPC::QVLFDX, PPC::QVLFSXs, PPC::QVLFDXb, + PPC::SPILLTOVSR_LD}}; + + return OpcodesForSpill[(Subtarget.hasP9Vector()) ? 1 : 0]; +} + // If this instruction has an immediate form and one of its operands is a // result of a load-immediate, convert it to the immediate form if the constant // is in range. Index: lib/Target/PowerPC/PPCInstrInfo.td =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.td +++ lib/Target/PowerPC/PPCInstrInfo.td @@ -1724,28 +1724,28 @@ // Instructions to support atomic operations let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in { -def LBARX : XForm_1<31, 52, (outs gprc:$rD), (ins memrr:$src), +def LBARX : XForm_1_memOp<31, 52, (outs gprc:$rD), (ins memrr:$src), "lbarx $rD, $src", IIC_LdStLWARX, []>, Requires<[HasPartwordAtomics]>; -def LHARX : XForm_1<31, 116, (outs gprc:$rD), (ins memrr:$src), +def LHARX : XForm_1_memOp<31, 116, (outs gprc:$rD), (ins memrr:$src), "lharx $rD, $src", IIC_LdStLWARX, []>, Requires<[HasPartwordAtomics]>; -def LWARX : XForm_1<31, 20, (outs gprc:$rD), (ins memrr:$src), +def LWARX : XForm_1_memOp<31, 20, (outs gprc:$rD), (ins memrr:$src), "lwarx $rD, $src", IIC_LdStLWARX, []>; // Instructions to support lock versions of atomics // (EH=1 - see Power ISA 2.07 Book II 4.4.2) -def LBARXL : XForm_1<31, 52, (outs gprc:$rD), (ins memrr:$src), +def LBARXL : XForm_1_memOp<31, 52, (outs gprc:$rD), (ins memrr:$src), "lbarx $rD, $src, 1", IIC_LdStLWARX, []>, isDOT, Requires<[HasPartwordAtomics]>; -def LHARXL : XForm_1<31, 116, (outs gprc:$rD), (ins memrr:$src), +def LHARXL : XForm_1_memOp<31, 116, (outs gprc:$rD), (ins memrr:$src), "lharx $rD, $src, 1", IIC_LdStLWARX, []>, isDOT, Requires<[HasPartwordAtomics]>; -def LWARXL : XForm_1<31, 20, (outs gprc:$rD), (ins memrr:$src), +def LWARXL : XForm_1_memOp<31, 20, (outs gprc:$rD), (ins memrr:$src), "lwarx $rD, $src, 1", IIC_LdStLWARX, []>, isDOT; // The atomic instructions use the destination register as well as the next one @@ -1757,15 +1757,15 @@ } let Defs = [CR0], mayStore = 1, mayLoad = 0, hasSideEffects = 0 in { -def STBCX : XForm_1<31, 694, (outs), (ins gprc:$rS, memrr:$dst), +def STBCX : XForm_1_memOp<31, 694, (outs), (ins gprc:$rS, memrr:$dst), "stbcx. $rS, $dst", IIC_LdStSTWCX, []>, isDOT, Requires<[HasPartwordAtomics]>; -def STHCX : XForm_1<31, 726, (outs), (ins gprc:$rS, memrr:$dst), +def STHCX : XForm_1_memOp<31, 726, (outs), (ins gprc:$rS, memrr:$dst), "sthcx. $rS, $dst", IIC_LdStSTWCX, []>, isDOT, Requires<[HasPartwordAtomics]>; -def STWCX : XForm_1<31, 150, (outs), (ins gprc:$rS, memrr:$dst), +def STWCX : XForm_1_memOp<31, 150, (outs), (ins gprc:$rS, memrr:$dst), "stwcx. $rS, $dst", IIC_LdStSTWCX, []>, isDOT; } @@ -1848,37 +1848,37 @@ // Indexed (r+r) Loads with Update (preinc). -def LBZUX : XForm_1<31, 119, (outs gprc:$rD, ptr_rc_nor0:$ea_result), +def LBZUX : XForm_1_memOp<31, 119, (outs gprc:$rD, ptr_rc_nor0:$ea_result), (ins memrr:$addr), "lbzux $rD, $addr", IIC_LdStLoadUpdX, []>, RegConstraint<"$addr.ptrreg = $ea_result">, NoEncode<"$ea_result">; -def LHAUX : XForm_1<31, 375, (outs gprc:$rD, ptr_rc_nor0:$ea_result), +def LHAUX : XForm_1_memOp<31, 375, (outs gprc:$rD, ptr_rc_nor0:$ea_result), (ins memrr:$addr), "lhaux $rD, $addr", IIC_LdStLHAUX, []>, RegConstraint<"$addr.ptrreg = $ea_result">, NoEncode<"$ea_result">; -def LHZUX : XForm_1<31, 311, (outs gprc:$rD, ptr_rc_nor0:$ea_result), +def LHZUX : XForm_1_memOp<31, 311, (outs gprc:$rD, ptr_rc_nor0:$ea_result), (ins memrr:$addr), "lhzux $rD, $addr", IIC_LdStLoadUpdX, []>, RegConstraint<"$addr.ptrreg = $ea_result">, NoEncode<"$ea_result">; -def LWZUX : XForm_1<31, 55, (outs gprc:$rD, ptr_rc_nor0:$ea_result), +def LWZUX : XForm_1_memOp<31, 55, (outs gprc:$rD, ptr_rc_nor0:$ea_result), (ins memrr:$addr), "lwzux $rD, $addr", IIC_LdStLoadUpdX, []>, RegConstraint<"$addr.ptrreg = $ea_result">, NoEncode<"$ea_result">; -def LFSUX : XForm_1<31, 567, (outs f4rc:$rD, ptr_rc_nor0:$ea_result), +def LFSUX : XForm_1_memOp<31, 567, (outs f4rc:$rD, ptr_rc_nor0:$ea_result), (ins memrr:$addr), "lfsux $rD, $addr", IIC_LdStLFDUX, []>, RegConstraint<"$addr.ptrreg = $ea_result">, NoEncode<"$ea_result">; -def LFDUX : XForm_1<31, 631, (outs f8rc:$rD, ptr_rc_nor0:$ea_result), +def LFDUX : XForm_1_memOp<31, 631, (outs f8rc:$rD, ptr_rc_nor0:$ea_result), (ins memrr:$addr), "lfdux $rD, $addr", IIC_LdStLFDUX, []>, RegConstraint<"$addr.ptrreg = $ea_result">, @@ -1889,37 +1889,37 @@ // Indexed (r+r) Loads. // let PPC970_Unit = 2, mayLoad = 1, mayStore = 0 in { -def LBZX : XForm_1<31, 87, (outs gprc:$rD), (ins memrr:$src), +def LBZX : XForm_1_memOp<31, 87, (outs gprc:$rD), (ins memrr:$src), "lbzx $rD, $src", IIC_LdStLoad, [(set i32:$rD, (zextloadi8 xaddr:$src))]>; -def LHAX : XForm_1<31, 343, (outs gprc:$rD), (ins memrr:$src), +def LHAX : XForm_1_memOp<31, 343, (outs gprc:$rD), (ins memrr:$src), "lhax $rD, $src", IIC_LdStLHA, [(set i32:$rD, (sextloadi16 xaddr:$src))]>, PPC970_DGroup_Cracked; -def LHZX : XForm_1<31, 279, (outs gprc:$rD), (ins memrr:$src), +def LHZX : XForm_1_memOp<31, 279, (outs gprc:$rD), (ins memrr:$src), "lhzx $rD, $src", IIC_LdStLoad, [(set i32:$rD, (zextloadi16 xaddr:$src))]>; -def LWZX : XForm_1<31, 23, (outs gprc:$rD), (ins memrr:$src), +def LWZX : XForm_1_memOp<31, 23, (outs gprc:$rD), (ins memrr:$src), "lwzx $rD, $src", IIC_LdStLoad, [(set i32:$rD, (load xaddr:$src))]>; -def LHBRX : XForm_1<31, 790, (outs gprc:$rD), (ins memrr:$src), +def LHBRX : XForm_1_memOp<31, 790, (outs gprc:$rD), (ins memrr:$src), "lhbrx $rD, $src", IIC_LdStLoad, [(set i32:$rD, (PPClbrx xoaddr:$src, i16))]>; -def LWBRX : XForm_1<31, 534, (outs gprc:$rD), (ins memrr:$src), +def LWBRX : XForm_1_memOp<31, 534, (outs gprc:$rD), (ins memrr:$src), "lwbrx $rD, $src", IIC_LdStLoad, [(set i32:$rD, (PPClbrx xoaddr:$src, i32))]>; -def LFSX : XForm_25<31, 535, (outs f4rc:$frD), (ins memrr:$src), +def LFSX : XForm_25_memOp<31, 535, (outs f4rc:$frD), (ins memrr:$src), "lfsx $frD, $src", IIC_LdStLFD, [(set f32:$frD, (load xaddr:$src))]>; -def LFDX : XForm_25<31, 599, (outs f8rc:$frD), (ins memrr:$src), +def LFDX : XForm_25_memOp<31, 599, (outs f8rc:$frD), (ins memrr:$src), "lfdx $frD, $src", IIC_LdStLFD, [(set f64:$frD, (load xaddr:$src))]>; -def LFIWAX : XForm_25<31, 855, (outs f8rc:$frD), (ins memrr:$src), +def LFIWAX : XForm_25_memOp<31, 855, (outs f8rc:$frD), (ins memrr:$src), "lfiwax $frD, $src", IIC_LdStLFD, [(set f64:$frD, (PPClfiwax xoaddr:$src))]>; -def LFIWZX : XForm_25<31, 887, (outs f8rc:$frD), (ins memrr:$src), +def LFIWZX : XForm_25_memOp<31, 887, (outs f8rc:$frD), (ins memrr:$src), "lfiwzx $frD, $src", IIC_LdStLFD, [(set f64:$frD, (PPClfiwzx xoaddr:$src))]>; } @@ -1986,62 +1986,72 @@ // Indexed (r+r) Stores. let PPC970_Unit = 2 in { -def STBX : XForm_8<31, 215, (outs), (ins gprc:$rS, memrr:$dst), +def STBX : XForm_8_memOp<31, 215, (outs), (ins gprc:$rS, memrr:$dst), "stbx $rS, $dst", IIC_LdStStore, [(truncstorei8 i32:$rS, xaddr:$dst)]>, PPC970_DGroup_Cracked; -def STHX : XForm_8<31, 407, (outs), (ins gprc:$rS, memrr:$dst), +def STHX : XForm_8_memOp<31, 407, (outs), (ins gprc:$rS, memrr:$dst), "sthx $rS, $dst", IIC_LdStStore, [(truncstorei16 i32:$rS, xaddr:$dst)]>, PPC970_DGroup_Cracked; -def STWX : XForm_8<31, 151, (outs), (ins gprc:$rS, memrr:$dst), +def STWX : XForm_8_memOp<31, 151, (outs), (ins gprc:$rS, memrr:$dst), "stwx $rS, $dst", IIC_LdStStore, [(store i32:$rS, xaddr:$dst)]>, PPC970_DGroup_Cracked; -def STHBRX: XForm_8<31, 918, (outs), (ins gprc:$rS, memrr:$dst), +def STHBRX: XForm_8_memOp<31, 918, (outs), (ins gprc:$rS, memrr:$dst), "sthbrx $rS, $dst", IIC_LdStStore, [(PPCstbrx i32:$rS, xoaddr:$dst, i16)]>, PPC970_DGroup_Cracked; -def STWBRX: XForm_8<31, 662, (outs), (ins gprc:$rS, memrr:$dst), +def STWBRX: XForm_8_memOp<31, 662, (outs), (ins gprc:$rS, memrr:$dst), "stwbrx $rS, $dst", IIC_LdStStore, [(PPCstbrx i32:$rS, xoaddr:$dst, i32)]>, PPC970_DGroup_Cracked; -def STFIWX: XForm_28<31, 983, (outs), (ins f8rc:$frS, memrr:$dst), +def STFIWX: XForm_28_memOp<31, 983, (outs), (ins f8rc:$frS, memrr:$dst), "stfiwx $frS, $dst", IIC_LdStSTFD, [(PPCstfiwx f64:$frS, xoaddr:$dst)]>; -def STFSX : XForm_28<31, 663, (outs), (ins f4rc:$frS, memrr:$dst), +def STFSX : XForm_28_memOp<31, 663, (outs), (ins f4rc:$frS, memrr:$dst), "stfsx $frS, $dst", IIC_LdStSTFD, [(store f32:$frS, xaddr:$dst)]>; -def STFDX : XForm_28<31, 727, (outs), (ins f8rc:$frS, memrr:$dst), +def STFDX : XForm_28_memOp<31, 727, (outs), (ins f8rc:$frS, memrr:$dst), "stfdx $frS, $dst", IIC_LdStSTFD, [(store f64:$frS, xaddr:$dst)]>; } // Indexed (r+r) Stores with Update (preinc). let PPC970_Unit = 2, mayStore = 1, mayLoad = 0 in { -def STBUX : XForm_8<31, 247, (outs ptr_rc_nor0:$ea_res), (ins gprc:$rS, memrr:$dst), - "stbux $rS, $dst", IIC_LdStStoreUpd, []>, - RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, - PPC970_DGroup_Cracked; -def STHUX : XForm_8<31, 439, (outs ptr_rc_nor0:$ea_res), (ins gprc:$rS, memrr:$dst), - "sthux $rS, $dst", IIC_LdStStoreUpd, []>, - RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, - PPC970_DGroup_Cracked; -def STWUX : XForm_8<31, 183, (outs ptr_rc_nor0:$ea_res), (ins gprc:$rS, memrr:$dst), - "stwux $rS, $dst", IIC_LdStStoreUpd, []>, - RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, - PPC970_DGroup_Cracked; -def STFSUX: XForm_8<31, 695, (outs ptr_rc_nor0:$ea_res), (ins f4rc:$rS, memrr:$dst), - "stfsux $rS, $dst", IIC_LdStSTFDU, []>, - RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, - PPC970_DGroup_Cracked; -def STFDUX: XForm_8<31, 759, (outs ptr_rc_nor0:$ea_res), (ins f8rc:$rS, memrr:$dst), - "stfdux $rS, $dst", IIC_LdStSTFDU, []>, - RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">, - PPC970_DGroup_Cracked; +def STBUX : XForm_8_memOp<31, 247, (outs ptr_rc_nor0:$ea_res), + (ins gprc:$rS, memrr:$dst), + "stbux $rS, $dst", IIC_LdStStoreUpd, []>, + RegConstraint<"$dst.ptrreg = $ea_res">, + NoEncode<"$ea_res">, + PPC970_DGroup_Cracked; +def STHUX : XForm_8_memOp<31, 439, (outs ptr_rc_nor0:$ea_res), + (ins gprc:$rS, memrr:$dst), + "sthux $rS, $dst", IIC_LdStStoreUpd, []>, + RegConstraint<"$dst.ptrreg = $ea_res">, + NoEncode<"$ea_res">, + PPC970_DGroup_Cracked; +def STWUX : XForm_8_memOp<31, 183, (outs ptr_rc_nor0:$ea_res), + (ins gprc:$rS, memrr:$dst), + "stwux $rS, $dst", IIC_LdStStoreUpd, []>, + RegConstraint<"$dst.ptrreg = $ea_res">, + NoEncode<"$ea_res">, + PPC970_DGroup_Cracked; +def STFSUX: XForm_8_memOp<31, 695, (outs ptr_rc_nor0:$ea_res), + (ins f4rc:$rS, memrr:$dst), + "stfsux $rS, $dst", IIC_LdStSTFDU, []>, + RegConstraint<"$dst.ptrreg = $ea_res">, + NoEncode<"$ea_res">, + PPC970_DGroup_Cracked; +def STFDUX: XForm_8_memOp<31, 759, (outs ptr_rc_nor0:$ea_res), + (ins f8rc:$rS, memrr:$dst), + "stfdux $rS, $dst", IIC_LdStSTFDU, []>, + RegConstraint<"$dst.ptrreg = $ea_res">, + NoEncode<"$ea_res">, + PPC970_DGroup_Cracked; } // Patterns to match the pre-inc stores. We can't put the patterns on @@ -3763,13 +3773,15 @@ // FIXME: For B=0 or B > 8, the registers following RT are used. // WARNING: Do not add patterns for this instruction without fixing this. -def LSWI : XForm_base_r3xo<31, 597, (outs gprc:$RT), (ins gprc:$A, u5imm:$B), - "lswi $RT, $A, $B", IIC_LdStLoad, []>; +def LSWI : XForm_base_r3xo_memOp<31, 597, (outs gprc:$RT), + (ins gprc:$A, u5imm:$B), + "lswi $RT, $A, $B", IIC_LdStLoad, []>; // FIXME: For B=0 or B > 8, the registers following RT are used. // WARNING: Do not add patterns for this instruction without fixing this. -def STSWI : XForm_base_r3xo<31, 725, (outs), (ins gprc:$RT, gprc:$A, u5imm:$B), - "stswi $RT, $A, $B", IIC_LdStLoad, []>; +def STSWI : XForm_base_r3xo_memOp<31, 725, (outs), + (ins gprc:$RT, gprc:$A, u5imm:$B), + "stswi $RT, $A, $B", IIC_LdStLoad, []>; def ISYNC : XLForm_2_ext<19, 150, 0, 0, 0, (outs), (ins), "isync", IIC_SprISYNC, []>; @@ -3932,23 +3944,31 @@ def ATTN : XForm_attn<0, 256, (outs), (ins), "attn", IIC_BrB>; -def LBZCIX : XForm_base_r3xo<31, 853, (outs gprc:$RST), (ins gprc:$A, gprc:$B), - "lbzcix $RST, $A, $B", IIC_LdStLoad, []>; -def LHZCIX : XForm_base_r3xo<31, 821, (outs gprc:$RST), (ins gprc:$A, gprc:$B), - "lhzcix $RST, $A, $B", IIC_LdStLoad, []>; -def LWZCIX : XForm_base_r3xo<31, 789, (outs gprc:$RST), (ins gprc:$A, gprc:$B), - "lwzcix $RST, $A, $B", IIC_LdStLoad, []>; -def LDCIX : XForm_base_r3xo<31, 885, (outs gprc:$RST), (ins gprc:$A, gprc:$B), - "ldcix $RST, $A, $B", IIC_LdStLoad, []>; - -def STBCIX : XForm_base_r3xo<31, 981, (outs), (ins gprc:$RST, gprc:$A, gprc:$B), - "stbcix $RST, $A, $B", IIC_LdStLoad, []>; -def STHCIX : XForm_base_r3xo<31, 949, (outs), (ins gprc:$RST, gprc:$A, gprc:$B), - "sthcix $RST, $A, $B", IIC_LdStLoad, []>; -def STWCIX : XForm_base_r3xo<31, 917, (outs), (ins gprc:$RST, gprc:$A, gprc:$B), - "stwcix $RST, $A, $B", IIC_LdStLoad, []>; -def STDCIX : XForm_base_r3xo<31, 1013, (outs), (ins gprc:$RST, gprc:$A, gprc:$B), - "stdcix $RST, $A, $B", IIC_LdStLoad, []>; +def LBZCIX : XForm_base_r3xo_memOp<31, 853, (outs gprc:$RST), + (ins gprc:$A, gprc:$B), + "lbzcix $RST, $A, $B", IIC_LdStLoad, []>; +def LHZCIX : XForm_base_r3xo_memOp<31, 821, (outs gprc:$RST), + (ins gprc:$A, gprc:$B), + "lhzcix $RST, $A, $B", IIC_LdStLoad, []>; +def LWZCIX : XForm_base_r3xo_memOp<31, 789, (outs gprc:$RST), + (ins gprc:$A, gprc:$B), + "lwzcix $RST, $A, $B", IIC_LdStLoad, []>; +def LDCIX : XForm_base_r3xo_memOp<31, 885, (outs gprc:$RST), + (ins gprc:$A, gprc:$B), + "ldcix $RST, $A, $B", IIC_LdStLoad, []>; + +def STBCIX : XForm_base_r3xo_memOp<31, 981, (outs), + (ins gprc:$RST, gprc:$A, gprc:$B), + "stbcix $RST, $A, $B", IIC_LdStLoad, []>; +def STHCIX : XForm_base_r3xo_memOp<31, 949, (outs), + (ins gprc:$RST, gprc:$A, gprc:$B), + "sthcix $RST, $A, $B", IIC_LdStLoad, []>; +def STWCIX : XForm_base_r3xo_memOp<31, 917, (outs), + (ins gprc:$RST, gprc:$A, gprc:$B), + "stwcix $RST, $A, $B", IIC_LdStLoad, []>; +def STDCIX : XForm_base_r3xo_memOp<31, 1013, (outs), + (ins gprc:$RST, gprc:$A, gprc:$B), + "stdcix $RST, $A, $B", IIC_LdStLoad, []>; // External PID Load Store Instructions @@ -3972,7 +3992,7 @@ "stbepx $rS, $dst", IIC_LdStStore, []>, Requires<[IsE500]>; -def STFDEPX : XForm_28<31, 735, (outs), (ins f8rc:$frS, memrr:$dst), +def STFDEPX : XForm_28_memOp<31, 735, (outs), (ins f8rc:$frS, memrr:$dst), "stfdepx $frS, $dst", IIC_LdStSTFD, []>, Requires<[IsE500]>; Index: lib/Target/PowerPC/PPCInstrQPX.td =================================================================== --- lib/Target/PowerPC/PPCInstrQPX.td +++ lib/Target/PowerPC/PPCInstrQPX.td @@ -502,14 +502,14 @@ // Load indexed instructions let mayLoad = 1 in { - def QVLFDX : XForm_1<31, 583, - (outs qfrc:$FRT), (ins memrr:$src), - "qvlfdx $FRT, $src", IIC_LdStLFD, - [(set v4f64:$FRT, (load xoaddr:$src))]>; + def QVLFDX : XForm_1_memOp<31, 583, + (outs qfrc:$FRT), (ins memrr:$src), + "qvlfdx $FRT, $src", IIC_LdStLFD, + [(set v4f64:$FRT, (load xoaddr:$src))]>; let isCodeGenOnly = 1 in - def QVLFDXb : XForm_1<31, 583, - (outs qbrc:$FRT), (ins memrr:$src), - "qvlfdx $FRT, $src", IIC_LdStLFD, []>; + def QVLFDXb : XForm_1_memOp<31, 583, + (outs qbrc:$FRT), (ins memrr:$src), + "qvlfdx $FRT, $src", IIC_LdStLFD, []>; let RC = 1 in def QVLFDXA : XForm_1<31, 583, @@ -527,10 +527,10 @@ (outs qfrc:$FRT), (ins memrr:$src), "qvlfduxa $FRT, $src", IIC_LdStLFD, []>; - def QVLFSX : XForm_1<31, 519, - (outs qfrc:$FRT), (ins memrr:$src), - "qvlfsx $FRT, $src", IIC_LdStLFD, - [(set v4f64:$FRT, (extloadv4f32 xoaddr:$src))]>; + def QVLFSX : XForm_1_memOp<31, 519, + (outs qfrc:$FRT), (ins memrr:$src), + "qvlfsx $FRT, $src", IIC_LdStLFD, + [(set v4f64:$FRT, (extloadv4f32 xoaddr:$src))]>; let isCodeGenOnly = 1 in def QVLFSXb : XForm_1<31, 519, @@ -538,10 +538,10 @@ "qvlfsx $FRT, $src", IIC_LdStLFD, [(set v4i1:$FRT, (PPCqvlfsb xoaddr:$src))]>; let isCodeGenOnly = 1 in - def QVLFSXs : XForm_1<31, 519, - (outs qsrc:$FRT), (ins memrr:$src), - "qvlfsx $FRT, $src", IIC_LdStLFD, - [(set v4f32:$FRT, (load xoaddr:$src))]>; + def QVLFSXs : XForm_1_memOp<31, 519, + (outs qsrc:$FRT), (ins memrr:$src), + "qvlfsx $FRT, $src", IIC_LdStLFD, + [(set v4f32:$FRT, (load xoaddr:$src))]>; let RC = 1 in def QVLFSXA : XForm_1<31, 519, @@ -634,12 +634,12 @@ // Store indexed instructions let mayStore = 1 in { - def QVSTFDX : XForm_8<31, 711, + def QVSTFDX : XForm_8_memOp<31, 711, (outs), (ins qfrc:$FRT, memrr:$dst), "qvstfdx $FRT, $dst", IIC_LdStSTFD, [(store qfrc:$FRT, xoaddr:$dst)]>; let isCodeGenOnly = 1 in - def QVSTFDXb : XForm_8<31, 711, + def QVSTFDXb : XForm_8_memOp<31, 711, (outs), (ins qbrc:$FRT, memrr:$dst), "qvstfdx $FRT, $dst", IIC_LdStSTFD, []>; @@ -675,12 +675,12 @@ (outs), (ins qfrc:$FRT, memrr:$dst), "qvstfduxia $FRT, $dst", IIC_LdStSTFD, []>; - def QVSTFSX : XForm_8<31, 647, + def QVSTFSX : XForm_8_memOp<31, 647, (outs), (ins qfrc:$FRT, memrr:$dst), "qvstfsx $FRT, $dst", IIC_LdStSTFD, [(truncstorev4f32 qfrc:$FRT, xoaddr:$dst)]>; let isCodeGenOnly = 1 in - def QVSTFSXs : XForm_8<31, 647, + def QVSTFSXs : XForm_8_memOp<31, 647, (outs), (ins qsrc:$FRT, memrr:$dst), "qvstfsx $FRT, $dst", IIC_LdStSTFD, [(store qsrc:$FRT, xoaddr:$dst)]>; Index: lib/Target/PowerPC/PPCInstrVSX.td =================================================================== --- lib/Target/PowerPC/PPCInstrVSX.td +++ lib/Target/PowerPC/PPCInstrVSX.td @@ -126,29 +126,29 @@ // Load indexed instructions let mayLoad = 1, mayStore = 0 in { let CodeSize = 3 in - def LXSDX : XX1Form<31, 588, + def LXSDX : XX1Form_memOp<31, 588, (outs vsfrc:$XT), (ins memrr:$src), "lxsdx $XT, $src", IIC_LdStLFD, [(set f64:$XT, (load xoaddr:$src))]>; // Pseudo instruction XFLOADf64 will be expanded to LXSDX or LFDX later let isPseudo = 1, CodeSize = 3 in - def XFLOADf64 : Pseudo<(outs vsfrc:$XT), (ins memrr:$src), + def XFLOADf64 : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src), "#XFLOADf64", [(set f64:$XT, (load xoaddr:$src))]>; let Predicates = [HasVSX, HasOnlySwappingMemOps] in - def LXVD2X : XX1Form<31, 844, + def LXVD2X : XX1Form_memOp<31, 844, (outs vsrc:$XT), (ins memrr:$src), "lxvd2x $XT, $src", IIC_LdStLFD, [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>; - def LXVDSX : XX1Form<31, 332, + def LXVDSX : XX1Form_memOp<31, 332, (outs vsrc:$XT), (ins memrr:$src), "lxvdsx $XT, $src", IIC_LdStLFD, []>; let Predicates = [HasVSX, HasOnlySwappingMemOps] in - def LXVW4X : XX1Form<31, 780, + def LXVW4X : XX1Form_memOp<31, 780, (outs vsrc:$XT), (ins memrr:$src), "lxvw4x $XT, $src", IIC_LdStLFD, []>; @@ -157,26 +157,26 @@ // Store indexed instructions let mayStore = 1, mayLoad = 0 in { let CodeSize = 3 in - def STXSDX : XX1Form<31, 716, + def STXSDX : XX1Form_memOp<31, 716, (outs), (ins vsfrc:$XT, memrr:$dst), "stxsdx $XT, $dst", IIC_LdStSTFD, [(store f64:$XT, xoaddr:$dst)]>; // Pseudo instruction XFSTOREf64 will be expanded to STXSDX or STFDX later let isPseudo = 1, CodeSize = 3 in - def XFSTOREf64 : Pseudo<(outs), (ins vsfrc:$XT, memrr:$dst), + def XFSTOREf64 : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst), "#XFSTOREf64", [(store f64:$XT, xoaddr:$dst)]>; let Predicates = [HasVSX, HasOnlySwappingMemOps] in { // The behaviour of this instruction is endianness-specific so we provide no // pattern to match it without considering endianness. - def STXVD2X : XX1Form<31, 972, + def STXVD2X : XX1Form_memOp<31, 972, (outs), (ins vsrc:$XT, memrr:$dst), "stxvd2x $XT, $dst", IIC_LdStSTFD, []>; - def STXVW4X : XX1Form<31, 908, + def STXVW4X : XX1Form_memOp<31, 908, (outs), (ins vsrc:$XT, memrr:$dst), "stxvw4x $XT, $dst", IIC_LdStSTFD, []>; @@ -1226,11 +1226,11 @@ // VSX scalar loads introduced in ISA 2.07 let mayLoad = 1, mayStore = 0 in { let CodeSize = 3 in - def LXSSPX : XX1Form<31, 524, (outs vssrc:$XT), (ins memrr:$src), + def LXSSPX : XX1Form_memOp<31, 524, (outs vssrc:$XT), (ins memrr:$src), "lxsspx $XT, $src", IIC_LdStLFD, []>; - def LXSIWAX : XX1Form<31, 76, (outs vsfrc:$XT), (ins memrr:$src), + def LXSIWAX : XX1Form_memOp<31, 76, (outs vsfrc:$XT), (ins memrr:$src), "lxsiwax $XT, $src", IIC_LdStLFD, []>; - def LXSIWZX : XX1Form<31, 12, (outs vsfrc:$XT), (ins memrr:$src), + def LXSIWZX : XX1Form_memOp<31, 12, (outs vsfrc:$XT), (ins memrr:$src), "lxsiwzx $XT, $src", IIC_LdStLFD, []>; // Please note let isPseudo = 1 is not part of class Pseudo<>. Missing it @@ -1238,15 +1238,15 @@ let isPseudo = 1 in { // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later let CodeSize = 3 in - def XFLOADf32 : Pseudo<(outs vssrc:$XT), (ins memrr:$src), + def XFLOADf32 : PseudoXFormMemOp<(outs vssrc:$XT), (ins memrr:$src), "#XFLOADf32", [(set f32:$XT, (load xoaddr:$src))]>; // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later - def LIWAX : Pseudo<(outs vsfrc:$XT), (ins memrr:$src), + def LIWAX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src), "#LIWAX", [(set f64:$XT, (PPClfiwax xoaddr:$src))]>; // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later - def LIWZX : Pseudo<(outs vsfrc:$XT), (ins memrr:$src), + def LIWZX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src), "#LIWZX", [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>; } @@ -1255,9 +1255,9 @@ // VSX scalar stores introduced in ISA 2.07 let mayStore = 1, mayLoad = 0 in { let CodeSize = 3 in - def STXSSPX : XX1Form<31, 652, (outs), (ins vssrc:$XT, memrr:$dst), + def STXSSPX : XX1Form_memOp<31, 652, (outs), (ins vssrc:$XT, memrr:$dst), "stxsspx $XT, $dst", IIC_LdStSTFD, []>; - def STXSIWX : XX1Form<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst), + def STXSIWX : XX1Form_memOp<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst), "stxsiwx $XT, $dst", IIC_LdStSTFD, []>; // Please note let isPseudo = 1 is not part of class Pseudo<>. Missing it @@ -1265,11 +1265,11 @@ let isPseudo = 1 in { // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later let CodeSize = 3 in - def XFSTOREf32 : Pseudo<(outs), (ins vssrc:$XT, memrr:$dst), + def XFSTOREf32 : PseudoXFormMemOp<(outs), (ins vssrc:$XT, memrr:$dst), "#XFSTOREf32", [(store f32:$XT, xoaddr:$dst)]>; // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later - def STIWX : Pseudo<(outs), (ins vsfrc:$XT, memrr:$dst), + def STIWX : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst), "#STIWX", [(PPCstfiwx f64:$XT, xoaddr:$dst)]>; } @@ -2670,7 +2670,7 @@ // "out" and "in" dag class X_XT6_RA5_RB5 opcode, bits<10> xo, string opc, RegisterOperand vtype, list pattern> - : XX1Form, UseVSXReg; // Load as Integer Byte/Halfword & Zero Indexed @@ -2687,11 +2687,11 @@ def LXVX : X_XT6_RA5_RB5<31, 268, "lxvx" , vsrc, [(set v2f64:$XT, (load xaddr:$src))]>; // Load Vector (Left-justified) with Length - def LXVL : XX1Form<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB), + def LXVL : XX1Form_memOp<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB), "lxvl $XT, $src, $rB", IIC_LdStLoad, [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>, UseVSXReg; - def LXVLL : XX1Form<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB), + def LXVLL : XX1Form_memOp<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB), "lxvll $XT, $src, $rB", IIC_LdStLoad, [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>, UseVSXReg; @@ -2716,7 +2716,7 @@ // [PO S RA RB XO SX] class X_XS6_RA5_RB5 opcode, bits<10> xo, string opc, RegisterOperand vtype, list pattern> - : XX1Form, UseVSXReg; // Store as Integer Byte/Halfword Indexed @@ -2738,14 +2738,18 @@ [(store v2f64:$XT, xaddr:$dst)]>; // Store Vector (Left-justified) with Length - def STXVL : XX1Form<31, 397, (outs), (ins vsrc:$XT, memr:$dst, g8rc:$rB), - "stxvl $XT, $dst, $rB", IIC_LdStLoad, - [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst, i64:$rB)]>, - UseVSXReg; - def STXVLL : XX1Form<31, 429, (outs), (ins vsrc:$XT, memr:$dst, g8rc:$rB), - "stxvll $XT, $dst, $rB", IIC_LdStLoad, - [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst, i64:$rB)]>, - UseVSXReg; + def STXVL : XX1Form_memOp<31, 397, (outs), + (ins vsrc:$XT, memr:$dst, g8rc:$rB), + "stxvl $XT, $dst, $rB", IIC_LdStLoad, + [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst, + i64:$rB)]>, + UseVSXReg; + def STXVLL : XX1Form_memOp<31, 429, (outs), + (ins vsrc:$XT, memr:$dst, g8rc:$rB), + "stxvll $XT, $dst, $rB", IIC_LdStLoad, + [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst, + i64:$rB)]>, + UseVSXReg; } // mayStore let Predicates = [IsLittleEndian] in { @@ -3071,14 +3075,16 @@ let Predicates = [HasP9Vector] in { let isPseudo = 1 in { let mayStore = 1 in { - def SPILLTOVSR_STX : Pseudo<(outs), (ins spilltovsrrc:$XT, memrr:$dst), - "#SPILLTOVSR_STX", []>; + def SPILLTOVSR_STX : PseudoXFormMemOp<(outs), + (ins spilltovsrrc:$XT, memrr:$dst), + "#SPILLTOVSR_STX", []>; def SPILLTOVSR_ST : Pseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst), "#SPILLTOVSR_ST", []>; } let mayLoad = 1 in { - def SPILLTOVSR_LDX : Pseudo<(outs spilltovsrrc:$XT), (ins memrr:$src), - "#SPILLTOVSR_LDX", []>; + def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT), + (ins memrr:$src), + "#SPILLTOVSR_LDX", []>; def SPILLTOVSR_LD : Pseudo<(outs spilltovsrrc:$XT), (ins memrix:$src), "#SPILLTOVSR_LD", []>; Index: test/CodeGen/PowerPC/vsxD-Form-spills.ll =================================================================== --- test/CodeGen/PowerPC/vsxD-Form-spills.ll +++ test/CodeGen/PowerPC/vsxD-Form-spills.ll @@ -24,14 +24,14 @@ ; CHECK-NEXT: blr ; ; CHECK-PWR9-LABEL: testSpill: -; CHECK-PWR9: stxv 62, 80(1) # 16-byte Folded Spill -; CHECK-PWR9: stxv 63, 96(1) # 16-byte Folded Spill -; CHECK-PWR9: stxv 60, 48(1) # 16-byte Folded Spill -; CHECK-PWR9: stxv 61, 64(1) # 16-byte Folded Spill -; CHECK-PWR9: lxv 63, 96(1) # 16-byte Folded Reload -; CHECK-PWR9: lxv 62, 80(1) # 16-byte Folded Reload -; CHECK-PWR9: lxv 61, 64(1) # 16-byte Folded Reload -; CHECK-PWR9: lxv 60, 48(1) # 16-byte Folded Reload +; CHECK-PWR9: stxv 62, 64(1) # 16-byte Folded Spill +; CHECK-PWR9: stxv 63, 80(1) # 16-byte Folded Spill +; CHECK-PWR9: stxv 60, 32(1) # 16-byte Folded Spill +; CHECK-PWR9: stxv 61, 48(1) # 16-byte Folded Spill +; CHECK-PWR9: lxv 63, 80(1) # 16-byte Folded Reload +; CHECK-PWR9: lxv 62, 64(1) # 16-byte Folded Reload +; CHECK-PWR9: lxv 61, 48(1) # 16-byte Folded Reload +; CHECK-PWR9: lxv 60, 32(1) # 16-byte Folded Reload ; CHECK-PWR9: mtlr 0 ; CHECK-PWR9-NEXT: blr