cmd/compile/internal/obj/arm64: add RPRFM instruction for range prefetch

Add support for the RPRFM (Range Prefetch Memory) instruction.
As per ARM Architecture Reference Manual, this instruction
signals the memory system that data memory accesses from a
specified range of addresses are likely to occur in the near
future.

Syntax: RPRFM (Rn), Rm, <operation>

where operation is one of:
    PLDKEEP  - prefetch for keep (load)
    PSTKEEP  - prefetch for keep (store)
    PLDSTRM  - prefetch for streaming (load)
    PSTSTRM  - prefetch for streaming (store)
or a numeric immediate 0..63.

Change-Id: Iad230fbe91b5cacf3f3ca208e0fcc18562ed8139
Reviewed-on: https://go-review.googlesource.com/c/go/+/763200
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
Ch1n-ch1nless 2026-04-06 23:02:52 +03:00 committed by Gopher Robot
parent 74c35fca7a
commit e49b53439d
6 changed files with 72 additions and 3 deletions

View file

@ -419,6 +419,9 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
PRFM 8(R12), PLIL3STRM // 8d0580f9
PRFM (R8), $25 // 190180f9
PRFM 8(R9), $30 // 3e0580f9
RPRFM (R1), R2, PLDKEEP // 3848a2f8
RPRFM (RSP), R4, PSTSTRM // fd4ba4f8
RPRFM (R6), R12, $25 // d978acf8
NOOP // 1f2003d5
HINT $0 // 1f2003d5
DMB $1

View file

@ -462,6 +462,10 @@ TEXT errors(SB),$0
AUTIA1716 $45 // ERROR "illegal combination"
AUTIB1716 R0 // ERROR "illegal combination"
SB $1 // ERROR "illegal combination"
RPRFM (R1), RSP, PLDKEEP // ERROR "illegal combination"
RPRFM 2(RSP), R4, PSTSTRM // ERROR "illegal combination"
RPRFM (R2), R3, $100 // ERROR "range prefetch immediate must be 0 to 63"
RPRFM (R5), R6, PLDL1KEEP // ERROR "illegal range prefetch operand"
// VMUL family invalid arrangement tests
VMUL V0.D2, V0.D2, V1.D2 // ERROR "invalid arrangement"

View file

@ -1006,6 +1006,7 @@ const (
AREVW
AROR
ARORW
ARPRFM
ASB
ASBC
ASBCS
@ -1482,5 +1483,11 @@ const (
SPOP_J
SPOP_JC
// Range PReFetch of Memory (RPRFM)
SPOP_PLDKEEP
SPOP_PSTKEEP
SPOP_PLDSTRM
SPOP_PSTSTRM
SPOP_END
)

View file

@ -353,6 +353,7 @@ var Anames = []string{
"REVW",
"ROR",
"RORW",
"RPRFM",
"SB",
"SBC",
"SBCS",

View file

@ -901,6 +901,8 @@ var optab = []Optab{
{AMSR, C_VCON, C_NONE, C_NONE, C_SPOP, C_NONE, 37, 4, 0, 0, 0},
{APRFM, C_UOREG32K, C_NONE, C_NONE, C_SPOP, C_NONE, 91, 4, 0, 0, 0},
{APRFM, C_UOREG32K, C_NONE, C_NONE, C_LCON, C_NONE, 91, 4, 0, 0, 0},
{ARPRFM, C_ZOREG, C_REG, C_NONE, C_SPOP, C_NONE, 110, 4, 0, 0, 0},
{ARPRFM, C_ZOREG, C_REG, C_NONE, C_LCON, C_NONE, 110, 4, 0, 0, 0},
{ADMB, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 51, 4, 0, 0, 0},
{AHINT, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 52, 4, 0, 0, 0},
{ASYS, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 50, 4, 0, 0, 0},
@ -943,6 +945,13 @@ var pstatefield = []struct {
{SPOP_DAIFClr, 3<<16 | 4<<12 | 7<<5},
}
var rprfopfield = map[SpecialOperand]uint32{
SPOP_PLDKEEP: 0,
SPOP_PSTKEEP: 1,
SPOP_PLDSTRM: 4,
SPOP_PSTSTRM: 5,
}
var prfopfield = map[SpecialOperand]uint32{
SPOP_PLDL1KEEP: 0,
SPOP_PLDL1STRM: 1,
@ -3416,6 +3425,7 @@ func buildop(ctxt *obj.Link) {
AVDUP,
AVMOVI,
APRFM,
ARPRFM,
AVEXT,
AVXAR:
break
@ -6088,6 +6098,43 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
rn := uint32(p.Reg & 31)
o1 |= Q<<30 | size<<22 | (rn << 5) | (rd)
case 110: /*rprfm (Rn), Rm, <rprfop/imm6>*/
rn := p.From.Reg
rm := p.Reg
var operation uint32
var ok bool
// Operation is either a 6-bit immediate or named prefetch operation.
if p.To.Type == obj.TYPE_CONST {
operation = uint32(p.To.Offset)
if operation > 63 {
c.ctxt.Diag("range prefetch immediate must be 0 to 63: %v", p)
}
} else {
operation, ok = rprfopfield[SpecialOperand(p.To.Offset)]
if !ok {
c.ctxt.Diag("illegal range prefetch operand, expected PLDKEEP, PSTKEEP, PLDSTRM or PSTSTRM: %v", p)
}
}
// 6-bit placement: the 6-bit value is scattered to match the
// architectural encoding (bits 15,13,12,2-0). This is because the
// instructions word reuses fields from the base load/store hint space.
// option2 (bit5) -> bit15
// option0 (bit4) -> bit13
// S (bit3) -> bit12
// Rt<2:0> (bits2-0) -> bits2-0
// Rt<4:3> are already set by c.opirr() and are fixed for RPRFM.
option2 := (operation & (1 << 5)) << 10
option0 := (operation & (1 << 4)) << 9
s := (operation & (1 << 3)) << 9
rt := (operation & 0x7)
encodedOperation := option2 | option0 | s | rt
o1 = c.opirr(p, p.As)
o1 |= (uint32(rm&31) << 16) | (uint32(rn&31) << 5) | uint32(encodedOperation)
case 127:
// Generic SVE instruction encoding
matched := false
@ -7277,6 +7324,9 @@ func (c *ctxt7) opirr(p *obj.Prog, a obj.As) uint32 {
case APRFM:
return 0xf9<<24 | 2<<22
case ARPRFM:
return 0xf8<<24 | 5<<21 | 18<<10 | 3<<3
}
c.ctxt.Diag("%v: bad irr %v", p, a)

View file

@ -156,12 +156,16 @@ func _() {
_ = x[SPOP_C-144]
_ = x[SPOP_J-145]
_ = x[SPOP_JC-146]
_ = x[SPOP_END-147]
_ = x[SPOP_PLDKEEP-147]
_ = x[SPOP_PSTKEEP-148]
_ = x[SPOP_PLDSTRM-149]
_ = x[SPOP_PSTSTRM-150]
_ = x[SPOP_END-151]
}
const _SpecialOperand_name = "PLDL1KEEPPLDL1STRMPLDL2KEEPPLDL2STRMPLDL3KEEPPLDL3STRMPLIL1KEEPPLIL1STRMPLIL2KEEPPLIL2STRMPLIL3KEEPPLIL3STRMPSTL1KEEPPSTL1STRMPSTL2KEEPPSTL2STRMPSTL3KEEPPSTL3STRMVLx2VLx4VMALLE1ISVAE1ISASIDE1ISVAAE1ISVALE1ISVAALE1ISVMALLE1VAE1ASIDE1VAAE1VALE1VAALE1IPAS2E1ISIPAS2LE1ISALLE2ISVAE2ISALLE1ISVALE2ISVMALLS12E1ISIPAS2E1IPAS2LE1ALLE2VAE2ALLE1VALE2VMALLS12E1ALLE3ISVAE3ISVALE3ISALLE3VAE3VALE3VMALLE1OSVAE1OSASIDE1OSVAAE1OSVALE1OSVAALE1OSRVAE1ISRVAAE1ISRVALE1ISRVAALE1ISRVAE1OSRVAAE1OSRVALE1OSRVAALE1OSRVAE1RVAAE1RVALE1RVAALE1RIPAS2E1ISRIPAS2LE1ISALLE2OSVAE2OSALLE1OSVALE2OSVMALLS12E1OSRVAE2ISRVALE2ISIPAS2E1OSRIPAS2E1RIPAS2E1OSIPAS2LE1OSRIPAS2LE1RIPAS2LE1OSRVAE2OSRVALE2OSRVAE2RVALE2ALLE3OSVAE3OSVALE3OSRVAE3ISRVALE3ISRVAE3OSRVALE3OSRVAE3RVALE3IVACISWCSWCISWZVACVACCVAUCIVACIGVACIGSWIGDVACIGDSWCGSWCGDSWCIGSWCIGDSWGVAGZVACGVACCGDVACCGVAPCGDVAPCGVADPCGDVADPCIGVACCIGDVACCVAPCVADPDAIFSetDAIFClrEQNEHSLOMIPLVSVCHILSGELTGTLEALNVCJJCEND"
const _SpecialOperand_name = "PLDL1KEEPPLDL1STRMPLDL2KEEPPLDL2STRMPLDL3KEEPPLDL3STRMPLIL1KEEPPLIL1STRMPLIL2KEEPPLIL2STRMPLIL3KEEPPLIL3STRMPSTL1KEEPPSTL1STRMPSTL2KEEPPSTL2STRMPSTL3KEEPPSTL3STRMVLx2VLx4VMALLE1ISVAE1ISASIDE1ISVAAE1ISVALE1ISVAALE1ISVMALLE1VAE1ASIDE1VAAE1VALE1VAALE1IPAS2E1ISIPAS2LE1ISALLE2ISVAE2ISALLE1ISVALE2ISVMALLS12E1ISIPAS2E1IPAS2LE1ALLE2VAE2ALLE1VALE2VMALLS12E1ALLE3ISVAE3ISVALE3ISALLE3VAE3VALE3VMALLE1OSVAE1OSASIDE1OSVAAE1OSVALE1OSVAALE1OSRVAE1ISRVAAE1ISRVALE1ISRVAALE1ISRVAE1OSRVAAE1OSRVALE1OSRVAALE1OSRVAE1RVAAE1RVALE1RVAALE1RIPAS2E1ISRIPAS2LE1ISALLE2OSVAE2OSALLE1OSVALE2OSVMALLS12E1OSRVAE2ISRVALE2ISIPAS2E1OSRIPAS2E1RIPAS2E1OSIPAS2LE1OSRIPAS2LE1RIPAS2LE1OSRVAE2OSRVALE2OSRVAE2RVALE2ALLE3OSVAE3OSVALE3OSRVAE3ISRVALE3ISRVAE3OSRVALE3OSRVAE3RVALE3IVACISWCSWCISWZVACVACCVAUCIVACIGVACIGSWIGDVACIGDSWCGSWCGDSWCIGSWCIGDSWGVAGZVACGVACCGDVACCGVAPCGDVAPCGVADPCGDVADPCIGVACCIGDVACCVAPCVADPDAIFSetDAIFClrEQNEHSLOMIPLVSVCHILSGELTGTLEALNVCJJCPLDKEEPPSTKEEPPLDSTRMPSTSTRMEND"
var _SpecialOperand_index = [...]uint16{0, 9, 18, 27, 36, 45, 54, 63, 72, 81, 90, 99, 108, 117, 126, 135, 144, 153, 162, 166, 170, 179, 185, 193, 200, 207, 215, 222, 226, 232, 237, 242, 248, 257, 267, 274, 280, 287, 294, 306, 313, 321, 326, 330, 335, 340, 350, 357, 363, 370, 375, 379, 384, 393, 399, 407, 414, 421, 429, 436, 444, 452, 461, 468, 476, 484, 493, 498, 504, 510, 517, 527, 538, 545, 551, 558, 565, 577, 584, 592, 601, 609, 619, 629, 638, 649, 656, 664, 669, 675, 682, 688, 695, 702, 710, 717, 725, 730, 736, 740, 743, 746, 750, 753, 757, 761, 766, 771, 775, 781, 786, 790, 795, 800, 806, 809, 813, 818, 824, 829, 835, 841, 848, 854, 861, 865, 870, 877, 884, 886, 888, 890, 892, 894, 896, 898, 900, 902, 904, 906, 908, 910, 912, 914, 916, 917, 918, 920, 923}
var _SpecialOperand_index = [...]uint16{0, 9, 18, 27, 36, 45, 54, 63, 72, 81, 90, 99, 108, 117, 126, 135, 144, 153, 162, 166, 170, 179, 185, 193, 200, 207, 215, 222, 226, 232, 237, 242, 248, 257, 267, 274, 280, 287, 294, 306, 313, 321, 326, 330, 335, 340, 350, 357, 363, 370, 375, 379, 384, 393, 399, 407, 414, 421, 429, 436, 444, 452, 461, 468, 476, 484, 493, 498, 504, 510, 517, 527, 538, 545, 551, 558, 565, 577, 584, 592, 601, 609, 619, 629, 638, 649, 656, 664, 669, 675, 682, 688, 695, 702, 710, 717, 725, 730, 736, 740, 743, 746, 750, 753, 757, 761, 766, 771, 775, 781, 786, 790, 795, 800, 806, 809, 813, 818, 824, 829, 835, 841, 848, 854, 861, 865, 870, 877, 884, 886, 888, 890, 892, 894, 896, 898, 900, 902, 904, 906, 908, 910, 912, 914, 916, 917, 918, 920, 927, 934, 941, 948, 951}
func (i SpecialOperand) String() string {
idx := int(i) - 0