cmd/internal/obj/loong64: add [X]VSHUF4I.{B/H/W/D} instructions support

Go asm syntax:
	 VSHUF4I{B/H/W/V}	$1, V1, V2
	XVSHUF4I{B/H/W/V}	$2, X1, X2

Equivalent platform assembler syntax:
	 vshuf4i.{b/h/w/d}	v2, v1, $1
	xvshuf4i.{b/h/w/d}	x2, x1, $2

Change-Id: I6a847ccbd2c93432d87bd1390b5cf1508da06496
Reviewed-on: https://go-review.googlesource.com/c/go/+/658376
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Xiaolin Zhao 2025-03-17 15:56:12 +08:00 committed by abner chenc
parent 87d1833c66
commit 0095b5d098
6 changed files with 91 additions and 0 deletions

View file

@ -1677,11 +1677,19 @@ func buildop(ctxt *obj.Link) {
opset(AVORB, r0)
opset(AVXORB, r0)
opset(AVNORB, r0)
opset(AVSHUF4IB, r0)
opset(AVSHUF4IH, r0)
opset(AVSHUF4IW, r0)
opset(AVSHUF4IV, r0)
case AXVANDB:
opset(AXVORB, r0)
opset(AXVXORB, r0)
opset(AXVNORB, r0)
opset(AXVSHUF4IB, r0)
opset(AXVSHUF4IH, r0)
opset(AXVSHUF4IW, r0)
opset(AXVSHUF4IV, r0)
case AVANDV:
opset(AVORV, r0)
@ -2155,6 +2163,12 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
r = int(p.To.Reg)
}
// the operand range available for instructions VSHUF4IV and XVSHUF4IV is [0, 15]
if p.As == AVSHUF4IV || p.As == AXVSHUF4IV {
operand := uint32(v)
c.checkoperand(p, operand, 15)
}
o1 = OP_8IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
case 24: // add $lcon,r1,r2
@ -2695,6 +2709,13 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
out[4] = o5
}
// checkoperand checks if operand >= 0 && operand <= maxoperand
func (c *ctxt0) checkoperand(p *obj.Prog, operand uint32, mask uint32) {
if (operand & ^mask) != 0 {
c.ctxt.Diag("operand out of range 0 to %d: %v", mask, p)
}
}
// checkindex checks if index >= 0 && index <= maxindex
func (c *ctxt0) checkindex(p *obj.Prog, index uint32, mask uint32) {
if (index & ^mask) != 0 {
@ -3813,6 +3834,22 @@ func (c *ctxt0) opirr(a obj.As) uint32 {
return 0xed1a << 15 // xvsubi.wu
case AXVSUBVU:
return 0xed1b << 15 // xvsubi.du
case AVSHUF4IB:
return 0x1ce4 << 18 // vshuf4i.b
case AVSHUF4IH:
return 0x1ce5 << 18 // vshuf4i.h
case AVSHUF4IW:
return 0x1ce6 << 18 // vshuf4i.w
case AVSHUF4IV:
return 0x1ce7 << 18 // vshuf4i.d
case AXVSHUF4IB:
return 0x1de4 << 18 // xvshuf4i.b
case AXVSHUF4IH:
return 0x1de5 << 18 // xvshuf4i.h
case AXVSHUF4IW:
return 0x1de6 << 18 // xvshuf4i.w
case AXVSHUF4IV:
return 0x1de7 << 18 // xvshuf4i.d
}
if a < 0 {