diff options
Diffstat (limited to 'lib/Target/PowerPC/PPCInstrInfo.td')
-rw-r--r-- | lib/Target/PowerPC/PPCInstrInfo.td | 425 |
1 files changed, 387 insertions, 38 deletions
diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index c2e3382..8c76c46 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -57,6 +57,9 @@ def SDT_PPCTC_ret : SDTypeProfile<0, 2, [ SDTCisPtrTy<0>, SDTCisVT<1, i32> ]>; +def tocentry32 : Operand<iPTR> { + let MIOperandInfo = (ops i32imm:$imm); +} //===----------------------------------------------------------------------===// // PowerPC specific DAG Nodes. @@ -107,10 +110,8 @@ def PPCldGotTprelL : SDNode<"PPCISD::LD_GOT_TPREL_L", SDTIntBinOp, def PPCaddTls : SDNode<"PPCISD::ADD_TLS", SDTIntBinOp, []>; def PPCaddisTlsgdHA : SDNode<"PPCISD::ADDIS_TLSGD_HA", SDTIntBinOp>; def PPCaddiTlsgdL : SDNode<"PPCISD::ADDI_TLSGD_L", SDTIntBinOp>; -def PPCgetTlsAddr : SDNode<"PPCISD::GET_TLS_ADDR", SDTIntBinOp>; def PPCaddisTlsldHA : SDNode<"PPCISD::ADDIS_TLSLD_HA", SDTIntBinOp>; def PPCaddiTlsldL : SDNode<"PPCISD::ADDI_TLSLD_L", SDTIntBinOp>; -def PPCgetTlsldAddr : SDNode<"PPCISD::GET_TLSLD_ADDR", SDTIntBinOp>; def PPCaddisDtprelHA : SDNode<"PPCISD::ADDIS_DTPREL_HA", SDTIntBinOp, [SDNPHasChain]>; def PPCaddiDtprelL : SDNode<"PPCISD::ADDI_DTPREL_L", SDTIntBinOp>; @@ -133,9 +134,15 @@ def SDT_PPCCall : SDTypeProfile<0, -1, [SDTCisInt<0>]>; def PPCcall : SDNode<"PPCISD::CALL", SDT_PPCCall, [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; +def PPCcall_tls : SDNode<"PPCISD::CALL_TLS", SDT_PPCCall, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, + SDNPVariadic]>; def PPCcall_nop : SDNode<"PPCISD::CALL_NOP", SDT_PPCCall, [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; +def PPCcall_nop_tls : SDNode<"PPCISD::CALL_NOP_TLS", SDT_PPCCall, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, + SDNPVariadic]>; def PPCload : SDNode<"PPCISD::LOAD", SDTypeProfile<1, 1, []>, [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; def PPCload_toc : SDNode<"PPCISD::LOAD_TOC", SDTypeProfile<0, 1, []>, @@ -417,6 +424,15 @@ def u2imm : Operand<i32> { let PrintMethod = "printU2ImmOperand"; let ParserMatchClass = PPCU2ImmAsmOperand; } + +def PPCU4ImmAsmOperand : AsmOperandClass { + let Name = "U4Imm"; let PredicateMethod = "isU4Imm"; + let RenderMethod = "addImmOperands"; +} +def u4imm : Operand<i32> { + let PrintMethod = "printU4ImmOperand"; + let ParserMatchClass = PPCU4ImmAsmOperand; +} def PPCS5ImmAsmOperand : AsmOperandClass { let Name = "S5Imm"; let PredicateMethod = "isS5Imm"; let RenderMethod = "addImmOperands"; @@ -446,7 +462,7 @@ def u6imm : Operand<i32> { } def PPCS16ImmAsmOperand : AsmOperandClass { let Name = "S16Imm"; let PredicateMethod = "isS16Imm"; - let RenderMethod = "addImmOperands"; + let RenderMethod = "addS16ImmOperands"; } def s16imm : Operand<i32> { let PrintMethod = "printS16ImmOperand"; @@ -456,7 +472,7 @@ def s16imm : Operand<i32> { } def PPCU16ImmAsmOperand : AsmOperandClass { let Name = "U16Imm"; let PredicateMethod = "isU16Imm"; - let RenderMethod = "addImmOperands"; + let RenderMethod = "addU16ImmOperands"; } def u16imm : Operand<i32> { let PrintMethod = "printU16ImmOperand"; @@ -466,7 +482,7 @@ def u16imm : Operand<i32> { } def PPCS17ImmAsmOperand : AsmOperandClass { let Name = "S17Imm"; let PredicateMethod = "isS17Imm"; - let RenderMethod = "addImmOperands"; + let RenderMethod = "addS16ImmOperands"; } def s17imm : Operand<i32> { // This operand type is used for addis/lis to allow the assembler parser @@ -542,7 +558,7 @@ def ptr_rc_idx : Operand<iPTR>, PointerLikeRegClass<0> { def PPCDispRIOperand : AsmOperandClass { let Name = "DispRI"; let PredicateMethod = "isS16Imm"; - let RenderMethod = "addImmOperands"; + let RenderMethod = "addS16ImmOperands"; } def dispRI : Operand<iPTR> { let ParserMatchClass = PPCDispRIOperand; @@ -554,6 +570,27 @@ def PPCDispRIXOperand : AsmOperandClass { def dispRIX : Operand<iPTR> { let ParserMatchClass = PPCDispRIXOperand; } +def PPCDispSPE8Operand : AsmOperandClass { + let Name = "DispSPE8"; let PredicateMethod = "isU8ImmX8"; + let RenderMethod = "addImmOperands"; +} +def dispSPE8 : Operand<iPTR> { + let ParserMatchClass = PPCDispSPE8Operand; +} +def PPCDispSPE4Operand : AsmOperandClass { + let Name = "DispSPE4"; let PredicateMethod = "isU7ImmX4"; + let RenderMethod = "addImmOperands"; +} +def dispSPE4 : Operand<iPTR> { + let ParserMatchClass = PPCDispSPE4Operand; +} +def PPCDispSPE2Operand : AsmOperandClass { + let Name = "DispSPE2"; let PredicateMethod = "isU6ImmX2"; + let RenderMethod = "addImmOperands"; +} +def dispSPE2 : Operand<iPTR> { + let ParserMatchClass = PPCDispSPE2Operand; +} def memri : Operand<iPTR> { let PrintMethod = "printMemRegImm"; @@ -571,6 +608,21 @@ def memrix : Operand<iPTR> { // memri where the imm is 4-aligned. let EncoderMethod = "getMemRIXEncoding"; let DecoderMethod = "decodeMemRIXOperands"; } +def spe8dis : Operand<iPTR> { // SPE displacement where the imm is 8-aligned. + let PrintMethod = "printMemRegImm"; + let MIOperandInfo = (ops dispSPE8:$imm, ptr_rc_nor0:$reg); + let EncoderMethod = "getSPE8DisEncoding"; +} +def spe4dis : Operand<iPTR> { // SPE displacement where the imm is 4-aligned. + let PrintMethod = "printMemRegImm"; + let MIOperandInfo = (ops dispSPE4:$imm, ptr_rc_nor0:$reg); + let EncoderMethod = "getSPE4DisEncoding"; +} +def spe2dis : Operand<iPTR> { // SPE displacement where the imm is 2-aligned. + let PrintMethod = "printMemRegImm"; + let MIOperandInfo = (ops dispSPE2:$imm, ptr_rc_nor0:$reg); + let EncoderMethod = "getSPE2DisEncoding"; +} // A single-register address. This is used with the SjLj // pseudo-instructions. @@ -585,6 +637,12 @@ def tlsreg32 : Operand<i32> { let EncoderMethod = "getTLSRegEncoding"; let ParserMatchClass = PPCTLSRegOperand; } +def tlsgd32 : Operand<i32> {} +def tlscall32 : Operand<i32> { + let PrintMethod = "printTLSCall"; + let MIOperandInfo = (ops calltarget:$func, tlsgd32:$sym); + let EncoderMethod = "getTLSCallEncoding"; +} // PowerPC Predicate operand. def pred : Operand<OtherVT> { @@ -611,6 +669,12 @@ def In32BitMode : Predicate<"!PPCSubTarget->isPPC64()">; def In64BitMode : Predicate<"PPCSubTarget->isPPC64()">; def IsBookE : Predicate<"PPCSubTarget->isBookE()">; def IsNotBookE : Predicate<"!PPCSubTarget->isBookE()">; +def HasOnlyMSYNC : Predicate<"PPCSubTarget->hasOnlyMSYNC()">; +def HasSYNC : Predicate<"!PPCSubTarget->hasOnlyMSYNC()">; +def IsPPC4xx : Predicate<"PPCSubTarget->isPPC4xx()">; +def IsPPC6xx : Predicate<"PPCSubTarget->isPPC6xx()">; +def IsE500 : Predicate<"PPCSubTarget->isE500()">; +def HasSPE : Predicate<"PPCSubTarget->HasSPE()">; //===----------------------------------------------------------------------===// // PowerPC Multiclass Definitions. @@ -967,6 +1031,9 @@ let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in { let Defs = [LR] in def MovePCtoLR : Pseudo<(outs), (ins), "#MovePCtoLR", []>, PPC970_Unit_BRU; +let Defs = [LR] in + def MoveGOTtoLR : Pseudo<(outs), (ins), "#MoveGOTtoLR", []>, + PPC970_Unit_BRU; let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in { let isBarrier = 1 in { @@ -1068,6 +1135,8 @@ let isCall = 1, PPC970_Unit = 7, Defs = [LR] in { "bla $func", IIC_BrB, [(PPCcall (i32 imm:$func))]>; let isCodeGenOnly = 1 in { + def BL_TLS : IForm<18, 0, 1, (outs), (ins tlscall32:$func), + "bl $func", IIC_BrB, []>; def BCCL : BForm<16, 0, 1, (outs), (ins pred:$cond, condbrtarget:$dst), "b${cond:cc}l${cond:pm} ${cond:reg}, $dst">; def BCCLA : BForm<16, 1, 1, (outs), (ins pred:$cond, abscondbrtarget:$dst), @@ -1243,8 +1312,15 @@ def DCBZL : DCB_Form<1014, 1, (outs), (ins memrr:$dst), "dcbzl $dst", IIC_LdStDCBF, [(int_ppc_dcbzl xoaddr:$dst)]>, PPC970_DGroup_Single; +def ICBT : XForm_icbt<31, 22, (outs), (ins u4imm:$CT, memrr:$src), + "icbt $CT, $src", IIC_LdStLoad>, Requires<[IsBookE]>; + def : Pat<(prefetch xoaddr:$dst, (i32 0), imm, (i32 1)), - (DCBT xoaddr:$dst)>; + (DCBT xoaddr:$dst)>; // data prefetch for loads +def : Pat<(prefetch xoaddr:$dst, (i32 1), imm, (i32 1)), + (DCBTST xoaddr:$dst)>; // data prefetch for stores +def : Pat<(prefetch xoaddr:$dst, (i32 0), imm, (i32 0)), + (ICBT 0, xoaddr:$dst)>; // inst prefetch (for read) // Atomic operations let usesCustomInserter = 1 in { @@ -1628,17 +1704,19 @@ def STMW : DForm_1<47, (outs), (ins gprc:$rS, memri:$dst), "stmw $rS, $dst", IIC_LdStLMW, []>; def SYNC : XForm_24_sync<31, 598, (outs), (ins i32imm:$L), - "sync $L", IIC_LdStSync, []>, Requires<[IsNotBookE]>; + "sync $L", IIC_LdStSync, []>; let isCodeGenOnly = 1 in { def MSYNC : XForm_24_sync<31, 598, (outs), (ins), - "msync", IIC_LdStSync, []>, Requires<[IsBookE]> { + "msync", IIC_LdStSync, []> { let L = 0; } } -def : Pat<(int_ppc_sync), (SYNC 0)>, Requires<[IsNotBookE]>; -def : Pat<(int_ppc_sync), (MSYNC)>, Requires<[IsBookE]>; +def : Pat<(int_ppc_sync), (SYNC 0)>, Requires<[HasSYNC]>; +def : Pat<(int_ppc_lwsync), (SYNC 1)>, Requires<[HasSYNC]>; +def : Pat<(int_ppc_sync), (MSYNC)>, Requires<[HasOnlyMSYNC]>; +def : Pat<(int_ppc_lwsync), (MSYNC)>, Requires<[HasOnlyMSYNC]>; //===----------------------------------------------------------------------===// // PPC32 Arithmetic Instructions. @@ -2355,6 +2433,8 @@ def : Pat<(PPCcall (i32 tglobaladdr:$dst)), def : Pat<(PPCcall (i32 texternalsym:$dst)), (BL texternalsym:$dst)>; +def : Pat<(PPCcall_tls texternalsym:$func, tglobaltlsaddr:$sym), + (BL_TLS texternalsym:$func, tglobaltlsaddr:$sym)>; def : Pat<(PPCtc_return (i32 tglobaladdr:$dst), imm:$imm), (TCRETURNdi tglobaladdr:$dst, imm:$imm)>; @@ -2393,13 +2473,47 @@ def : Pat<(add i32:$in, (PPChi tblockaddress:$g, 0)), def PPC32GOT: Pseudo<(outs gprc:$rD), (ins), "#PPC32GOT", [(set i32:$rD, (PPCppc32GOT))]>; +// Get the _GLOBAL_OFFSET_TABLE_ in PIC mode. +// This uses two output registers, the first as the real output, the second as a +// temporary register, used internally in code generation. +def PPC32PICGOT: Pseudo<(outs gprc:$rD, gprc:$rT), (ins), "#PPC32PICGOT", + []>, NoEncode<"$rT">; + def LDgotTprelL32: Pseudo<(outs gprc:$rD), (ins s16imm:$disp, gprc_nor0:$reg), - "#LDgotTprelL32", - [(set i32:$rD, - (PPCldGotTprelL tglobaltlsaddr:$disp, i32:$reg))]>; + "#LDgotTprelL32", + [(set i32:$rD, + (PPCldGotTprelL tglobaltlsaddr:$disp, i32:$reg))]>; def : Pat<(PPCaddTls i32:$in, tglobaltlsaddr:$g), (ADD4TLS $in, tglobaltlsaddr:$g)>; +def ADDItlsgdL32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp), + "#ADDItlsgdL32", + [(set i32:$rD, + (PPCaddiTlsgdL i32:$reg, tglobaltlsaddr:$disp))]>; +def ADDItlsldL32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp), + "#ADDItlsldL32", + [(set i32:$rD, + (PPCaddiTlsldL i32:$reg, tglobaltlsaddr:$disp))]>; +def ADDIdtprelL32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp), + "#ADDIdtprelL32", + [(set i32:$rD, + (PPCaddiDtprelL i32:$reg, tglobaltlsaddr:$disp))]>; +def ADDISdtprelHA32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp), + "#ADDISdtprelHA32", + [(set i32:$rD, + (PPCaddisDtprelHA i32:$reg, + tglobaltlsaddr:$disp))]>; + +// Support for Position-independent code +def LWZtoc : Pseudo<(outs gprc:$rD), (ins tocentry32:$disp, gprc:$reg), + "#LWZtoc", + [(set i32:$rD, + (PPCtoc_entry tglobaladdr:$disp, i32:$reg))]>; +// Get Global (GOT) Base Register offset, from the word immediately preceding +// the function label. +def UpdateGBR : Pseudo<(outs gprc:$rD, gprc:$rT), (ins gprc:$rI), "#UpdateGBR", []>; + + // Standard shifts. These are represented separately from the real shifts above // so that we can distinguish between shifts that allow 5-bit and 6-bit shift // amounts. @@ -2434,8 +2548,15 @@ def : Pat<(f64 (extloadf32 xaddr:$src)), def : Pat<(f64 (fextend f32:$src)), (COPY_TO_REGCLASS $src, F8RC)>; -def : Pat<(atomic_fence (imm), (imm)), (SYNC 0)>, Requires<[IsNotBookE]>; -def : Pat<(atomic_fence (imm), (imm)), (MSYNC)>, Requires<[IsBookE]>; +// Only seq_cst fences require the heavyweight sync (SYNC 0). +// All others can use the lightweight sync (SYNC 1). +// source: http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html +// The rule for seq_cst is duplicated to work with both 64 bits and 32 bits +// versions of Power. +def : Pat<(atomic_fence (i64 7), (imm)), (SYNC 0)>, Requires<[HasSYNC]>; +def : Pat<(atomic_fence (i32 7), (imm)), (SYNC 0)>, Requires<[HasSYNC]>; +def : Pat<(atomic_fence (imm), (imm)), (SYNC 1)>, Requires<[HasSYNC]>; +def : Pat<(atomic_fence (imm), (imm)), (MSYNC)>, Requires<[HasOnlyMSYNC]>; // Additional FNMSUB patterns: -a*c + b == -(a*c - b) def : Pat<(fma (fneg f64:$A), f64:$C, f64:$B), @@ -2454,6 +2575,7 @@ def : Pat<(fcopysign f32:$frB, f64:$frA), (FCPSGNS (COPY_TO_REGCLASS $frA, F4RC), $frB)>; include "PPCInstrAltivec.td" +include "PPCInstrSPE.td" include "PPCInstr64Bit.td" include "PPCInstrVSX.td" @@ -2970,6 +3092,16 @@ def : Pat<(i1 (not (trunc i64:$in))), // PowerPC Instructions used for assembler/disassembler only // +// 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, []>; + +// 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 ISYNC : XLForm_2_ext<19, 150, 0, 0, 0, (outs), (ins), "isync", IIC_SprISYNC, []>; @@ -2982,9 +3114,47 @@ def EIEIO : XForm_24_eieio<31, 854, (outs), (ins), def WAIT : XForm_24_sync<31, 62, (outs), (ins i32imm:$L), "wait $L", IIC_LdStLoad, []>; +def MBAR : XForm_mbar<31, 854, (outs), (ins u5imm:$MO), + "mbar $MO", IIC_LdStLoad>, Requires<[IsBookE]>; + +def MTSR: XForm_sr<31, 210, (outs), (ins gprc:$RS, u4imm:$SR), + "mtsr $SR, $RS", IIC_SprMTSR>; + +def MFSR: XForm_sr<31, 595, (outs gprc:$RS), (ins u4imm:$SR), + "mfsr $RS, $SR", IIC_SprMFSR>; + +def MTSRIN: XForm_srin<31, 242, (outs), (ins gprc:$RS, gprc:$RB), + "mtsrin $RS, $RB", IIC_SprMTSR>; + +def MFSRIN: XForm_srin<31, 659, (outs gprc:$RS), (ins gprc:$RB), + "mfsrin $RS, $RB", IIC_SprMFSR>; + def MTMSR: XForm_mtmsr<31, 146, (outs), (ins gprc:$RS, i32imm:$L), "mtmsr $RS, $L", IIC_SprMTMSR>; +def WRTEE: XForm_mtmsr<31, 131, (outs), (ins gprc:$RS), + "wrtee $RS", IIC_SprMTMSR>, Requires<[IsBookE]> { + let L = 0; +} + +def WRTEEI: I<31, (outs), (ins i1imm:$E), "wrteei $E", IIC_SprMTMSR>, + Requires<[IsBookE]> { + bits<1> E; + + let Inst{16} = E; + let Inst{21-30} = 163; +} + +def DCCCI : XForm_tlb<454, (outs), (ins gprc:$A, gprc:$B), + "dccci $A, $B", IIC_LdStLoad>, Requires<[IsPPC4xx]>; +def ICCCI : XForm_tlb<966, (outs), (ins gprc:$A, gprc:$B), + "iccci $A, $B", IIC_LdStLoad>, Requires<[IsPPC4xx]>; + +def : InstAlias<"dci 0", (DCCCI R0, R0)>, Requires<[IsPPC4xx]>; +def : InstAlias<"dccci", (DCCCI R0, R0)>, Requires<[IsPPC4xx]>; +def : InstAlias<"ici 0", (ICCCI R0, R0)>, Requires<[IsPPC4xx]>; +def : InstAlias<"iccci", (ICCCI R0, R0)>, Requires<[IsPPC4xx]>; + def MFMSR : XForm_rs<31, 83, (outs gprc:$RT), (ins), "mfmsr $RT", IIC_SprMFMSR, []>; @@ -3002,15 +3172,66 @@ def SLBMFEE : XForm_26<31, 915, (outs gprc:$RT), (ins gprc:$RB), def SLBIA : XForm_0<31, 498, (outs), (ins), "slbia", IIC_SprSLBIA, []>; +def TLBIA : XForm_0<31, 370, (outs), (ins), + "tlbia", IIC_SprTLBIA, []>; + def TLBSYNC : XForm_0<31, 566, (outs), (ins), "tlbsync", IIC_SprTLBSYNC, []>; def TLBIEL : XForm_16b<31, 274, (outs), (ins gprc:$RB), "tlbiel $RB", IIC_SprTLBIEL, []>; +def TLBLD : XForm_16b<31, 978, (outs), (ins gprc:$RB), + "tlbld $RB", IIC_LdStLoad, []>, Requires<[IsPPC6xx]>; +def TLBLI : XForm_16b<31, 1010, (outs), (ins gprc:$RB), + "tlbli $RB", IIC_LdStLoad, []>, Requires<[IsPPC6xx]>; + def TLBIE : XForm_26<31, 306, (outs), (ins gprc:$RS, gprc:$RB), "tlbie $RB,$RS", IIC_SprTLBIE, []>; +def TLBSX : XForm_tlb<914, (outs), (ins gprc:$A, gprc:$B), "tlbsx $A, $B", + IIC_LdStLoad>, Requires<[IsBookE]>; + +def TLBIVAX : XForm_tlb<786, (outs), (ins gprc:$A, gprc:$B), "tlbivax $A, $B", + IIC_LdStLoad>, Requires<[IsBookE]>; + +def TLBRE : XForm_24_eieio<31, 946, (outs), (ins), + "tlbre", IIC_LdStLoad, []>, Requires<[IsBookE]>; + +def TLBWE : XForm_24_eieio<31, 978, (outs), (ins), + "tlbwe", IIC_LdStLoad, []>, Requires<[IsBookE]>; + +def TLBRE2 : XForm_tlbws<31, 946, (outs gprc:$RS), (ins gprc:$A, i1imm:$WS), + "tlbre $RS, $A, $WS", IIC_LdStLoad, []>, Requires<[IsPPC4xx]>; + +def TLBWE2 : XForm_tlbws<31, 978, (outs), (ins gprc:$RS, gprc:$A, i1imm:$WS), + "tlbwe $RS, $A, $WS", IIC_LdStLoad, []>, Requires<[IsPPC4xx]>; + +def TLBSX2 : XForm_base_r3xo<31, 914, (outs), (ins gprc:$RST, gprc:$A, gprc:$B), + "tlbsx $RST, $A, $B", IIC_LdStLoad, []>, + Requires<[IsPPC4xx]>; +def TLBSX2D : XForm_base_r3xo<31, 914, (outs), + (ins gprc:$RST, gprc:$A, gprc:$B), + "tlbsx. $RST, $A, $B", IIC_LdStLoad, []>, + Requires<[IsPPC4xx]>, isDOT; + +def RFID : XForm_0<19, 18, (outs), (ins), "rfid", IIC_IntRFID, []>; + +def RFI : XForm_0<19, 50, (outs), (ins), "rfi", IIC_SprRFI, []>, + Requires<[IsBookE]>; +def RFCI : XForm_0<19, 51, (outs), (ins), "rfci", IIC_BrB, []>, + Requires<[IsBookE]>; + +def RFDI : XForm_0<19, 39, (outs), (ins), "rfdi", IIC_BrB, []>, + Requires<[IsE500]>; +def RFMCI : XForm_0<19, 38, (outs), (ins), "rfmci", IIC_BrB, []>, + Requires<[IsE500]>; + +def MFDCR : XFXForm_1<31, 323, (outs gprc:$RT), (ins i32imm:$SPR), + "mfdcr $RT, $SPR", IIC_SprMFSPR>, Requires<[IsPPC4xx]>; +def MTDCR : XFXForm_1<31, 451, (outs), (ins gprc:$RT, i32imm:$SPR), + "mtdcr $SPR, $RT", IIC_SprMTSPR>, Requires<[IsPPC4xx]>; + //===----------------------------------------------------------------------===// // PowerPC Assembler Instruction Aliases // @@ -3033,15 +3254,17 @@ class PPCAsmPseudo<string asm, dag iops> def : InstAlias<"sc", (SC 0)>; -def : InstAlias<"sync", (SYNC 0)>, Requires<[IsNotBookE]>; -def : InstAlias<"msync", (SYNC 0)>, Requires<[IsNotBookE]>; -def : InstAlias<"lwsync", (SYNC 1)>, Requires<[IsNotBookE]>; -def : InstAlias<"ptesync", (SYNC 2)>, Requires<[IsNotBookE]>; +def : InstAlias<"sync", (SYNC 0)>, Requires<[HasSYNC]>; +def : InstAlias<"msync", (SYNC 0)>, Requires<[HasSYNC]>; +def : InstAlias<"lwsync", (SYNC 1)>, Requires<[HasSYNC]>; +def : InstAlias<"ptesync", (SYNC 2)>, Requires<[HasSYNC]>; def : InstAlias<"wait", (WAIT 0)>; def : InstAlias<"waitrsv", (WAIT 1)>; def : InstAlias<"waitimpl", (WAIT 2)>; +def : InstAlias<"mbar", (MBAR 0)>, Requires<[IsBookE]>; + 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)>; @@ -3050,9 +3273,57 @@ def : InstAlias<"crnot $bx, $by", (CRNOR crbitrc:$bx, crbitrc:$by, crbitrc:$by)> def : InstAlias<"mtxer $Rx", (MTSPR 1, gprc:$Rx)>; def : InstAlias<"mfxer $Rx", (MFSPR gprc:$Rx, 1)>; +def : InstAlias<"mfrtcu $Rx", (MFSPR gprc:$Rx, 4)>; +def : InstAlias<"mfrtcl $Rx", (MFSPR gprc:$Rx, 5)>; + +def : InstAlias<"mtdscr $Rx", (MTSPR 17, gprc:$Rx)>; +def : InstAlias<"mfdscr $Rx", (MFSPR gprc:$Rx, 17)>; + +def : InstAlias<"mtdsisr $Rx", (MTSPR 18, gprc:$Rx)>; +def : InstAlias<"mfdsisr $Rx", (MFSPR gprc:$Rx, 18)>; + +def : InstAlias<"mtdar $Rx", (MTSPR 19, gprc:$Rx)>; +def : InstAlias<"mfdar $Rx", (MFSPR gprc:$Rx, 19)>; + +def : InstAlias<"mtdec $Rx", (MTSPR 22, gprc:$Rx)>; +def : InstAlias<"mfdec $Rx", (MFSPR gprc:$Rx, 22)>; + +def : InstAlias<"mtsdr1 $Rx", (MTSPR 25, gprc:$Rx)>; +def : InstAlias<"mfsdr1 $Rx", (MFSPR gprc:$Rx, 25)>; + +def : InstAlias<"mtsrr0 $Rx", (MTSPR 26, gprc:$Rx)>; +def : InstAlias<"mfsrr0 $Rx", (MFSPR gprc:$Rx, 26)>; + +def : InstAlias<"mtsrr1 $Rx", (MTSPR 27, gprc:$Rx)>; +def : InstAlias<"mfsrr1 $Rx", (MFSPR gprc:$Rx, 27)>; + +def : InstAlias<"mtsrr2 $Rx", (MTSPR 990, gprc:$Rx)>, Requires<[IsPPC4xx]>; +def : InstAlias<"mfsrr2 $Rx", (MFSPR gprc:$Rx, 990)>, Requires<[IsPPC4xx]>; + +def : InstAlias<"mtsrr3 $Rx", (MTSPR 991, gprc:$Rx)>, Requires<[IsPPC4xx]>; +def : InstAlias<"mfsrr3 $Rx", (MFSPR gprc:$Rx, 991)>, Requires<[IsPPC4xx]>; + +def : InstAlias<"mtcfar $Rx", (MTSPR 28, gprc:$Rx)>; +def : InstAlias<"mfcfar $Rx", (MFSPR gprc:$Rx, 28)>; + +def : InstAlias<"mtamr $Rx", (MTSPR 29, gprc:$Rx)>; +def : InstAlias<"mfamr $Rx", (MFSPR gprc:$Rx, 29)>; + +def : InstAlias<"mtpid $Rx", (MTSPR 48, gprc:$Rx)>, Requires<[IsBookE]>; +def : InstAlias<"mfpid $Rx", (MFSPR gprc:$Rx, 48)>, Requires<[IsBookE]>; + def : InstAlias<"mftb $Rx", (MFTB gprc:$Rx, 268)>; +def : InstAlias<"mftbl $Rx", (MFTB gprc:$Rx, 268)>; def : InstAlias<"mftbu $Rx", (MFTB gprc:$Rx, 269)>; +def : InstAlias<"mttbl $Rx", (MTSPR 284, gprc:$Rx)>; +def : InstAlias<"mttbu $Rx", (MTSPR 285, gprc:$Rx)>; + +def : InstAlias<"mftblo $Rx", (MFSPR gprc:$Rx, 989)>, Requires<[IsPPC4xx]>; +def : InstAlias<"mttblo $Rx", (MTSPR 989, gprc:$Rx)>, Requires<[IsPPC4xx]>; +def : InstAlias<"mftbhi $Rx", (MFSPR gprc:$Rx, 988)>, Requires<[IsPPC4xx]>; +def : InstAlias<"mttbhi $Rx", (MTSPR 988, gprc:$Rx)>, Requires<[IsPPC4xx]>; + def : InstAlias<"xnop", (XORI R0, R0, 0)>; def : InstAlias<"mr $rA, $rB", (OR8 g8rc:$rA, g8rc:$rB, g8rc:$rB)>; @@ -3063,6 +3334,60 @@ def : InstAlias<"not. $rA, $rB", (NOR8o g8rc:$rA, g8rc:$rB, g8rc:$rB)>; def : InstAlias<"mtcr $rA", (MTCRF8 255, g8rc:$rA)>; +foreach BATR = 0-3 in { + def : InstAlias<"mtdbatu "#BATR#", $Rx", + (MTSPR !add(BATR, !add(BATR, 536)), gprc:$Rx)>, + Requires<[IsPPC6xx]>; + def : InstAlias<"mfdbatu $Rx, "#BATR, + (MFSPR gprc:$Rx, !add(BATR, !add(BATR, 536)))>, + Requires<[IsPPC6xx]>; + def : InstAlias<"mtdbatl "#BATR#", $Rx", + (MTSPR !add(BATR, !add(BATR, 537)), gprc:$Rx)>, + Requires<[IsPPC6xx]>; + def : InstAlias<"mfdbatl $Rx, "#BATR, + (MFSPR gprc:$Rx, !add(BATR, !add(BATR, 537)))>, + Requires<[IsPPC6xx]>; + def : InstAlias<"mtibatu "#BATR#", $Rx", + (MTSPR !add(BATR, !add(BATR, 528)), gprc:$Rx)>, + Requires<[IsPPC6xx]>; + def : InstAlias<"mfibatu $Rx, "#BATR, + (MFSPR gprc:$Rx, !add(BATR, !add(BATR, 528)))>, + Requires<[IsPPC6xx]>; + def : InstAlias<"mtibatl "#BATR#", $Rx", + (MTSPR !add(BATR, !add(BATR, 529)), gprc:$Rx)>, + Requires<[IsPPC6xx]>; + def : InstAlias<"mfibatl $Rx, "#BATR, + (MFSPR gprc:$Rx, !add(BATR, !add(BATR, 529)))>, + Requires<[IsPPC6xx]>; +} + +foreach BR = 0-7 in { + def : InstAlias<"mfbr"#BR#" $Rx", + (MFDCR gprc:$Rx, !add(BR, 0x80))>, + Requires<[IsPPC4xx]>; + def : InstAlias<"mtbr"#BR#" $Rx", + (MTDCR gprc:$Rx, !add(BR, 0x80))>, + Requires<[IsPPC4xx]>; +} + +def : InstAlias<"mtdccr $Rx", (MTSPR 1018, gprc:$Rx)>, Requires<[IsPPC4xx]>; +def : InstAlias<"mfdccr $Rx", (MFSPR gprc:$Rx, 1018)>, Requires<[IsPPC4xx]>; + +def : InstAlias<"mticcr $Rx", (MTSPR 1019, gprc:$Rx)>, Requires<[IsPPC4xx]>; +def : InstAlias<"mficcr $Rx", (MFSPR gprc:$Rx, 1019)>, Requires<[IsPPC4xx]>; + +def : InstAlias<"mtdear $Rx", (MTSPR 981, gprc:$Rx)>, Requires<[IsPPC4xx]>; +def : InstAlias<"mfdear $Rx", (MFSPR gprc:$Rx, 981)>, Requires<[IsPPC4xx]>; + +def : InstAlias<"mtesr $Rx", (MTSPR 980, gprc:$Rx)>, Requires<[IsPPC4xx]>; +def : InstAlias<"mfesr $Rx", (MFSPR gprc:$Rx, 980)>, Requires<[IsPPC4xx]>; + +def : InstAlias<"mfspefscr $Rx", (MFSPR gprc:$Rx, 512)>; +def : InstAlias<"mtspefscr $Rx", (MTSPR 512, gprc:$Rx)>; + +def : InstAlias<"mttcr $Rx", (MTSPR 986, gprc:$Rx)>, Requires<[IsPPC4xx]>; +def : InstAlias<"mftcr $Rx", (MFSPR gprc:$Rx, 986)>, Requires<[IsPPC4xx]>; + def LAx : PPCAsmPseudo<"la $rA, $addr", (ins gprc:$rA, memri:$addr)>; def SUBI : PPCAsmPseudo<"subi $rA, $rB, $imm", @@ -3082,25 +3407,25 @@ def : InstAlias<"subc. $rA, $rB, $rC", (SUBFC8o g8rc:$rA, g8rc:$rC, g8rc:$rB)>; def : InstAlias<"mtmsrd $RS", (MTMSRD gprc:$RS, 0)>; def : InstAlias<"mtmsr $RS", (MTMSR gprc:$RS, 0)>; -def : InstAlias<"mfsprg $RT, 0", (MFSPR gprc:$RT, 272)>; -def : InstAlias<"mfsprg $RT, 1", (MFSPR gprc:$RT, 273)>; -def : InstAlias<"mfsprg $RT, 2", (MFSPR gprc:$RT, 274)>; -def : InstAlias<"mfsprg $RT, 3", (MFSPR gprc:$RT, 275)>; - -def : InstAlias<"mfsprg0 $RT", (MFSPR gprc:$RT, 272)>; -def : InstAlias<"mfsprg1 $RT", (MFSPR gprc:$RT, 273)>; -def : InstAlias<"mfsprg2 $RT", (MFSPR gprc:$RT, 274)>; -def : InstAlias<"mfsprg3 $RT", (MFSPR gprc:$RT, 275)>; +def : InstAlias<"mfasr $RT", (MFSPR gprc:$RT, 280)>; +def : InstAlias<"mtasr $RT", (MTSPR 280, gprc:$RT)>; -def : InstAlias<"mtsprg 0, $RT", (MTSPR 272, gprc:$RT)>; -def : InstAlias<"mtsprg 1, $RT", (MTSPR 273, gprc:$RT)>; -def : InstAlias<"mtsprg 2, $RT", (MTSPR 274, gprc:$RT)>; -def : InstAlias<"mtsprg 3, $RT", (MTSPR 275, gprc:$RT)>; - -def : InstAlias<"mtsprg0 $RT", (MTSPR 272, gprc:$RT)>; -def : InstAlias<"mtsprg1 $RT", (MTSPR 273, gprc:$RT)>; -def : InstAlias<"mtsprg2 $RT", (MTSPR 274, gprc:$RT)>; -def : InstAlias<"mtsprg3 $RT", (MTSPR 275, gprc:$RT)>; +foreach SPRG = 0-3 in { + def : InstAlias<"mfsprg $RT, "#SPRG, (MFSPR gprc:$RT, !add(SPRG, 272))>; + def : InstAlias<"mfsprg"#SPRG#" $RT", (MFSPR gprc:$RT, !add(SPRG, 272))>; + def : InstAlias<"mtsprg "#SPRG#", $RT", (MTSPR !add(SPRG, 272), gprc:$RT)>; + def : InstAlias<"mtsprg"#SPRG#" $RT", (MTSPR !add(SPRG, 272), gprc:$RT)>; +} +foreach SPRG = 4-7 in { + def : InstAlias<"mfsprg $RT, "#SPRG, (MFSPR gprc:$RT, !add(SPRG, 256))>, + Requires<[IsBookE]>; + def : InstAlias<"mfsprg"#SPRG#" $RT", (MFSPR gprc:$RT, !add(SPRG, 256))>, + Requires<[IsBookE]>; + def : InstAlias<"mtsprg "#SPRG#", $RT", (MTSPR !add(SPRG, 256), gprc:$RT)>, + Requires<[IsBookE]>; + def : InstAlias<"mtsprg"#SPRG#" $RT", (MTSPR !add(SPRG, 256), gprc:$RT)>, + Requires<[IsBookE]>; +} def : InstAlias<"mtasr $RS", (MTSPR 280, gprc:$RS)>; @@ -3119,6 +3444,15 @@ def : InstAlias<"mtsrr1 $RT", (MTSPR 27, gprc:$RT)>; def : InstAlias<"tlbie $RB", (TLBIE R0, gprc:$RB)>; +def : InstAlias<"tlbrehi $RS, $A", (TLBRE2 gprc:$RS, gprc:$A, 0)>, + Requires<[IsPPC4xx]>; +def : InstAlias<"tlbrelo $RS, $A", (TLBRE2 gprc:$RS, gprc:$A, 1)>, + Requires<[IsPPC4xx]>; +def : InstAlias<"tlbwehi $RS, $A", (TLBWE2 gprc:$RS, gprc:$A, 0)>, + Requires<[IsPPC4xx]>; +def : InstAlias<"tlbwelo $RS, $A", (TLBWE2 gprc:$RS, gprc:$A, 1)>, + Requires<[IsPPC4xx]>; + def EXTLWI : PPCAsmPseudo<"extlwi $rA, $rS, $n, $b", (ins gprc:$rA, gprc:$rS, u5imm:$n, u5imm:$b)>; def EXTLWIo : PPCAsmPseudo<"extlwi. $rA, $rS, $n, $b", @@ -3367,3 +3701,18 @@ defm : TrapExtendedMnemonic<"lnl", 5>; defm : TrapExtendedMnemonic<"lng", 6>; defm : TrapExtendedMnemonic<"u", 31>; +// Atomic loads +def : Pat<(atomic_load_8 iaddr:$src), (LBZ memri:$src)>; +def : Pat<(atomic_load_16 iaddr:$src), (LHZ memri:$src)>; +def : Pat<(atomic_load_32 iaddr:$src), (LWZ memri:$src)>; +def : Pat<(atomic_load_8 xaddr:$src), (LBZX memrr:$src)>; +def : Pat<(atomic_load_16 xaddr:$src), (LHZX memrr:$src)>; +def : Pat<(atomic_load_32 xaddr:$src), (LWZX memrr:$src)>; + +// Atomic stores +def : Pat<(atomic_store_8 iaddr:$ptr, i32:$val), (STB gprc:$val, memri:$ptr)>; +def : Pat<(atomic_store_16 iaddr:$ptr, i32:$val), (STH gprc:$val, memri:$ptr)>; +def : Pat<(atomic_store_32 iaddr:$ptr, i32:$val), (STW gprc:$val, memri:$ptr)>; +def : Pat<(atomic_store_8 xaddr:$ptr, i32:$val), (STBX gprc:$val, memrr:$ptr)>; +def : Pat<(atomic_store_16 xaddr:$ptr, i32:$val), (STHX gprc:$val, memrr:$ptr)>; +def : Pat<(atomic_store_32 xaddr:$ptr, i32:$val), (STWX gprc:$val, memrr:$ptr)>; |