mirror of
https://github.com/golang/go
synced 2024-11-05 15:36:09 -07:00
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: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
7d547b6411
commit
db6f3bbc9a
@ -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
|
||||
}
|
||||
|
133
src/cmd/asm/internal/asm/testdata/s390x.s
vendored
133
src/cmd/asm/internal/asm/testdata/s390x.s
vendored
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user