diff options
author | Joel Sing <joel@sing.id.au> | 2023-01-08 03:00:21 +1100 |
---|---|---|
committer | Joel Sing <joel@sing.id.au> | 2023-08-03 16:17:47 +0000 |
commit | 499a12009938fe2ffff90775832b9d67ca3e46b2 (patch) | |
tree | d02d6011e4d47cd1ee39384ff3c392b03f90fb35 | |
parent | 9ff01162295c815c252dec812f6ce983aa90a62b (diff) | |
download | go-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.go | 109 |
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)®_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 { |