Commit c413c45e authored by Russ Cox's avatar Russ Cox

cmd/internal/obj: make Prog.From3 a pointer

It is almost never set and Addr is large, so having the full struct
in the Prog wastes memory most of the time.

Before (on a 64-bit system):

$ sizeof -p cmd/internal/obj Addr Prog
Addr 80
Prog 376
$

After:

$ sizeof -p cmd/internal/obj Addr Prog
Addr 80
Prog 304
$

Change-Id: I491f201241f87543964a7d0f48b85830759be9d0
Reviewed-on: https://go-review.googlesource.com/10457Reviewed-by: default avatarJosh Bleecher Snyder <josharian@gmail.com>
parent 80864cf1
......@@ -151,7 +151,7 @@ func (p *Parser) asmText(word string, operands [][]lex.Token) {
As: obj.ATEXT,
Lineno: p.histLineNum,
From: nameAddr,
From3: obj.Addr{
From3: &obj.Addr{
Type: obj.TYPE_CONST,
Offset: flag,
},
......@@ -205,7 +205,7 @@ func (p *Parser) asmData(word string, operands [][]lex.Token) {
As: obj.ADATA,
Lineno: p.histLineNum,
From: nameAddr,
From3: obj.Addr{
From3: &obj.Addr{
Offset: int64(scale),
},
To: valueAddr,
......@@ -244,7 +244,7 @@ func (p *Parser) asmGlobl(word string, operands [][]lex.Token) {
As: obj.AGLOBL,
Lineno: p.histLineNum,
From: nameAddr,
From3: obj.Addr{
From3: &obj.Addr{
Offset: flag,
},
To: addr,
......@@ -504,7 +504,7 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
prog.To = a[2]
case '6', '8':
prog.From = a[0]
prog.From3 = a[1]
prog.From3 = newAddr(a[1])
prog.To = a[2]
case '9':
if arch.IsPPC64CMP(op) {
......@@ -526,7 +526,7 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
prog.To = a[2]
case obj.TYPE_CONST:
prog.From = a[0]
prog.From3 = a[1]
prog.From3 = newAddr(a[1])
prog.To = a[2]
default:
p.errorf("invalid addressing modes for %s instruction", obj.Aconv(op))
......@@ -551,7 +551,7 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
if p.arch.Thechar == '7' {
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
prog.From3 = a[2]
prog.From3 = newAddr(a[2])
prog.To = a[3]
break
}
......@@ -561,7 +561,7 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
// That is, are there 4-operand instructions without this property?
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
prog.From3 = a[2]
prog.From3 = newAddr(a[2])
prog.To = a[3]
break
}
......@@ -579,7 +579,7 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
} else {
mask = (^uint32(0) >> uint(mask2+1)) & (^uint32(0) << uint(31-(mask1-1)))
}
prog.From3 = obj.Addr{
prog.From3 = &obj.Addr{
Type: obj.TYPE_CONST,
Offset: int64(mask),
}
......@@ -615,6 +615,13 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
p.append(prog, cond, true)
}
// newAddr returns a new(Addr) initialized to x.
func newAddr(x obj.Addr) *obj.Addr {
p := new(obj.Addr)
*p = x
return p
}
var emptyProg obj.Prog
// getConstantPseudo checks that addr represents a plain constant and returns its value.
......
......@@ -418,9 +418,9 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
// can be rewritten independently)
// 0 otherwise (not touched)
func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.From3.Type != obj.TYPE_NONE {
if p.From3Type() != obj.TYPE_NONE {
// 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.RegTo2 != obj.REG_NONE {
// 7g never generates a to2
......
......@@ -214,6 +214,7 @@ func ggloblnod(nam *Node) {
p.To.Sym = nil
p.To.Type = obj.TYPE_CONST
p.To.Offset = nam.Type.Width
p.From3 = new(obj.Addr)
if nam.Name.Readonly {
p.From3.Offset = obj.RODATA
}
......@@ -233,6 +234,7 @@ func ggloblsym(s *Sym, width int32, flags int16) {
}
p.To.Type = obj.TYPE_CONST
p.To.Offset = int64(width)
p.From3 = new(obj.Addr)
p.From3.Offset = int64(flags)
}
......
......@@ -286,6 +286,7 @@ func dstringptr(s *Sym, off int, str string) int {
p.From.Name = obj.NAME_EXTERN
p.From.Sym = Linksym(s)
p.From.Offset = int64(off)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(Widthptr)
......@@ -334,6 +335,7 @@ func dgostrlitptr(s *Sym, off int, lit *string) int {
p.From.Name = obj.NAME_EXTERN
p.From.Sym = Linksym(s)
p.From.Offset = int64(off)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(Widthptr)
datagostring(*lit, &p.To)
......@@ -350,6 +352,7 @@ func dsname(s *Sym, off int, t string) int {
p.From.Name = obj.NAME_EXTERN
p.From.Offset = int64(off)
p.From.Sym = Linksym(s)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(len(t))
......@@ -366,6 +369,7 @@ func dsymptr(s *Sym, off int, x *Sym, xoff int) int {
p.From.Name = obj.NAME_EXTERN
p.From.Sym = Linksym(s)
p.From.Offset = int64(off)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(Widthptr)
p.To.Type = obj.TYPE_ADDR
......@@ -391,6 +395,7 @@ func gdata(nam *Node, nr *Node, wid int) {
}
p := Thearch.Gins(obj.ADATA, nam, nr)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(wid)
}
......@@ -400,12 +405,14 @@ func gdatacomplex(nam *Node, cval *Mpcplx) {
w = int(Types[w].Width)
p := Thearch.Gins(obj.ADATA, nam, nil)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(w)
p.To.Type = obj.TYPE_FCONST
p.To.Val = mpgetflt(&cval.Real)
p = Thearch.Gins(obj.ADATA, nam, nil)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(w)
p.From.Offset += int64(w)
......@@ -418,6 +425,7 @@ func gdatastring(nam *Node, sval string) {
p := Thearch.Gins(obj.ADATA, nam, nil)
Datastring(sval, &p.To)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = Types[Tptr].Width
p.To.Type = obj.TYPE_ADDR
......@@ -427,6 +435,7 @@ func gdatastring(nam *Node, sval string) {
Nodconst(&nod1, Types[TINT], int64(len(sval)))
p = Thearch.Gins(obj.ADATA, nam, &nod1)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(Widthint)
p.From.Offset += int64(Widthptr)
......
......@@ -413,6 +413,7 @@ func compile(fn *Node) {
nam = nil
}
ptxt = Thearch.Gins(obj.ATEXT, nam, &nod1)
ptxt.From3 = new(obj.Addr)
if fn.Func.Dupok {
ptxt.From3.Offset |= obj.DUPOK
}
......
......@@ -1119,7 +1119,7 @@ func regopt(firstp *obj.Prog) {
// Currently we never generate three register forms.
// If we do, this will need to change.
if p.From3.Type != obj.TYPE_NONE {
if p.From3Type() != obj.TYPE_NONE {
Fatal("regopt not implemented for from3")
}
......
......@@ -606,9 +606,9 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
// can be rewritten independently)
// 0 otherwise (not touched)
func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.From3.Type != obj.TYPE_NONE {
if p.From3Type() != obj.TYPE_NONE {
// 9g 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))
}
switch p.As {
......
......@@ -2040,7 +2040,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
rt := int(p.To.Reg)
var r int
var ra int
if p.From3.Type == obj.TYPE_REG {
if p.From3Type() == obj.TYPE_REG {
r = int(p.From3.Reg)
ra = int(p.Reg)
if ra == 0 {
......@@ -2091,7 +2091,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
r := int(p.Reg)
var rf int
if r != 0 {
if p.From3.Type == obj.TYPE_NONE {
if p.From3Type() == obj.TYPE_NONE {
/* CINC/CINV/CNEG */
rf = r
......@@ -2348,7 +2348,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
ctxt.Diag("requires uimm16\n%v", p)
}
s := 0
if p.From3.Type != obj.TYPE_NONE {
if p.From3Type() != obj.TYPE_NONE {
if p.From3.Type != obj.TYPE_CONST {
ctxt.Diag("missing bit position\n%v", p)
}
......@@ -2656,8 +2656,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
ctxt.Diag("implausible condition\n%v", p)
}
rf := int(p.Reg)
if p.From3.Reg < REG_F0 || p.From3.Reg > REG_F31 {
if p.From3 == nil || p.From3.Reg < REG_F0 || p.From3.Reg > REG_F31 {
ctxt.Diag("illegal FCCMP\n%v", p)
break
}
rt := int(p.From3.Reg)
o1 |= uint32(rf&31)<<16 | uint32(cond)<<12 | uint32(rt&31)<<5 | uint32(nzcv)
......
......@@ -55,7 +55,7 @@ func Nopout(p *Prog) {
p.As = ANOP
p.Scond = 0
p.From = Addr{}
p.From3 = Addr{}
p.From3 = nil
p.Reg = 0
p.To = Addr{}
}
......
......@@ -204,7 +204,7 @@ type Prog struct {
Ctxt *Link
Link *Prog
From Addr
From3 Addr
From3 *Addr // optional
To Addr
Opt interface{}
Forwd *Prog
......@@ -231,6 +231,14 @@ type Prog struct {
Info ProgInfo
}
// From3Type returns From3.Type, or TYPE_NONE when From3 is nil.
func (p *Prog) From3Type() int16 {
if p.From3 == nil {
return TYPE_NONE
}
return p.From3.Type
}
// ProgInfo holds information about the instruction for use
// by clients such as the compiler. The exact meaning of this
// data is up to the client and is not interpreted by the cmd/internal/obj/... packages.
......
......@@ -157,7 +157,9 @@ func linkpatch(ctxt *Link, sym *LSym) {
for p := sym.Text; p != nil; p = p.Link {
checkaddr(ctxt, p, &p.From)
checkaddr(ctxt, p, &p.From3)
if p.From3 != nil {
checkaddr(ctxt, p, p.From3)
}
checkaddr(ctxt, p, &p.To)
if ctxt.Arch.Progedit != nil {
......
......@@ -724,10 +724,13 @@ func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
}
a1--
a3 := int(p.From3.Class)
if a3 == 0 {
a3 = aclass(ctxt, &p.From3) + 1
p.From3.Class = int8(a3)
a3 := C_NONE
if p.From3 != nil {
a3 = int(p.From3.Class)
if a3 == 0 {
a3 = aclass(ctxt, p.From3) + 1
p.From3.Class = int8(a3)
}
}
a3--
......@@ -1703,7 +1706,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
if r == 0 {
r = int(p.To.Reg)
}
d := vregoff(ctxt, &p.From3)
d := vregoff(ctxt, p.From3)
var mask [2]uint8
maskgen64(ctxt, p, mask[:], uint64(d))
var a int
......@@ -1916,7 +1919,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
v := regoff(ctxt, &p.From3)
v := regoff(ctxt, p.From3)
r := int(p.From.Reg)
o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
......@@ -1925,7 +1928,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
ctxt.Diag("can't synthesize large constant\n%v", p)
}
v := regoff(ctxt, &p.From3)
v := regoff(ctxt, p.From3)
o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))
o3 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)
......@@ -1938,7 +1941,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
v := regoff(ctxt, &p.From)
d := vregoff(ctxt, &p.From3)
d := vregoff(ctxt, p.From3)
var mask [2]uint8
maskgen64(ctxt, p, mask[:], uint64(d))
var a int
......@@ -1978,7 +1981,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 30: /* rldimi $sh,s,$mask,a */
v := regoff(ctxt, &p.From)
d := vregoff(ctxt, &p.From3)
d := vregoff(ctxt, p.From3)
var mask [2]uint8
maskgen64(ctxt, p, mask[:], uint64(d))
if int32(mask[1]) != (63 - v) {
......@@ -2069,10 +2072,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o1 = uint32(regoff(ctxt, &p.From))
case 41: /* stswi */
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(regoff(ctxt, &p.From3))&0x7F)<<11
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(regoff(ctxt, p.From3))&0x7F)<<11
case 42: /* lswi */
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(regoff(ctxt, &p.From3))&0x7F)<<11
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(regoff(ctxt, p.From3))&0x7F)<<11
case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, uint32(p.From.Index), uint32(p.From.Reg))
......@@ -2242,21 +2245,21 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v := regoff(ctxt, &p.From)
var mask [2]uint8
maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, &p.From3)))
maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, p.From3)))
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.Reg), uint32(p.To.Reg), uint32(v))
o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
case 63: /* rlwmi b,s,$mask,a */
var mask [2]uint8
maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, &p.From3)))
maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, p.From3)))
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg))
o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
case 64: /* mtfsf fr[, $m] {,fpcsr} */
var v int32
if p.From3.Type != obj.TYPE_NONE {
v = regoff(ctxt, &p.From3) & 255
if p.From3Type() != obj.TYPE_NONE {
v = regoff(ctxt, p.From3) & 255
} else {
v = 255
}
......@@ -2307,11 +2310,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 69: /* mtcrf CRM,rS */
var v int32
if p.From3.Type != obj.TYPE_NONE {
if p.From3Type() != obj.TYPE_NONE {
if p.To.Reg != 0 {
ctxt.Diag("can't use both mask and CR(n)\n%v", p)
}
v = regoff(ctxt, &p.From3) & 0xff
v = regoff(ctxt, p.From3) & 0xff
} else {
if p.To.Reg == 0 {
v = 0xff /* CR */
......@@ -2408,7 +2411,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
func vregoff(ctxt *obj.Link, a *obj.Addr) int64 {
ctxt.Instoffset = 0
aclass(ctxt, a)
if a != nil {
aclass(ctxt, a)
}
return ctxt.Instoffset
}
......
......@@ -315,12 +315,12 @@ func (p *Prog) String() string {
fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.Reg)))
sep = ", "
}
if p.From3.Type != TYPE_NONE {
if p.From3Type() != TYPE_NONE {
if p.From3.Type == TYPE_CONST && (p.As == ADATA || p.As == ATEXT || p.As == AGLOBL) {
// Special case - omit $.
fmt.Fprintf(&buf, "%s%d", sep, p.From3.Offset)
} else {
fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.From3))
fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, p.From3))
}
sep = ", "
}
......
......@@ -2945,6 +2945,7 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
// Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX.
// Change encoding generated by assemblers and compilers and remove.
if (p.From.Type == obj.TYPE_CONST || p.From.Type == obj.TYPE_REG) && p.From.Index != REG_NONE && p.From.Scale == 0 {
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_REG
p.From3.Reg = p.From.Index
p.From.Index = 0
......@@ -2954,16 +2955,18 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
// Change encoding generated by assemblers and compilers (if any) and remove.
switch p.As {
case AIMUL3Q, APEXTRW, APINSRW, APINSRD, APINSRQ, APSHUFHW, APSHUFL, APSHUFW, ASHUFPD, ASHUFPS, AAESKEYGENASSIST, APSHUFD, APCLMULQDQ:
if p.From3.Type == obj.TYPE_NONE {
p.From3 = p.From
if p.From3Type() == obj.TYPE_NONE {
p.From3 = new(obj.Addr)
*p.From3 = p.From
p.From = obj.Addr{}
p.From.Type = obj.TYPE_CONST
p.From.Offset = p.To.Offset
p.To.Offset = 0
}
case ACMPSD, ACMPSS, ACMPPS, ACMPPD:
if p.From3.Type == obj.TYPE_NONE {
p.From3 = p.To
if p.From3Type() == obj.TYPE_NONE {
p.From3 = new(obj.Addr)
*p.From3 = p.To
p.To = obj.Addr{}
p.To.Type = obj.TYPE_CONST
p.To.Offset = p.From3.Offset
......@@ -2979,7 +2982,10 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
}
ft := int(p.Ft) * Ymax
f3t := oclass(ctxt, p, &p.From3) * Ymax
f3t := Ynone * Ymax
if p.From3 != nil {
f3t = oclass(ctxt, p, p.From3) * Ymax
}
tt := int(p.Tt) * Ymax
xo := obj.Bool2int(o.op[0] == 0x0f)
......@@ -3153,7 +3159,7 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
case Zm_r_i_xm:
mediaop(ctxt, o, op, int(yt.zoffset), z)
asmand(ctxt, p, &p.From, &p.From3)
asmand(ctxt, p, &p.From, p.From3)
ctxt.Andptr[0] = byte(p.To.Offset)
ctxt.Andptr = ctxt.Andptr[1:]
......@@ -3177,7 +3183,7 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
ctxt.Andptr[0] = byte(op)
ctxt.Andptr = ctxt.Andptr[1:]
}
asmand(ctxt, p, &p.From3, &p.To)
asmand(ctxt, p, p.From3, &p.To)
ctxt.Andptr[0] = byte(p.From.Offset)
ctxt.Andptr = ctxt.Andptr[1:]
......
......@@ -209,7 +209,9 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
}
if ctxt.Headtype == obj.Hnacl && p.Mode == 64 {
nacladdr(ctxt, p, &p.From3)
if p.From3 != nil {
nacladdr(ctxt, p, p.From3)
}
nacladdr(ctxt, p, &p.From)
nacladdr(ctxt, p, &p.To)
}
......@@ -347,7 +349,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
p.From.Offset = 0
}
}
if p.From3.Name == obj.NAME_EXTERN {
if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
ctxt.Diag("don't know how to handle %v with -dynlink", p)
}
var source *obj.Addr
......@@ -715,12 +717,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
if a == obj.NAME_PARAM {
p.From.Offset += int64(deltasp) + int64(pcsize)
}
a = int(p.From3.Name)
if a == obj.NAME_AUTO {
p.From3.Offset += int64(deltasp) - int64(bpsize)
}
if a == obj.NAME_PARAM {
p.From3.Offset += int64(deltasp) + int64(pcsize)
if p.From3 != nil {
a = int(p.From3.Name)
if a == obj.NAME_AUTO {
p.From3.Offset += int64(deltasp) - int64(bpsize)
}
if a == obj.NAME_PARAM {
p.From3.Offset += int64(deltasp) + int64(pcsize)
}
}
a = int(p.To.Name)
if a == obj.NAME_AUTO {
......
......@@ -221,12 +221,16 @@ inst:
{
asm.Settext($2.Sym);
outcode($1, Always, &$2, 0, &$5);
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
}
}
| LTYPEB name ',' con ',' '$' textsize
{
asm.Settext($2.Sym);
outcode($1, Always, &$2, 0, &$7);
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST;
lastpc.From3.Offset = int64($4)
}
......@@ -238,12 +242,16 @@ inst:
{
asm.Settext($2.Sym)
outcode($1, Always, &$2, 0, &$4)
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
}
}
| LGLOBL name ',' con ',' imm
{
asm.Settext($2.Sym)
outcode($1, Always, &$2, 0, &$6)
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = int64($4)
}
......@@ -256,6 +264,7 @@ inst:
{
outcode($1, Always, &$2, 0, &$6)
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = int64($4)
}
......
This diff is collapsed.
......@@ -196,6 +196,7 @@ spec1: /* DATA */
a.to = $6
outcode(obj.ADATA, &a)
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
......@@ -206,12 +207,16 @@ spec2: /* TEXT */
{
asm.Settext($2.Sym);
outcode(obj.ATEXT, &Addr2{from: $2, to: $5})
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
}
}
| LTYPET mem ',' con ',' '$' textsize
{
asm.Settext($2.Sym);
outcode(obj.ATEXT, &Addr2{from: $2, to: $7})
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
......@@ -222,12 +227,16 @@ spec11: /* GLOBL */
{
asm.Settext($2.Sym)
outcode(obj.AGLOBL, &Addr2{from: $2, to: $4})
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
}
}
| LTYPEG mem ',' con ',' imm
{
asm.Settext($2.Sym)
outcode(obj.AGLOBL, &Addr2{from: $2, to: $6})
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
......
......@@ -960,7 +960,10 @@ func outcode(a int, g2 *Addr2) {
p.As = int16(a)
p.Lineno = stmtline
p.From = g2.from
p.From3 = g2.from3
if g2.from3.Type != 0 {
p.From3 = new(obj.Addr)
*p.From3 = g2.from3
}
p.To = g2.to
p.Pc = int64(asm.PC)
......
This diff is collapsed.
......@@ -194,6 +194,7 @@ spec1: /* DATA */
{
outcode(obj.ADATA, &Addr2{$2, $6})
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
......@@ -204,12 +205,16 @@ spec2: /* TEXT */
{
asm.Settext($2.Sym);
outcode(obj.ATEXT, &Addr2{$2, $5})
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
}
}
| LTYPET mem ',' con ',' '$' textsize
{
asm.Settext($2.Sym);
outcode(obj.ATEXT, &Addr2{$2, $7})
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
......@@ -220,12 +225,16 @@ spec8: /* GLOBL */
{
asm.Settext($2.Sym);
outcode(obj.AGLOBL, &Addr2{$2, $4})
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
}
}
| LTYPEG mem ',' con ',' imm
{
asm.Settext($2.Sym);
outcode(obj.AGLOBL, &Addr2{$2, $6})
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
......
This diff is collapsed.
......@@ -630,12 +630,16 @@ inst:
{
asm.Settext($2.Sym);
outcode(int($1), &$2, 0, &$5);
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
}
}
| LTEXT name ',' con ',' '$' textsize
{
asm.Settext($2.Sym);
outcode(int($1), &$2, int($4), &$7);
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
......@@ -647,12 +651,16 @@ inst:
{
asm.Settext($2.Sym)
outcode(int($1), &$2, 0, &$4)
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
}
}
| LGLOBL name ',' con ',' imm
{
asm.Settext($2.Sym)
outcode(int($1), &$2, 0, &$6)
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
......@@ -665,6 +673,7 @@ inst:
{
outcode(int($1), &$2, 0, &$6);
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
......@@ -673,6 +682,7 @@ inst:
{
outcode(int($1), &$2, 0, &$6);
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
......@@ -681,6 +691,7 @@ inst:
{
outcode(int($1), &$2, 0, &$6);
if asm.Pass > 1 {
lastpc.From3 = new(obj.Addr)
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
......
......@@ -536,7 +536,10 @@ func outgcode(a int, g1 *obj.Addr, reg int, g2, g3 *obj.Addr) {
}
p.From = *g1
p.Reg = int16(reg)
p.From3 = *g2
if g2.Type != 0 {
p.From3 = new(obj.Addr)
*p.From3 = *g2
}
p.To = *g3
p.Pc = int64(asm.PC)
......
This diff is collapsed.
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