diff --git a/src/cmd/asm/internal/asm/testdata/s390x.s b/src/cmd/asm/internal/asm/testdata/s390x.s index 93c3ec9ea7..cb9a9917a5 100644 --- a/src/cmd/asm/internal/asm/testdata/s390x.s +++ b/src/cmd/asm/internal/asm/testdata/s390x.s @@ -456,6 +456,7 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16- VST V1, (R15) // e710f000000e VL (R15), V31 // e7f0f0000806 VST V31, (R15) // e7f0f000080e + VSTRL V4, $6, 1(R4) // e6064001403d VESLB $5, V14 // e7ee00050030 VESRAG $0, V15, V16 // e70f0000383a VLM (R15), V8, V23 // e787f0000436 diff --git a/src/cmd/internal/obj/s390x/a.out.go b/src/cmd/internal/obj/s390x/a.out.go index 6b16d7a9bd..db038080ee 100644 --- a/src/cmd/internal/obj/s390x/a.out.go +++ b/src/cmd/internal/obj/s390x/a.out.go @@ -946,6 +946,7 @@ const ( AVSTEG AVSTEB AVSTM + AVSTRL AVSTL AVSTRC AVSTRCB diff --git a/src/cmd/internal/obj/s390x/anames.go b/src/cmd/internal/obj/s390x/anames.go index a6f2820f85..85f846b714 100644 --- a/src/cmd/internal/obj/s390x/anames.go +++ b/src/cmd/internal/obj/s390x/anames.go @@ -669,6 +669,7 @@ var Anames = []string{ "VSTEG", "VSTEB", "VSTM", + "VSTRL", "VSTL", "VSTRC", "VSTRCB", diff --git a/src/cmd/internal/obj/s390x/asmz.go b/src/cmd/internal/obj/s390x/asmz.go index 3706bb1b74..7db714c204 100644 --- a/src/cmd/internal/obj/s390x/asmz.go +++ b/src/cmd/internal/obj/s390x/asmz.go @@ -458,6 +458,10 @@ var optab = []Optab{ // MVC storage and storage {i: 127, as: AMVCLE, a1: C_LOREG, a2: C_REG, a6: C_REG}, {i: 127, as: AMVCLE, a1: C_SCON, a2: C_REG, a6: C_REG}, + + // VSI store rightmost with length + {i: 129, as: AVSTRL, a1: C_VREG, a3: C_SCON, a6: C_SOREG}, + {i: 129, as: AVSTRL, a1: C_VREG, a3: C_SCON, a6: C_SAUTO}, } var oprange [ALAST & obj.AMask][]Optab @@ -2634,6 +2638,7 @@ const ( op_VSTEG uint32 = 0xE70A // VRX VECTOR STORE ELEMENT (64) op_VSTEB uint32 = 0xE708 // VRX VECTOR STORE ELEMENT (8) op_VSTM uint32 = 0xE73E // VRS-a VECTOR STORE MULTIPLE + op_VSTRL uint32 = 0xE63D // VSI VECTOR STORE RIGHTMOST WITH LENGTH op_VSTL uint32 = 0xE73F // VRS-b VECTOR STORE WITH LENGTH op_VSTRC uint32 = 0xE78A // VRR-d VECTOR STRING RANGE COMPARE op_VS uint32 = 0xE7F7 // VRR-c VECTOR SUBTRACT @@ -4459,7 +4464,7 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) { } zRRF(opcode, uint32(p.Reg), 0, uint32(p.From.Reg), uint32(p.To.Reg), asm) - case 127: + case 127: // RS-a Move Long Extended // NOTE: Mapping MVCLE operands is as follows: // Instruction Format: MVCLE R1,R3,D2(B2) // R1 - prog.To (for Destination) @@ -4482,6 +4487,17 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) { m5 := singleElementMask(p.As) m6 := uint32(c.vregoff(&p.From)) zVRRc(op, uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), m6, m5, m4, asm) + + case 129: // VSI Vector Store Rightmost with Length + op, _, _ := vop(p.As) + v1 := p.From.Reg + b2 := p.To.Reg + if b2 == 0 { + b2 = REGSP + } + d2 := uint32(c.vregoff(&p.To)) + i3 := uint32(c.vregoff(p.GetFrom3())) + zVSI(op, uint32(v1), uint32(b2), d2, i3, asm) } } @@ -5081,3 +5097,13 @@ func zVRIe(op, v1, v2, i3, m5, m4 uint32, asm *[]byte) { (uint8(m4)<<4)|rxb(v1, v2, 0, 0), uint8(op)) } + +func zVSI(op, v1, b2, d2, i3 uint32, asm *[]byte) { + *asm = append(*asm, + uint8(op>>8), + uint8(i3), + (uint8(b2)<<4)|(uint8(d2>>8)&0xf), + uint8(d2), + (uint8(v1)<<4)|rxb(v1, 0, 0, 0), + uint8(op)) +} diff --git a/src/cmd/internal/obj/s390x/vector.go b/src/cmd/internal/obj/s390x/vector.go index 966cd04c27..ecb9c96ddc 100644 --- a/src/cmd/internal/obj/s390x/vector.go +++ b/src/cmd/internal/obj/s390x/vector.go @@ -915,6 +915,8 @@ func vop(as obj.As) (opcode, es, cs uint32) { return op_VSTEB, 0, 0 case AVSTM: return op_VSTM, 0, 0 + case AVSTRL: + return op_VSTRL, 0, 0 case AVSTL: return op_VSTL, 0, 0 case AVSTRC: