@@ -901,6 +901,8 @@ var optab = []Optab{
901901 {AMSR , C_VCON , C_NONE , C_NONE , C_SPOP , C_NONE , 37 , 4 , 0 , 0 , 0 },
902902 {APRFM , C_UOREG32K , C_NONE , C_NONE , C_SPOP , C_NONE , 91 , 4 , 0 , 0 , 0 },
903903 {APRFM , C_UOREG32K , C_NONE , C_NONE , C_LCON , C_NONE , 91 , 4 , 0 , 0 , 0 },
904+ {ARPRFM , C_ZOREG , C_REG , C_NONE , C_SPOP , C_NONE , 110 , 4 , 0 , 0 , 0 },
905+ {ARPRFM , C_ZOREG , C_REG , C_NONE , C_LCON , C_NONE , 110 , 4 , 0 , 0 , 0 },
904906 {ADMB , C_VCON , C_NONE , C_NONE , C_NONE , C_NONE , 51 , 4 , 0 , 0 , 0 },
905907 {AHINT , C_VCON , C_NONE , C_NONE , C_NONE , C_NONE , 52 , 4 , 0 , 0 , 0 },
906908 {ASYS , C_VCON , C_NONE , C_NONE , C_NONE , C_NONE , 50 , 4 , 0 , 0 , 0 },
@@ -943,6 +945,13 @@ var pstatefield = []struct {
943945 {SPOP_DAIFClr , 3 << 16 | 4 << 12 | 7 << 5 },
944946}
945947
948+ var rprfopfield = map [SpecialOperand ]uint32 {
949+ SPOP_PLDKEEP : 0 ,
950+ SPOP_PSTKEEP : 1 ,
951+ SPOP_PLDSTRM : 4 ,
952+ SPOP_PSTSTRM : 5 ,
953+ }
954+
946955var prfopfield = map [SpecialOperand ]uint32 {
947956 SPOP_PLDL1KEEP : 0 ,
948957 SPOP_PLDL1STRM : 1 ,
@@ -3416,6 +3425,7 @@ func buildop(ctxt *obj.Link) {
34163425 AVDUP ,
34173426 AVMOVI ,
34183427 APRFM ,
3428+ ARPRFM ,
34193429 AVEXT ,
34203430 AVXAR :
34213431 break
@@ -6088,6 +6098,43 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
60886098 rn := uint32 (p .Reg & 31 )
60896099 o1 |= Q << 30 | size << 22 | (rn << 5 ) | (rd )
60906100
6101+ case 110 : /*rprfm (Rn), Rm, <rprfop/imm6>*/
6102+ rn := p .From .Reg
6103+ rm := p .Reg
6104+ var operation uint32
6105+ var ok bool
6106+
6107+ // Operation is either a 6-bit immediate or named prefetch operation.
6108+ if p .To .Type == obj .TYPE_CONST {
6109+ operation = uint32 (p .To .Offset )
6110+ if operation > 63 {
6111+ c .ctxt .Diag ("range prefetch immediate must be 0 to 63: %v" , p )
6112+ }
6113+ } else {
6114+ operation , ok = rprfopfield [SpecialOperand (p .To .Offset )]
6115+ if ! ok {
6116+ c .ctxt .Diag ("illegal range prefetch operand, expected PLDKEEP, PSTKEEP, PLDSTRM or PSTSTRM: %v" , p )
6117+ }
6118+ }
6119+
6120+ // 6-bit placement: the 6-bit value is scattered to match the
6121+ // architectural encoding (bits 15,13,12,2-0). This is because the
6122+ // instructions word reuses fields from the base load/store hint space.
6123+ // option2 (bit5) -> bit15
6124+ // option0 (bit4) -> bit13
6125+ // S (bit3) -> bit12
6126+ // Rt<2:0> (bits2-0) -> bits2-0
6127+ // Rt<4:3> are already set by c.opirr() and are fixed for RPRFM.
6128+ option2 := (operation & (1 << 5 )) << 10
6129+ option0 := (operation & (1 << 4 )) << 9
6130+ s := (operation & (1 << 3 )) << 9
6131+ rt := (operation & 0x7 )
6132+
6133+ encodedOperation := option2 | option0 | s | rt
6134+
6135+ o1 = c .opirr (p , p .As )
6136+ o1 |= (uint32 (rm & 31 ) << 16 ) | (uint32 (rn & 31 ) << 5 ) | uint32 (encodedOperation )
6137+
60916138 case 127 :
60926139 // Generic SVE instruction encoding
60936140 matched := false
@@ -7277,6 +7324,9 @@ func (c *ctxt7) opirr(p *obj.Prog, a obj.As) uint32 {
72777324
72787325 case APRFM :
72797326 return 0xf9 << 24 | 2 << 22
7327+
7328+ case ARPRFM :
7329+ return 0xf8 << 24 | 5 << 21 | 18 << 10 | 3 << 3
72807330 }
72817331
72827332 c .ctxt .Diag ("%v: bad irr %v" , p , a )
0 commit comments