From 0f79510dc5d2e586924dae6e531529fe5fa7cbd2 Mon Sep 17 00:00:00 2001 From: Michael Munday Date: Thu, 24 Jan 2019 16:16:41 +0000 Subject: [PATCH] cmd/asm: add s390x 'rotate then ... selected bits' instructions MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This CL adds the following instructions, useful for shifting/rotating and masking operations: * RNSBG - rotate then and selected bits * ROSBG - rotate then or selected bits * RXSBG - rotate then exclusive or selected bits * RISBG - rotate then insert selected bits It also adds the 'T' (test), 'Z' (zero), 'H' (high), 'L' (low) and 'N' (no test) variants of these instructions as appropriate. Operands are ordered as: I₃, I₄, I₅, R₂, R₁. Key: I₃=start, I₄=end, I₅=amount, R₂=source, R₁=destination Change-Id: I200d12287e1df7447f37f4919da5e9a93d27c792 Reviewed-on: https://go-review.googlesource.com/c/go/+/159357 Run-TryBot: Michael Munday TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/cmd/asm/internal/asm/asm.go | 6 +++ src/cmd/asm/internal/asm/testdata/s390x.s | 15 ++++++++ src/cmd/internal/obj/s390x/a.out.go | 14 +++++++ src/cmd/internal/obj/s390x/anames.go | 14 +++++++ src/cmd/internal/obj/s390x/asmz.go | 46 +++++++++++++++++++++++ 5 files changed, 95 insertions(+) diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go index 3d99af6889..d83cfb2284 100644 --- a/src/cmd/asm/internal/asm/asm.go +++ b/src/cmd/asm/internal/asm/asm.go @@ -789,6 +789,12 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { prog.To = a[4] break } + if p.arch.Family == sys.S390X { + prog.From = a[0] + prog.RestArgs = []obj.Addr{a[1], a[2], a[3]} + prog.To = a[4] + break + } p.errorf("can't handle %s instruction with 5 operands", op) return case 6: diff --git a/src/cmd/asm/internal/asm/testdata/s390x.s b/src/cmd/asm/internal/asm/testdata/s390x.s index fbe1203aaa..713ad12aca 100644 --- a/src/cmd/asm/internal/asm/testdata/s390x.s +++ b/src/cmd/asm/internal/asm/testdata/s390x.s @@ -182,6 +182,21 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16- XORW (R1), R2 // 57201000 XORW -1(R1), R2 // e3201fffff57 + RNSBG $0, $31, $32, R1, R2 // ec21001f2054 + RXSBG $17, $8, $16, R3, R4 // ec4311081057 + ROSBG $9, $24, $11, R5, R6 // ec6509180b56 + RNSBGT $0, $31, $32, R7, R8 // ec87801f2054 + RXSBGT $17, $8, $16, R9, R10 // eca991081057 + ROSBGT $9, $24, $11, R11, R0 // ec0b89180b56 + RISBG $0, $31, $32, R1, R2 // ec21001f2055 + RISBGN $17, $8, $16, R3, R4 // ec4311081059 + RISBGZ $9, $24, $11, R5, R6 // ec6509980b55 + RISBGNZ $0, $31, $32, R7, R8 // ec87009f2059 + RISBHG $17, $8, $16, R9, R10 // eca91108105d + RISBLG $9, $24, $11, R11, R0 // ec0b09180b51 + RISBHGZ $17, $8, $16, R9, R10 // eca91188105d + RISBLGZ $9, $24, $11, R11, R0 // ec0b09980b51 + LAA R1, R2, 524287(R3) // eb213fff7ff8 LAAG R4, R5, -524288(R6) // eb54600080e8 LAAL R7, R8, 8192(R9) // eb87900002fa diff --git a/src/cmd/internal/obj/s390x/a.out.go b/src/cmd/internal/obj/s390x/a.out.go index fb246cbc47..d11a3834b0 100644 --- a/src/cmd/internal/obj/s390x/a.out.go +++ b/src/cmd/internal/obj/s390x/a.out.go @@ -289,6 +289,20 @@ const ( ASRAD ARLL ARLLG + ARNSBG + ARXSBG + AROSBG + ARNSBGT + ARXSBGT + AROSBGT + ARISBG + ARISBGN + ARISBGZ + ARISBGNZ + ARISBHG + ARISBLG + ARISBHGZ + ARISBLGZ // floating point AFABS diff --git a/src/cmd/internal/obj/s390x/anames.go b/src/cmd/internal/obj/s390x/anames.go index 3a21e90ab1..a9bdfcafe9 100644 --- a/src/cmd/internal/obj/s390x/anames.go +++ b/src/cmd/internal/obj/s390x/anames.go @@ -60,6 +60,20 @@ var Anames = []string{ "SRAD", "RLL", "RLLG", + "RNSBG", + "RXSBG", + "ROSBG", + "RNSBGT", + "RXSBGT", + "ROSBGT", + "RISBG", + "RISBGN", + "RISBGZ", + "RISBGNZ", + "RISBHG", + "RISBLG", + "RISBHGZ", + "RISBLGZ", "FABS", "FADD", "FADDS", diff --git a/src/cmd/internal/obj/s390x/asmz.go b/src/cmd/internal/obj/s390x/asmz.go index f4f2317e1e..5cd4dca2a2 100644 --- a/src/cmd/internal/obj/s390x/asmz.go +++ b/src/cmd/internal/obj/s390x/asmz.go @@ -196,6 +196,7 @@ var optab = []Optab{ Optab{i: 7, as: ASLD, a1: C_REG, a2: C_REG, a6: C_REG}, Optab{i: 7, as: ASLD, a1: C_SCON, a2: C_REG, a6: C_REG}, Optab{i: 7, as: ASLD, a1: C_SCON, a6: C_REG}, + Optab{i: 13, as: ARNSBG, a1: C_SCON, a3: C_SCON, a4: C_SCON, a5: C_REG, a6: C_REG}, // compare and swap Optab{i: 79, as: ACSG, a1: C_REG, a2: C_REG, a6: C_SOREG}, @@ -953,6 +954,20 @@ func buildop(ctxt *obj.Link) { opset(ASRAW, r) opset(ARLL, r) opset(ARLLG, r) + case ARNSBG: + opset(ARXSBG, r) + opset(AROSBG, r) + opset(ARNSBGT, r) + opset(ARXSBGT, r) + opset(AROSBGT, r) + opset(ARISBG, r) + opset(ARISBGN, r) + opset(ARISBGZ, r) + opset(ARISBGNZ, r) + opset(ARISBHG, r) + opset(ARISBLG, r) + opset(ARISBHGZ, r) + opset(ARISBLGZ, r) case ACSG: opset(ACS, r) case ASUB: @@ -2993,6 +3008,37 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) { zRXY(opxy, uint32(r1), uint32(x2), uint32(b2), uint32(d2), asm) } + case 13: // rotate, followed by operation + r1 := p.To.Reg + r2 := p.RestArgs[2].Reg + i3 := uint8(p.From.Offset) // start + i4 := uint8(p.RestArgs[0].Offset) // end + i5 := uint8(p.RestArgs[1].Offset) // rotate amount + switch p.As { + case ARNSBGT, ARXSBGT, AROSBGT: + i3 |= 0x80 // test-results + case ARISBGZ, ARISBGNZ, ARISBHGZ, ARISBLGZ: + i4 |= 0x80 // zero-remaining-bits + } + var opcode uint32 + switch p.As { + case ARNSBG, ARNSBGT: + opcode = op_RNSBG + case ARXSBG, ARXSBGT: + opcode = op_RXSBG + case AROSBG, AROSBGT: + opcode = op_ROSBG + case ARISBG, ARISBGZ: + opcode = op_RISBG + case ARISBGN, ARISBGNZ: + opcode = op_RISBGN + case ARISBHG, ARISBHGZ: + opcode = op_RISBHG + case ARISBLG, ARISBLGZ: + opcode = op_RISBLG + } + zRIE(_f, uint32(opcode), uint32(r1), uint32(r2), 0, uint32(i3), uint32(i4), 0, uint32(i5), asm) + case 15: // br/bl (reg) r := p.To.Reg if p.As == ABCL || p.As == ABL { -- 2.48.1