From: Michael Munday Date: Tue, 11 Apr 2017 18:30:18 +0000 (-0400) Subject: cmd: fix the order that s390x operands are printed in X-Git-Tag: go1.9beta1~488 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=db6f3bbc9a2d35a9b310f4d9ded1f1d63ef48234;p=gostls13.git cmd: fix the order that s390x operands are printed in The assembler reordered the operands of some instructions to put the first operand into From3. Unfortunately this meant that when the instructions were printed the operands were in a different order than the assembler would expect as input. For example, 'MVC $8, (R1), (R2)' would be printed as 'MVC (R1), $8, (R2)'. Originally this was done to ensure that From contained the source memory operand. The current compiler no longer requires this and so this CL simply makes all instructions use the standard order for operands: From, Reg, From3 and finally To. Fixes #18295 Change-Id: Ib2b5ec29c647ca7a995eb03dc78f82d99618b092 Reviewed-on: https://go-review.googlesource.com/40299 Run-TryBot: Michael Munday TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang --- diff --git a/src/cmd/asm/internal/arch/s390x.go b/src/cmd/asm/internal/arch/s390x.go index 115f7e06d8..d6d46f86f2 100644 --- a/src/cmd/asm/internal/arch/s390x.go +++ b/src/cmd/asm/internal/arch/s390x.go @@ -68,38 +68,6 @@ func IsS390xNEG(op obj.As) bool { return false } -// IsS390xWithLength reports whether the op (as defined by an s390x.A* constant) -// refers to an instruction which takes a length as its first argument. -func IsS390xWithLength(op obj.As) bool { - switch op { - case s390x.AMVC, s390x.ACLC, s390x.AXC, s390x.AOC, s390x.ANC: - return true - case s390x.AVLL, s390x.AVSTL: - return true - } - return false -} - -// IsS390xWithIndex reports whether the op (as defined by an s390x.A* constant) -// refers to an instruction which takes an index as its first argument. -func IsS390xWithIndex(op obj.As) bool { - switch op { - case s390x.AVSCEG, s390x.AVSCEF, s390x.AVGEG, s390x.AVGEF: - return true - case s390x.AVGMG, s390x.AVGMF, s390x.AVGMH, s390x.AVGMB: - return true - case s390x.AVLEIG, s390x.AVLEIF, s390x.AVLEIH, s390x.AVLEIB: - return true - case s390x.AVLEG, s390x.AVLEF, s390x.AVLEH, s390x.AVLEB: - return true - case s390x.AVSTEG, s390x.AVSTEF, s390x.AVSTEH, s390x.AVSTEB: - return true - case s390x.AVPDI: - return true - } - return false -} - func s390xRegisterNumber(name string, n int16) (int16, bool) { switch name { case "AR": diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go index b0df240997..fa32e76f33 100644 --- a/src/cmd/asm/internal/asm/asm.go +++ b/src/cmd/asm/internal/asm/asm.go @@ -623,12 +623,11 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { return } case sys.S390X: - if arch.IsS390xWithLength(op) || arch.IsS390xWithIndex(op) { - prog.From = a[1] - prog.From3 = newAddr(a[0]) - } else { + prog.From = a[0] + if a[1].Type == obj.TYPE_REG { prog.Reg = p.getRegister(prog, op, &a[1]) - prog.From = a[0] + } else { + prog.From3 = newAddr(a[1]) } prog.To = a[2] default: @@ -711,9 +710,13 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { } } if p.arch.Family == sys.S390X { - prog.From = a[1] - prog.Reg = p.getRegister(prog, op, &a[2]) - prog.From3 = newAddr(a[0]) + if a[1].Type != obj.TYPE_REG { + p.errorf("second operand must be a register in %s instruction", op) + return + } + prog.From = a[0] + prog.Reg = p.getRegister(prog, op, &a[1]) + prog.From3 = newAddr(a[2]) prog.To = a[3] break } diff --git a/src/cmd/asm/internal/asm/testdata/s390x.s b/src/cmd/asm/internal/asm/testdata/s390x.s index 0bc06f137f..d8688e7ba6 100644 --- a/src/cmd/asm/internal/asm/testdata/s390x.s +++ b/src/cmd/asm/internal/asm/testdata/s390x.s @@ -186,13 +186,13 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16- LAO R1, R2, (R3) // eb21300000f6 LAOG R4, R5, (R6) // eb54600000e6 - XC $8, (R15), n-8(SP) // XC (R15), $8, n-8(SP) // d707f010f000 - NC $8, (R15), n-8(SP) // NC (R15), $8, n-8(SP) // d407f010f000 - OC $8, (R15), n-8(SP) // OC (R15), $8, n-8(SP) // d607f010f000 - MVC $8, (R15), n-8(SP) // MVC (R15), $8, n-8(SP) // d207f010f000 - CLC $8, (R15), n-8(SP) // CLC (R15), $8, n-8(SP) // d507f000f010 - XC $256, -8(R15), -8(R15) // XC -8(R15), $256, -8(R15) // b90400afc2a8fffffff8d7ffa000a000 - MVC $256, 8192(R1), 8192(R2) // MVC 8192(R1), $256, 8192(R2) // b90400a2c2a800002000b90400b1c2b800002000d2ffa000b000 + XC $8, (R15), n-8(SP) // d707f010f000 + NC $8, (R15), n-8(SP) // d407f010f000 + OC $8, (R15), n-8(SP) // d607f010f000 + MVC $8, (R15), n-8(SP) // d207f010f000 + CLC $8, (R15), n-8(SP) // d507f000f010 + XC $256, -8(R15), -8(R15) // b90400afc2a8fffffff8d7ffa000a000 + MVC $256, 8192(R1), 8192(R2) // b90400a2c2a800002000b90400b1c2b800002000d2ffa000b000 CMP R1, R2 // b9200012 CMP R3, $32767 // a73f7fff @@ -291,67 +291,64 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16- FMSUB F4, F5, F5 // b31f5045 FMSUBS F6, F6, F7 // b30f7066 - VL (R15), V1 // e710f0000006 - VST V1, (R15) // e710f000000e - VL (R15), V31 // e7f0f0000806 - VST V31, (R15) // e7f0f000080e - VESLB $5, V14 // e7ee00050030 - VESRAG $0, V15, V16 // e70f0000383a - VLM (R15), V8, V23 // e787f0000436 - VSTM V8, V23, (R15) // e787f000043e - VONE V1 // e710ffff0044 - VZERO V16 // e70000000844 - VGBM $52428, V31 // e7f0cccc0844 - VREPIB $255, V4 // e74000ff0045 - VREPIH $-1, V16 // e700ffff1845 - VREPIF $-32768, V0 // e70080002045 - VREPIG $32767, V31 // e7f07fff3845 - VREPG $1, V4, V16 // e7040001384d - VREPB $4, V31, V1 // e71f0004044d - VFTCIDB $4095, V1, V2 // e721fff0304a - WFTCIDB $3276, V15, V16 // e70fccc8384a - VPOPCT V8, V19 // e73800000850 - VFEEZBS V1, V2, V31 // e7f120300880 - WFCHDBS V22, V23, V4 // e746701836eb - VMNH V1, V2, V30 // e7e1200018fe - VO V2, V1, V0 // e7021000006a - VERLLVF V2, V30, V27 // e7be20002c73 - VSCBIB V0, V23, V24 // e78700000cf5 - VNOT V16, V1 // e7101000046b - VCLZF V16, V17 // e71000002c53 - VLVGP R3, R4, V8 // e78340000062 - - // Some vector instructions have their inputs reordered. - // Typically the reordering puts the length/index input into From3. - VGEG $1, 8(R15)(V30*1), V31 // VGEG 8(R15)(V30*1), $1, V31 // e7fef0081c12 - VSCEG $1, V31, 16(R15)(V30*1) // VSCEG V31, $1, 16(R15)(V30*1) // e7fef0101c1a - VGEF $0, 2048(R15)(V1*1), V2 // VGEF 2048(R15)(V1*1), $0, V2 // e721f8000013 - VSCEF $0, V2, 4095(R15)(V1*1) // VSCEF V2, $0, 4095(R15)(V1*1) // e721ffff001b - VLL R0, (R15), V1 // VLL (R15), R0, V1 // e710f0000037 - VSTL R0, V16, (R15) // VSTL V16, R0, (R15) // e700f000083f - VGMH $8, $16, V12 // VGMH $16, $8, V12 // e7c008101046 - VLEIB $15, $255, V0 // VLEIB $255, $15, V0 // e70000fff040 - VLEIH $7, $-32768, V15 // VLEIH $-32768, $7, V15 // e7f080007041 - VLEIF $2, $-43, V16 // VLEIF $-43, $2, V16 // e700ffd52843 - VLEIG $1, $32767, V31 // VLEIG $32767, $1, V31 // e7f07fff1842 - VSLDB $3, V1, V16, V18 // VSLDB V1, V16, $3, V18 // e72100030a77 - VERIMB $2, V31, V1, V2 // VERIMB V31, V1, $2, V2 // e72f10020472 - VSEL V1, V2, V3, V4 // VSEL V2, V3, V1, V4 // e7412000308d - VGFMAH V21, V31, V24, V0 // VGFMAH V31, V24, V21, V0 // e705f10087bc - VFMADB V16, V8, V9, V10 // VFMADB V8, V9, V16, V10 // e7a08300948f - WFMADB V17, V18, V19, V20 // WFMADB V18, V19, V17, V20 // e74123083f8f - VFMSDB V2, V25, V24, V31 // VFMSDB V25, V24, V2, V31 // e7f293008b8e - WFMSDB V31, V2, V3, V4 // WFMSDB V2, V3, V31, V4 // e74f2308348e - VPERM V31, V0, V2, V3 // VPERM V0, V2, V31, V3 // e73f0000248c - VPDI $1, V2, V31, V1 // VPDI V2, V31, $1, V1 // e712f0001284 - VLEG $1, (R3), V1 // VLEG (R3), $1, V1 // e71030001002 - VLEF $2, (R0), V31 // VLEF (R0), $2, V31 // e7f000002803 - VLEH $3, (R12), V16 // VLEH (R12), $3, V16 // e700c0003801 - VLEB $15, 4095(R9), V15 // VLEB 4095(R9), $15, V15 // e7f09ffff000 - VSTEG $1, V30, (R1)(R2*1) // VSTEG V30, $1, (R1)(R2*1) // e7e21000180a - VSTEF $3, V2, (R9) // VSTEF V2, $3, (R9) // e7209000300b - VSTEH $7, V31, (R2) // VSTEH V31, $7, (R2) // e7f020007809 - VSTEB $15, V29, 4094(R12) // VSTEB V29, $15, 4094(R12) // e7d0cffef808 + VL (R15), V1 // e710f0000006 + VST V1, (R15) // e710f000000e + VL (R15), V31 // e7f0f0000806 + VST V31, (R15) // e7f0f000080e + VESLB $5, V14 // e7ee00050030 + VESRAG $0, V15, V16 // e70f0000383a + VLM (R15), V8, V23 // e787f0000436 + VSTM V8, V23, (R15) // e787f000043e + VONE V1 // e710ffff0044 + VZERO V16 // e70000000844 + VGBM $52428, V31 // e7f0cccc0844 + VREPIB $255, V4 // e74000ff0045 + VREPIH $-1, V16 // e700ffff1845 + VREPIF $-32768, V0 // e70080002045 + VREPIG $32767, V31 // e7f07fff3845 + VREPG $1, V4, V16 // e7040001384d + VREPB $4, V31, V1 // e71f0004044d + VFTCIDB $4095, V1, V2 // e721fff0304a + WFTCIDB $3276, V15, V16 // e70fccc8384a + VPOPCT V8, V19 // e73800000850 + VFEEZBS V1, V2, V31 // e7f120300880 + WFCHDBS V22, V23, V4 // e746701836eb + VMNH V1, V2, V30 // e7e1200018fe + VO V2, V1, V0 // e7021000006a + VERLLVF V2, V30, V27 // e7be20002c73 + VSCBIB V0, V23, V24 // e78700000cf5 + VNOT V16, V1 // e7101000046b + VCLZF V16, V17 // e71000002c53 + VLVGP R3, R4, V8 // e78340000062 + VGEG $1, 8(R15)(V30*1), V31 // e7fef0081c12 + VSCEG $1, V31, 16(R15)(V30*1) // e7fef0101c1a + VGEF $0, 2048(R15)(V1*1), V2 // e721f8000013 + VSCEF $0, V2, 4095(R15)(V1*1) // e721ffff001b + VLL R0, (R15), V1 // e710f0000037 + VSTL R0, V16, (R15) // e700f000083f + VGMH $8, $16, V12 // e7c008101046 + VLEIB $15, $255, V0 // e70000fff040 + VLEIH $7, $-32768, V15 // e7f080007041 + VLEIF $2, $-43, V16 // e700ffd52843 + VLEIG $1, $32767, V31 // e7f07fff1842 + VSLDB $3, V1, V16, V18 // e72100030a77 + VERIMB $2, V31, V1, V2 // e72f10020472 + VSEL V1, V2, V3, V4 // e7412000308d + VGFMAH V21, V31, V24, V0 // e705f10087bc + VFMADB V16, V8, V9, V10 // e7a08300948f + WFMADB V17, V18, V19, V20 // e74123083f8f + VFMSDB V2, V25, V24, V31 // e7f293008b8e + WFMSDB V31, V2, V3, V4 // e74f2308348e + VPERM V31, V0, V2, V3 // e73f0000248c + VPDI $1, V2, V31, V1 // e712f0001284 + VLEG $1, (R3), V1 // e71030001002 + VLEF $2, (R0), V31 // e7f000002803 + VLEH $3, (R12), V16 // e700c0003801 + VLEB $15, 4095(R9), V15 // e7f09ffff000 + VSTEG $1, V30, (R1)(R2*1) // e7e21000180a + VSTEF $3, V2, (R9) // e7209000300b + VSTEH $7, V31, (R2) // e7f020007809 + VSTEB $15, V29, 4094(R12) // e7d0cffef808 RET diff --git a/src/cmd/compile/internal/s390x/ggen.go b/src/cmd/compile/internal/s390x/ggen.go index 36e30a5fee..f1ab5b0ddc 100644 --- a/src/cmd/compile/internal/s390x/ggen.go +++ b/src/cmd/compile/internal/s390x/ggen.go @@ -42,10 +42,7 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog { end := int16(s390x.REGRT2) p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, off+n, obj.TYPE_REG, end, 0) p.Reg = reg - p = pp.Appendpp(p, s390x.AXC, obj.TYPE_MEM, reg, off, obj.TYPE_MEM, reg, off) - p.From3 = new(obj.Addr) - p.From3.Type = obj.TYPE_CONST - p.From3.Offset = 256 + p = pp.Appendpp(p, s390x.ACLEAR, obj.TYPE_CONST, 0, 256, obj.TYPE_MEM, reg, off) pl := p p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, 256, obj.TYPE_REG, reg, 0) p = pp.Appendpp(p, s390x.ACMP, obj.TYPE_REG, reg, 0, obj.TYPE_REG, end, 0) @@ -78,12 +75,9 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog { } p = pp.Appendpp(p, ins, obj.TYPE_CONST, 0, 0, obj.TYPE_MEM, reg, off) - // Handle clears that would require multiple move instructions with XC. + // Handle clears that would require multiple move instructions with CLEAR (assembled as XC). default: - p = pp.Appendpp(p, s390x.AXC, obj.TYPE_MEM, reg, off, obj.TYPE_MEM, reg, off) - p.From3 = new(obj.Addr) - p.From3.Type = obj.TYPE_CONST - p.From3.Offset = n + p = pp.Appendpp(p, s390x.ACLEAR, obj.TYPE_CONST, 0, n, obj.TYPE_MEM, reg, off) } cnt -= n diff --git a/src/cmd/compile/internal/s390x/ssa.go b/src/cmd/compile/internal/s390x/ssa.go index 9ccd3c762c..d755859dcf 100644 --- a/src/cmd/compile/internal/s390x/ssa.go +++ b/src/cmd/compile/internal/s390x/ssa.go @@ -531,15 +531,15 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { case ssa.OpS390XMVC: vo := v.AuxValAndOff() p := s.Prog(s390x.AMVC) - p.From.Type = obj.TYPE_MEM - p.From.Reg = v.Args[1].Reg() - p.From.Offset = vo.Off() + p.From.Type = obj.TYPE_CONST + p.From.Offset = vo.Val() + p.From3 = new(obj.Addr) + p.From3.Type = obj.TYPE_MEM + p.From3.Reg = v.Args[1].Reg() + p.From3.Offset = vo.Off() p.To.Type = obj.TYPE_MEM p.To.Reg = v.Args[0].Reg() p.To.Offset = vo.Off() - p.From3 = new(obj.Addr) - p.From3.Type = obj.TYPE_CONST - p.From3.Offset = vo.Val() case ssa.OpS390XSTMG2, ssa.OpS390XSTMG3, ssa.OpS390XSTMG4, ssa.OpS390XSTM2, ssa.OpS390XSTM3, ssa.OpS390XSTM4: for i := 2; i < len(v.Args)-1; i++ { @@ -567,13 +567,13 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { // MVC $rem, 0(R2), 0(R1) // if rem > 0 // arg2 is the last address to move in the loop + 256 mvc := s.Prog(s390x.AMVC) - mvc.From.Type = obj.TYPE_MEM - mvc.From.Reg = v.Args[1].Reg() + mvc.From.Type = obj.TYPE_CONST + mvc.From.Offset = 256 + mvc.From3 = new(obj.Addr) + mvc.From3.Type = obj.TYPE_MEM + mvc.From3.Reg = v.Args[1].Reg() mvc.To.Type = obj.TYPE_MEM mvc.To.Reg = v.Args[0].Reg() - mvc.From3 = new(obj.Addr) - mvc.From3.Type = obj.TYPE_CONST - mvc.From3.Offset = 256 for i := 0; i < 2; i++ { movd := s.Prog(s390x.AMOVD) @@ -596,13 +596,13 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { if v.AuxInt > 0 { mvc := s.Prog(s390x.AMVC) - mvc.From.Type = obj.TYPE_MEM - mvc.From.Reg = v.Args[1].Reg() + mvc.From.Type = obj.TYPE_CONST + mvc.From.Offset = v.AuxInt + mvc.From3 = new(obj.Addr) + mvc.From3.Type = obj.TYPE_MEM + mvc.From3.Reg = v.Args[1].Reg() mvc.To.Type = obj.TYPE_MEM mvc.To.Reg = v.Args[0].Reg() - mvc.From3 = new(obj.Addr) - mvc.From3.Type = obj.TYPE_CONST - mvc.From3.Offset = v.AuxInt } case ssa.OpS390XLoweredZero: // Input must be valid pointers to memory, diff --git a/src/cmd/internal/obj/s390x/asmz.go b/src/cmd/internal/obj/s390x/asmz.go index 7b25b88fa8..df466d6d92 100644 --- a/src/cmd/internal/obj/s390x/asmz.go +++ b/src/cmd/internal/obj/s390x/asmz.go @@ -276,9 +276,9 @@ var optab = []Optab{ Optab{ASTCK, C_NONE, C_NONE, C_NONE, C_SOREG, 88, 0}, // storage and storage - Optab{AMVC, C_LOREG, C_NONE, C_SCON, C_LOREG, 84, 0}, - Optab{AMVC, C_LOREG, C_NONE, C_SCON, C_LAUTO, 84, REGSP}, - Optab{AMVC, C_LAUTO, C_NONE, C_SCON, C_LAUTO, 84, REGSP}, + Optab{AMVC, C_SCON, C_NONE, C_LOREG, C_LOREG, 84, 0}, + Optab{AMVC, C_SCON, C_NONE, C_LOREG, C_LAUTO, 84, REGSP}, + Optab{AMVC, C_SCON, C_NONE, C_LAUTO, C_LAUTO, 84, REGSP}, // address Optab{ALARL, C_LCON, C_NONE, C_NONE, C_REG, 85, 0}, @@ -299,22 +299,22 @@ var optab = []Optab{ // VRX store Optab{AVST, C_VREG, C_NONE, C_NONE, C_SOREG, 100, 0}, Optab{AVST, C_VREG, C_NONE, C_NONE, C_SAUTO, 100, REGSP}, - Optab{AVSTEG, C_VREG, C_NONE, C_SCON, C_SOREG, 100, 0}, - Optab{AVSTEG, C_VREG, C_NONE, C_SCON, C_SAUTO, 100, REGSP}, + Optab{AVSTEG, C_SCON, C_VREG, C_NONE, C_SOREG, 100, 0}, + Optab{AVSTEG, C_SCON, C_VREG, C_NONE, C_SAUTO, 100, REGSP}, // VRX load Optab{AVL, C_SOREG, C_NONE, C_NONE, C_VREG, 101, 0}, Optab{AVL, C_SAUTO, C_NONE, C_NONE, C_VREG, 101, REGSP}, - Optab{AVLEG, C_SOREG, C_NONE, C_SCON, C_VREG, 101, 0}, - Optab{AVLEG, C_SAUTO, C_NONE, C_SCON, C_VREG, 101, REGSP}, + Optab{AVLEG, C_SCON, C_NONE, C_SOREG, C_VREG, 101, 0}, + Optab{AVLEG, C_SCON, C_NONE, C_SAUTO, C_VREG, 101, REGSP}, // VRV scatter - Optab{AVSCEG, C_VREG, C_NONE, C_SCON, C_SOREG, 102, 0}, - Optab{AVSCEG, C_VREG, C_NONE, C_SCON, C_SAUTO, 102, REGSP}, + Optab{AVSCEG, C_SCON, C_VREG, C_NONE, C_SOREG, 102, 0}, + Optab{AVSCEG, C_SCON, C_VREG, C_NONE, C_SAUTO, 102, REGSP}, // VRV gather - Optab{AVGEG, C_SOREG, C_NONE, C_SCON, C_VREG, 103, 0}, - Optab{AVGEG, C_SAUTO, C_NONE, C_SCON, C_VREG, 103, REGSP}, + Optab{AVGEG, C_SCON, C_NONE, C_SOREG, C_VREG, 103, 0}, + Optab{AVGEG, C_SCON, C_NONE, C_SAUTO, C_VREG, 103, REGSP}, // VRS element shift/rotate and load gr to/from vr element Optab{AVESLG, C_SCON, C_VREG, C_NONE, C_VREG, 104, 0}, @@ -335,19 +335,19 @@ var optab = []Optab{ Optab{AVLM, C_SAUTO, C_VREG, C_NONE, C_VREG, 106, REGSP}, // VRS store with length - Optab{AVSTL, C_VREG, C_NONE, C_REG, C_SOREG, 107, 0}, - Optab{AVSTL, C_VREG, C_NONE, C_REG, C_SAUTO, 107, REGSP}, + Optab{AVSTL, C_REG, C_VREG, C_NONE, C_SOREG, 107, 0}, + Optab{AVSTL, C_REG, C_VREG, C_NONE, C_SAUTO, 107, REGSP}, // VRS load with length - Optab{AVLL, C_SOREG, C_NONE, C_REG, C_VREG, 108, 0}, - Optab{AVLL, C_SAUTO, C_NONE, C_REG, C_VREG, 108, REGSP}, + Optab{AVLL, C_REG, C_NONE, C_SOREG, C_VREG, 108, 0}, + Optab{AVLL, C_REG, C_NONE, C_SAUTO, C_VREG, 108, REGSP}, // VRI-a Optab{AVGBM, C_ANDCON, C_NONE, C_NONE, C_VREG, 109, 0}, Optab{AVZERO, C_NONE, C_NONE, C_NONE, C_VREG, 109, 0}, Optab{AVREPIG, C_ADDCON, C_NONE, C_NONE, C_VREG, 109, 0}, Optab{AVREPIG, C_SCON, C_NONE, C_NONE, C_VREG, 109, 0}, - Optab{AVLEIG, C_ADDCON, C_NONE, C_SCON, C_VREG, 109, 0}, + Optab{AVLEIG, C_SCON, C_NONE, C_ADDCON, C_VREG, 109, 0}, Optab{AVLEIG, C_SCON, C_NONE, C_SCON, C_VREG, 109, 0}, // VRI-b generate mask @@ -358,8 +358,8 @@ var optab = []Optab{ // VRI-d element rotate and insert under mask and // shift left double by byte - Optab{AVERIMG, C_VREG, C_VREG, C_SCON, C_VREG, 112, 0}, - Optab{AVSLDB, C_VREG, C_VREG, C_SCON, C_VREG, 112, 0}, + Optab{AVERIMG, C_SCON, C_VREG, C_VREG, C_VREG, 112, 0}, + Optab{AVSLDB, C_SCON, C_VREG, C_VREG, C_VREG, 112, 0}, // VRI-d fp test data class immediate Optab{AVFTCIDB, C_SCON, C_VREG, C_NONE, C_VREG, 113, 0}, @@ -379,7 +379,7 @@ var optab = []Optab{ Optab{AVAQ, C_VREG, C_VREG, C_NONE, C_VREG, 118, 0}, Optab{AVAQ, C_VREG, C_NONE, C_NONE, C_VREG, 118, 0}, Optab{AVNOT, C_VREG, C_NONE, C_NONE, C_VREG, 118, 0}, - Optab{AVPDI, C_VREG, C_VREG, C_SCON, C_VREG, 123, 0}, + Optab{AVPDI, C_SCON, C_VREG, C_VREG, C_VREG, 123, 0}, // VRR-c shifts Optab{AVERLLVG, C_VREG, C_VREG, C_NONE, C_VREG, 119, 0}, @@ -3542,16 +3542,16 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) { // M4 is reserved and must be 0 zRRF(opcode, 5, 0, uint32(p.To.Reg), uint32(p.From.Reg), asm) - case 84: // storage-and-storage operations $length mem mem (length in From3) - l := c.regoff(p.From3) + case 84: // storage-and-storage operations $length mem mem + l := c.regoff(&p.From) if l < 1 || l > 256 { c.ctxt.Diag("number of bytes (%v) not in range [1,256]", l) } - if p.From.Index != 0 || p.To.Index != 0 { + if p.From3.Index != 0 || p.To.Index != 0 { c.ctxt.Diag("cannot use index reg") } b1 := p.To.Reg - b2 := p.From.Reg + b2 := p.From3.Reg if b1 == 0 { b1 = o.param } @@ -3559,7 +3559,7 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) { b2 = o.param } d1 := c.regoff(&p.To) - d2 := c.regoff(&p.From) + d2 := c.regoff(p.From3) if d1 < 0 || d1 >= DISP12 { if b2 == REGTMP { c.ctxt.Diag("REGTMP conflict") @@ -3891,51 +3891,51 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) { case 100: // VRX STORE op, m3, _ := vop(p.As) - if p.From3 != nil { - m3 = uint32(c.vregoff(p.From3)) + v1 := p.From.Reg + if p.Reg != 0 { + m3 = uint32(c.vregoff(&p.From)) + v1 = p.Reg } b2 := p.To.Reg if b2 == 0 { b2 = o.param } d2 := uint32(c.vregoff(&p.To)) - zVRX(op, uint32(p.From.Reg), uint32(p.To.Index), uint32(b2), d2, m3, asm) + zVRX(op, uint32(v1), uint32(p.To.Index), uint32(b2), d2, m3, asm) case 101: // VRX LOAD op, m3, _ := vop(p.As) + src := &p.From if p.From3 != nil { - m3 = uint32(c.vregoff(p.From3)) + m3 = uint32(c.vregoff(&p.From)) + src = p.From3 } - b2 := p.From.Reg + b2 := src.Reg if b2 == 0 { b2 = o.param } - d2 := uint32(c.vregoff(&p.From)) - zVRX(op, uint32(p.To.Reg), uint32(p.From.Index), uint32(b2), d2, m3, asm) + d2 := uint32(c.vregoff(src)) + zVRX(op, uint32(p.To.Reg), uint32(src.Index), uint32(b2), d2, m3, asm) case 102: // VRV SCATTER - op, m3, _ := vop(p.As) - if p.From3 != nil { - m3 = uint32(c.vregoff(p.From3)) - } + op, _, _ := vop(p.As) + m3 := uint32(c.vregoff(&p.From)) b2 := p.To.Reg if b2 == 0 { b2 = o.param } d2 := uint32(c.vregoff(&p.To)) - zVRV(op, uint32(p.From.Reg), uint32(p.To.Index), uint32(b2), d2, m3, asm) + zVRV(op, uint32(p.Reg), uint32(p.To.Index), uint32(b2), d2, m3, asm) case 103: // VRV GATHER - op, m3, _ := vop(p.As) - if p.From3 != nil { - m3 = uint32(c.vregoff(p.From3)) - } - b2 := p.From.Reg + op, _, _ := vop(p.As) + m3 := uint32(c.vregoff(&p.From)) + b2 := p.From3.Reg if b2 == 0 { b2 = o.param } - d2 := uint32(c.vregoff(&p.From)) - zVRV(op, uint32(p.To.Reg), uint32(p.From.Index), uint32(b2), d2, m3, asm) + d2 := uint32(c.vregoff(p.From3)) + zVRV(op, uint32(p.To.Reg), uint32(p.From3.Index), uint32(b2), d2, m3, asm) case 104: // VRS SHIFT/ROTATE and LOAD GR FROM VR ELEMENT op, m4, _ := vop(p.As) @@ -3971,35 +3971,36 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) { if reg == 0 { reg = o.param } - zVRS(op, uint32(p.From.Reg), uint32(p.From3.Reg), uint32(reg), offset, 0, asm) + zVRS(op, uint32(p.Reg), uint32(p.From.Reg), uint32(reg), offset, 0, asm) case 108: // VRS LOAD WITH LENGTH op, _, _ := vop(p.As) - offset := uint32(c.vregoff(&p.From)) - reg := p.From.Reg + offset := uint32(c.vregoff(p.From3)) + reg := p.From3.Reg if reg == 0 { reg = o.param } - zVRS(op, uint32(p.To.Reg), uint32(p.From3.Reg), uint32(reg), offset, 0, asm) + zVRS(op, uint32(p.To.Reg), uint32(p.From.Reg), uint32(reg), offset, 0, asm) case 109: // VRI-a op, m3, _ := vop(p.As) i2 := uint32(c.vregoff(&p.From)) + if p.From3 != nil { + m3 = uint32(c.vregoff(&p.From)) + i2 = uint32(c.vregoff(p.From3)) + } switch p.As { case AVZERO: i2 = 0 case AVONE: i2 = 0xffff } - if p.From3 != nil { - m3 = uint32(c.vregoff(p.From3)) - } zVRIa(op, uint32(p.To.Reg), i2, m3, asm) case 110: op, m4, _ := vop(p.As) - i2 := uint32(c.vregoff(p.From3)) - i3 := uint32(c.vregoff(&p.From)) + i2 := uint32(c.vregoff(&p.From)) + i3 := uint32(c.vregoff(p.From3)) zVRIb(op, uint32(p.To.Reg), i2, i3, m4, asm) case 111: @@ -4009,8 +4010,8 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) { case 112: op, m5, _ := vop(p.As) - i4 := uint32(c.vregoff(p.From3)) - zVRId(op, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), i4, m5, asm) + i4 := uint32(c.vregoff(&p.From)) + zVRId(op, uint32(p.To.Reg), uint32(p.Reg), uint32(p.From3.Reg), i4, m5, asm) case 113: op, m4, _ := vop(p.As) @@ -4028,8 +4029,6 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) { m4 := singleElementMask(p.As) zVRRa(op, uint32(p.From.Reg), uint32(p.To.Reg), m5, m4, m3, asm) - case 116: // VRR-a - case 117: // VRR-b op, m4, m5 := vop(p.As) zVRRb(op, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), m5, m4, asm) @@ -4056,18 +4055,18 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) { op, m6, _ := vop(p.As) m5 := singleElementMask(p.As) v1 := uint32(p.To.Reg) - v2 := uint32(p.From3.Reg) - v3 := uint32(p.From.Reg) - v4 := uint32(p.Reg) + v2 := uint32(p.From.Reg) + v3 := uint32(p.Reg) + v4 := uint32(p.From3.Reg) zVRRd(op, v1, v2, v3, m6, m5, v4, asm) case 121: // VRR-e op, m6, _ := vop(p.As) m5 := singleElementMask(p.As) v1 := uint32(p.To.Reg) - v2 := uint32(p.From3.Reg) - v3 := uint32(p.From.Reg) - v4 := uint32(p.Reg) + v2 := uint32(p.From.Reg) + v3 := uint32(p.Reg) + v4 := uint32(p.From3.Reg) zVRRe(op, v1, v2, v3, m6, m5, v4, asm) case 122: // VRR-f LOAD VRS FROM GRS DISJOINT @@ -4076,8 +4075,8 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) { case 123: // VPDI $m4, V2, V3, V1 op, _, _ := vop(p.As) - m4 := c.regoff(p.From3) - zVRRc(op, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), 0, 0, uint32(m4), asm) + m4 := c.regoff(&p.From) + zVRRc(op, uint32(p.To.Reg), uint32(p.Reg), uint32(p.From3.Reg), 0, 0, uint32(m4), asm) } }