Skip to content

Commit

Permalink
[AArch64][SVE] Asm: Support for contiguous PRF prefetch instructions.
Browse files Browse the repository at this point in the history
Reviewers: rengolin, fhahn, samparker, SjoerdMeijer, javed.absar

Reviewed By: SjoerdMeijer

Differential Revision: https://reviews.llvm.org/D46682

llvm-svn: 332433
  • Loading branch information
sdesmalen-arm committed May 16, 2018
1 parent 2cafed7 commit 67f9154
Show file tree
Hide file tree
Showing 13 changed files with 1,106 additions and 3 deletions.
8 changes: 8 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,14 @@ def uimm6s8 : Operand<i64>, ImmLeaf<i64,
let ParserMatchClass = UImm6s8Operand;
}

// simm6sN predicate - True if the immediate is a multiple of N in the range
// [-32 * N, 31 * N].
def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>;
def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> {
let ParserMatchClass = SImm6s1Operand;
let DecoderMethod = "DecodeSImm<6>";
}

// simm4sN predicate - True if the immediate is a multiple of N in the range
// [ -8* N, 7 * N].
def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>;
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,18 @@ let Predicates = [HasSVE] in {
defm STR_ZXI : sve_mem_z_spill<"str">;
defm STR_PXI : sve_mem_p_spill<"str">;

// Contiguous prefetch (register + immediate)
defm PRFB_PRI : sve_mem_prfm_si<0b00, "prfb">;
defm PRFH_PRI : sve_mem_prfm_si<0b01, "prfh">;
defm PRFW_PRI : sve_mem_prfm_si<0b10, "prfw">;
defm PRFD_PRI : sve_mem_prfm_si<0b11, "prfd">;

// Contiguous prefetch (register + register)
def PRFB_PRR : sve_mem_prfm_ss<0b001, "prfb", GPR64NoXZRshifted8>;
def PRFH_PRR : sve_mem_prfm_ss<0b011, "prfh", GPR64NoXZRshifted16>;
def PRFS_PRR : sve_mem_prfm_ss<0b101, "prfw", GPR64NoXZRshifted32>;
def PRFD_PRR : sve_mem_prfm_ss<0b111, "prfd", GPR64NoXZRshifted64>;

defm ZIP1_ZZZ : sve_int_perm_bin_perm_zz<0b000, "zip1">;
defm ZIP2_ZZZ : sve_int_perm_bin_perm_zz<0b001, "zip2">;

Expand Down
7 changes: 5 additions & 2 deletions llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2087,13 +2087,13 @@ AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
}

if (Tok.isNot(AsmToken::Identifier)) {
TokError("pre-fetch hint expected");
TokError("prefetch hint expected");
return MatchOperand_ParseFail;
}

auto PRFM = LookupByName(Tok.getString());
if (!PRFM) {
TokError("pre-fetch hint expected");
TokError("prefetch hint expected");
return MatchOperand_ParseFail;
}

Expand Down Expand Up @@ -3653,6 +3653,8 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
return Error(Loc, "index must be a multiple of 4 in range [-32, 28].");
case Match_InvalidMemoryIndexed16SImm4:
return Error(Loc, "index must be a multiple of 16 in range [-128, 112].");
case Match_InvalidMemoryIndexed1SImm6:
return Error(Loc, "index must be an integer in range [-32, 31].");
case Match_InvalidMemoryIndexedSImm9:
return Error(Loc, "index must be an integer in range [-256, 255].");
case Match_InvalidMemoryIndexed8SImm10:
Expand Down Expand Up @@ -4233,6 +4235,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidMemoryIndexed2SImm4:
case Match_InvalidMemoryIndexed3SImm4:
case Match_InvalidMemoryIndexed4SImm4:
case Match_InvalidMemoryIndexed1SImm6:
case Match_InvalidMemoryIndexed16SImm4:
case Match_InvalidMemoryIndexed4SImm7:
case Match_InvalidMemoryIndexed8SImm7:
Expand Down
52 changes: 52 additions & 0 deletions llvm/lib/Target/AArch64/SVEInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -1251,6 +1251,58 @@ multiclass sve_mem_32b_gld_vi_32_ptrs<bits<4> opc, string asm, Operand imm_ty> {
(!cast<Instruction>(NAME # _IMM_REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
}

class sve_mem_prfm_si<bits<2> msz, string asm>
: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, simm6s1:$imm6),
asm, "\t$prfop, $Pg, [$Rn, $imm6, mul vl]",
"",
[]>, Sched<[]> {
bits<5> Rn;
bits<3> Pg;
bits<6> imm6;
bits<4> prfop;
let Inst{31-22} = 0b1000010111;
let Inst{21-16} = imm6;
let Inst{15} = 0b0;
let Inst{14-13} = msz;
let Inst{12-10} = Pg;
let Inst{9-5} = Rn;
let Inst{4} = 0b0;
let Inst{3-0} = prfop;

let hasSideEffects = 1;
}

multiclass sve_mem_prfm_si<bits<2> msz, string asm> {
def NAME : sve_mem_prfm_si<msz, asm>;

def : InstAlias<asm # "\t$prfop, $Pg, [$Rn]",
(!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
}

class sve_mem_prfm_ss<bits<3> opc, string asm, RegisterOperand gprty>
: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
asm, "\t$prfop, $Pg, [$Rn, $Rm]",
"",
[]>, Sched<[]> {
bits<5> Rm;
bits<5> Rn;
bits<3> Pg;
bits<4> prfop;
let Inst{31-25} = 0b1000010;
let Inst{24-23} = opc{2-1};
let Inst{22-21} = 0b00;
let Inst{20-16} = Rm;
let Inst{15} = 0b1;
let Inst{14} = opc{0};
let Inst{13} = 0b0;
let Inst{12-10} = Pg;
let Inst{9-5} = Rn;
let Inst{4} = 0b0;
let Inst{3-0} = prfop;

let hasSideEffects = 1;
}

class sve_mem_z_fill<string asm>
: I<(outs ZPRAny:$Zt), (ins GPR64sp:$Rn, simm9:$imm9),
asm, "\t$Zt, [$Rn, $imm9, mul vl]",
Expand Down
63 changes: 63 additions & 0 deletions llvm/test/MC/AArch64/SVE/prfb-diagnostics.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s


// --------------------------------------------------------------------------//
// invalid/missing predicate operation specifier

prfb p0, [x0]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: prefetch hint expected
// CHECK-NEXT: prfb p0, [x0]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

prfb #16, p0, [x0]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: prefetch operand out of range, [0,15] expected
// CHECK-NEXT: prfb #16, p0, [x0]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

prfb plil1keep, p0, [x0]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: prefetch hint expected
// CHECK-NEXT: prfb plil1keep, p0, [x0]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

prfb #pldl1keep, p0, [x0]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate value expected for prefetch operand
// CHECK-NEXT: prfb #pldl1keep, p0, [x0]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


// --------------------------------------------------------------------------//
// invalid addressing modes

prfb #0, p0, [x0, #-33, mul vl]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-32, 31].
// CHECK-NEXT: prfb #0, p0, [x0, #-33, mul vl]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

prfb #0, p0, [x0, #32, mul vl]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-32, 31].
// CHECK-NEXT: prfb #0, p0, [x0, #32, mul vl]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

prfb #0, p0, [x0, w0]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 without shift
// CHECK-NEXT: prfb #0, p0, [x0, w0]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

prfb #0, p0, [x0, x0, uxtw]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 without shift
// CHECK-NEXT: prfb #0, p0, [x0, x0, uxtw]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

prfb #0, p0, [x0, x0, lsl #2]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 without shift
// CHECK-NEXT: prfb #0, p0, [x0, x0, lsl #2]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


// --------------------------------------------------------------------------//
// invalid predicate

prfb #0, p8, [x0]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7].
// CHECK-NEXT: prfb #0, p8, [x0]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
194 changes: 194 additions & 0 deletions llvm/test/MC/AArch64/SVE/prfb.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \
// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN

// --------------------------------------------------------------------------//
// Test all possible prefetch operation specifiers

prfb #0, p0, [x0]
// CHECK-INST: prfb pldl1keep, p0, [x0]
// CHECK-ENCODING: [0x00,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 00 c0 85 <unknown>

prfb pldl1keep, p0, [x0]
// CHECK-INST: prfb pldl1keep, p0, [x0]
// CHECK-ENCODING: [0x00,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 00 c0 85 <unknown>

prfb #1, p0, [x0]
// CHECK-INST: prfb pldl1strm, p0, [x0]
// CHECK-ENCODING: [0x01,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 01 00 c0 85 <unknown>

prfb pldl1strm, p0, [x0]
// CHECK-INST: prfb pldl1strm, p0, [x0]
// CHECK-ENCODING: [0x01,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 01 00 c0 85 <unknown>

prfb #2, p0, [x0]
// CHECK-INST: prfb pldl2keep, p0, [x0]
// CHECK-ENCODING: [0x02,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 02 00 c0 85 <unknown>

prfb pldl2keep, p0, [x0]
// CHECK-INST: prfb pldl2keep, p0, [x0]
// CHECK-ENCODING: [0x02,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 02 00 c0 85 <unknown>

prfb #3, p0, [x0]
// CHECK-INST: prfb pldl2strm, p0, [x0]
// CHECK-ENCODING: [0x03,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 03 00 c0 85 <unknown>

prfb pldl2strm, p0, [x0]
// CHECK-INST: prfb pldl2strm, p0, [x0]
// CHECK-ENCODING: [0x03,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 03 00 c0 85 <unknown>

prfb #4, p0, [x0]
// CHECK-INST: prfb pldl3keep, p0, [x0]
// CHECK-ENCODING: [0x04,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 04 00 c0 85 <unknown>

prfb pldl3keep, p0, [x0]
// CHECK-INST: prfb pldl3keep, p0, [x0]
// CHECK-ENCODING: [0x04,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 04 00 c0 85 <unknown>

prfb #5, p0, [x0]
// CHECK-INST: prfb pldl3strm, p0, [x0]
// CHECK-ENCODING: [0x05,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 05 00 c0 85 <unknown>

prfb pldl3strm, p0, [x0]
// CHECK-INST: prfb pldl3strm, p0, [x0]
// CHECK-ENCODING: [0x05,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 05 00 c0 85 <unknown>

prfb #6, p0, [x0]
// CHECK-INST: prfb #6, p0, [x0]
// CHECK-ENCODING: [0x06,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 06 00 c0 85 <unknown>

prfb #7, p0, [x0]
// CHECK-INST: prfb #7, p0, [x0]
// CHECK-ENCODING: [0x07,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 07 00 c0 85 <unknown>

prfb #8, p0, [x0]
// CHECK-INST: prfb pstl1keep, p0, [x0]
// CHECK-ENCODING: [0x08,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 08 00 c0 85 <unknown>

prfb pstl1keep, p0, [x0]
// CHECK-INST: prfb pstl1keep, p0, [x0]
// CHECK-ENCODING: [0x08,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 08 00 c0 85 <unknown>

prfb #9, p0, [x0]
// CHECK-INST: prfb pstl1strm, p0, [x0]
// CHECK-ENCODING: [0x09,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 09 00 c0 85 <unknown>

prfb pstl1strm, p0, [x0]
// CHECK-INST: prfb pstl1strm, p0, [x0]
// CHECK-ENCODING: [0x09,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 09 00 c0 85 <unknown>

prfb #10, p0, [x0]
// CHECK-INST: prfb pstl2keep, p0, [x0]
// CHECK-ENCODING: [0x0a,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 0a 00 c0 85 <unknown>

prfb pstl2keep, p0, [x0]
// CHECK-INST: prfb pstl2keep, p0, [x0]
// CHECK-ENCODING: [0x0a,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 0a 00 c0 85 <unknown>

prfb #11, p0, [x0]
// CHECK-INST: prfb pstl2strm, p0, [x0]
// CHECK-ENCODING: [0x0b,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 0b 00 c0 85 <unknown>

prfb pstl2strm, p0, [x0]
// CHECK-INST: prfb pstl2strm, p0, [x0]
// CHECK-ENCODING: [0x0b,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 0b 00 c0 85 <unknown>

prfb #12, p0, [x0]
// CHECK-INST: prfb pstl3keep, p0, [x0]
// CHECK-ENCODING: [0x0c,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 0c 00 c0 85 <unknown>

prfb pstl3keep, p0, [x0]
// CHECK-INST: prfb pstl3keep, p0, [x0]
// CHECK-ENCODING: [0x0c,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 0c 00 c0 85 <unknown>

prfb #13, p0, [x0]
// CHECK-INST: prfb pstl3strm, p0, [x0]
// CHECK-ENCODING: [0x0d,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 0d 00 c0 85 <unknown>

prfb pstl3strm, p0, [x0]
// CHECK-INST: prfb pstl3strm, p0, [x0]
// CHECK-ENCODING: [0x0d,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 0d 00 c0 85 <unknown>

prfb #14, p0, [x0]
// CHECK-INST: prfb #14, p0, [x0]
// CHECK-ENCODING: [0x0e,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 0e 00 c0 85 <unknown>

prfb #15, p0, [x0]
// CHECK-INST: prfb #15, p0, [x0]
// CHECK-ENCODING: [0x0f,0x00,0xc0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 0f 00 c0 85 <unknown>

// --------------------------------------------------------------------------//
// Test addressing modes

prfb #1, p0, [x0, #-32, mul vl]
// CHECK-INST: prfb pldl1strm, p0, [x0, #-32, mul vl]
// CHECK-ENCODING: [0x01,0x00,0xe0,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 01 00 e0 85 <unknown>

prfb #1, p0, [x0, #31, mul vl]
// CHECK-INST: prfb pldl1strm, p0, [x0, #31, mul vl]
// CHECK-ENCODING: [0x01,0x00,0xdf,0x85]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 01 00 df 85 <unknown>
Loading

0 comments on commit 67f9154

Please sign in to comment.