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) } }