Add RETGUARD implementation for powerpc and powerpc64. Index: lib/Target/PowerPC/PPCInstrInfo.td --- lib/Target/PowerPC/PPCInstrInfo.td.orig +++ lib/Target/PowerPC/PPCInstrInfo.td @@ -1690,6 +1690,31 @@ let Defs = [LR] in def MoveGOTtoLR : PPCEmitTimePseudo<(outs), (ins), "#MoveGOTtoLR", []>, PPC970_Unit_BRU; +// Pseudo instruction used by retguard. +// +// We need to get the PC into a register in order to calculate the address of +// the retguard cookies. This pseudo will branch immediately forward to get PC +// in LR, and then move LR into the destination register. The current value of +// LR is saved and restored via the given temp register, which is trashed. +let Size = 16 in { +def RETGUARD_LOAD_PC : PPCEmitTimePseudo<(outs gprc:$dest), (ins gprc:$tmp), + "#RGLoadPC", []>; +} + +// Once we have the PC in a register, we need to load the address of the GOT +// into another register so we can then finally load the local offset of the +// retguard symbol entry from the GOT and then the cookie value. +let Size = 8 in { +def RETGUARD_LOAD_GOT : PPCEmitTimePseudo<(outs gprc:$dest), + (ins gprc:$pc, calltarget:$sym), "RGLoadGOT", []>; +} + +let Size = 8 in { +// For static linkage, we can load the cookie directly +def RETGUARD_LOAD_COOKIE : PPCEmitTimePseudo<(outs gprc:$dest), + (ins calltarget:$sym), "RGLoadCookie", []>; +} + let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in { let isBarrier = 1 in { let isPredicable = 1 in