diff --git a/src/cmd/asm/internal/asm/testdata/s390x.s b/src/cmd/asm/internal/asm/testdata/s390x.s index 95a8c50dab0..a19292b2636 100644 --- a/src/cmd/asm/internal/asm/testdata/s390x.s +++ b/src/cmd/asm/internal/asm/testdata/s390x.s @@ -263,10 +263,15 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16- NC $8, (R15), n-8(SP) // d407f010f000 OC $8, (R15), n-8(SP) // d607f010f000 MVC $8, (R15), n-8(SP) // d207f010f000 + MVC $256, 8192(R1), 8192(R2) // b90400a2c2a800002000b90400b1c2b800002000d2ffa000b000 MVCIN $8, (R15), n-8(SP) // e807f010f000 CLC $8, (R15), n-8(SP) // d507f000f010 XC $256, -8(R15), -8(R15) // b90400afc2a8fffffff8d7ffa000a000 - MVC $256, 8192(R1), 8192(R2) // b90400a2c2a800002000b90400b1c2b800002000d2ffa000b000 + MVCLE 0, R4, R6 // a8640000 + MVCLE 4095, R4, R6 // a8640fff + MVCLE $4095, R4, R6 // a8640fff + MVCLE (R3), R4, R6 // a8643000 + MVCLE 10(R3), R4, R6 // a864300a CMP R1, R2 // b9200012 CMP R3, $32767 // a73f7fff diff --git a/src/cmd/internal/obj/s390x/a.out.go b/src/cmd/internal/obj/s390x/a.out.go index 3eed4624b12..1a64370efa8 100644 --- a/src/cmd/internal/obj/s390x/a.out.go +++ b/src/cmd/internal/obj/s390x/a.out.go @@ -444,6 +444,7 @@ const ( // storage-and-storage AMVC AMVCIN + AMVCLE ACLC AXC AOC diff --git a/src/cmd/internal/obj/s390x/anames.go b/src/cmd/internal/obj/s390x/anames.go index ae86d2092b0..c0a0c401fa0 100644 --- a/src/cmd/internal/obj/s390x/anames.go +++ b/src/cmd/internal/obj/s390x/anames.go @@ -181,6 +181,7 @@ var Anames = []string{ "CMPUBNE", "MVC", "MVCIN", + "MVCLE", "CLC", "XC", "OC", diff --git a/src/cmd/internal/obj/s390x/asmz.go b/src/cmd/internal/obj/s390x/asmz.go index 6511549eeb3..72d92abbaf2 100644 --- a/src/cmd/internal/obj/s390x/asmz.go +++ b/src/cmd/internal/obj/s390x/asmz.go @@ -449,6 +449,10 @@ var optab = []Optab{ // VRR-f {i: 122, as: AVLVGP, a1: C_REG, a2: C_REG, a6: C_VREG}, + + // 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}, } var oprange [ALAST & obj.AMask][]Optab @@ -4453,6 +4457,24 @@ 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: + // NOTE: Mapping MVCLE operands is as follows: + // Instruction Format: MVCLE R1,R3,D2(B2) + // R1 - prog.To (for Destination) + // R3 - prog.Reg (for Source) + // B2 - prog.From (for Padding Byte) + d2 := c.regoff(&p.From) + if p.To.Reg&1 != 0 { + c.ctxt.Diag("output argument must be even register in %v", p) + } + if p.Reg&1 != 0 { + c.ctxt.Diag("input argument must be an even register in %v", p) + } + if (p.From.Reg == p.To.Reg) || (p.From.Reg == p.Reg) { + c.ctxt.Diag("padding byte register cannot be same as input or output register %v", p) + } + zRS(op_MVCLE, uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), uint32(d2), asm) } }