mirror of
https://github.com/golang/go
synced 2024-11-05 16:56:16 -07:00
cmd/internal/obj: make arm64 use RegTo2 instead of a full fledged Addr To2
It shrinks Prog type from 448 bytes down to 376 bytes on amd64. It also makes sense, because I don't know of any modern architecture that have instructions which can write to two destinations, none of which is a register (even x86 doesn't have such instructions). Change-Id: I3061f1c9ac93d79ee2b92ecb9049641d0e0f6300 Reviewed-on: https://go-review.googlesource.com/10330 Reviewed-by: Aram Hăvărneanu <aram@mgk.ro> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
4e4c1f9c4d
commit
0f27b91522
@ -493,7 +493,10 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
|
|||||||
if arch.IsARM64STLXR(op) {
|
if arch.IsARM64STLXR(op) {
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.To = a[1]
|
prog.To = a[1]
|
||||||
prog.To2 = a[2]
|
if a[2].Type != obj.TYPE_REG {
|
||||||
|
p.errorf("invalid addressing modes for third operand to %s instruction, must be register", obj.Aconv(op))
|
||||||
|
}
|
||||||
|
prog.RegTo2 = a[2].Reg
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
|
@ -422,9 +422,9 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
|
|||||||
// 7g never generates a from3
|
// 7g never generates a from3
|
||||||
fmt.Printf("copyu: from3 (%v) not implemented\n", gc.Ctxt.Dconv(&p.From3))
|
fmt.Printf("copyu: from3 (%v) not implemented\n", gc.Ctxt.Dconv(&p.From3))
|
||||||
}
|
}
|
||||||
if p.To2.Type != obj.TYPE_NONE {
|
if p.RegTo2 != obj.REG_NONE {
|
||||||
// 7g never generates a to2
|
// 7g never generates a to2
|
||||||
fmt.Printf("copyu: to2 (%v) not implemented\n", gc.Ctxt.Dconv(&p.To2))
|
fmt.Printf("copyu: RegTo2 (%v) not implemented\n", obj.Rconv(int(p.RegTo2)))
|
||||||
}
|
}
|
||||||
|
|
||||||
switch p.As {
|
switch p.As {
|
||||||
|
@ -2677,8 +2677,8 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 59: /* stxr/stlxr */
|
case 59: /* stxr/stlxr */
|
||||||
o1 = opstore(ctxt, int(p.As))
|
o1 = opstore(ctxt, int(p.As))
|
||||||
|
|
||||||
if p.To2.Type != obj.TYPE_NONE {
|
if p.RegTo2 != obj.REG_NONE {
|
||||||
o1 |= uint32(p.To2.Reg&31) << 16
|
o1 |= uint32(p.RegTo2&31) << 16
|
||||||
} else {
|
} else {
|
||||||
o1 |= 0x1F << 16
|
o1 |= 0x1F << 16
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,6 @@ type Prog struct {
|
|||||||
From Addr
|
From Addr
|
||||||
From3 Addr
|
From3 Addr
|
||||||
To Addr
|
To Addr
|
||||||
To2 Addr
|
|
||||||
Opt interface{}
|
Opt interface{}
|
||||||
Forwd *Prog
|
Forwd *Prog
|
||||||
Pcond *Prog
|
Pcond *Prog
|
||||||
@ -217,6 +216,7 @@ type Prog struct {
|
|||||||
Spadj int32
|
Spadj int32
|
||||||
As int16
|
As int16
|
||||||
Reg int16
|
Reg int16
|
||||||
|
RegTo2 int16 // 2nd register output operand
|
||||||
Mark uint16
|
Mark uint16
|
||||||
Optab uint16
|
Optab uint16
|
||||||
Scond uint8
|
Scond uint8
|
||||||
|
@ -327,8 +327,8 @@ func (p *Prog) String() string {
|
|||||||
if p.To.Type != TYPE_NONE {
|
if p.To.Type != TYPE_NONE {
|
||||||
fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.To))
|
fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.To))
|
||||||
}
|
}
|
||||||
if p.To2.Type != TYPE_NONE {
|
if p.RegTo2 != REG_NONE {
|
||||||
fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.To2))
|
fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.RegTo2)))
|
||||||
}
|
}
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
@ -350,9 +350,6 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
if p.From3.Name == obj.NAME_EXTERN {
|
if p.From3.Name == obj.NAME_EXTERN {
|
||||||
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
||||||
}
|
}
|
||||||
if p.To2.Name == obj.NAME_EXTERN {
|
|
||||||
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
|
||||||
}
|
|
||||||
var source *obj.Addr
|
var source *obj.Addr
|
||||||
if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
|
if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
|
||||||
if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
|
if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
|
||||||
|
Loading…
Reference in New Issue
Block a user