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