aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorMichael Munday <mike.munday@ibm.com>2019-01-24 16:16:41 +0000
committerMichael Munday <mike.munday@ibm.com>2019-04-16 09:17:24 +0000
commit0f79510dc5d2e586924dae6e531529fe5fa7cbd2 (patch)
treece1eba2fdaeb3f2e0df1b83d91139c20176cfa19 /src/cmd
parent9c843f031d31d85891d08f68ca5e6009a83bb0ce (diff)
downloadgo-0f79510dc5d2e586924dae6e531529fe5fa7cbd2.tar.xz
cmd/asm: add s390x 'rotate then ... selected bits' instructions
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 <mike.munday@ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/asm/internal/asm/asm.go6
-rw-r--r--src/cmd/asm/internal/asm/testdata/s390x.s15
-rw-r--r--src/cmd/internal/obj/s390x/a.out.go14
-rw-r--r--src/cmd/internal/obj/s390x/anames.go14
-rw-r--r--src/cmd/internal/obj/s390x/asmz.go46
5 files changed, 95 insertions, 0 deletions
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 {