Commit db6f3bbc authored by Michael Munday's avatar Michael Munday

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 <munday@ca.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
parent 7d547b64
......@@ -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":
......
......@@ -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
}
......
......@@ -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
......
......@@ -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
......
......@@ -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,
......
......@@ -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)
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment