aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sing <joel@sing.id.au>2023-01-08 03:00:21 +1100
committerJoel Sing <joel@sing.id.au>2023-08-03 16:17:47 +0000
commit499a12009938fe2ffff90775832b9d67ca3e46b2 (patch)
treed02d6011e4d47cd1ee39384ff3c392b03f90fb35
parent9ff01162295c815c252dec812f6ce983aa90a62b (diff)
downloadgo-499a12009938fe2ffff90775832b9d67ca3e46b2.tar.gz
go-499a12009938fe2ffff90775832b9d67ca3e46b2.zip
cmd/internal/obj/arm64: move register encoding into opxrrr
Rather than having register encoding knowledge in each caller of opxrrr, pass the registers into opxrrr and let it handle the encoding. This reduces duplication and improves readability. Change-Id: I202c503465a0169277a0f64340598203c9dcf20c Reviewed-on: https://go-review.googlesource.com/c/go/+/461140 Run-TryBot: Joel Sing <joel@sing.id.au> Reviewed-by: David Chase <drchase@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
-rw-r--r--src/cmd/internal/obj/arm64/asm7.go109
1 files changed, 50 insertions, 59 deletions
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index ea53a838e3..2b8c2180f5 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -3684,26 +3684,24 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
if num == 0 {
c.ctxt.Diag("invalid constant: %v", p)
}
- rt := int(p.To.Reg)
+
+ rt, r, rf := p.To.Reg, p.Reg, int16(REGTMP)
if p.To.Type == obj.TYPE_NONE {
rt = REGZERO
}
- r := int(p.Reg)
if r == obj.REG_NONE {
r = rt
}
- if p.To.Type != obj.TYPE_NONE && (p.To.Reg == REGSP || r == REGSP) {
- o = c.opxrrr(p, p.As, false)
- o |= REGTMP & 31 << 16
+ if p.To.Type != obj.TYPE_NONE && (rt == REGSP || r == REGSP) {
+ o = c.opxrrr(p, p.As, rt, r, rf, false)
o |= LSL0_64
} else {
o = c.oprrr(p, p.As)
- o |= REGTMP & 31 << 16 /* shift is 0 */
+ o |= uint32(rf&31) << 16 /* shift is 0 */
+ o |= uint32(r&31) << 5
+ o |= uint32(rt & 31)
}
- o |= uint32(r&31) << 5
- o |= uint32(rt & 31)
-
os[num] = o
o1 = os[0]
o2 = os[1]
@@ -3947,27 +3945,24 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
if p.To.Reg == REG_RSP && isADDSop(p.As) {
c.ctxt.Diag("illegal destination register: %v\n", p)
}
+ rt, r, rf := p.To.Reg, p.Reg, p.From.Reg
+ if p.To.Type == obj.TYPE_NONE {
+ rt = REGZERO
+ }
+ if r == obj.REG_NONE {
+ r = rt
+ }
if (p.From.Reg-obj.RBaseARM64)&REG_EXT != 0 ||
(p.From.Reg >= REG_LSL && p.From.Reg < REG_ARNG) {
amount := (p.From.Reg >> 5) & 7
if amount > 4 {
c.ctxt.Diag("shift amount out of range 0 to 4: %v", p)
}
- o1 = c.opxrrr(p, p.As, true)
+ o1 = c.opxrrr(p, p.As, rt, r, obj.REG_NONE, true)
o1 |= c.encRegShiftOrExt(p, &p.From, p.From.Reg) /* includes reg, op, etc */
} else {
- o1 = c.opxrrr(p, p.As, false)
- o1 |= uint32(p.From.Reg&31) << 16
- }
- rt := int(p.To.Reg)
- if p.To.Type == obj.TYPE_NONE {
- rt = REGZERO
- }
- r := int(p.Reg)
- if r == obj.REG_NONE {
- r = rt
+ o1 = c.opxrrr(p, p.As, rt, r, rf, false)
}
- o1 |= (uint32(r&31) << 5) | uint32(rt&31)
case 28: /* logop $vcon, [R], R (64 bit literal) */
if p.Reg == REGTMP {
@@ -4163,15 +4158,12 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
case 34: /* mov $lacon,R */
o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
- o2 = c.opxrrr(p, AADD, false)
- o2 |= REGTMP & 31 << 16
- o2 |= LSL0_64
- r := int(p.From.Reg)
+ rt, r, rf := p.To.Reg, p.From.Reg, int16(REGTMP)
if r == obj.REG_NONE {
- r = int(o.param)
+ r = o.param
}
- o2 |= uint32(r&31) << 5
- o2 |= uint32(p.To.Reg & 31)
+ o2 = c.opxrrr(p, AADD, rt, r, rf, false)
+ o2 |= LSL0_64
case 35: /* mov SPR,R -> mrs */
o1 = c.oprrr(p, AMRS)
@@ -4608,24 +4600,22 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
o1 = c.omovconst(AMOVD, p, &p.From, REGTMP)
}
- rt := int(p.To.Reg)
+ rt, r, rf := p.To.Reg, p.Reg, int16(REGTMP)
if p.To.Type == obj.TYPE_NONE {
rt = REGZERO
}
- r := int(p.Reg)
if r == obj.REG_NONE {
r = rt
}
- if p.To.Reg == REGSP || r == REGSP {
- o2 = c.opxrrr(p, p.As, false)
- o2 |= REGTMP & 31 << 16
+ if rt == REGSP || r == REGSP {
+ o2 = c.opxrrr(p, p.As, rt, r, rf, false)
o2 |= uint32(lsl0)
} else {
o2 = c.oprrr(p, p.As)
- o2 |= REGTMP & 31 << 16 /* shift is 0 */
+ o2 |= uint32(rf&31) << 16 /* shift is 0 */
+ o2 |= uint32(r&31) << 5
+ o2 |= uint32(rt & 31)
}
- o2 |= uint32(r&31) << 5
- o2 |= uint32(rt & 31)
case 63: /* op Vm.<t>, Vn.<T>, Vd.<T> */
o1 |= c.oprrr(p, p.As)
@@ -4876,21 +4866,18 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
// mov $L, Rtmp (from constant pool)
// add Rtmp, R, Rtmp
// ldp (Rtmp), (R1, R2)
- rf, rt1, rt2 := int(p.From.Reg), p.To.Reg, int16(p.To.Offset)
+ rf, rt1, rt2 := p.From.Reg, p.To.Reg, int16(p.To.Offset)
if rf == REGTMP {
c.ctxt.Diag("REGTMP used in large offset load: %v", p)
}
if rf == obj.REG_NONE {
- rf = int(o.param)
+ rf = o.param
}
if rf == obj.REG_NONE {
c.ctxt.Diag("invalid ldp source: %v", p)
}
o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
- o2 = c.opxrrr(p, AADD, false)
- o2 |= (REGTMP & 31) << 16
- o2 |= uint32(rf&31) << 5
- o2 |= uint32(REGTMP & 31)
+ o2 = c.opxrrr(p, AADD, REGTMP, rf, REGTMP, false)
o3 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1)
case 76:
@@ -4914,21 +4901,18 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
// mov $L, Rtmp (from constant pool)
// add Rtmp, R, Rtmp
// stp (R1, R2), (Rtmp)
- rt, rf1, rf2 := int(p.To.Reg), p.From.Reg, int16(p.From.Offset)
+ rt, rf1, rf2 := p.To.Reg, p.From.Reg, int16(p.From.Offset)
if rt == REGTMP || rf1 == REGTMP || rf2 == REGTMP {
c.ctxt.Diag("REGTMP used in large offset store: %v", p)
}
if rt == obj.REG_NONE {
- rt = int(o.param)
+ rt = o.param
}
if rt == obj.REG_NONE {
c.ctxt.Diag("invalid stp destination: %v", p)
}
o1 = c.omovlit(AMOVD, p, &p.To, REGTMP)
- o2 = c.opxrrr(p, AADD, false)
- o2 |= REGTMP & 31 << 16
- o2 |= uint32(rt&31) << 5
- o2 |= uint32(REGTMP & 31)
+ o2 = c.opxrrr(p, AADD, REGTMP, rt, REGTMP, false)
o3 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0)
case 78: /* vmov R, V.<T>[index] */
@@ -6795,7 +6779,7 @@ func (c *ctxt7) opbit(p *obj.Prog, a obj.As) uint32 {
/*
* add/subtract sign or zero-extended register
*/
-func (c *ctxt7) opxrrr(p *obj.Prog, a obj.As, extend bool) uint32 {
+func (c *ctxt7) opxrrr(p *obj.Prog, a obj.As, rd, rn, rm int16, extend bool) uint32 {
extension := uint32(0)
if !extend {
if isADDop(a) {
@@ -6806,34 +6790,41 @@ func (c *ctxt7) opxrrr(p *obj.Prog, a obj.As, extend bool) uint32 {
}
}
+ var op uint32
+
switch a {
case AADD:
- return S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
+ op = S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
case AADDW:
- return S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
+ op = S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
case ACMN, AADDS:
- return S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
+ op = S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
case ACMNW, AADDSW:
- return S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
+ op = S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
case ASUB:
- return S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
+ op = S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
case ASUBW:
- return S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
+ op = S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
case ACMP, ASUBS:
- return S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
+ op = S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
case ACMPW, ASUBSW:
- return S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
+ op = S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
+
+ default:
+ c.ctxt.Diag("bad opxrrr %v\n%v", a, p)
+ return 0
}
- c.ctxt.Diag("bad opxrrr %v\n%v", a, p)
- return 0
+ op |= uint32(rm&0x1f)<<16 | uint32(rn&0x1f)<<5 | uint32(rd&0x1f)
+
+ return op
}
func (c *ctxt7) opimm(p *obj.Prog, a obj.As) uint32 {