Skip to content

Commit 16fe741

Browse files
Stefan Pintiliestefanp-synopsys
authored andcommitted
[PowerPC] Add ROP Protection Instructions for PowerPC
There are four new PowerPC instructions that are introduced in Power 10. They are hashst, hashchk, hashstp, hashchkp. These instructions will be used for ROP Protection. This patch adds the four instructions. Reviewed By: nemanjai, amyk, #powerpc Differential Revision: https://reviews.llvm.org/D99375
1 parent 206343f commit 16fe741

File tree

12 files changed

+185
-0
lines changed

12 files changed

+185
-0
lines changed

llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,15 @@ struct PPCOperand : public MCParsedAsmOperand {
359359
bool isS16ImmX4() const { return Kind == Expression ||
360360
(Kind == Immediate && isInt<16>(getImm()) &&
361361
(getImm() & 3) == 0); }
362+
363+
bool isHashImmX8() const {
364+
// The Hash Imm form is used for instructions that check or store a hash.
365+
// These instructions have a small immediate range that spans between
366+
// -8 and -512.
367+
return (Kind == Immediate && getImm() <= -8 && getImm() >= -512 &&
368+
(getImm() & 7) == 0);
369+
}
370+
362371
bool isS16ImmX16() const { return Kind == Expression ||
363372
(Kind == Immediate && isInt<16>(getImm()) &&
364373
(getImm() & 15) == 0); }

llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,23 @@ static DecodeStatus decodeMemRIXOperands(MCInst &Inst, uint64_t Imm,
279279
return MCDisassembler::Success;
280280
}
281281

282+
static DecodeStatus decodeMemRIHashOperands(MCInst &Inst, uint64_t Imm,
283+
int64_t Address,
284+
const void *Decoder) {
285+
// Decode the memrix field for a hash store or hash check operation.
286+
// The field is composed of a register and an immediate value that is 6 bits
287+
// and covers the range -8 to -512. The immediate is always negative and 2s
288+
// complement which is why we sign extend a 7 bit value.
289+
const uint64_t Base = Imm >> 6;
290+
const uint64_t Disp = SignExtend64<7>((Imm & 0x3F) + 64) << 3;
291+
292+
assert(Base < 32 && "Invalid base register");
293+
294+
Inst.addOperand(MCOperand::createImm(Disp));
295+
Inst.addOperand(MCOperand::createReg(RRegs[Base]));
296+
return MCDisassembler::Success;
297+
}
298+
282299
static DecodeStatus decodeMemRIX16Operands(MCInst &Inst, uint64_t Imm,
283300
int64_t Address, const void *Decoder) {
284301
// Decode the memrix16 field (imm, reg), which has the low 12-bits as the

llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,15 @@ void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
514514
O << ')';
515515
}
516516

517+
void PPCInstPrinter::printMemRegImmHash(const MCInst *MI, unsigned OpNo,
518+
const MCSubtargetInfo &STI,
519+
raw_ostream &O) {
520+
O << MI->getOperand(OpNo).getImm();
521+
O << '(';
522+
printOperand(MI, OpNo + 1, STI, O);
523+
O << ')';
524+
}
525+
517526
void PPCInstPrinter::printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo,
518527
const MCSubtargetInfo &STI,
519528
raw_ostream &O) {

llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ class PPCInstPrinter : public MCInstPrinter {
9797

9898
void printMemRegImm(const MCInst *MI, unsigned OpNo,
9999
const MCSubtargetInfo &STI, raw_ostream &O);
100+
void printMemRegImmHash(const MCInst *MI, unsigned OpNo,
101+
const MCSubtargetInfo &STI, raw_ostream &O);
100102
void printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo,
101103
const MCSubtargetInfo &STI, raw_ostream &O);
102104
void printMemRegImm34(const MCInst *MI, unsigned OpNo,

llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,24 @@ unsigned PPCMCCodeEmitter::getMemRIX16Encoding(const MCInst &MI, unsigned OpNo,
203203
return RegBits;
204204
}
205205

206+
unsigned
207+
PPCMCCodeEmitter::getMemRIHashEncoding(const MCInst &MI, unsigned OpNo,
208+
SmallVectorImpl<MCFixup> &Fixups,
209+
const MCSubtargetInfo &STI) const {
210+
// Encode (imm, reg) for the hash load/store to stack for the ROP Protection
211+
// instructions.
212+
const MCOperand &RegMO = MI.getOperand(OpNo + 1);
213+
const MCOperand &MO = MI.getOperand(OpNo);
214+
215+
assert(RegMO.isReg() && "Base address must be a register.");
216+
assert(MO.isImm() && "Expecting an immediate operand.");
217+
assert(!(MO.getImm() % 8) && "Expecting offset to be 8 byte aligned.");
218+
219+
unsigned RegBits = getMachineOpValue(MI, RegMO, Fixups, STI) << 6;
220+
unsigned DX = (MO.getImm() >> 3) & 0x3F;
221+
return RegBits | DX;
222+
}
223+
206224
uint64_t
207225
PPCMCCodeEmitter::getMemRI34PCRelEncoding(const MCInst &MI, unsigned OpNo,
208226
SmallVectorImpl<MCFixup> &Fixups,

llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ class PPCMCCodeEmitter : public MCCodeEmitter {
6969
unsigned getMemRIX16Encoding(const MCInst &MI, unsigned OpNo,
7070
SmallVectorImpl<MCFixup> &Fixups,
7171
const MCSubtargetInfo &STI) const;
72+
unsigned getMemRIHashEncoding(const MCInst &MI, unsigned OpNo,
73+
SmallVectorImpl<MCFixup> &Fixups,
74+
const MCSubtargetInfo &STI) const;
7275
uint64_t getMemRI34PCRelEncoding(const MCInst &MI, unsigned OpNo,
7376
SmallVectorImpl<MCFixup> &Fixups,
7477
const MCSubtargetInfo &STI) const;

llvm/lib/Target/PowerPC/P9InstrResources.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,7 @@ def : InstRW<[],
14091409
(instregex "NOP_GT_PWR(6|7)$"),
14101410
(instregex "TLB(IA|IVAX|SX|SX2|SX2D|LD|LI|RE|RE2|WE|WE2)$"),
14111411
(instregex "WRTEE(I)?$"),
1412+
(instregex "HASH(ST|STP|CHK|CHKP)$"),
14121413
ATTN,
14131414
CLRBHRB,
14141415
MFBHRBE,

llvm/lib/Target/PowerPC/PPCInstr64Bit.td

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,29 @@ defm FCTIWUZ : XForm_26r<63, 143, (outs f8rc:$frD), (ins f8rc:$frB),
15211521
[(set f64:$frD, (PPCany_fctiwuz f64:$frB))]>, isPPC64;
15221522
}
15231523

1524+
// These instructions store a hash computed from the value of the link register
1525+
// and the value of the stack pointer.
1526+
let mayStore = 1 in {
1527+
def HASHST : XForm_XD6_RA5_RB5<31, 722, (outs),
1528+
(ins g8rc:$RB, memrihash:$D_RA_XD),
1529+
"hashst $RB, $D_RA_XD", IIC_IntGeneral, []>;
1530+
def HASHSTP : XForm_XD6_RA5_RB5<31, 658, (outs),
1531+
(ins g8rc:$RB, memrihash:$D_RA_XD),
1532+
"hashstp $RB, $D_RA_XD", IIC_IntGeneral, []>;
1533+
}
1534+
1535+
// These instructions check a hash computed from the value of the link register
1536+
// and the value of the stack pointer. The hasSideEffects flag is needed as the
1537+
// instruction may TRAP if the hash does not match the hash stored at the
1538+
// specified address.
1539+
let mayLoad = 1, hasSideEffects = 1 in {
1540+
def HASHCHK : XForm_XD6_RA5_RB5<31, 754, (outs),
1541+
(ins g8rc:$RB, memrihash:$D_RA_XD),
1542+
"hashchk $RB, $D_RA_XD", IIC_IntGeneral, []>;
1543+
def HASHCHKP : XForm_XD6_RA5_RB5<31, 690, (outs),
1544+
(ins g8rc:$RB, memrihash:$D_RA_XD),
1545+
"hashchkp $RB, $D_RA_XD", IIC_IntGeneral, []>;
1546+
}
15241547

15251548
//===----------------------------------------------------------------------===//
15261549
// Instruction Patterns

llvm/lib/Target/PowerPC/PPCInstrFormats.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,21 @@ class XX2_RD6_DCMX7_RS6<bits<6> opcode, bits<4> xo1, bits<3> xo2,
11951195
let Inst{31} = XT{5};
11961196
}
11971197

1198+
class XForm_XD6_RA5_RB5<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
1199+
string asmstr, InstrItinClass itin, list<dag> pattern>
1200+
: I<opcode, OOL, IOL, asmstr, itin> {
1201+
bits<11> D_RA_XD;
1202+
bits<5> RB;
1203+
1204+
let Pattern = pattern;
1205+
1206+
let Inst{6-10} = D_RA_XD{4-0}; // D
1207+
let Inst{11-15} = D_RA_XD{10-6}; // RA
1208+
let Inst{16-20} = RB;
1209+
let Inst{21-30} = xo;
1210+
let Inst{31} = D_RA_XD{5}; // DX
1211+
}
1212+
11981213
class XX3Form<bits<6> opcode, bits<8> xo, dag OOL, dag IOL, string asmstr,
11991214
InstrItinClass itin, list<dag> pattern>
12001215
: I<opcode, OOL, IOL, asmstr, itin> {

llvm/lib/Target/PowerPC/PPCInstrInfo.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,13 @@ def PPCDispRIXOperand : AsmOperandClass {
991991
def dispRIX : Operand<iPTR> {
992992
let ParserMatchClass = PPCDispRIXOperand;
993993
}
994+
def PPCDispRIHashOperand : AsmOperandClass {
995+
let Name = "DispRIHash"; let PredicateMethod = "isHashImmX8";
996+
let RenderMethod = "addImmOperands";
997+
}
998+
def dispRIHash : Operand<iPTR> {
999+
let ParserMatchClass = PPCDispRIHashOperand;
1000+
}
9941001
def PPCDispRIX16Operand : AsmOperandClass {
9951002
let Name = "DispRIX16"; let PredicateMethod = "isS16ImmX16";
9961003
let RenderMethod = "addImmOperands";
@@ -1039,6 +1046,14 @@ def memrix : Operand<iPTR> { // memri where the imm is 4-aligned.
10391046
let DecoderMethod = "decodeMemRIXOperands";
10401047
let OperandType = "OPERAND_MEMORY";
10411048
}
1049+
def memrihash : Operand<iPTR> {
1050+
// memrihash 8-aligned for ROP Protection Instructions.
1051+
let PrintMethod = "printMemRegImmHash";
1052+
let MIOperandInfo = (ops dispRIHash:$imm, ptr_rc_nor0:$reg);
1053+
let EncoderMethod = "getMemRIHashEncoding";
1054+
let DecoderMethod = "decodeMemRIHashOperands";
1055+
let OperandType = "OPERAND_MEMORY";
1056+
}
10421057
def memrix16 : Operand<iPTR> { // memri, imm is 16-aligned, 12-bit, Inst{16:27}
10431058
let PrintMethod = "printMemRegImm";
10441059
let MIOperandInfo = (ops dispRIX16:$imm, ptr_rc_nor0:$reg);

llvm/test/MC/Disassembler/PowerPC/ppc64-encoding-ISA31.txt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,3 +767,40 @@
767767

768768
# CHECK: xvcvbf16spn 33, 34
769769
0xf0 0x30 0x17 0x6f
770+
771+
# CHECK: hashst 5, -8(1)
772+
0x7f 0xe1 0x2d 0xa5
773+
774+
# CHECK: hashst 0, -8(30)
775+
0x7f 0xfe 0x05 0xa5
776+
777+
# CHECK: hashst 5, -512(1)
778+
0x7c 0x01 0x2d 0xa4
779+
780+
# CHECK: hashchk 5, -8(1)
781+
0x7f 0xe1 0x2d 0xe5
782+
783+
# CHECK: hashchk 0, -8(30)
784+
0x7f 0xfe 0x05 0xe5
785+
786+
# CHECK: hashchk 5, -512(1)
787+
0x7c 0x01 0x2d 0xe4
788+
789+
# CHECK: hashstp 5, -8(1)
790+
0x7f 0xe1 0x2d 0x25
791+
792+
# CHECK: hashstp 0, -8(30)
793+
0x7f 0xfe 0x05 0x25
794+
795+
# CHECK: hashstp 5, -512(1)
796+
0x7c 0x01 0x2d 0x24
797+
798+
# CHECK: hashchkp 5, -8(1)
799+
0x7f 0xe1 0x2d 0x65
800+
801+
# CHECK: hashchkp 0, -8(30)
802+
0x7f 0xfe 0x05 0x65
803+
804+
# CHECK: hashchkp 5, -512(1)
805+
0x7c 0x01 0x2d 0x64
806+

llvm/test/MC/PowerPC/ppc64-encoding-ISA31.s

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,3 +963,39 @@
963963
# CHECK-BE: xvcvbf16spn 33, 34 # encoding: [0xf0,0x30,0x17,0x6f]
964964
# CHECK-LE: xvcvbf16spn 33, 34 # encoding: [0x6f,0x17,0x30,0xf0]
965965
xvcvbf16spn 33, 34
966+
# CHECK-BE: hashst 5, -8(1) # encoding: [0x7f,0xe1,0x2d,0xa5]
967+
# CHECK-LE: hashst 5, -8(1) # encoding: [0xa5,0x2d,0xe1,0x7f]
968+
hashst 5, -8(1)
969+
# CHECK-BE: hashst 0, -8(30) # encoding: [0x7f,0xfe,0x05,0xa5]
970+
# CHECK-LE: hashst 0, -8(30) # encoding: [0xa5,0x05,0xfe,0x7f]
971+
hashst 0, -8(30)
972+
# CHECK-BE: hashst 5, -512(1) # encoding: [0x7c,0x01,0x2d,0xa4]
973+
# CHECK-LE: hashst 5, -512(1) # encoding: [0xa4,0x2d,0x01,0x7c]
974+
hashst 5, -512(1)
975+
# CHECK-BE: hashchk 5, -8(1) # encoding: [0x7f,0xe1,0x2d,0xe5]
976+
# CHECK-LE: hashchk 5, -8(1) # encoding: [0xe5,0x2d,0xe1,0x7f]
977+
hashchk 5, -8(1)
978+
# CHECK-BE: hashchk 0, -8(30) # encoding: [0x7f,0xfe,0x05,0xe5]
979+
# CHECK-LE: hashchk 0, -8(30) # encoding: [0xe5,0x05,0xfe,0x7f]
980+
hashchk 0, -8(30)
981+
# CHECK-BE: hashchk 5, -512(1) # encoding: [0x7c,0x01,0x2d,0xe4]
982+
# CHECK-LE: hashchk 5, -512(1) # encoding: [0xe4,0x2d,0x01,0x7c]
983+
hashchk 5, -512(1)
984+
# CHECK-BE: hashstp 5, -8(1) # encoding: [0x7f,0xe1,0x2d,0x25]
985+
# CHECK-LE: hashstp 5, -8(1) # encoding: [0x25,0x2d,0xe1,0x7f]
986+
hashstp 5, -8(1)
987+
# CHECK-BE: hashstp 0, -8(30) # encoding: [0x7f,0xfe,0x05,0x25]
988+
# CHECK-LE: hashstp 0, -8(30) # encoding: [0x25,0x05,0xfe,0x7f]
989+
hashstp 0, -8(30)
990+
# CHECK-BE: hashstp 5, -512(1) # encoding: [0x7c,0x01,0x2d,0x24]
991+
# CHECK-LE: hashstp 5, -512(1) # encoding: [0x24,0x2d,0x01,0x7c]
992+
hashstp 5, -512(1)
993+
# CHECK-BE: hashchkp 5, -8(1) # encoding: [0x7f,0xe1,0x2d,0x65]
994+
# CHECK-LE: hashchkp 5, -8(1) # encoding: [0x65,0x2d,0xe1,0x7f]
995+
hashchkp 5, -8(1)
996+
# CHECK-BE: hashchkp 0, -8(30) # encoding: [0x7f,0xfe,0x05,0x65]
997+
# CHECK-LE: hashchkp 0, -8(30) # encoding: [0x65,0x05,0xfe,0x7f]
998+
hashchkp 0, -8(30)
999+
# CHECK-BE: hashchkp 5, -512(1) # encoding: [0x7c,0x01,0x2d,0x64]
1000+
# CHECK-LE: hashchkp 5, -512(1) # encoding: [0x64,0x2d,0x01,0x7c]
1001+
hashchkp 5, -512(1)

0 commit comments

Comments
 (0)